Committed by
Gerrit Code Review
Adding tests for meter service.
Change-Id: Ic220fdaa89b421661019f1a6ef23c7b02eef127c
Showing
14 changed files
with
896 additions
and
77 deletions
... | @@ -22,10 +22,9 @@ import org.onosproject.core.CoreService; | ... | @@ -22,10 +22,9 @@ import org.onosproject.core.CoreService; |
22 | import org.onosproject.net.DeviceId; | 22 | import org.onosproject.net.DeviceId; |
23 | import org.onosproject.net.meter.Band; | 23 | import org.onosproject.net.meter.Band; |
24 | import org.onosproject.net.meter.DefaultBand; | 24 | import org.onosproject.net.meter.DefaultBand; |
25 | -import org.onosproject.net.meter.DefaultMeter; | 25 | +import org.onosproject.net.meter.DefaultMeterRequest; |
26 | import org.onosproject.net.meter.Meter; | 26 | import org.onosproject.net.meter.Meter; |
27 | -import org.onosproject.net.meter.MeterId; | 27 | +import org.onosproject.net.meter.MeterRequest; |
28 | -import org.onosproject.net.meter.MeterOperation; | ||
29 | import org.onosproject.net.meter.MeterService; | 28 | import org.onosproject.net.meter.MeterService; |
30 | 29 | ||
31 | import java.util.Collections; | 30 | import java.util.Collections; |
... | @@ -41,7 +40,7 @@ public class AddMeter extends AbstractShellCommand { | ... | @@ -41,7 +40,7 @@ public class AddMeter extends AbstractShellCommand { |
41 | required = true, multiValued = false) | 40 | required = true, multiValued = false) |
42 | String uri = null; | 41 | String uri = null; |
43 | 42 | ||
44 | - private final String appId = "org.onosproject.cli.addMeter"; | 43 | + private final String appId = "org.onosproject.cli.meterCmd"; |
45 | 44 | ||
46 | @Override | 45 | @Override |
47 | protected void execute() { | 46 | protected void execute() { |
... | @@ -50,25 +49,20 @@ public class AddMeter extends AbstractShellCommand { | ... | @@ -50,25 +49,20 @@ public class AddMeter extends AbstractShellCommand { |
50 | 49 | ||
51 | DeviceId deviceId = DeviceId.deviceId(uri); | 50 | DeviceId deviceId = DeviceId.deviceId(uri); |
52 | 51 | ||
53 | - MeterId meterId = service.allocateMeterId(); | ||
54 | - | ||
55 | Band band = DefaultBand.builder() | 52 | Band band = DefaultBand.builder() |
56 | .ofType(Band.Type.DROP) | 53 | .ofType(Band.Type.DROP) |
57 | .withRate(500) | 54 | .withRate(500) |
58 | .build(); | 55 | .build(); |
59 | 56 | ||
60 | 57 | ||
61 | - Meter meter = DefaultMeter.builder() | 58 | + MeterRequest request = DefaultMeterRequest.builder() |
62 | .forDevice(deviceId) | 59 | .forDevice(deviceId) |
63 | .fromApp(coreService.registerApplication(appId)) | 60 | .fromApp(coreService.registerApplication(appId)) |
64 | - .withId(meterId) | ||
65 | .withUnit(Meter.Unit.KB_PER_SEC) | 61 | .withUnit(Meter.Unit.KB_PER_SEC) |
66 | .withBands(Collections.singleton(band)) | 62 | .withBands(Collections.singleton(band)) |
67 | - .build(); | 63 | + .add(); |
68 | - | ||
69 | - MeterOperation op = new MeterOperation(meter, MeterOperation.Type.ADD, null); | ||
70 | 64 | ||
71 | - service.addMeter(op); | 65 | + service.submit(request); |
72 | 66 | ||
73 | } | 67 | } |
74 | } | 68 | } | ... | ... |
... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.meter; | 16 | package org.onosproject.net.meter; |
17 | 17 | ||
18 | +import com.google.common.base.Objects; | ||
18 | import com.google.common.collect.ImmutableSet; | 19 | import com.google.common.collect.ImmutableSet; |
19 | import org.onosproject.core.ApplicationId; | 20 | import org.onosproject.core.ApplicationId; |
20 | import org.onosproject.net.DeviceId; | 21 | import org.onosproject.net.DeviceId; |
... | @@ -151,6 +152,26 @@ public final class DefaultMeter implements Meter, MeterEntry { | ... | @@ -151,6 +152,26 @@ public final class DefaultMeter implements Meter, MeterEntry { |
151 | .add("bands", bands).toString(); | 152 | .add("bands", bands).toString(); |
152 | } | 153 | } |
153 | 154 | ||
155 | + @Override | ||
156 | + public boolean equals(Object o) { | ||
157 | + if (this == o) { | ||
158 | + return true; | ||
159 | + } | ||
160 | + if (o == null || getClass() != o.getClass()) { | ||
161 | + return false; | ||
162 | + } | ||
163 | + DefaultMeter that = (DefaultMeter) o; | ||
164 | + return Objects.equal(id, that.id) && | ||
165 | + Objects.equal(appId, that.appId) && | ||
166 | + Objects.equal(unit, that.unit) && | ||
167 | + Objects.equal(deviceId, that.deviceId); | ||
168 | + } | ||
169 | + | ||
170 | + @Override | ||
171 | + public int hashCode() { | ||
172 | + return Objects.hashCode(id, appId, unit, deviceId); | ||
173 | + } | ||
174 | + | ||
154 | public static final class Builder implements Meter.Builder { | 175 | public static final class Builder implements Meter.Builder { |
155 | 176 | ||
156 | private MeterId id; | 177 | private MeterId id; | ... | ... |
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.net.meter; | ||
17 | + | ||
18 | +import com.google.common.collect.ImmutableSet; | ||
19 | +import org.onosproject.core.ApplicationId; | ||
20 | +import org.onosproject.net.DeviceId; | ||
21 | + | ||
22 | +import java.util.Collection; | ||
23 | +import java.util.Optional; | ||
24 | + | ||
25 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
26 | +import static com.google.common.base.Preconditions.checkArgument; | ||
27 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
28 | + | ||
29 | +/** | ||
30 | + * A default implementation of a meter. | ||
31 | + */ | ||
32 | +public final class DefaultMeterRequest implements MeterRequest { | ||
33 | + | ||
34 | + | ||
35 | + | ||
36 | + private final ApplicationId appId; | ||
37 | + private final Meter.Unit unit; | ||
38 | + private final boolean burst; | ||
39 | + private final Collection<Band> bands; | ||
40 | + private final DeviceId deviceId; | ||
41 | + private final Optional<MeterContext> context; | ||
42 | + private final Type op; | ||
43 | + | ||
44 | + private DefaultMeterRequest(DeviceId deviceId, ApplicationId appId, | ||
45 | + Meter.Unit unit, boolean burst, | ||
46 | + Collection<Band> bands, MeterContext context, Type op) { | ||
47 | + this.deviceId = deviceId; | ||
48 | + this.appId = appId; | ||
49 | + this.unit = unit; | ||
50 | + this.burst = burst; | ||
51 | + this.bands = bands; | ||
52 | + this.context = Optional.ofNullable(context); | ||
53 | + this.op = op; | ||
54 | + } | ||
55 | + | ||
56 | + @Override | ||
57 | + public DeviceId deviceId() { | ||
58 | + return deviceId; | ||
59 | + } | ||
60 | + | ||
61 | + @Override | ||
62 | + public ApplicationId appId() { | ||
63 | + return appId; | ||
64 | + } | ||
65 | + | ||
66 | + @Override | ||
67 | + public Meter.Unit unit() { | ||
68 | + return unit; | ||
69 | + } | ||
70 | + | ||
71 | + @Override | ||
72 | + public boolean isBurst() { | ||
73 | + return burst; | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public Collection<Band> bands() { | ||
78 | + return bands; | ||
79 | + } | ||
80 | + | ||
81 | + @Override | ||
82 | + public Optional<MeterContext> context() { | ||
83 | + return context; | ||
84 | + } | ||
85 | + | ||
86 | + | ||
87 | + | ||
88 | + public static Builder builder() { | ||
89 | + return new Builder(); | ||
90 | + } | ||
91 | + | ||
92 | + @Override | ||
93 | + public String toString() { | ||
94 | + return toStringHelper(this) | ||
95 | + .add("device", deviceId) | ||
96 | + .add("appId", appId.name()) | ||
97 | + .add("unit", unit) | ||
98 | + .add("isBurst", burst) | ||
99 | + .add("bands", bands).toString(); | ||
100 | + } | ||
101 | + | ||
102 | + public static final class Builder implements MeterRequest.Builder { | ||
103 | + | ||
104 | + private ApplicationId appId; | ||
105 | + private Meter.Unit unit = Meter.Unit.KB_PER_SEC; | ||
106 | + private boolean burst = false; | ||
107 | + private Collection<Band> bands; | ||
108 | + private DeviceId deviceId; | ||
109 | + private MeterContext context; | ||
110 | + | ||
111 | + | ||
112 | + @Override | ||
113 | + public MeterRequest.Builder forDevice(DeviceId deviceId) { | ||
114 | + this.deviceId = deviceId; | ||
115 | + return this; | ||
116 | + } | ||
117 | + | ||
118 | + @Override | ||
119 | + public MeterRequest.Builder fromApp(ApplicationId appId) { | ||
120 | + this.appId = appId; | ||
121 | + return this; | ||
122 | + } | ||
123 | + | ||
124 | + @Override | ||
125 | + public MeterRequest.Builder withUnit(Meter.Unit unit) { | ||
126 | + this.unit = unit; | ||
127 | + return this; | ||
128 | + } | ||
129 | + | ||
130 | + @Override | ||
131 | + public MeterRequest.Builder burst() { | ||
132 | + this.burst = true; | ||
133 | + return this; | ||
134 | + } | ||
135 | + | ||
136 | + @Override | ||
137 | + public MeterRequest.Builder withBands(Collection<Band> bands) { | ||
138 | + this.bands = ImmutableSet.copyOf(bands); | ||
139 | + return this; | ||
140 | + } | ||
141 | + | ||
142 | + @Override | ||
143 | + public MeterRequest.Builder withContext(MeterContext context) { | ||
144 | + this.context = context; | ||
145 | + return this; | ||
146 | + } | ||
147 | + | ||
148 | + @Override | ||
149 | + public MeterRequest add() { | ||
150 | + validate(); | ||
151 | + return new DefaultMeterRequest(deviceId, appId, unit, burst, bands, | ||
152 | + context, Type.ADD); | ||
153 | + } | ||
154 | + | ||
155 | + @Override | ||
156 | + public MeterRequest remove() { | ||
157 | + validate(); | ||
158 | + return new DefaultMeterRequest(deviceId, appId, unit, burst, bands, | ||
159 | + context, Type.REMOVE); | ||
160 | + } | ||
161 | + | ||
162 | + private void validate() { | ||
163 | + checkNotNull(deviceId, "Must specify a device"); | ||
164 | + checkNotNull(bands, "Must have bands."); | ||
165 | + checkArgument(bands.size() > 0, "Must have at least one band."); | ||
166 | + checkNotNull(appId, "Must have an application id"); | ||
167 | + } | ||
168 | + | ||
169 | + | ||
170 | + } | ||
171 | +} |
... | @@ -130,7 +130,7 @@ public interface Meter { | ... | @@ -130,7 +130,7 @@ public interface Meter { |
130 | /** | 130 | /** |
131 | * Assigns the id to this meter. | 131 | * Assigns the id to this meter. |
132 | * | 132 | * |
133 | - * @param id a meter id | 133 | + * @param id a e |
134 | * @return this | 134 | * @return this |
135 | */ | 135 | */ |
136 | Builder withId(MeterId id); | 136 | Builder withId(MeterId id); | ... | ... |
... | @@ -26,7 +26,7 @@ public interface MeterContext { | ... | @@ -26,7 +26,7 @@ public interface MeterContext { |
26 | * | 26 | * |
27 | * @param op a meter | 27 | * @param op a meter |
28 | */ | 28 | */ |
29 | - default void onSuccess(Meter op) {} | 29 | + default void onSuccess(MeterRequest op) {} |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * Invoked when error is encountered while installing a meter. | 32 | * Invoked when error is encountered while installing a meter. |
... | @@ -34,5 +34,5 @@ public interface MeterContext { | ... | @@ -34,5 +34,5 @@ public interface MeterContext { |
34 | * @param op a meter | 34 | * @param op a meter |
35 | * @param reason the reason why it failed | 35 | * @param reason the reason why it failed |
36 | */ | 36 | */ |
37 | - default void onError(Meter op, MeterFailReason reason) {} | 37 | + default void onError(MeterRequest op, MeterFailReason reason) {} |
38 | } | 38 | } | ... | ... |
... | @@ -16,15 +16,13 @@ | ... | @@ -16,15 +16,13 @@ |
16 | package org.onosproject.net.meter; | 16 | package org.onosproject.net.meter; |
17 | 17 | ||
18 | import com.google.common.base.MoreObjects; | 18 | import com.google.common.base.MoreObjects; |
19 | - | 19 | +import com.google.common.base.Objects; |
20 | -import java.util.Optional; | ||
21 | 20 | ||
22 | /** | 21 | /** |
23 | * Representation of an operation on the meter table. | 22 | * Representation of an operation on the meter table. |
24 | */ | 23 | */ |
25 | public class MeterOperation { | 24 | public class MeterOperation { |
26 | 25 | ||
27 | - private final Optional<MeterContext> context; | ||
28 | 26 | ||
29 | /** | 27 | /** |
30 | * Tyoe of meter operation. | 28 | * Tyoe of meter operation. |
... | @@ -39,10 +37,9 @@ public class MeterOperation { | ... | @@ -39,10 +37,9 @@ public class MeterOperation { |
39 | private final Type type; | 37 | private final Type type; |
40 | 38 | ||
41 | 39 | ||
42 | - public MeterOperation(Meter meter, Type type, MeterContext context) { | 40 | + public MeterOperation(Meter meter, Type type) { |
43 | this.meter = meter; | 41 | this.meter = meter; |
44 | this.type = type; | 42 | this.type = type; |
45 | - this.context = Optional.ofNullable(context); | ||
46 | } | 43 | } |
47 | 44 | ||
48 | /** | 45 | /** |
... | @@ -63,16 +60,6 @@ public class MeterOperation { | ... | @@ -63,16 +60,6 @@ public class MeterOperation { |
63 | return meter; | 60 | return meter; |
64 | } | 61 | } |
65 | 62 | ||
66 | - /** | ||
67 | - * Returns a context which allows application to | ||
68 | - * be notified on the success value of this operation. | ||
69 | - * | ||
70 | - * @return a meter context | ||
71 | - */ | ||
72 | - public Optional<MeterContext> context() { | ||
73 | - return this.context; | ||
74 | - } | ||
75 | - | ||
76 | @Override | 63 | @Override |
77 | public String toString() { | 64 | public String toString() { |
78 | return MoreObjects.toStringHelper(this) | 65 | return MoreObjects.toStringHelper(this) |
... | @@ -80,4 +67,22 @@ public class MeterOperation { | ... | @@ -80,4 +67,22 @@ public class MeterOperation { |
80 | .add("type", type) | 67 | .add("type", type) |
81 | .toString(); | 68 | .toString(); |
82 | } | 69 | } |
70 | + | ||
71 | + @Override | ||
72 | + public boolean equals(Object o) { | ||
73 | + if (this == o) { | ||
74 | + return true; | ||
75 | + } | ||
76 | + if (o == null || getClass() != o.getClass()) { | ||
77 | + return false; | ||
78 | + } | ||
79 | + MeterOperation that = (MeterOperation) o; | ||
80 | + return Objects.equal(meter, that.meter) && | ||
81 | + Objects.equal(type, that.type); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public int hashCode() { | ||
86 | + return Objects.hashCode(meter, type); | ||
87 | + } | ||
83 | } | 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.net.meter; | ||
17 | + | ||
18 | +import org.onosproject.core.ApplicationId; | ||
19 | +import org.onosproject.net.DeviceId; | ||
20 | + | ||
21 | +import java.util.Collection; | ||
22 | +import java.util.Optional; | ||
23 | + | ||
24 | +/** | ||
25 | + * Represents a generalized meter request to be deployed on a device. | ||
26 | + */ | ||
27 | +public interface MeterRequest { | ||
28 | + | ||
29 | + enum Type { | ||
30 | + ADD, | ||
31 | + MODIFY, | ||
32 | + REMOVE | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * The target device for this meter. | ||
37 | + * | ||
38 | + * @return a device id | ||
39 | + */ | ||
40 | + DeviceId deviceId(); | ||
41 | + | ||
42 | + /** | ||
43 | + * The id of the application which created this meter. | ||
44 | + * | ||
45 | + * @return an application id | ||
46 | + */ | ||
47 | + ApplicationId appId(); | ||
48 | + | ||
49 | + /** | ||
50 | + * The unit used within this meter. | ||
51 | + * | ||
52 | + * @return the unit | ||
53 | + */ | ||
54 | + Meter.Unit unit(); | ||
55 | + | ||
56 | + /** | ||
57 | + * Signals whether this meter applies to bursts only. | ||
58 | + * | ||
59 | + * @return a boolean | ||
60 | + */ | ||
61 | + boolean isBurst(); | ||
62 | + | ||
63 | + /** | ||
64 | + * The collection of bands to apply on the dataplane. | ||
65 | + * | ||
66 | + * @return a collection of bands. | ||
67 | + */ | ||
68 | + Collection<Band> bands(); | ||
69 | + | ||
70 | + /** | ||
71 | + * Returns the callback context for this meter. | ||
72 | + * | ||
73 | + * @return an optional meter context | ||
74 | + */ | ||
75 | + Optional<MeterContext> context(); | ||
76 | + | ||
77 | + /** | ||
78 | + * A meter builder. | ||
79 | + */ | ||
80 | + interface Builder { | ||
81 | + | ||
82 | + /** | ||
83 | + * Assigns the target device for this meter. | ||
84 | + * | ||
85 | + * @param deviceId a device id | ||
86 | + * @return this | ||
87 | + */ | ||
88 | + Builder forDevice(DeviceId deviceId); | ||
89 | + | ||
90 | + /** | ||
91 | + * Assigns the application that built this meter. | ||
92 | + * | ||
93 | + * @param appId an application id | ||
94 | + * @return this | ||
95 | + */ | ||
96 | + Builder fromApp(ApplicationId appId); | ||
97 | + | ||
98 | + /** | ||
99 | + * Assigns the @See Unit to use for this meter. | ||
100 | + * Defaults to kb/s | ||
101 | + * | ||
102 | + * @param unit a unit | ||
103 | + * @return this | ||
104 | + */ | ||
105 | + Builder withUnit(Meter.Unit unit); | ||
106 | + | ||
107 | + /** | ||
108 | + * Sets this meter as applicable to burst traffic only. | ||
109 | + * Defaults to false. | ||
110 | + * | ||
111 | + * @return this | ||
112 | + */ | ||
113 | + Builder burst(); | ||
114 | + | ||
115 | + /** | ||
116 | + * Assigns bands to this meter. There must be at least one band. | ||
117 | + * | ||
118 | + * @param bands a collection of bands | ||
119 | + * @return this | ||
120 | + */ | ||
121 | + Builder withBands(Collection<Band> bands); | ||
122 | + | ||
123 | + /** | ||
124 | + * Assigns an execution context for this meter request. | ||
125 | + * | ||
126 | + * @param context a meter context | ||
127 | + * @return this | ||
128 | + */ | ||
129 | + Builder withContext(MeterContext context); | ||
130 | + | ||
131 | + /** | ||
132 | + * Requests the addition of a meter. | ||
133 | + * | ||
134 | + * @return a meter request | ||
135 | + */ | ||
136 | + MeterRequest add(); | ||
137 | + | ||
138 | + /** | ||
139 | + * Requests the removal of a meter. | ||
140 | + * | ||
141 | + * @return a meter request | ||
142 | + */ | ||
143 | + MeterRequest remove(); | ||
144 | + | ||
145 | + } | ||
146 | + | ||
147 | +} |
... | @@ -30,23 +30,18 @@ public interface MeterService | ... | @@ -30,23 +30,18 @@ public interface MeterService |
30 | /** | 30 | /** |
31 | * Adds a meter to the system and performs it installation. | 31 | * Adds a meter to the system and performs it installation. |
32 | * | 32 | * |
33 | - * @param meter a meter. | 33 | + * @param meter a meter |
34 | + * @return a meter (with a meter id) | ||
34 | */ | 35 | */ |
35 | - void addMeter(MeterOperation meter); | 36 | + Meter submit(MeterRequest meter); |
36 | - | ||
37 | - /** | ||
38 | - * Updates a meter by adding statistic information to the meter. | ||
39 | - * | ||
40 | - * @param meter an updated meter | ||
41 | - */ | ||
42 | - void updateMeter(MeterOperation meter); | ||
43 | 37 | ||
44 | /** | 38 | /** |
45 | * Remove a meter from the system and the dataplane. | 39 | * Remove a meter from the system and the dataplane. |
46 | * | 40 | * |
47 | * @param meter a meter to remove | 41 | * @param meter a meter to remove |
42 | + * @param meterId the meter id of the meter to remove. | ||
48 | */ | 43 | */ |
49 | - void removeMeter(MeterOperation meter); | 44 | + void withdraw(MeterRequest meter, MeterId meterId); |
50 | 45 | ||
51 | /** | 46 | /** |
52 | * Fetch the meter by the meter id. | 47 | * Fetch the meter by the meter id. |
... | @@ -63,10 +58,4 @@ public interface MeterService | ... | @@ -63,10 +58,4 @@ public interface MeterService |
63 | */ | 58 | */ |
64 | Collection<Meter> getAllMeters(); | 59 | Collection<Meter> getAllMeters(); |
65 | 60 | ||
66 | - /** | ||
67 | - * Allocate a meter id which must be used to create the meter. | ||
68 | - * | ||
69 | - * @return a meter id | ||
70 | - */ | ||
71 | - MeterId allocateMeterId(); | ||
72 | } | 61 | } | ... | ... |
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.net.meter; | ||
17 | + | ||
18 | +import com.google.common.testing.EqualsTester; | ||
19 | +import org.junit.Before; | ||
20 | +import org.junit.Test; | ||
21 | + | ||
22 | +import java.util.Collections; | ||
23 | + | ||
24 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
25 | +import static org.hamcrest.Matchers.is; | ||
26 | +import static org.onosproject.net.NetTestTools.APP_ID; | ||
27 | +import static org.onosproject.net.NetTestTools.did; | ||
28 | + | ||
29 | + | ||
30 | +/** | ||
31 | + * DefaultMeter Tests. | ||
32 | + */ | ||
33 | +public class DefaultMeterTest { | ||
34 | + | ||
35 | + private Meter m1; | ||
36 | + private Meter sameAsm1; | ||
37 | + private Meter m2; | ||
38 | + | ||
39 | + @Before | ||
40 | + public void setup() { | ||
41 | + | ||
42 | + Band band = DefaultBand.builder() | ||
43 | + .ofType(Band.Type.DROP) | ||
44 | + .withRate(500) | ||
45 | + .build(); | ||
46 | + | ||
47 | + m1 = DefaultMeter.builder() | ||
48 | + .forDevice(did("1")) | ||
49 | + .fromApp(APP_ID) | ||
50 | + .withId(MeterId.meterId(1)) | ||
51 | + .withUnit(Meter.Unit.KB_PER_SEC) | ||
52 | + .withBands(Collections.singletonList(band)) | ||
53 | + .build(); | ||
54 | + | ||
55 | + sameAsm1 = DefaultMeter.builder() | ||
56 | + .forDevice(did("1")) | ||
57 | + .fromApp(APP_ID) | ||
58 | + .withId(MeterId.meterId(1)) | ||
59 | + .withUnit(Meter.Unit.KB_PER_SEC) | ||
60 | + .withBands(Collections.singletonList(band)) | ||
61 | + .build(); | ||
62 | + | ||
63 | + m2 = DefaultMeter.builder() | ||
64 | + .forDevice(did("2")) | ||
65 | + .fromApp(APP_ID) | ||
66 | + .withId(MeterId.meterId(2)) | ||
67 | + .withUnit(Meter.Unit.KB_PER_SEC) | ||
68 | + .withBands(Collections.singletonList(band)) | ||
69 | + .build(); | ||
70 | + | ||
71 | + } | ||
72 | + | ||
73 | + @Test | ||
74 | + public void testEquality() { | ||
75 | + new EqualsTester() | ||
76 | + .addEqualityGroup(m1, sameAsm1) | ||
77 | + .addEqualityGroup(m2).testEquals(); | ||
78 | + } | ||
79 | + | ||
80 | + @Test | ||
81 | + public void testConstruction() { | ||
82 | + DefaultMeter m = (DefaultMeter) m1; | ||
83 | + | ||
84 | + assertThat(m.deviceId(), is(did("1"))); | ||
85 | + assertThat(m.appId(), is(APP_ID)); | ||
86 | + assertThat(m.id(), is(MeterId.meterId(1))); | ||
87 | + assertThat(m.isBurst(), is(false)); | ||
88 | + | ||
89 | + assertThat(m.life(), is(0L)); | ||
90 | + assertThat(m.bytesSeen(), is(0L)); | ||
91 | + assertThat(m.packetsSeen(), is(0L)); | ||
92 | + assertThat(m.referenceCount(), is(0L)); | ||
93 | + | ||
94 | + } | ||
95 | + | ||
96 | + | ||
97 | + | ||
98 | + | ||
99 | +} |
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.net.meter; | ||
17 | + | ||
18 | +import com.google.common.testing.EqualsTester; | ||
19 | +import org.junit.Test; | ||
20 | +import org.onosproject.core.ApplicationId; | ||
21 | +import org.onosproject.net.DeviceId; | ||
22 | + | ||
23 | +import java.util.Collection; | ||
24 | + | ||
25 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
26 | +import static org.hamcrest.Matchers.is; | ||
27 | +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass; | ||
28 | + | ||
29 | +/** | ||
30 | + * Unit tests for the MeterOperationTest object. | ||
31 | + */ | ||
32 | +public class MeterOperationTest { | ||
33 | + | ||
34 | + | ||
35 | + | ||
36 | + /** | ||
37 | + * Checks that the MeterOperation class is immutable. | ||
38 | + */ | ||
39 | + @Test | ||
40 | + public void testImmutability() { | ||
41 | + assertThatClassIsImmutableBaseClass(MeterOperation.class); | ||
42 | + } | ||
43 | + | ||
44 | + @Test | ||
45 | + public void testEquality() { | ||
46 | + final Meter m1 = new TestMeter(); | ||
47 | + final Meter m2 = new TestMeter(); | ||
48 | + final MeterOperation op1 = new MeterOperation(m1, | ||
49 | + MeterOperation.Type.ADD); | ||
50 | + final MeterOperation sameAsOp1 = new MeterOperation(m1, | ||
51 | + MeterOperation.Type.ADD); | ||
52 | + final MeterOperation op2 = new MeterOperation(m2, | ||
53 | + MeterOperation.Type.ADD); | ||
54 | + | ||
55 | + new EqualsTester() | ||
56 | + .addEqualityGroup(op1, sameAsOp1) | ||
57 | + .addEqualityGroup(op2) | ||
58 | + .testEquals(); | ||
59 | + } | ||
60 | + | ||
61 | + @Test | ||
62 | + public void testConstruction() { | ||
63 | + final Meter m1 = new TestMeter(); | ||
64 | + | ||
65 | + final MeterOperation op = new MeterOperation(m1, MeterOperation.Type.ADD); | ||
66 | + | ||
67 | + assertThat(op.meter(), is(m1)); | ||
68 | + } | ||
69 | + | ||
70 | + private static final class TestMeter implements Meter { | ||
71 | + | ||
72 | + @Override | ||
73 | + public DeviceId deviceId() { | ||
74 | + return null; | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public MeterId id() { | ||
79 | + return null; | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public ApplicationId appId() { | ||
84 | + return null; | ||
85 | + } | ||
86 | + | ||
87 | + @Override | ||
88 | + public Unit unit() { | ||
89 | + return null; | ||
90 | + } | ||
91 | + | ||
92 | + @Override | ||
93 | + public boolean isBurst() { | ||
94 | + return false; | ||
95 | + } | ||
96 | + | ||
97 | + @Override | ||
98 | + public Collection<Band> bands() { | ||
99 | + return null; | ||
100 | + } | ||
101 | + | ||
102 | + @Override | ||
103 | + public MeterState state() { | ||
104 | + return null; | ||
105 | + } | ||
106 | + | ||
107 | + @Override | ||
108 | + public long life() { | ||
109 | + return 0; | ||
110 | + } | ||
111 | + | ||
112 | + @Override | ||
113 | + public long referenceCount() { | ||
114 | + return 0; | ||
115 | + } | ||
116 | + | ||
117 | + @Override | ||
118 | + public long packetsSeen() { | ||
119 | + return 0; | ||
120 | + } | ||
121 | + | ||
122 | + @Override | ||
123 | + public long bytesSeen() { | ||
124 | + return 0; | ||
125 | + } | ||
126 | + } | ||
127 | + | ||
128 | +} |
... | @@ -21,6 +21,7 @@ import java.util.LinkedList; | ... | @@ -21,6 +21,7 @@ import java.util.LinkedList; |
21 | import java.util.List; | 21 | import java.util.List; |
22 | import java.util.Map; | 22 | import java.util.Map; |
23 | import java.util.Set; | 23 | import java.util.Set; |
24 | +import java.util.concurrent.atomic.AtomicLong; | ||
24 | import java.util.function.BiFunction; | 25 | import java.util.function.BiFunction; |
25 | import java.util.function.Function; | 26 | import java.util.function.Function; |
26 | import java.util.function.Predicate; | 27 | import java.util.function.Predicate; |
... | @@ -38,6 +39,7 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { | ... | @@ -38,6 +39,7 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { |
38 | private final List<MapEventListener<K, V>> listeners; | 39 | private final List<MapEventListener<K, V>> listeners; |
39 | private final HashMap<K, V> map; | 40 | private final HashMap<K, V> map; |
40 | private final String mapName; | 41 | private final String mapName; |
42 | + private final AtomicLong counter = new AtomicLong(0); | ||
41 | 43 | ||
42 | private TestConsistentMap(String mapName) { | 44 | private TestConsistentMap(String mapName) { |
43 | map = new HashMap<>(); | 45 | map = new HashMap<>(); |
... | @@ -46,7 +48,7 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { | ... | @@ -46,7 +48,7 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { |
46 | } | 48 | } |
47 | 49 | ||
48 | private Versioned<V> version(V v) { | 50 | private Versioned<V> version(V v) { |
49 | - return new Versioned<>(v, 1, System.currentTimeMillis()); | 51 | + return new Versioned<>(v, counter.incrementAndGet(), System.currentTimeMillis()); |
50 | } | 52 | } |
51 | 53 | ||
52 | /** | 54 | /** |
... | @@ -115,8 +117,12 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { | ... | @@ -115,8 +117,12 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { |
115 | 117 | ||
116 | @Override | 118 | @Override |
117 | public Versioned<V> put(K key, V value) { | 119 | public Versioned<V> put(K key, V value) { |
118 | - Versioned<V> result = version(map.put(key, value)); | 120 | + Versioned<V> result = version(value); |
121 | + if (map.put(key, value) == null) { | ||
119 | notifyListeners(mapName, INSERT, key, result); | 122 | notifyListeners(mapName, INSERT, key, result); |
123 | + } else { | ||
124 | + notifyListeners(mapName, UPDATE, key, result); | ||
125 | + } | ||
120 | return result; | 126 | return result; |
121 | } | 127 | } |
122 | 128 | ||
... | @@ -213,6 +219,11 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { | ... | @@ -213,6 +219,11 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { |
213 | listeners.remove(listener); | 219 | listeners.remove(listener); |
214 | } | 220 | } |
215 | 221 | ||
222 | + @Override | ||
223 | + public Map<K, V> asJavaMap() { | ||
224 | + return map; | ||
225 | + } | ||
226 | + | ||
216 | public static Builder builder() { | 227 | public static Builder builder() { |
217 | return new Builder(); | 228 | return new Builder(); |
218 | } | 229 | } | ... | ... |
... | @@ -32,6 +32,7 @@ import org.onosproject.net.meter.MeterOperation; | ... | @@ -32,6 +32,7 @@ import org.onosproject.net.meter.MeterOperation; |
32 | import org.onosproject.net.meter.MeterProvider; | 32 | import org.onosproject.net.meter.MeterProvider; |
33 | import org.onosproject.net.meter.MeterProviderRegistry; | 33 | import org.onosproject.net.meter.MeterProviderRegistry; |
34 | import org.onosproject.net.meter.MeterProviderService; | 34 | import org.onosproject.net.meter.MeterProviderService; |
35 | +import org.onosproject.net.meter.MeterRequest; | ||
35 | import org.onosproject.net.meter.MeterService; | 36 | import org.onosproject.net.meter.MeterService; |
36 | import org.onosproject.net.meter.MeterState; | 37 | import org.onosproject.net.meter.MeterState; |
37 | import org.onosproject.net.meter.MeterStore; | 38 | import org.onosproject.net.meter.MeterStore; |
... | @@ -72,7 +73,7 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -72,7 +73,7 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
72 | 73 | ||
73 | private AtomicCounter meterIdCounter; | 74 | private AtomicCounter meterIdCounter; |
74 | 75 | ||
75 | - private TriConsumer<MeterOperation, MeterStoreResult, Throwable> onComplete; | 76 | + private TriConsumer<MeterRequest, MeterStoreResult, Throwable> onComplete; |
76 | 77 | ||
77 | @Activate | 78 | @Activate |
78 | public void activate() { | 79 | public void activate() { |
... | @@ -82,16 +83,16 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -82,16 +83,16 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
82 | 83 | ||
83 | store.setDelegate(delegate); | 84 | store.setDelegate(delegate); |
84 | 85 | ||
85 | - onComplete = (op, result, error) -> | 86 | + onComplete = (request, result, error) -> |
86 | { | 87 | { |
87 | - op.context().ifPresent(c -> { | 88 | + request.context().ifPresent(c -> { |
88 | if (error != null) { | 89 | if (error != null) { |
89 | - c.onError(op.meter(), MeterFailReason.UNKNOWN); | 90 | + c.onError(request, MeterFailReason.UNKNOWN); |
90 | } else { | 91 | } else { |
91 | if (result.reason().isPresent()) { | 92 | if (result.reason().isPresent()) { |
92 | - c.onError(op.meter(), result.reason().get()); | 93 | + c.onError(request, result.reason().get()); |
93 | } else { | 94 | } else { |
94 | - c.onSuccess(op.meter()); | 95 | + c.onSuccess(request); |
95 | } | 96 | } |
96 | } | 97 | } |
97 | }); | 98 | }); |
... | @@ -112,27 +113,42 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -112,27 +113,42 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
112 | } | 113 | } |
113 | 114 | ||
114 | @Override | 115 | @Override |
115 | - public void addMeter(MeterOperation op) { | 116 | + public Meter submit(MeterRequest request) { |
116 | - DefaultMeter m = (DefaultMeter) op.meter(); | 117 | + |
118 | + Meter.Builder mBuilder = DefaultMeter.builder() | ||
119 | + .forDevice(request.deviceId()) | ||
120 | + .fromApp(request.appId()) | ||
121 | + .withBands(request.bands()) | ||
122 | + .withId(allocateMeterId()) | ||
123 | + .withUnit(request.unit()); | ||
124 | + | ||
125 | + if (request.isBurst()) { | ||
126 | + mBuilder.burst(); | ||
127 | + } | ||
128 | + DefaultMeter m = (DefaultMeter) mBuilder.build(); | ||
117 | m.setState(MeterState.PENDING_ADD); | 129 | m.setState(MeterState.PENDING_ADD); |
118 | store.storeMeter(m).whenComplete((result, error) -> | 130 | store.storeMeter(m).whenComplete((result, error) -> |
119 | - onComplete.accept(op, result, error)); | 131 | + onComplete.accept(request, result, error)); |
132 | + return m; | ||
120 | } | 133 | } |
121 | 134 | ||
122 | @Override | 135 | @Override |
123 | - public void updateMeter(MeterOperation op) { | 136 | + public void withdraw(MeterRequest request, MeterId meterId) { |
124 | - DefaultMeter m = (DefaultMeter) op.meter(); | 137 | + Meter.Builder mBuilder = DefaultMeter.builder() |
125 | - m.setState(MeterState.PENDING_ADD); | 138 | + .forDevice(request.deviceId()) |
126 | - store.updateMeter(m).whenComplete((result, error) -> | 139 | + .fromApp(request.appId()) |
127 | - onComplete.accept(op, result, error)); | 140 | + .withBands(request.bands()) |
141 | + .withId(meterId) | ||
142 | + .withUnit(request.unit()); | ||
143 | + | ||
144 | + if (request.isBurst()) { | ||
145 | + mBuilder.burst(); | ||
128 | } | 146 | } |
129 | 147 | ||
130 | - @Override | 148 | + DefaultMeter m = (DefaultMeter) mBuilder.build(); |
131 | - public void removeMeter(MeterOperation op) { | ||
132 | - DefaultMeter m = (DefaultMeter) op.meter(); | ||
133 | m.setState(MeterState.PENDING_REMOVE); | 149 | m.setState(MeterState.PENDING_REMOVE); |
134 | store.deleteMeter(m).whenComplete((result, error) -> | 150 | store.deleteMeter(m).whenComplete((result, error) -> |
135 | - onComplete.accept(op, result, error)); | 151 | + onComplete.accept(request, result, error)); |
136 | } | 152 | } |
137 | 153 | ||
138 | @Override | 154 | @Override |
... | @@ -145,10 +161,9 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -145,10 +161,9 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
145 | return store.getAllMeters(); | 161 | return store.getAllMeters(); |
146 | } | 162 | } |
147 | 163 | ||
148 | - @Override | 164 | + private MeterId allocateMeterId() { |
149 | - public MeterId allocateMeterId() { | ||
150 | // FIXME: This will break one day. | 165 | // FIXME: This will break one day. |
151 | - return MeterId.meterId((int) meterIdCounter.getAndIncrement()); | 166 | + return MeterId.meterId((int) meterIdCounter.incrementAndGet()); |
152 | } | 167 | } |
153 | 168 | ||
154 | private class InternalMeterProviderService | 169 | private class InternalMeterProviderService |
... | @@ -185,8 +200,7 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -185,8 +200,7 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
185 | if (m.state() == MeterState.PENDING_ADD) { | 200 | if (m.state() == MeterState.PENDING_ADD) { |
186 | provider().performMeterOperation(m.deviceId(), | 201 | provider().performMeterOperation(m.deviceId(), |
187 | new MeterOperation(m, | 202 | new MeterOperation(m, |
188 | - MeterOperation.Type.ADD, | 203 | + MeterOperation.Type.ADD)); |
189 | - null)); | ||
190 | } else { | 204 | } else { |
191 | store.deleteMeterNow(m); | 205 | store.deleteMeterNow(m); |
192 | } | 206 | } |
... | @@ -203,13 +217,11 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M | ... | @@ -203,13 +217,11 @@ public class MeterManager extends AbstractListenerProviderRegistry<MeterEvent, M |
203 | switch (event.type()) { | 217 | switch (event.type()) { |
204 | case METER_ADD_REQ: | 218 | case METER_ADD_REQ: |
205 | p.performMeterOperation(deviceId, new MeterOperation(event.subject(), | 219 | p.performMeterOperation(deviceId, new MeterOperation(event.subject(), |
206 | - MeterOperation.Type.ADD, | 220 | + MeterOperation.Type.ADD)); |
207 | - null)); | ||
208 | break; | 221 | break; |
209 | case METER_REM_REQ: | 222 | case METER_REM_REQ: |
210 | p.performMeterOperation(deviceId, new MeterOperation(event.subject(), | 223 | p.performMeterOperation(deviceId, new MeterOperation(event.subject(), |
211 | - MeterOperation.Type.REMOVE, | 224 | + MeterOperation.Type.REMOVE)); |
212 | - null)); | ||
213 | break; | 225 | break; |
214 | default: | 226 | default: |
215 | log.warn("Unknown meter event {}", event.type()); | 227 | log.warn("Unknown meter event {}", event.type()); | ... | ... |
incubator/net/src/test/java/org/onosproject/incubator/net/meter/impl/MeterManagerTest.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.net.meter.impl; | ||
17 | + | ||
18 | +import com.google.common.collect.Maps; | ||
19 | +import com.google.common.collect.Sets; | ||
20 | +import org.junit.After; | ||
21 | +import org.junit.Before; | ||
22 | +import org.junit.Test; | ||
23 | +import org.onlab.junit.TestUtils; | ||
24 | +import org.onlab.packet.IpAddress; | ||
25 | +import org.onosproject.cluster.ClusterServiceAdapter; | ||
26 | +import org.onosproject.cluster.ControllerNode; | ||
27 | +import org.onosproject.cluster.DefaultControllerNode; | ||
28 | +import org.onosproject.cluster.NodeId; | ||
29 | +import org.onosproject.common.event.impl.TestEventDispatcher; | ||
30 | +import org.onosproject.core.ApplicationId; | ||
31 | +import org.onosproject.core.DefaultApplicationId; | ||
32 | +import org.onosproject.incubator.store.meter.impl.DistributedMeterStore; | ||
33 | +import org.onosproject.mastership.MastershipServiceAdapter; | ||
34 | +import org.onosproject.net.DeviceId; | ||
35 | +import org.onosproject.net.meter.Band; | ||
36 | +import org.onosproject.net.meter.DefaultBand; | ||
37 | +import org.onosproject.net.meter.DefaultMeter; | ||
38 | +import org.onosproject.net.meter.DefaultMeterRequest; | ||
39 | +import org.onosproject.net.meter.Meter; | ||
40 | +import org.onosproject.net.meter.MeterId; | ||
41 | +import org.onosproject.net.meter.MeterOperation; | ||
42 | +import org.onosproject.net.meter.MeterOperations; | ||
43 | +import org.onosproject.net.meter.MeterProvider; | ||
44 | +import org.onosproject.net.meter.MeterProviderRegistry; | ||
45 | +import org.onosproject.net.meter.MeterProviderService; | ||
46 | +import org.onosproject.net.meter.MeterRequest; | ||
47 | +import org.onosproject.net.meter.MeterService; | ||
48 | +import org.onosproject.net.meter.MeterState; | ||
49 | +import org.onosproject.net.provider.AbstractProvider; | ||
50 | +import org.onosproject.net.provider.ProviderId; | ||
51 | +import org.onosproject.store.service.TestStorageService; | ||
52 | + | ||
53 | +import java.util.Collections; | ||
54 | +import java.util.Map; | ||
55 | +import java.util.Set; | ||
56 | + | ||
57 | +import static org.hamcrest.Matchers.is; | ||
58 | +import static org.junit.Assert.assertFalse; | ||
59 | +import static org.junit.Assert.assertThat; | ||
60 | +import static org.junit.Assert.assertTrue; | ||
61 | +import static org.onosproject.net.NetTestTools.APP_ID; | ||
62 | +import static org.onosproject.net.NetTestTools.did; | ||
63 | +import static org.onosproject.net.NetTestTools.injectEventDispatcher; | ||
64 | + | ||
65 | +/** | ||
66 | + * Meter manager tests. | ||
67 | + */ | ||
68 | +public class MeterManagerTest { | ||
69 | + | ||
70 | + private static final ProviderId PID = new ProviderId("of", "foo"); | ||
71 | + private static final NodeId NID_LOCAL = new NodeId("local"); | ||
72 | + private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1"); | ||
73 | + | ||
74 | + private MeterService service; | ||
75 | + private MeterManager manager; | ||
76 | + private DistributedMeterStore meterStore; | ||
77 | + private MeterProviderRegistry registry; | ||
78 | + private MeterProviderService providerService; | ||
79 | + | ||
80 | + private TestProvider provider; | ||
81 | + | ||
82 | + private ApplicationId appId; | ||
83 | + | ||
84 | + | ||
85 | + private Meter m1; | ||
86 | + private Meter m2; | ||
87 | + private MeterRequest.Builder m1Request; | ||
88 | + private MeterRequest.Builder m2Request; | ||
89 | + | ||
90 | + private Map<MeterId, Meter> meters = Maps.newHashMap(); | ||
91 | + | ||
92 | + @Before | ||
93 | + public void setup() throws Exception { | ||
94 | + meterStore = new DistributedMeterStore(); | ||
95 | + TestUtils.setField(meterStore, "storageService", new TestStorageService()); | ||
96 | + TestUtils.setField(meterStore, "clusterService", new TestClusterService()); | ||
97 | + TestUtils.setField(meterStore, "mastershipService", new TestMastershipService()); | ||
98 | + meterStore.activate(); | ||
99 | + | ||
100 | + manager = new MeterManager(); | ||
101 | + manager.store = meterStore; | ||
102 | + TestUtils.setField(manager, "storageService", new TestStorageService()); | ||
103 | + injectEventDispatcher(manager, new TestEventDispatcher()); | ||
104 | + service = manager; | ||
105 | + registry = manager; | ||
106 | + | ||
107 | + manager.activate(); | ||
108 | + | ||
109 | + provider = new TestProvider(PID); | ||
110 | + providerService = registry.register(provider); | ||
111 | + | ||
112 | + appId = new TestApplicationId(0, "MeterManagerTest"); | ||
113 | + | ||
114 | + assertTrue("provider should be registered", | ||
115 | + registry.getProviders().contains(provider.id())); | ||
116 | + | ||
117 | + Band band = DefaultBand.builder() | ||
118 | + .ofType(Band.Type.DROP) | ||
119 | + .withRate(500) | ||
120 | + .build(); | ||
121 | + | ||
122 | + m1 = DefaultMeter.builder() | ||
123 | + .forDevice(did("1")) | ||
124 | + .fromApp(APP_ID) | ||
125 | + .withId(MeterId.meterId(1)) | ||
126 | + .withUnit(Meter.Unit.KB_PER_SEC) | ||
127 | + .withBands(Collections.singletonList(band)) | ||
128 | + .build(); | ||
129 | + | ||
130 | + m2 = DefaultMeter.builder() | ||
131 | + .forDevice(did("2")) | ||
132 | + .fromApp(APP_ID) | ||
133 | + .withId(MeterId.meterId(2)) | ||
134 | + .withUnit(Meter.Unit.KB_PER_SEC) | ||
135 | + .withBands(Collections.singletonList(band)) | ||
136 | + .build(); | ||
137 | + | ||
138 | + m1Request = DefaultMeterRequest.builder() | ||
139 | + .forDevice(did("1")) | ||
140 | + .fromApp(APP_ID) | ||
141 | + .withUnit(Meter.Unit.KB_PER_SEC) | ||
142 | + .withBands(Collections.singletonList(band)); | ||
143 | + | ||
144 | + m2Request = DefaultMeterRequest.builder() | ||
145 | + .forDevice(did("2")) | ||
146 | + .fromApp(APP_ID) | ||
147 | + .withUnit(Meter.Unit.KB_PER_SEC) | ||
148 | + .withBands(Collections.singletonList(band)); | ||
149 | + | ||
150 | + | ||
151 | + } | ||
152 | + | ||
153 | + @After | ||
154 | + public void tearDown() { | ||
155 | + registry.unregister(provider); | ||
156 | + assertFalse("provider should not be registered", | ||
157 | + registry.getProviders().contains(provider.id())); | ||
158 | + | ||
159 | + manager.deactivate(); | ||
160 | + injectEventDispatcher(manager, null); | ||
161 | + | ||
162 | + } | ||
163 | + | ||
164 | + @Test | ||
165 | + public void testAddition() { | ||
166 | + manager.submit(m1Request.add()); | ||
167 | + | ||
168 | + assertTrue("The meter was not added", manager.getAllMeters().size() == 1); | ||
169 | + | ||
170 | + assertThat(manager.getMeter(MeterId.meterId(1)), is(m1)); | ||
171 | + } | ||
172 | + | ||
173 | + @Test | ||
174 | + public void testRemove() { | ||
175 | + manager.submit(m1Request.add()); | ||
176 | + manager.withdraw(m1Request.remove(), m1.id()); | ||
177 | + | ||
178 | + assertThat(manager.getMeter(MeterId.meterId(1)).state(), | ||
179 | + is(MeterState.PENDING_REMOVE)); | ||
180 | + | ||
181 | + providerService.pushMeterMetrics(m1.deviceId(), Collections.emptyList()); | ||
182 | + | ||
183 | + assertTrue("The meter was not removed", manager.getAllMeters().size() == 0); | ||
184 | + | ||
185 | + } | ||
186 | + | ||
187 | + | ||
188 | + | ||
189 | + public class TestApplicationId extends DefaultApplicationId { | ||
190 | + public TestApplicationId(int id, String name) { | ||
191 | + super(id, name); | ||
192 | + } | ||
193 | + } | ||
194 | + | ||
195 | + private class TestProvider extends AbstractProvider implements MeterProvider { | ||
196 | + | ||
197 | + protected TestProvider(ProviderId id) { | ||
198 | + super(PID); | ||
199 | + } | ||
200 | + | ||
201 | + @Override | ||
202 | + public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) { | ||
203 | + //Currently unused. | ||
204 | + } | ||
205 | + | ||
206 | + @Override | ||
207 | + public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) { | ||
208 | + meters.put(meterOp.meter().id(), meterOp.meter()); | ||
209 | + } | ||
210 | + } | ||
211 | + | ||
212 | + private final class TestClusterService extends ClusterServiceAdapter { | ||
213 | + | ||
214 | + ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST); | ||
215 | + | ||
216 | + @Override | ||
217 | + public ControllerNode getLocalNode() { | ||
218 | + return local; | ||
219 | + } | ||
220 | + | ||
221 | + @Override | ||
222 | + public Set<ControllerNode> getNodes() { | ||
223 | + return Sets.newHashSet(); | ||
224 | + } | ||
225 | + | ||
226 | + } | ||
227 | + | ||
228 | + private class TestMastershipService extends MastershipServiceAdapter { | ||
229 | + @Override | ||
230 | + public NodeId getMasterFor(DeviceId deviceId) { | ||
231 | + return NID_LOCAL; | ||
232 | + } | ||
233 | + } | ||
234 | +} |
... | @@ -143,7 +143,9 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD | ... | @@ -143,7 +143,9 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD |
143 | // update the state of the meter. It will be pruned by observing | 143 | // update the state of the meter. It will be pruned by observing |
144 | // that it has been removed from the dataplane. | 144 | // that it has been removed from the dataplane. |
145 | try { | 145 | try { |
146 | - meters.put(meter.id(), data); | 146 | + if (meters.computeIfPresent(meter.id(), (k, v) -> data) == null) { |
147 | + future.complete(MeterStoreResult.success()); | ||
148 | + } | ||
147 | } catch (StorageException e) { | 149 | } catch (StorageException e) { |
148 | future.completeExceptionally(e); | 150 | future.completeExceptionally(e); |
149 | } | 151 | } |
... | @@ -159,7 +161,9 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD | ... | @@ -159,7 +161,9 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD |
159 | 161 | ||
160 | MeterData data = new MeterData(meter, null, local); | 162 | MeterData data = new MeterData(meter, null, local); |
161 | try { | 163 | try { |
162 | - meters.put(meter.id(), data); | 164 | + if (meters.computeIfPresent(meter.id(), (k, v) -> data) == null) { |
165 | + future.complete(MeterStoreResult.fail(MeterFailReason.INVALID_METER)); | ||
166 | + } | ||
163 | } catch (StorageException e) { | 167 | } catch (StorageException e) { |
164 | future.completeExceptionally(e); | 168 | future.completeExceptionally(e); |
165 | } | 169 | } |
... | @@ -227,6 +231,10 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD | ... | @@ -227,6 +231,10 @@ public class DistributedMeterStore extends AbstractStore<MeterEvent, MeterStoreD |
227 | } | 231 | } |
228 | break; | 232 | break; |
229 | case ADDED: | 233 | case ADDED: |
234 | + if (local.equals(data.origin()) && data.meter().state() == MeterState.PENDING_ADD) { | ||
235 | + futures.remove(data.meter().id()).complete(MeterStoreResult.success()); | ||
236 | + } | ||
237 | + break; | ||
230 | case REMOVED: | 238 | case REMOVED: |
231 | if (local.equals(data.origin()) && data.meter().state() == MeterState.PENDING_REMOVE) { | 239 | if (local.equals(data.origin()) && data.meter().state() == MeterState.PENDING_REMOVE) { |
232 | futures.remove(data.meter().id()).complete(MeterStoreResult.success()); | 240 | futures.remove(data.meter().id()).complete(MeterStoreResult.success()); | ... | ... |
-
Please register or login to post a comment