alshabib

Initial implementation of Meter Service (needs testing)

Change-Id: Ie07bd3e2bd7c67a6499c965d8926eb361ad16462

store impl started

Change-Id: Ib8b474f40dcecff335a421c12ad149fe9830c427

full implementation

Change-Id: Ie59fd61d02972bd04d887bdcca9745793b880681
...@@ -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 }
......
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
......