Initial implementation of Meter Service (needs testing)
Change-Id: Ie07bd3e2bd7c67a6499c965d8926eb361ad16462 store impl started Change-Id: Ib8b474f40dcecff335a421c12ad149fe9830c427 full implementation Change-Id: Ie59fd61d02972bd04d887bdcca9745793b880681
Showing
16 changed files
with
766 additions
and
56 deletions
... | @@ -69,6 +69,20 @@ public interface Band { | ... | @@ -69,6 +69,20 @@ public interface Band { |
69 | */ | 69 | */ |
70 | Type type(); | 70 | Type type(); |
71 | 71 | ||
72 | + /** | ||
73 | + * Returns the packets seen by this band. | ||
74 | + * | ||
75 | + * @return a long value | ||
76 | + */ | ||
77 | + long packets(); | ||
78 | + | ||
79 | + /** | ||
80 | + * Return the bytes seen by this band. | ||
81 | + * | ||
82 | + * @return a byte counter | ||
83 | + */ | ||
84 | + long bytes(); | ||
85 | + | ||
72 | interface Builder { | 86 | interface Builder { |
73 | 87 | ||
74 | /** | 88 | /** | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.incubator.net.meter; | ||
17 | + | ||
18 | +/** | ||
19 | + * Represents a stored band. | ||
20 | + */ | ||
21 | +public interface BandEntry extends Band { | ||
22 | + | ||
23 | + /** | ||
24 | + * Sets the number of packets seen by this band. | ||
25 | + * | ||
26 | + * @param packets a packet count | ||
27 | + */ | ||
28 | + void setPackets(long packets); | ||
29 | + | ||
30 | + /** | ||
31 | + * Sets the number of bytes seen by this band. | ||
32 | + * | ||
33 | + * @param bytes a byte counter | ||
34 | + */ | ||
35 | + void setBytes(long bytes); | ||
36 | + | ||
37 | +} |
... | @@ -20,12 +20,14 @@ import static com.google.common.base.Preconditions.checkArgument; | ... | @@ -20,12 +20,14 @@ import static com.google.common.base.Preconditions.checkArgument; |
20 | /** | 20 | /** |
21 | * A default implementation for a Band. | 21 | * A default implementation for a Band. |
22 | */ | 22 | */ |
23 | -public final class DefaultBand implements Band { | 23 | +public final class DefaultBand implements Band, BandEntry { |
24 | 24 | ||
25 | private final Type type; | 25 | private final Type type; |
26 | private final long rate; | 26 | private final long rate; |
27 | private final long burstSize; | 27 | private final long burstSize; |
28 | private final short prec; | 28 | private final short prec; |
29 | + private long packets; | ||
30 | + private long bytes; | ||
29 | 31 | ||
30 | public DefaultBand(Type type, long rate, | 32 | public DefaultBand(Type type, long rate, |
31 | long burstSize, short prec) { | 33 | long burstSize, short prec) { |
... | @@ -55,6 +57,26 @@ public final class DefaultBand implements Band { | ... | @@ -55,6 +57,26 @@ public final class DefaultBand implements Band { |
55 | return type; | 57 | return type; |
56 | } | 58 | } |
57 | 59 | ||
60 | + @Override | ||
61 | + public long packets() { | ||
62 | + return packets; | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public long bytes() { | ||
67 | + return bytes; | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public void setPackets(long packets) { | ||
72 | + this.packets = packets; | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public void setBytes(long bytes) { | ||
77 | + this.bytes = bytes; | ||
78 | + } | ||
79 | + | ||
58 | public static Builder builder() { | 80 | public static Builder builder() { |
59 | return new Builder(); | 81 | return new Builder(); |
60 | } | 82 | } |
... | @@ -91,7 +113,7 @@ public final class DefaultBand implements Band { | ... | @@ -91,7 +113,7 @@ public final class DefaultBand implements Band { |
91 | } | 113 | } |
92 | 114 | ||
93 | @Override | 115 | @Override |
94 | - public Band build() { | 116 | + public DefaultBand build() { |
95 | checkArgument(prec != null && type == Type.REMARK, | 117 | checkArgument(prec != null && type == Type.REMARK, |
96 | "Only REMARK bands can have a precendence."); | 118 | "Only REMARK bands can have a precendence."); |
97 | 119 | ... | ... |
... | @@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
28 | /** | 28 | /** |
29 | * A default implementation of a meter. | 29 | * A default implementation of a meter. |
30 | */ | 30 | */ |
31 | -public final class DefaultMeter implements Meter { | 31 | +public final class DefaultMeter implements Meter, MeterEntry { |
32 | 32 | ||
33 | 33 | ||
34 | private final MeterId id; | 34 | private final MeterId id; |
... | @@ -39,6 +39,12 @@ public final class DefaultMeter implements Meter { | ... | @@ -39,6 +39,12 @@ public final class DefaultMeter implements Meter { |
39 | private final DeviceId deviceId; | 39 | private final DeviceId deviceId; |
40 | private final Optional<MeterContext> context; | 40 | private final Optional<MeterContext> context; |
41 | 41 | ||
42 | + private MeterState state; | ||
43 | + private long life; | ||
44 | + private long refCount; | ||
45 | + private long packets; | ||
46 | + private long bytes; | ||
47 | + | ||
42 | private DefaultMeter(DeviceId deviceId, MeterId id, ApplicationId appId, | 48 | private DefaultMeter(DeviceId deviceId, MeterId id, ApplicationId appId, |
43 | Unit unit, boolean burst, | 49 | Unit unit, boolean burst, |
44 | Collection<Band> bands, Optional<MeterContext> context) { | 50 | Collection<Band> bands, Optional<MeterContext> context) { |
... | @@ -86,10 +92,60 @@ public final class DefaultMeter implements Meter { | ... | @@ -86,10 +92,60 @@ public final class DefaultMeter implements Meter { |
86 | return null; | 92 | return null; |
87 | } | 93 | } |
88 | 94 | ||
95 | + @Override | ||
96 | + public MeterState state() { | ||
97 | + return state; | ||
98 | + } | ||
99 | + | ||
100 | + @Override | ||
101 | + public long life() { | ||
102 | + return life; | ||
103 | + } | ||
104 | + | ||
105 | + @Override | ||
106 | + public long referenceCount() { | ||
107 | + return refCount; | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + public long packetsSeen() { | ||
112 | + return packets; | ||
113 | + } | ||
114 | + | ||
115 | + @Override | ||
116 | + public long bytesSeen() { | ||
117 | + return bytes; | ||
118 | + } | ||
119 | + | ||
89 | public static Builder builder() { | 120 | public static Builder builder() { |
90 | return new Builder(); | 121 | return new Builder(); |
91 | } | 122 | } |
92 | 123 | ||
124 | + @Override | ||
125 | + public void setState(MeterState state) { | ||
126 | + this.state = state; | ||
127 | + } | ||
128 | + | ||
129 | + @Override | ||
130 | + public void setLife(long life) { | ||
131 | + this.life = life; | ||
132 | + } | ||
133 | + | ||
134 | + @Override | ||
135 | + public void setReferenceCount(long count) { | ||
136 | + this.refCount = count; | ||
137 | + } | ||
138 | + | ||
139 | + @Override | ||
140 | + public void setProcessedPackets(long packets) { | ||
141 | + this.packets = packets; | ||
142 | + } | ||
143 | + | ||
144 | + @Override | ||
145 | + public void setProcessedBytes(long bytes) { | ||
146 | + this.bytes = bytes; | ||
147 | + } | ||
148 | + | ||
93 | public static final class Builder implements Meter.Builder { | 149 | public static final class Builder implements Meter.Builder { |
94 | 150 | ||
95 | private MeterId id; | 151 | private MeterId id; |
... | @@ -108,7 +164,7 @@ public final class DefaultMeter implements Meter { | ... | @@ -108,7 +164,7 @@ public final class DefaultMeter implements Meter { |
108 | } | 164 | } |
109 | 165 | ||
110 | @Override | 166 | @Override |
111 | - public Meter.Builder withId(int id) { | 167 | + public Meter.Builder withId(long id) { |
112 | this.id = MeterId.meterId(id); | 168 | this.id = MeterId.meterId(id); |
113 | return this; | 169 | return this; |
114 | } | 170 | } |
... | @@ -144,7 +200,7 @@ public final class DefaultMeter implements Meter { | ... | @@ -144,7 +200,7 @@ public final class DefaultMeter implements Meter { |
144 | } | 200 | } |
145 | 201 | ||
146 | @Override | 202 | @Override |
147 | - public Meter build() { | 203 | + public DefaultMeter build() { |
148 | checkNotNull(deviceId, "Must specify a device"); | 204 | checkNotNull(deviceId, "Must specify a device"); |
149 | checkNotNull(bands, "Must have bands."); | 205 | checkNotNull(bands, "Must have bands."); |
150 | checkArgument(bands.size() > 0, "Must have at least one band."); | 206 | checkArgument(bands.size() > 0, "Must have at least one band."); | ... | ... |
... | @@ -89,6 +89,41 @@ public interface Meter { | ... | @@ -89,6 +89,41 @@ public interface Meter { |
89 | Optional<MeterContext> context(); | 89 | Optional<MeterContext> context(); |
90 | 90 | ||
91 | /** | 91 | /** |
92 | + * Fetches the state of this meter. | ||
93 | + * | ||
94 | + * @return a meter state | ||
95 | + */ | ||
96 | + MeterState state(); | ||
97 | + | ||
98 | + /** | ||
99 | + * The lifetime in seconds of this meter. | ||
100 | + * | ||
101 | + * @return number of seconds | ||
102 | + */ | ||
103 | + long life(); | ||
104 | + | ||
105 | + /** | ||
106 | + * The number of flows pointing to this meter. | ||
107 | + * | ||
108 | + * @return a reference count | ||
109 | + */ | ||
110 | + long referenceCount(); | ||
111 | + | ||
112 | + /** | ||
113 | + * Number of packets processed by this meter. | ||
114 | + * | ||
115 | + * @return a packet count | ||
116 | + */ | ||
117 | + long packetsSeen(); | ||
118 | + | ||
119 | + /** | ||
120 | + * Number of bytes processed by this meter. | ||
121 | + * | ||
122 | + * @return a byte count | ||
123 | + */ | ||
124 | + long bytesSeen(); | ||
125 | + | ||
126 | + /** | ||
92 | * A meter builder. | 127 | * A meter builder. |
93 | */ | 128 | */ |
94 | interface Builder { | 129 | interface Builder { |
... | @@ -104,10 +139,10 @@ public interface Meter { | ... | @@ -104,10 +139,10 @@ public interface Meter { |
104 | /** | 139 | /** |
105 | * Assigns the id to this meter. | 140 | * Assigns the id to this meter. |
106 | * | 141 | * |
107 | - * @param id an integer | 142 | + * @param id a long |
108 | * @return this | 143 | * @return this |
109 | */ | 144 | */ |
110 | - Builder withId(int id); | 145 | + Builder withId(long id); |
111 | 146 | ||
112 | /** | 147 | /** |
113 | * Assigns the application that built this meter. | 148 | * Assigns the application that built this meter. | ... | ... |
... | @@ -34,6 +34,5 @@ public interface MeterContext { | ... | @@ -34,6 +34,5 @@ public interface MeterContext { |
34 | * @param op a meter operation | 34 | * @param op a meter operation |
35 | * @param reason the reason why it failed | 35 | * @param reason the reason why it failed |
36 | */ | 36 | */ |
37 | - default void onError(MeterOperation op, MeterFailReason reason) { | 37 | + default void onError(MeterOperation op, MeterFailReason reason) {} |
38 | - } | ||
39 | } | 38 | } | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.incubator.net.meter; | ||
17 | + | ||
18 | +/** | ||
19 | + * Represents a stored meter. | ||
20 | + */ | ||
21 | +public interface MeterEntry extends Meter { | ||
22 | + | ||
23 | + /** | ||
24 | + * Updates the state of this meter. | ||
25 | + * | ||
26 | + * @param state a meter state | ||
27 | + */ | ||
28 | + void setState(MeterState state); | ||
29 | + | ||
30 | + /** | ||
31 | + * Set the amount of time the meter has existed in seconds. | ||
32 | + * | ||
33 | + * @param life number of seconds | ||
34 | + */ | ||
35 | + void setLife(long life); | ||
36 | + | ||
37 | + /** | ||
38 | + * Sets the number of flows which are using this meter. | ||
39 | + * | ||
40 | + * @param count a reference count. | ||
41 | + */ | ||
42 | + void setReferenceCount(long count); | ||
43 | + | ||
44 | + /** | ||
45 | + * Updates the number of packets seen by this meter. | ||
46 | + * | ||
47 | + * @param packets a packet count. | ||
48 | + */ | ||
49 | + void setProcessedPackets(long packets); | ||
50 | + | ||
51 | + /** | ||
52 | + * Updates the number of bytes seen by the meter. | ||
53 | + * | ||
54 | + * @param bytes a byte counter. | ||
55 | + */ | ||
56 | + void setProcessedBytes(long bytes); | ||
57 | +} |
... | @@ -20,20 +20,12 @@ import org.onosproject.event.AbstractEvent; | ... | @@ -20,20 +20,12 @@ import org.onosproject.event.AbstractEvent; |
20 | /** | 20 | /** |
21 | * Entity that represents Meter events. | 21 | * Entity that represents Meter events. |
22 | */ | 22 | */ |
23 | -public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> { | 23 | +public class MeterEvent extends AbstractEvent<MeterEvent.Type, MeterOperation> { |
24 | 24 | ||
25 | 25 | ||
26 | - enum Type { | 26 | + private final MeterFailReason reason; |
27 | 27 | ||
28 | - /** | 28 | + public enum Type { |
29 | - * Signals that a new meter has been added. | ||
30 | - */ | ||
31 | - METER_ADDED, | ||
32 | - | ||
33 | - /** | ||
34 | - * Signals that a meter has been removed. | ||
35 | - */ | ||
36 | - METER_REMOVED, | ||
37 | 29 | ||
38 | /** | 30 | /** |
39 | * Signals that a meter has been added. | 31 | * Signals that a meter has been added. |
... | @@ -41,19 +33,15 @@ public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> { | ... | @@ -41,19 +33,15 @@ public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> { |
41 | METER_UPDATED, | 33 | METER_UPDATED, |
42 | 34 | ||
43 | /** | 35 | /** |
44 | - * Signals that a meter addition failed. | 36 | + * Signals that a meter update failed. |
45 | */ | 37 | */ |
46 | - METER_ADD_FAILED, | 38 | + METER_OP_FAILED, |
47 | 39 | ||
48 | /** | 40 | /** |
49 | - * Signals that a meter removal failed. | 41 | + * A meter operation was requested. |
50 | */ | 42 | */ |
51 | - METER_REMOVE_FAILED, | 43 | + METER_OP_REQ, |
52 | 44 | ||
53 | - /** | ||
54 | - * Signals that a meter update failed. | ||
55 | - */ | ||
56 | - METER_UPDATE_FAILED | ||
57 | } | 45 | } |
58 | 46 | ||
59 | 47 | ||
... | @@ -62,21 +50,32 @@ public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> { | ... | @@ -62,21 +50,32 @@ public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> { |
62 | * current time. | 50 | * current time. |
63 | * | 51 | * |
64 | * @param type meter event type | 52 | * @param type meter event type |
65 | - * @param meter event subject | 53 | + * @param op event subject |
66 | */ | 54 | */ |
67 | - public MeterEvent(Type type, Meter meter) { | 55 | + public MeterEvent(Type type, MeterOperation op) { |
68 | - super(type, meter); | 56 | + super(type, op); |
57 | + this.reason = null; | ||
69 | } | 58 | } |
70 | 59 | ||
71 | /** | 60 | /** |
72 | * Creates an event of a given type and for the specified meter and time. | 61 | * Creates an event of a given type and for the specified meter and time. |
73 | * | 62 | * |
74 | * @param type meter event type | 63 | * @param type meter event type |
75 | - * @param meter event subject | 64 | + * @param op event subject |
76 | * @param time occurrence time | 65 | * @param time occurrence time |
77 | */ | 66 | */ |
78 | - public MeterEvent(Type type, Meter meter, long time) { | 67 | + public MeterEvent(Type type, MeterOperation op, long time) { |
79 | - super(type, meter, time); | 68 | + super(type, op, time); |
69 | + this.reason = null; | ||
70 | + } | ||
71 | + | ||
72 | + public MeterEvent(Type type, MeterOperation op, MeterFailReason reason) { | ||
73 | + super(type, op); | ||
74 | + this.reason = reason; | ||
75 | + } | ||
76 | + | ||
77 | + public MeterFailReason reason() { | ||
78 | + return reason; | ||
80 | } | 79 | } |
81 | 80 | ||
82 | } | 81 | } | ... | ... |
... | @@ -19,19 +19,19 @@ import static com.google.common.base.Preconditions.checkArgument; | ... | @@ -19,19 +19,19 @@ import static com.google.common.base.Preconditions.checkArgument; |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * A representation of a meter id. | 21 | * A representation of a meter id. |
22 | - * Uniquely identifies a meter for a given device. | 22 | + * Uniquely identifies a meter system wide. |
23 | */ | 23 | */ |
24 | public final class MeterId { | 24 | public final class MeterId { |
25 | 25 | ||
26 | static final long MAX = 0xFFFF0000; | 26 | static final long MAX = 0xFFFF0000; |
27 | 27 | ||
28 | - private final int id; | 28 | + private final long id; |
29 | 29 | ||
30 | public static final MeterId SLOWPATH = new MeterId(0xFFFFFFFD); | 30 | public static final MeterId SLOWPATH = new MeterId(0xFFFFFFFD); |
31 | public static final MeterId CONTROLLER = new MeterId(0xFFFFFFFE); | 31 | public static final MeterId CONTROLLER = new MeterId(0xFFFFFFFE); |
32 | public static final MeterId ALL = new MeterId(0xFFFFFFFF); | 32 | public static final MeterId ALL = new MeterId(0xFFFFFFFF); |
33 | 33 | ||
34 | - private MeterId(int id) { | 34 | + private MeterId(long id) { |
35 | checkArgument(id <= MAX, "id cannot be larger than 0xFFFF0000"); | 35 | checkArgument(id <= MAX, "id cannot be larger than 0xFFFF0000"); |
36 | this.id = id; | 36 | this.id = id; |
37 | } | 37 | } |
... | @@ -39,9 +39,9 @@ public final class MeterId { | ... | @@ -39,9 +39,9 @@ public final class MeterId { |
39 | /** | 39 | /** |
40 | * The integer representation of the meter id. | 40 | * The integer representation of the meter id. |
41 | * | 41 | * |
42 | - * @return an integer | 42 | + * @return a long |
43 | */ | 43 | */ |
44 | - public int id() { | 44 | + public long id() { |
45 | return id; | 45 | return id; |
46 | } | 46 | } |
47 | 47 | ||
... | @@ -62,10 +62,10 @@ public final class MeterId { | ... | @@ -62,10 +62,10 @@ public final class MeterId { |
62 | 62 | ||
63 | @Override | 63 | @Override |
64 | public int hashCode() { | 64 | public int hashCode() { |
65 | - return id; | 65 | + return Long.hashCode(id); |
66 | } | 66 | } |
67 | 67 | ||
68 | - public static MeterId meterId(int id) { | 68 | + public static MeterId meterId(long id) { |
69 | return new MeterId(id); | 69 | return new MeterId(id); |
70 | 70 | ||
71 | } | 71 | } | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.incubator.net.meter; | ||
17 | + | ||
18 | +/** | ||
19 | + * Represents the state of the meter as seen by the store. | ||
20 | + */ | ||
21 | +public enum MeterState { | ||
22 | + | ||
23 | + /** | ||
24 | + * The meter is in the process of being added. | ||
25 | + */ | ||
26 | + PENDING_ADD, | ||
27 | + | ||
28 | + /** | ||
29 | + * THe meter has been added. | ||
30 | + */ | ||
31 | + ADDED, | ||
32 | + | ||
33 | + /** | ||
34 | + * The meter is in the process of being removed. | ||
35 | + */ | ||
36 | + PENDING_REMOVE, | ||
37 | + | ||
38 | + /** | ||
39 | + * The meter has been removed. | ||
40 | + */ | ||
41 | + REMOVED, | ||
42 | + | ||
43 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.incubator.net.meter; | ||
17 | + | ||
18 | +import org.onosproject.store.Store; | ||
19 | + | ||
20 | +import java.util.Collection; | ||
21 | + | ||
22 | +/** | ||
23 | + * Entity that stores and distributed meter objects. | ||
24 | + */ | ||
25 | +public interface MeterStore extends Store<MeterEvent, MeterStoreDelegate> { | ||
26 | + | ||
27 | + /** | ||
28 | + * Adds a meter to the store. | ||
29 | + * | ||
30 | + * @param meter a meter | ||
31 | + */ | ||
32 | + void storeMeter(Meter meter); | ||
33 | + | ||
34 | + /** | ||
35 | + * Deletes a meter from the store. | ||
36 | + * | ||
37 | + * @param meter a meter | ||
38 | + */ | ||
39 | + void deleteMeter(Meter meter); | ||
40 | + | ||
41 | + /** | ||
42 | + * Updates a meter whose meter id is the same as the passed meter. | ||
43 | + * | ||
44 | + * @param meter a new meter | ||
45 | + */ | ||
46 | + void updateMeter(Meter meter); | ||
47 | + | ||
48 | + /** | ||
49 | + * Updates a given meter's state with the provided state. | ||
50 | + * @param meter a meter | ||
51 | + */ | ||
52 | + void updateMeterState(Meter meter); | ||
53 | + | ||
54 | + /** | ||
55 | + * Obtains a meter matching the given meter id. | ||
56 | + * | ||
57 | + * @param meterId a meter id | ||
58 | + * @return a meter | ||
59 | + */ | ||
60 | + Meter getMeter(MeterId meterId); | ||
61 | + | ||
62 | + /** | ||
63 | + * Returns all meters stored in the store. | ||
64 | + * | ||
65 | + * @return a collection of meters | ||
66 | + */ | ||
67 | + Collection<Meter> getAllMeters(); | ||
68 | + | ||
69 | + /** | ||
70 | + * Update the store by deleting the failed meter. | ||
71 | + * Notifies the delegate that the meter failed to allow it | ||
72 | + * to nofity the app. | ||
73 | + * | ||
74 | + * @param op a failed meter operation | ||
75 | + * @param reason a failure reason | ||
76 | + */ | ||
77 | + void failedMeter(MeterOperation op, MeterFailReason reason); | ||
78 | +} |
... | @@ -21,6 +21,7 @@ import org.apache.felix.scr.annotations.Deactivate; | ... | @@ -21,6 +21,7 @@ import org.apache.felix.scr.annotations.Deactivate; |
21 | import org.apache.felix.scr.annotations.Reference; | 21 | import org.apache.felix.scr.annotations.Reference; |
22 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 22 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
23 | import org.apache.felix.scr.annotations.Service; | 23 | import org.apache.felix.scr.annotations.Service; |
24 | +import org.onosproject.incubator.net.meter.DefaultMeter; | ||
24 | import org.onosproject.incubator.net.meter.Meter; | 25 | import org.onosproject.incubator.net.meter.Meter; |
25 | import org.onosproject.incubator.net.meter.MeterEvent; | 26 | import org.onosproject.incubator.net.meter.MeterEvent; |
26 | import org.onosproject.incubator.net.meter.MeterFailReason; | 27 | import org.onosproject.incubator.net.meter.MeterFailReason; |
... | @@ -31,6 +32,8 @@ import org.onosproject.incubator.net.meter.MeterProvider; | ... | @@ -31,6 +32,8 @@ import org.onosproject.incubator.net.meter.MeterProvider; |
31 | import org.onosproject.incubator.net.meter.MeterProviderRegistry; | 32 | import org.onosproject.incubator.net.meter.MeterProviderRegistry; |
32 | import org.onosproject.incubator.net.meter.MeterProviderService; | 33 | import org.onosproject.incubator.net.meter.MeterProviderService; |
33 | import org.onosproject.incubator.net.meter.MeterService; | 34 | import org.onosproject.incubator.net.meter.MeterService; |
35 | +import org.onosproject.incubator.net.meter.MeterState; | ||
36 | +import org.onosproject.incubator.net.meter.MeterStore; | ||
34 | import org.onosproject.incubator.net.meter.MeterStoreDelegate; | 37 | import org.onosproject.incubator.net.meter.MeterStoreDelegate; |
35 | import org.onosproject.net.DeviceId; | 38 | import org.onosproject.net.DeviceId; |
36 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; | 39 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; |
... | @@ -41,6 +44,7 @@ import org.slf4j.Logger; | ... | @@ -41,6 +44,7 @@ import org.slf4j.Logger; |
41 | 44 | ||
42 | import java.util.Collection; | 45 | import java.util.Collection; |
43 | 46 | ||
47 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
44 | import static org.slf4j.LoggerFactory.getLogger; | 48 | import static org.slf4j.LoggerFactory.getLogger; |
45 | 49 | ||
46 | 50 | ||
... | @@ -60,6 +64,9 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -60,6 +64,9 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
60 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 64 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
61 | protected StorageService storageService; | 65 | protected StorageService storageService; |
62 | 66 | ||
67 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
68 | + MeterStore store; | ||
69 | + | ||
63 | private AtomicCounter meterIdCounter; | 70 | private AtomicCounter meterIdCounter; |
64 | 71 | ||
65 | @Activate | 72 | @Activate |
... | @@ -82,27 +89,35 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -82,27 +89,35 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
82 | 89 | ||
83 | @Override | 90 | @Override |
84 | public void addMeter(Meter meter) { | 91 | public void addMeter(Meter meter) { |
85 | - | 92 | + DefaultMeter m = (DefaultMeter) meter; |
93 | + m.setState(MeterState.PENDING_ADD); | ||
94 | + store.storeMeter(m); | ||
86 | } | 95 | } |
87 | 96 | ||
88 | @Override | 97 | @Override |
89 | public void updateMeter(Meter meter) { | 98 | public void updateMeter(Meter meter) { |
90 | - | 99 | + DefaultMeter m = (DefaultMeter) meter; |
100 | + m.setState(MeterState.PENDING_ADD); | ||
101 | + store.updateMeter(m); | ||
91 | } | 102 | } |
92 | 103 | ||
93 | @Override | 104 | @Override |
94 | public void removeMeter(Meter meter) { | 105 | public void removeMeter(Meter meter) { |
95 | - | 106 | + DefaultMeter m = (DefaultMeter) meter; |
107 | + m.setState(MeterState.PENDING_REMOVE); | ||
108 | + store.deleteMeter(m); | ||
96 | } | 109 | } |
97 | 110 | ||
98 | @Override | 111 | @Override |
99 | public void removeMeter(MeterId id) { | 112 | public void removeMeter(MeterId id) { |
100 | - | 113 | + DefaultMeter meter = (DefaultMeter) store.getMeter(id); |
114 | + checkNotNull(meter, "No such meter {}", id); | ||
115 | + removeMeter(meter); | ||
101 | } | 116 | } |
102 | 117 | ||
103 | @Override | 118 | @Override |
104 | public Meter getMeter(MeterId id) { | 119 | public Meter getMeter(MeterId id) { |
105 | - return null; | 120 | + return store.getMeter(id); |
106 | } | 121 | } |
107 | 122 | ||
108 | @Override | 123 | @Override |
... | @@ -125,13 +140,14 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -125,13 +140,14 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
125 | } | 140 | } |
126 | 141 | ||
127 | @Override | 142 | @Override |
128 | - public void meterOperationFailed(MeterOperation operation, MeterFailReason reason) { | 143 | + public void meterOperationFailed(MeterOperation operation, |
129 | - | 144 | + MeterFailReason reason) { |
145 | + store.failedMeter(operation, reason); | ||
130 | } | 146 | } |
131 | 147 | ||
132 | @Override | 148 | @Override |
133 | public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) { | 149 | public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) { |
134 | - | 150 | + meterEntries.forEach(m -> store.updateMeterState(m)); |
135 | } | 151 | } |
136 | } | 152 | } |
137 | 153 | ||
... | @@ -139,6 +155,21 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -139,6 +155,21 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
139 | 155 | ||
140 | @Override | 156 | @Override |
141 | public void notify(MeterEvent event) { | 157 | public void notify(MeterEvent event) { |
158 | + DeviceId deviceId = event.subject().meter().deviceId(); | ||
159 | + MeterProvider p = getProvider(event.subject().meter().deviceId()); | ||
160 | + switch (event.type()) { | ||
161 | + case METER_UPDATED: | ||
162 | + break; | ||
163 | + case METER_OP_FAILED: | ||
164 | + event.subject().meter().context().ifPresent(c -> | ||
165 | + c.onError(event.subject(), event.reason())); | ||
166 | + break; | ||
167 | + case METER_OP_REQ: | ||
168 | + p.performMeterOperation(deviceId, event.subject()); | ||
169 | + break; | ||
170 | + default: | ||
171 | + log.warn("Unknown meter event {}", event.type()); | ||
172 | + } | ||
142 | 173 | ||
143 | } | 174 | } |
144 | } | 175 | } | ... | ... |
incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.incubator.store.meter.impl; | ||
17 | + | ||
18 | +import org.apache.felix.scr.annotations.Activate; | ||
19 | +import org.apache.felix.scr.annotations.Deactivate; | ||
20 | +import org.apache.felix.scr.annotations.Property; | ||
21 | +import org.apache.felix.scr.annotations.Reference; | ||
22 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
23 | +import org.onlab.util.KryoNamespace; | ||
24 | +import org.onlab.util.Tools; | ||
25 | +import org.onosproject.cluster.ClusterService; | ||
26 | +import org.onosproject.cluster.NodeId; | ||
27 | +import org.onosproject.incubator.net.meter.DefaultBand; | ||
28 | +import org.onosproject.incubator.net.meter.DefaultMeter; | ||
29 | +import org.onosproject.incubator.net.meter.Meter; | ||
30 | +import org.onosproject.incubator.net.meter.MeterEvent; | ||
31 | +import org.onosproject.incubator.net.meter.MeterFailReason; | ||
32 | +import org.onosproject.incubator.net.meter.MeterId; | ||
33 | +import org.onosproject.incubator.net.meter.MeterOperation; | ||
34 | +import org.onosproject.incubator.net.meter.MeterStore; | ||
35 | +import org.onosproject.incubator.net.meter.MeterStoreDelegate; | ||
36 | +import org.onosproject.mastership.MastershipService; | ||
37 | +import org.onosproject.store.AbstractStore; | ||
38 | +import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
39 | +import org.onosproject.store.cluster.messaging.MessageSubject; | ||
40 | +import org.onosproject.store.service.ConsistentMap; | ||
41 | +import org.onosproject.store.service.Serializer; | ||
42 | +import org.onosproject.store.service.StorageService; | ||
43 | +import org.slf4j.Logger; | ||
44 | + | ||
45 | +import java.util.Collection; | ||
46 | +import java.util.Objects; | ||
47 | +import java.util.concurrent.ExecutorService; | ||
48 | +import java.util.concurrent.Executors; | ||
49 | +import java.util.stream.Collectors; | ||
50 | + | ||
51 | +import static org.slf4j.LoggerFactory.getLogger; | ||
52 | + | ||
53 | +/** | ||
54 | + * A distributed meter store implementation. Meters are stored consistently | ||
55 | + * across the cluster. | ||
56 | + */ | ||
57 | +public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreDelegate> | ||
58 | + implements MeterStore { | ||
59 | + | ||
60 | + private Logger log = getLogger(getClass()); | ||
61 | + | ||
62 | + private static final String METERSTORE = "onos-meter-store"; | ||
63 | + private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8; | ||
64 | + | ||
65 | + private static final MessageSubject UPDATE_METER = new MessageSubject("peer-mod-meter"); | ||
66 | + | ||
67 | + | ||
68 | + @Property(name = "msgHandlerPoolSize", intValue = MESSAGE_HANDLER_THREAD_POOL_SIZE, | ||
69 | + label = "Number of threads in the message handler pool") | ||
70 | + private int msgPoolSize; | ||
71 | + | ||
72 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
73 | + private StorageService storageService; | ||
74 | + | ||
75 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
76 | + private ClusterCommunicationService clusterCommunicationService; | ||
77 | + | ||
78 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
79 | + private MastershipService mastershipService; | ||
80 | + | ||
81 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
82 | + private ClusterService clusterService; | ||
83 | + | ||
84 | + private ConsistentMap<MeterId, Meter> meters; | ||
85 | + private NodeId local; | ||
86 | + private KryoNamespace kryoNameSpace; | ||
87 | + | ||
88 | + private Serializer serializer; | ||
89 | + | ||
90 | + @Activate | ||
91 | + public void activate() { | ||
92 | + | ||
93 | + local = clusterService.getLocalNode().id(); | ||
94 | + | ||
95 | + kryoNameSpace = | ||
96 | + KryoNamespace.newBuilder() | ||
97 | + .register(DefaultMeter.class) | ||
98 | + .register(DefaultBand.class) | ||
99 | + .build(); | ||
100 | + | ||
101 | + serializer = Serializer.using(kryoNameSpace); | ||
102 | + | ||
103 | + meters = storageService.<MeterId, Meter>consistentMapBuilder() | ||
104 | + .withName(METERSTORE) | ||
105 | + .withSerializer(serializer) | ||
106 | + .build(); | ||
107 | + | ||
108 | + ExecutorService executors = Executors.newFixedThreadPool( | ||
109 | + msgPoolSize, Tools.groupedThreads("onos/store/meter", "message-handlers")); | ||
110 | + registerMessageHandlers(executors); | ||
111 | + | ||
112 | + log.info("Started"); | ||
113 | + } | ||
114 | + | ||
115 | + @Deactivate | ||
116 | + public void deactivate() { | ||
117 | + | ||
118 | + | ||
119 | + log.info("Stopped"); | ||
120 | + } | ||
121 | + | ||
122 | + private void registerMessageHandlers(ExecutorService executor) { | ||
123 | + clusterCommunicationService.<MeterEvent>addSubscriber(UPDATE_METER, kryoNameSpace::deserialize, | ||
124 | + this::notifyDelegate, executor); | ||
125 | + | ||
126 | + } | ||
127 | + | ||
128 | + | ||
129 | + @Override | ||
130 | + public void storeMeter(Meter meter) { | ||
131 | + NodeId master = mastershipService.getMasterFor(meter.deviceId()); | ||
132 | + | ||
133 | + meters.put(meter.id(), meter); | ||
134 | + | ||
135 | + MeterEvent event = new MeterEvent(MeterEvent.Type.METER_OP_REQ, | ||
136 | + new MeterOperation(meter, MeterOperation.Type.ADD)); | ||
137 | + if (Objects.equals(local, master)) { | ||
138 | + notifyDelegate(event); | ||
139 | + } else { | ||
140 | + clusterCommunicationService.unicast( | ||
141 | + event, | ||
142 | + UPDATE_METER, | ||
143 | + serializer::encode, | ||
144 | + master | ||
145 | + ).whenComplete((result, error) -> { | ||
146 | + if (error != null) { | ||
147 | + log.warn("Failed to install meter {} because {} on {}", | ||
148 | + meter, error, master); | ||
149 | + | ||
150 | + // notify app of failure | ||
151 | + meter.context().ifPresent(c -> c.onError( | ||
152 | + event.subject(), MeterFailReason.UNKNOWN)); | ||
153 | + } | ||
154 | + }); | ||
155 | + } | ||
156 | + | ||
157 | + } | ||
158 | + | ||
159 | + @Override | ||
160 | + public void deleteMeter(Meter meter) { | ||
161 | + | ||
162 | + NodeId master = mastershipService.getMasterFor(meter.deviceId()); | ||
163 | + | ||
164 | + // update the state of the meter. It will be pruned by observing | ||
165 | + // that it has been removed from the dataplane. | ||
166 | + meters.put(meter.id(), meter); | ||
167 | + | ||
168 | + MeterEvent event = new MeterEvent(MeterEvent.Type.METER_OP_REQ, | ||
169 | + new MeterOperation(meter, MeterOperation.Type.REMOVE)); | ||
170 | + if (Objects.equals(local, master)) { | ||
171 | + notifyDelegate(event); | ||
172 | + } else { | ||
173 | + clusterCommunicationService.unicast( | ||
174 | + event, | ||
175 | + UPDATE_METER, | ||
176 | + serializer::encode, | ||
177 | + master | ||
178 | + ).whenComplete((result, error) -> { | ||
179 | + if (error != null) { | ||
180 | + log.warn("Failed to delete meter {} because {} on {}", | ||
181 | + meter, error, master); | ||
182 | + | ||
183 | + // notify app of failure | ||
184 | + meter.context().ifPresent(c -> c.onError( | ||
185 | + event.subject(), MeterFailReason.UNKNOWN)); | ||
186 | + } | ||
187 | + }); | ||
188 | + } | ||
189 | + | ||
190 | + } | ||
191 | + | ||
192 | + @Override | ||
193 | + public void updateMeter(Meter meter) { | ||
194 | + | ||
195 | + NodeId master = mastershipService.getMasterFor(meter.deviceId()); | ||
196 | + | ||
197 | + meters.put(meter.id(), meter); | ||
198 | + | ||
199 | + MeterEvent event = new MeterEvent(MeterEvent.Type.METER_OP_REQ, | ||
200 | + new MeterOperation(meter, MeterOperation.Type.MODIFY)); | ||
201 | + if (Objects.equals(local, master)) { | ||
202 | + notifyDelegate(event); | ||
203 | + } else { | ||
204 | + clusterCommunicationService.unicast( | ||
205 | + event, | ||
206 | + UPDATE_METER, | ||
207 | + serializer::encode, | ||
208 | + master | ||
209 | + ).whenComplete((result, error) -> { | ||
210 | + if (error != null) { | ||
211 | + log.warn("Failed to update meter {} because {} on {}", | ||
212 | + meter, error, master); | ||
213 | + | ||
214 | + // notify app of failure | ||
215 | + meter.context().ifPresent(c -> c.onError( | ||
216 | + event.subject(), MeterFailReason.UNKNOWN)); | ||
217 | + } | ||
218 | + }); | ||
219 | + } | ||
220 | + | ||
221 | + } | ||
222 | + | ||
223 | + @Override | ||
224 | + public void updateMeterState(Meter meter) { | ||
225 | + meters.compute(meter.id(), (id, v) -> { | ||
226 | + DefaultMeter m = (DefaultMeter) v; | ||
227 | + m.setState(meter.state()); | ||
228 | + m.setProcessedPackets(meter.packetsSeen()); | ||
229 | + m.setProcessedBytes(meter.bytesSeen()); | ||
230 | + m.setLife(meter.life()); | ||
231 | + m.setReferenceCount(meter.referenceCount()); | ||
232 | + return m; | ||
233 | + }); | ||
234 | + } | ||
235 | + | ||
236 | + @Override | ||
237 | + public Meter getMeter(MeterId meterId) { | ||
238 | + return meters.get(meterId).value(); | ||
239 | + } | ||
240 | + | ||
241 | + @Override | ||
242 | + public Collection<Meter> getAllMeters() { | ||
243 | + return meters.values().stream() | ||
244 | + .map(v -> v.value()).collect(Collectors.toSet()); | ||
245 | + } | ||
246 | + | ||
247 | + @Override | ||
248 | + public void failedMeter(MeterOperation op, MeterFailReason reason) { | ||
249 | + NodeId master = mastershipService.getMasterFor(op.meter().deviceId()); | ||
250 | + meters.remove(op.meter().id()); | ||
251 | + | ||
252 | + MeterEvent event = new MeterEvent(MeterEvent.Type.METER_OP_FAILED, op, reason); | ||
253 | + if (Objects.equals(local, master)) { | ||
254 | + notifyDelegate(event); | ||
255 | + } else { | ||
256 | + clusterCommunicationService.unicast( | ||
257 | + event, | ||
258 | + UPDATE_METER, | ||
259 | + serializer::encode, | ||
260 | + master | ||
261 | + ).whenComplete((result, error) -> { | ||
262 | + if (error != null) { | ||
263 | + log.warn("Failed to delete failed meter {} because {} on {}", | ||
264 | + op.meter(), error, master); | ||
265 | + | ||
266 | + // Can't do any more... | ||
267 | + } | ||
268 | + }); | ||
269 | + } | ||
270 | + | ||
271 | + } | ||
272 | + | ||
273 | +} |
... | @@ -46,7 +46,7 @@ public final class MeterModBuilder { | ... | @@ -46,7 +46,7 @@ public final class MeterModBuilder { |
46 | private final OFFactory factory; | 46 | private final OFFactory factory; |
47 | private Meter.Unit unit = Meter.Unit.KB_PER_SEC; | 47 | private Meter.Unit unit = Meter.Unit.KB_PER_SEC; |
48 | private boolean burst = false; | 48 | private boolean burst = false; |
49 | - private Integer id; | 49 | + private Long id; |
50 | private Collection<Band> bands; | 50 | private Collection<Band> bands; |
51 | 51 | ||
52 | public MeterModBuilder(long xid, OFFactory factory) { | 52 | public MeterModBuilder(long xid, OFFactory factory) { | ... | ... |
... | @@ -20,7 +20,6 @@ package org.onosproject.provider.of.meter.impl; | ... | @@ -20,7 +20,6 @@ package org.onosproject.provider.of.meter.impl; |
20 | import com.google.common.cache.Cache; | 20 | import com.google.common.cache.Cache; |
21 | import com.google.common.cache.CacheBuilder; | 21 | import com.google.common.cache.CacheBuilder; |
22 | import com.google.common.cache.RemovalCause; | 22 | import com.google.common.cache.RemovalCause; |
23 | - | ||
24 | import com.google.common.cache.RemovalNotification; | 23 | import com.google.common.cache.RemovalNotification; |
25 | import com.google.common.collect.Maps; | 24 | import com.google.common.collect.Maps; |
26 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
... | @@ -28,7 +27,10 @@ import org.apache.felix.scr.annotations.Component; | ... | @@ -28,7 +27,10 @@ import org.apache.felix.scr.annotations.Component; |
28 | import org.apache.felix.scr.annotations.Deactivate; | 27 | import org.apache.felix.scr.annotations.Deactivate; |
29 | import org.apache.felix.scr.annotations.Reference; | 28 | import org.apache.felix.scr.annotations.Reference; |
30 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 29 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
31 | -import org.onosproject.net.DeviceId; | 30 | +import org.onosproject.core.CoreService; |
31 | +import org.onosproject.incubator.net.meter.Band; | ||
32 | +import org.onosproject.incubator.net.meter.DefaultBand; | ||
33 | +import org.onosproject.incubator.net.meter.DefaultMeter; | ||
32 | import org.onosproject.incubator.net.meter.Meter; | 34 | import org.onosproject.incubator.net.meter.Meter; |
33 | import org.onosproject.incubator.net.meter.MeterFailReason; | 35 | import org.onosproject.incubator.net.meter.MeterFailReason; |
34 | import org.onosproject.incubator.net.meter.MeterOperation; | 36 | import org.onosproject.incubator.net.meter.MeterOperation; |
... | @@ -36,6 +38,8 @@ import org.onosproject.incubator.net.meter.MeterOperations; | ... | @@ -36,6 +38,8 @@ import org.onosproject.incubator.net.meter.MeterOperations; |
36 | import org.onosproject.incubator.net.meter.MeterProvider; | 38 | import org.onosproject.incubator.net.meter.MeterProvider; |
37 | import org.onosproject.incubator.net.meter.MeterProviderRegistry; | 39 | import org.onosproject.incubator.net.meter.MeterProviderRegistry; |
38 | import org.onosproject.incubator.net.meter.MeterProviderService; | 40 | import org.onosproject.incubator.net.meter.MeterProviderService; |
41 | +import org.onosproject.incubator.net.meter.MeterState; | ||
42 | +import org.onosproject.net.DeviceId; | ||
39 | import org.onosproject.net.provider.AbstractProvider; | 43 | import org.onosproject.net.provider.AbstractProvider; |
40 | import org.onosproject.net.provider.ProviderId; | 44 | import org.onosproject.net.provider.ProviderId; |
41 | import org.onosproject.openflow.controller.Dpid; | 45 | import org.onosproject.openflow.controller.Dpid; |
... | @@ -47,15 +51,23 @@ import org.onosproject.openflow.controller.RoleState; | ... | @@ -47,15 +51,23 @@ import org.onosproject.openflow.controller.RoleState; |
47 | import org.projectfloodlight.openflow.protocol.OFErrorMsg; | 51 | import org.projectfloodlight.openflow.protocol.OFErrorMsg; |
48 | import org.projectfloodlight.openflow.protocol.OFErrorType; | 52 | import org.projectfloodlight.openflow.protocol.OFErrorType; |
49 | import org.projectfloodlight.openflow.protocol.OFMessage; | 53 | import org.projectfloodlight.openflow.protocol.OFMessage; |
54 | +import org.projectfloodlight.openflow.protocol.OFMeterBandStats; | ||
55 | +import org.projectfloodlight.openflow.protocol.OFMeterConfigStatsReply; | ||
56 | +import org.projectfloodlight.openflow.protocol.OFMeterStats; | ||
57 | +import org.projectfloodlight.openflow.protocol.OFMeterStatsReply; | ||
50 | import org.projectfloodlight.openflow.protocol.OFPortStatus; | 58 | import org.projectfloodlight.openflow.protocol.OFPortStatus; |
51 | import org.projectfloodlight.openflow.protocol.OFStatsReply; | 59 | import org.projectfloodlight.openflow.protocol.OFStatsReply; |
60 | +import org.projectfloodlight.openflow.protocol.OFStatsType; | ||
52 | import org.projectfloodlight.openflow.protocol.OFVersion; | 61 | import org.projectfloodlight.openflow.protocol.OFVersion; |
53 | import org.projectfloodlight.openflow.protocol.errormsg.OFMeterModFailedErrorMsg; | 62 | import org.projectfloodlight.openflow.protocol.errormsg.OFMeterModFailedErrorMsg; |
54 | import org.slf4j.Logger; | 63 | import org.slf4j.Logger; |
55 | 64 | ||
65 | +import java.util.Collection; | ||
66 | +import java.util.List; | ||
56 | import java.util.Map; | 67 | import java.util.Map; |
57 | import java.util.concurrent.TimeUnit; | 68 | import java.util.concurrent.TimeUnit; |
58 | import java.util.concurrent.atomic.AtomicLong; | 69 | import java.util.concurrent.atomic.AtomicLong; |
70 | +import java.util.stream.Collectors; | ||
59 | 71 | ||
60 | import static org.slf4j.LoggerFactory.getLogger; | 72 | import static org.slf4j.LoggerFactory.getLogger; |
61 | 73 | ||
... | @@ -74,6 +86,9 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv | ... | @@ -74,6 +86,9 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv |
74 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 86 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
75 | protected MeterProviderRegistry providerRegistry; | 87 | protected MeterProviderRegistry providerRegistry; |
76 | 88 | ||
89 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
90 | + protected CoreService coreService; | ||
91 | + | ||
77 | private MeterProviderService providerService; | 92 | private MeterProviderService providerService; |
78 | 93 | ||
79 | private static final AtomicLong XID_COUNTER = new AtomicLong(1); | 94 | private static final AtomicLong XID_COUNTER = new AtomicLong(1); |
... | @@ -81,8 +96,7 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv | ... | @@ -81,8 +96,7 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv |
81 | static final int POLL_INTERVAL = 10; | 96 | static final int POLL_INTERVAL = 10; |
82 | static final long TIMEOUT = 30; | 97 | static final long TIMEOUT = 30; |
83 | 98 | ||
84 | - private Cache<Integer, MeterOperation> pendingOperations; | 99 | + private Cache<Long, MeterOperation> pendingOperations; |
85 | - private Cache<Long, MeterOperation> pendingXid; | ||
86 | 100 | ||
87 | 101 | ||
88 | private InternalMeterListener listener = new InternalMeterListener(); | 102 | private InternalMeterListener listener = new InternalMeterListener(); |
... | @@ -101,7 +115,7 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv | ... | @@ -101,7 +115,7 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv |
101 | 115 | ||
102 | pendingOperations = CacheBuilder.newBuilder() | 116 | pendingOperations = CacheBuilder.newBuilder() |
103 | .expireAfterWrite(TIMEOUT, TimeUnit.SECONDS) | 117 | .expireAfterWrite(TIMEOUT, TimeUnit.SECONDS) |
104 | - .removalListener((RemovalNotification<Integer, MeterOperation> notification) -> { | 118 | + .removalListener((RemovalNotification<Long, MeterOperation> notification) -> { |
105 | if (notification.getCause() == RemovalCause.EXPIRED) { | 119 | if (notification.getCause() == RemovalCause.EXPIRED) { |
106 | providerService.meterOperationFailed(notification.getValue(), | 120 | providerService.meterOperationFailed(notification.getValue(), |
107 | MeterFailReason.TIMEOUT); | 121 | MeterFailReason.TIMEOUT); |
... | @@ -149,6 +163,8 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv | ... | @@ -149,6 +163,8 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv |
149 | return; | 163 | return; |
150 | } | 164 | } |
151 | 165 | ||
166 | + performOperation(sw, meterOp); | ||
167 | + | ||
152 | } | 168 | } |
153 | 169 | ||
154 | private void performOperation(OpenFlowSwitch sw, MeterOperation op) { | 170 | private void performOperation(OpenFlowSwitch sw, MeterOperation op) { |
... | @@ -203,7 +219,57 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv | ... | @@ -203,7 +219,57 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv |
203 | } | 219 | } |
204 | 220 | ||
205 | private void pushMeterStats(Dpid dpid, OFStatsReply msg) { | 221 | private void pushMeterStats(Dpid dpid, OFStatsReply msg) { |
222 | + DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid)); | ||
223 | + | ||
224 | + if (msg.getStatsType() == OFStatsType.METER) { | ||
225 | + OFMeterStatsReply reply = (OFMeterStatsReply) msg; | ||
226 | + Collection<Meter> meters = buildMeters(deviceId, reply.getEntries()); | ||
227 | + //TODO do meter accounting here. | ||
228 | + providerService.pushMeterMetrics(deviceId, meters); | ||
229 | + } else if (msg.getStatsType() == OFStatsType.METER_CONFIG) { | ||
230 | + OFMeterConfigStatsReply reply = (OFMeterConfigStatsReply) msg; | ||
231 | + // FIXME: Map<Long, Meter> meters = collectMeters(deviceId, reply); | ||
232 | + } | ||
233 | + | ||
234 | + } | ||
235 | + | ||
236 | + private Map<Long, Meter> collectMeters(DeviceId deviceId, | ||
237 | + OFMeterConfigStatsReply reply) { | ||
238 | + return Maps.newHashMap(); | ||
239 | + //TODO: Needs a fix to be applied to loxi MeterConfig stat is incorrect | ||
240 | + } | ||
241 | + | ||
242 | + private Collection<Meter> buildMeters(DeviceId deviceId, | ||
243 | + List<OFMeterStats> entries) { | ||
244 | + return entries.stream().map(stat -> { | ||
245 | + DefaultMeter.Builder builder = DefaultMeter.builder(); | ||
246 | + Collection<Band> bands = buildBands(stat.getBandStats()); | ||
247 | + builder.forDevice(deviceId) | ||
248 | + .withId(stat.getMeterId()) | ||
249 | + //FIXME: need to encode appId in meter id, but that makes | ||
250 | + // things a little annoying for debugging | ||
251 | + .fromApp(coreService.getAppId("org.onosproject.core")) | ||
252 | + .withBands(bands); | ||
253 | + DefaultMeter meter = builder.build(); | ||
254 | + meter.setState(MeterState.ADDED); | ||
255 | + meter.setLife(stat.getDurationSec()); | ||
256 | + meter.setProcessedBytes(stat.getByteInCount().getValue()); | ||
257 | + meter.setProcessedPackets(stat.getPacketInCount().getValue()); | ||
258 | + meter.setReferenceCount(stat.getFlowCount()); | ||
259 | + | ||
260 | + // marks the meter as seen on the dataplane | ||
261 | + pendingOperations.invalidate(stat.getMeterId()); | ||
262 | + return meter; | ||
263 | + }).collect(Collectors.toSet()); | ||
264 | + } | ||
206 | 265 | ||
266 | + private Collection<Band> buildBands(List<OFMeterBandStats> bandStats) { | ||
267 | + return bandStats.stream().map(stat -> { | ||
268 | + DefaultBand band = DefaultBand.builder().build(); | ||
269 | + band.setBytes(stat.getByteBandCount().getValue()); | ||
270 | + band.setPackets(stat.getPacketBandCount().getValue()); | ||
271 | + return band; | ||
272 | + }).collect(Collectors.toSet()); | ||
207 | } | 273 | } |
208 | 274 | ||
209 | private void signalMeterError(OFMeterModFailedErrorMsg meterError, | 275 | private void signalMeterError(OFMeterModFailedErrorMsg meterError, | ... | ... |
... | @@ -29,4 +29,4 @@ fi | ... | @@ -29,4 +29,4 @@ fi |
29 | 29 | ||
30 | set -x | 30 | set -x |
31 | 31 | ||
32 | -ssh $ONOS_USER@$node /tmp/$ONOS_BITS/bin/onos-form-cluster -u $user -p $password $nodes | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
32 | +ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-form-cluster -u $user -p $password $nodes | ... | ... |
-
Please register or login to post a comment