Committed by
Gerrit Code Review
Adding tests for meter service.
Change-Id: Ic220fdaa89b421661019f1a6ef23c7b02eef127c
Showing
14 changed files
with
898 additions
and
79 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); |
| 119 | - notifyListeners(mapName, INSERT, key, result); | 121 | + if (map.put(key, value) == null) { |
| 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()) |
| 128 | - } | 141 | + .withId(meterId) |
| 142 | + .withUnit(request.unit()); | ||
| 143 | + | ||
| 144 | + if (request.isBurst()) { | ||
| 145 | + mBuilder.burst(); | ||
| 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