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