Committed by
Gerrit Code Review
Made OpticalPathProvisioner to store connectivity data in distributed store. (ONOS-4518)
Change-Id: I7f9ef02cab4aa1848c8926d2e88478e035076c99
Showing
8 changed files
with
661 additions
and
270 deletions
| ... | @@ -89,6 +89,12 @@ | ... | @@ -89,6 +89,12 @@ |
| 89 | </dependency> | 89 | </dependency> |
| 90 | 90 | ||
| 91 | <dependency> | 91 | <dependency> |
| 92 | + <groupId>org.onosproject</groupId> | ||
| 93 | + <artifactId>onos-core-serializers</artifactId> | ||
| 94 | + <version>${project.version}</version> | ||
| 95 | + </dependency> | ||
| 96 | + | ||
| 97 | + <dependency> | ||
| 92 | <groupId>com.google.guava</groupId> | 98 | <groupId>com.google.guava</groupId> |
| 93 | <artifactId>guava-testlib</artifactId> | 99 | <artifactId>guava-testlib</artifactId> |
| 94 | <scope>test</scope> | 100 | <scope>test</scope> | ... | ... |
| ... | @@ -22,14 +22,14 @@ import org.onlab.util.Bandwidth; | ... | @@ -22,14 +22,14 @@ import org.onlab.util.Bandwidth; |
| 22 | import org.onosproject.newoptical.api.OpticalConnectivityId; | 22 | import org.onosproject.newoptical.api.OpticalConnectivityId; |
| 23 | import org.onosproject.net.ConnectPoint; | 23 | import org.onosproject.net.ConnectPoint; |
| 24 | import org.onosproject.net.Link; | 24 | import org.onosproject.net.Link; |
| 25 | -import org.onosproject.net.Path; | ||
| 26 | 25 | ||
| 27 | import java.time.Duration; | 26 | import java.time.Duration; |
| 28 | -import java.util.HashSet; | ||
| 29 | import java.util.List; | 27 | import java.util.List; |
| 28 | +import java.util.Optional; | ||
| 30 | import java.util.Set; | 29 | import java.util.Set; |
| 30 | +import java.util.stream.Collectors; | ||
| 31 | 31 | ||
| 32 | -import static com.google.common.base.Preconditions.checkNotNull; | 32 | +import static com.google.common.base.Preconditions.checkState; |
| 33 | 33 | ||
| 34 | /** | 34 | /** |
| 35 | * Entity to store optical connectivity request and related information. | 35 | * Entity to store optical connectivity request and related information. |
| ... | @@ -42,48 +42,48 @@ public class OpticalConnectivity { | ... | @@ -42,48 +42,48 @@ public class OpticalConnectivity { |
| 42 | private final Bandwidth requestBandwidth; | 42 | private final Bandwidth requestBandwidth; |
| 43 | private final Duration requestLatency; | 43 | private final Duration requestLatency; |
| 44 | 44 | ||
| 45 | - // Bandwidth capacity of optical layer | 45 | + /** |
| 46 | - private Bandwidth opticalCapacity; | 46 | + * Set of packet link that is not yet established. |
| 47 | - | 47 | + * Packet links in this set are expected to be discovered after underlying (optical) path has been provisioned. |
| 48 | - private final Set<PacketLinkRealizedByOptical> realizingLinks = new HashSet<>(); | 48 | + */ |
| 49 | - | 49 | + private final ImmutableSet<PacketLinkRealizedByOptical> unestablishedLinks; |
| 50 | - private State state = State.CREATED; | ||
| 51 | - | ||
| 52 | - public enum State { | ||
| 53 | - CREATED, | ||
| 54 | - INSTALLING, | ||
| 55 | - INSTALLED, | ||
| 56 | - WITHDRAWING, | ||
| 57 | - WITHDRAWN, | ||
| 58 | - FAILED | ||
| 59 | - } | ||
| 60 | 50 | ||
| 61 | - public OpticalConnectivity(OpticalConnectivityId id, Path path, Bandwidth requestBandwidth, | 51 | + /** |
| 62 | - Duration requestLatency) { | 52 | + * Set of packet link that is already established. |
| 53 | + */ | ||
| 54 | + private final ImmutableSet<PacketLinkRealizedByOptical> establishedLinks; | ||
| 55 | + | ||
| 56 | + public OpticalConnectivity(OpticalConnectivityId id, | ||
| 57 | + List<Link> links, | ||
| 58 | + Bandwidth requestBandwidth, | ||
| 59 | + Duration requestLatency, | ||
| 60 | + Set<PacketLinkRealizedByOptical> unestablishedLinks, | ||
| 61 | + Set<PacketLinkRealizedByOptical> establishedLinks) { | ||
| 63 | this.id = id; | 62 | this.id = id; |
| 64 | - this.links = ImmutableList.copyOf(path.links()); | 63 | + this.links = ImmutableList.copyOf(links); |
| 65 | this.requestBandwidth = requestBandwidth; | 64 | this.requestBandwidth = requestBandwidth; |
| 66 | this.requestLatency = requestLatency; | 65 | this.requestLatency = requestLatency; |
| 66 | + this.unestablishedLinks = ImmutableSet.copyOf(unestablishedLinks); | ||
| 67 | + this.establishedLinks = ImmutableSet.copyOf(establishedLinks); | ||
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | - public void setLinkEstablished(ConnectPoint src, ConnectPoint dst) { | 70 | + private OpticalConnectivity(OpticalConnectivity connectivity) { |
| 70 | - realizingLinks.stream().filter(l -> l.isBetween(src, dst)) | 71 | + this.id = connectivity.id; |
| 71 | - .findAny() | 72 | + this.links = ImmutableList.copyOf(connectivity.links); |
| 72 | - .ifPresent(l -> l.setEstablished(true)); | 73 | + this.requestBandwidth = connectivity.requestBandwidth; |
| 73 | - } | 74 | + this.requestLatency = connectivity.requestLatency; |
| 74 | - | 75 | + this.unestablishedLinks = ImmutableSet.copyOf(connectivity.unestablishedLinks); |
| 75 | - public void setLinkRemoved(ConnectPoint src, ConnectPoint dst) { | 76 | + this.establishedLinks = ImmutableSet.copyOf(connectivity.establishedLinks); |
| 76 | - realizingLinks.stream().filter(l -> l.isBetween(src, dst)) | ||
| 77 | - .findAny() | ||
| 78 | - .ifPresent(l -> l.setEstablished(false)); | ||
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | public boolean isAllRealizingLinkEstablished() { | 79 | public boolean isAllRealizingLinkEstablished() { |
| 82 | - return realizingLinks.stream().allMatch(PacketLinkRealizedByOptical::isEstablished); | 80 | + // Check if all links are established |
| 81 | + return unestablishedLinks.isEmpty(); | ||
| 83 | } | 82 | } |
| 84 | 83 | ||
| 85 | public boolean isAllRealizingLinkNotEstablished() { | 84 | public boolean isAllRealizingLinkNotEstablished() { |
| 86 | - return !realizingLinks.stream().anyMatch(PacketLinkRealizedByOptical::isEstablished); | 85 | + // Check if any link is not established |
| 86 | + return establishedLinks.isEmpty(); | ||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | public OpticalConnectivityId id() { | 89 | public OpticalConnectivityId id() { |
| ... | @@ -102,59 +102,64 @@ public class OpticalConnectivity { | ... | @@ -102,59 +102,64 @@ public class OpticalConnectivity { |
| 102 | return requestLatency; | 102 | return requestLatency; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | - public State state() { | 105 | + public Set<PacketLinkRealizedByOptical> getEstablishedLinks() { |
| 106 | - return state; | 106 | + return establishedLinks; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | - public boolean state(State state) { | 109 | + public Set<PacketLinkRealizedByOptical> getUnestablishedLinks() { |
| 110 | - boolean valid = true; | 110 | + return unestablishedLinks; |
| 111 | - // reject invalid state transition | ||
| 112 | - switch (this.state) { | ||
| 113 | - case CREATED: | ||
| 114 | - valid = (state == State.INSTALLING || state == State.FAILED); | ||
| 115 | - break; | ||
| 116 | - case INSTALLING: | ||
| 117 | - valid = (state == State.INSTALLED || state == State.FAILED); | ||
| 118 | - break; | ||
| 119 | - case INSTALLED: | ||
| 120 | - valid = (state == State.WITHDRAWING || state == State.FAILED); | ||
| 121 | - break; | ||
| 122 | - case WITHDRAWING: | ||
| 123 | - valid = (state == State.WITHDRAWN || state == State.FAILED); | ||
| 124 | - break; | ||
| 125 | - case FAILED: | ||
| 126 | - valid = (state == State.INSTALLING || state == State.WITHDRAWING || state == State.FAILED); | ||
| 127 | - break; | ||
| 128 | - default: | ||
| 129 | - break; | ||
| 130 | } | 111 | } |
| 131 | 112 | ||
| 132 | - if (valid) { | 113 | + public OpticalConnectivity setLinkEstablished(ConnectPoint src, |
| 133 | - this.state = state; | 114 | + ConnectPoint dst, |
| 134 | - } | 115 | + boolean established) { |
| 116 | + Set<PacketLinkRealizedByOptical> newEstablishedLinks; | ||
| 117 | + Set<PacketLinkRealizedByOptical> newUnestablishedLinks; | ||
| 135 | 118 | ||
| 136 | - return valid; | 119 | + if (established) { |
| 137 | - } | 120 | + // move PacketLink from unestablished set to established set |
| 121 | + Optional<PacketLinkRealizedByOptical> link = this.unestablishedLinks.stream() | ||
| 122 | + .filter(l -> l.isBetween(src, dst)).findAny(); | ||
| 123 | + checkState(link.isPresent()); | ||
| 138 | 124 | ||
| 139 | - public Bandwidth getOpticalCapacity() { | 125 | + newUnestablishedLinks = this.unestablishedLinks.stream() |
| 140 | - return opticalCapacity; | 126 | + .filter(l -> !l.isBetween(src, dst)) |
| 141 | - } | 127 | + .collect(Collectors.toSet()); |
| 128 | + newEstablishedLinks = ImmutableSet.<PacketLinkRealizedByOptical>builder() | ||
| 129 | + .addAll(this.establishedLinks) | ||
| 130 | + .add(link.get()) | ||
| 131 | + .build(); | ||
| 132 | + } else { | ||
| 133 | + // move PacketLink from established set to unestablished set | ||
| 134 | + Optional<PacketLinkRealizedByOptical> link = this.establishedLinks.stream() | ||
| 135 | + .filter(l -> l.isBetween(src, dst)).findAny(); | ||
| 136 | + checkState(link.isPresent()); | ||
| 142 | 137 | ||
| 143 | - public void setOpticalCapacity(Bandwidth opticalCapacity) { | 138 | + newEstablishedLinks = this.establishedLinks.stream() |
| 144 | - this.opticalCapacity = opticalCapacity; | 139 | + .filter(l -> !l.isBetween(src, dst)) |
| 140 | + .collect(Collectors.toSet()); | ||
| 141 | + newUnestablishedLinks = ImmutableSet.<PacketLinkRealizedByOptical>builder() | ||
| 142 | + .addAll(this.unestablishedLinks) | ||
| 143 | + .add(link.get()) | ||
| 144 | + .build(); | ||
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | - public void addRealizingLink(PacketLinkRealizedByOptical link) { | 147 | + return new OpticalConnectivity(this.id, |
| 148 | - checkNotNull(link); | 148 | + this.links, |
| 149 | - realizingLinks.add(link); | 149 | + this.requestBandwidth, |
| 150 | + this.requestLatency, | ||
| 151 | + newUnestablishedLinks, | ||
| 152 | + newEstablishedLinks); | ||
| 150 | } | 153 | } |
| 151 | 154 | ||
| 152 | - public void removeRealizingLink(PacketLinkRealizedByOptical link) { | 155 | + public Set<PacketLinkRealizedByOptical> getRealizingLinks() { |
| 153 | - checkNotNull(link); | 156 | + return ImmutableSet.<PacketLinkRealizedByOptical>builder() |
| 154 | - realizingLinks.remove(link); | 157 | + .addAll(unestablishedLinks) |
| 158 | + .addAll(establishedLinks) | ||
| 159 | + .build(); | ||
| 155 | } | 160 | } |
| 156 | 161 | ||
| 157 | - public Set<PacketLinkRealizedByOptical> getRealizingLinks() { | 162 | + public static OpticalConnectivity copyOf(OpticalConnectivity connectivity) { |
| 158 | - return ImmutableSet.copyOf(realizingLinks); | 163 | + return new OpticalConnectivity(connectivity); |
| 159 | } | 164 | } |
| 160 | } | 165 | } | ... | ... |
| ... | @@ -17,7 +17,6 @@ package org.onosproject.newoptical; | ... | @@ -17,7 +17,6 @@ package org.onosproject.newoptical; |
| 17 | 17 | ||
| 18 | import com.google.common.annotations.Beta; | 18 | import com.google.common.annotations.Beta; |
| 19 | import com.google.common.collect.ImmutableList; | 19 | import com.google.common.collect.ImmutableList; |
| 20 | -import com.google.common.collect.Sets; | ||
| 21 | 20 | ||
| 22 | import org.apache.commons.lang3.tuple.Pair; | 21 | import org.apache.commons.lang3.tuple.Pair; |
| 23 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
| ... | @@ -27,8 +26,8 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -27,8 +26,8 @@ import org.apache.felix.scr.annotations.Reference; |
| 27 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 28 | import org.apache.felix.scr.annotations.Service; | 27 | import org.apache.felix.scr.annotations.Service; |
| 29 | import org.onlab.util.Bandwidth; | 28 | import org.onlab.util.Bandwidth; |
| 29 | +import org.onlab.util.KryoNamespace; | ||
| 30 | import org.onosproject.cluster.ClusterService; | 30 | import org.onosproject.cluster.ClusterService; |
| 31 | -import org.onosproject.cluster.NodeId; | ||
| 32 | import org.onosproject.core.ApplicationId; | 31 | import org.onosproject.core.ApplicationId; |
| 33 | import org.onosproject.core.CoreService; | 32 | import org.onosproject.core.CoreService; |
| 34 | import org.onosproject.event.ListenerTracker; | 33 | import org.onosproject.event.ListenerTracker; |
| ... | @@ -66,20 +65,29 @@ import org.onosproject.net.resource.Resources; | ... | @@ -66,20 +65,29 @@ import org.onosproject.net.resource.Resources; |
| 66 | import org.onosproject.net.topology.LinkWeight; | 65 | import org.onosproject.net.topology.LinkWeight; |
| 67 | import org.onosproject.net.topology.PathService; | 66 | import org.onosproject.net.topology.PathService; |
| 68 | import org.onosproject.net.topology.TopologyEdge; | 67 | import org.onosproject.net.topology.TopologyEdge; |
| 68 | +import org.onosproject.store.serializers.KryoNamespaces; | ||
| 69 | import org.onosproject.store.service.AtomicCounter; | 69 | import org.onosproject.store.service.AtomicCounter; |
| 70 | +import org.onosproject.store.service.ConsistentMap; | ||
| 71 | +import org.onosproject.store.service.DistributedSet; | ||
| 72 | +import org.onosproject.store.service.MapEvent; | ||
| 73 | +import org.onosproject.store.service.MapEventListener; | ||
| 74 | +import org.onosproject.store.service.Serializer; | ||
| 70 | import org.onosproject.store.service.StorageService; | 75 | import org.onosproject.store.service.StorageService; |
| 76 | +import org.onosproject.store.service.Versioned; | ||
| 71 | import org.slf4j.Logger; | 77 | import org.slf4j.Logger; |
| 72 | import org.slf4j.LoggerFactory; | 78 | import org.slf4j.LoggerFactory; |
| 73 | 79 | ||
| 74 | import java.time.Duration; | 80 | import java.time.Duration; |
| 81 | +import java.util.ArrayList; | ||
| 75 | import java.util.Collections; | 82 | import java.util.Collections; |
| 83 | +import java.util.HashMap; | ||
| 84 | +import java.util.HashSet; | ||
| 76 | import java.util.Iterator; | 85 | import java.util.Iterator; |
| 77 | import java.util.LinkedList; | 86 | import java.util.LinkedList; |
| 78 | import java.util.List; | 87 | import java.util.List; |
| 79 | import java.util.Map; | 88 | import java.util.Map; |
| 80 | import java.util.Optional; | 89 | import java.util.Optional; |
| 81 | import java.util.Set; | 90 | import java.util.Set; |
| 82 | -import java.util.concurrent.ConcurrentHashMap; | ||
| 83 | import java.util.stream.Collectors; | 91 | import java.util.stream.Collectors; |
| 84 | import java.util.stream.Stream; | 92 | import java.util.stream.Stream; |
| 85 | 93 | ||
| ... | @@ -99,6 +107,9 @@ public class OpticalPathProvisioner | ... | @@ -99,6 +107,9 @@ public class OpticalPathProvisioner |
| 99 | protected static final Logger log = LoggerFactory.getLogger(OpticalPathProvisioner.class); | 107 | protected static final Logger log = LoggerFactory.getLogger(OpticalPathProvisioner.class); |
| 100 | 108 | ||
| 101 | private static final String OPTICAL_CONNECTIVITY_ID_COUNTER = "optical-connectivity-id"; | 109 | private static final String OPTICAL_CONNECTIVITY_ID_COUNTER = "optical-connectivity-id"; |
| 110 | + private static final String LINKPATH_MAP_NAME = "newoptical-linkpath"; | ||
| 111 | + private static final String CONNECTIVITY_MAP_NAME = "newoptical-connectivity"; | ||
| 112 | + private static final String CROSSCONNECTLINK_SET_NAME = "newoptical-crossconnectlink"; | ||
| 102 | 113 | ||
| 103 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 114 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 104 | protected IntentService intentService; | 115 | protected IntentService intentService; |
| ... | @@ -137,14 +148,28 @@ public class OpticalPathProvisioner | ... | @@ -137,14 +148,28 @@ public class OpticalPathProvisioner |
| 137 | 148 | ||
| 138 | private ListenerTracker listeners; | 149 | private ListenerTracker listeners; |
| 139 | 150 | ||
| 140 | - private Map<PacketLinkRealizedByOptical, OpticalConnectivity> linkPathMap = new ConcurrentHashMap<>(); | 151 | + private InternalStoreListener storeListener = new InternalStoreListener(); |
| 141 | 152 | ||
| 142 | - // TODO this should be stored to distributed store | 153 | + private ConsistentMap<PacketLinkRealizedByOptical, OpticalConnectivity> linkPathMap; |
| 143 | - private Map<OpticalConnectivityId, OpticalConnectivity> connectivities = new ConcurrentHashMap<>(); | 154 | + |
| 155 | + private ConsistentMap<OpticalConnectivityId, OpticalConnectivity> connectivityMap; | ||
| 144 | 156 | ||
| 145 | - // TODO this should be stored to distributed store | ||
| 146 | // Map of cross connect link and installed path which uses the link | 157 | // Map of cross connect link and installed path which uses the link |
| 147 | - private Set<Link> usedCrossConnectLinks = Sets.newConcurrentHashSet(); | 158 | + private DistributedSet<Link> usedCrossConnectLinkSet; |
| 159 | + | ||
| 160 | + private static final KryoNamespace.Builder LINKPATH_SERIALIZER = KryoNamespace.newBuilder() | ||
| 161 | + .register(KryoNamespaces.API) | ||
| 162 | + .register(PacketLinkRealizedByOptical.class) | ||
| 163 | + .register(OpticalConnectivityId.class) | ||
| 164 | + .register(OpticalConnectivity.class); | ||
| 165 | + | ||
| 166 | + private static final KryoNamespace.Builder CONNECTIVITY_SERIALIZER = KryoNamespace.newBuilder() | ||
| 167 | + .register(KryoNamespaces.API) | ||
| 168 | + .register(OpticalConnectivityId.class) | ||
| 169 | + .register(OpticalConnectivity.class); | ||
| 170 | + | ||
| 171 | + private static final KryoNamespace.Builder CROSSCONNECTLINKS_SERIALIZER = KryoNamespace.newBuilder() | ||
| 172 | + .register(KryoNamespaces.API); | ||
| 148 | 173 | ||
| 149 | @Activate | 174 | @Activate |
| 150 | protected void activate() { | 175 | protected void activate() { |
| ... | @@ -153,17 +178,39 @@ public class OpticalPathProvisioner | ... | @@ -153,17 +178,39 @@ public class OpticalPathProvisioner |
| 153 | 178 | ||
| 154 | idCounter = storageService.getAtomicCounter(OPTICAL_CONNECTIVITY_ID_COUNTER); | 179 | idCounter = storageService.getAtomicCounter(OPTICAL_CONNECTIVITY_ID_COUNTER); |
| 155 | 180 | ||
| 181 | + linkPathMap = storageService.<PacketLinkRealizedByOptical, OpticalConnectivity>consistentMapBuilder() | ||
| 182 | + .withSerializer(Serializer.using(LINKPATH_SERIALIZER.build())) | ||
| 183 | + .withName(LINKPATH_MAP_NAME) | ||
| 184 | + .withApplicationId(appId) | ||
| 185 | + .build(); | ||
| 186 | + | ||
| 187 | + connectivityMap = storageService.<OpticalConnectivityId, OpticalConnectivity>consistentMapBuilder() | ||
| 188 | + .withSerializer(Serializer.using(CONNECTIVITY_SERIALIZER.build())) | ||
| 189 | + .withName(CONNECTIVITY_MAP_NAME) | ||
| 190 | + .withApplicationId(appId) | ||
| 191 | + .build(); | ||
| 192 | + | ||
| 193 | + usedCrossConnectLinkSet = storageService.<Link>setBuilder() | ||
| 194 | + .withSerializer(Serializer.using(CROSSCONNECTLINKS_SERIALIZER.build())) | ||
| 195 | + .withName(CROSSCONNECTLINK_SET_NAME) | ||
| 196 | + .withApplicationId(appId) | ||
| 197 | + .build() | ||
| 198 | + .asDistributedSet(); | ||
| 199 | + | ||
| 156 | eventDispatcher.addSink(OpticalPathEvent.class, listenerRegistry); | 200 | eventDispatcher.addSink(OpticalPathEvent.class, listenerRegistry); |
| 157 | 201 | ||
| 158 | listeners = new ListenerTracker(); | 202 | listeners = new ListenerTracker(); |
| 159 | listeners.addListener(linkService, new InternalLinkListener()) | 203 | listeners.addListener(linkService, new InternalLinkListener()) |
| 160 | .addListener(intentService, new InternalIntentListener()); | 204 | .addListener(intentService, new InternalIntentListener()); |
| 161 | 205 | ||
| 206 | + linkPathMap.addListener(storeListener); | ||
| 207 | + | ||
| 162 | log.info("Started"); | 208 | log.info("Started"); |
| 163 | } | 209 | } |
| 164 | 210 | ||
| 165 | @Deactivate | 211 | @Deactivate |
| 166 | protected void deactivate() { | 212 | protected void deactivate() { |
| 213 | + linkPathMap.removeListener(storeListener); | ||
| 167 | listeners.removeListeners(); | 214 | listeners.removeListeners(); |
| 168 | eventDispatcher.removeSink(OpticalPathEvent.class); | 215 | eventDispatcher.removeSink(OpticalPathEvent.class); |
| 169 | 216 | ||
| ... | @@ -205,22 +252,67 @@ public class OpticalPathProvisioner | ... | @@ -205,22 +252,67 @@ public class OpticalPathProvisioner |
| 205 | checkNotNull(path); | 252 | checkNotNull(path); |
| 206 | log.info("setupPath({}, {}, {})", path, bandwidth, latency); | 253 | log.info("setupPath({}, {}, {})", path, bandwidth, latency); |
| 207 | 254 | ||
| 208 | - // validate optical path | 255 | + // map of cross connect points (optical port -> packet port) |
| 209 | - List<Pair<ConnectPoint, ConnectPoint>> xcPointPairs = getCrossConnectPoints(path); | 256 | + Map<ConnectPoint, ConnectPoint> crossConnectPointMap = new HashMap<>(); |
| 210 | - if (!checkXcPoints(xcPointPairs)) { | 257 | + |
| 211 | - // Can't setup path if cross connect points are mismatched | 258 | + // list of (src, dst) pair of optical ports between which optical path should be installed |
| 212 | - log.error("Failed to setup path because of mismatched cross connect points."); | 259 | + List<Pair<ConnectPoint, ConnectPoint>> crossConnectPoints = new ArrayList<>(); |
| 260 | + | ||
| 261 | + // Scan path to find pairs of connect points between which optical intent is installed | ||
| 262 | + // opticalSrcPort works as a flag parameter to show scanning status | ||
| 263 | + ConnectPoint opticalSrcPort = null; | ||
| 264 | + for (Link link : path.links()) { | ||
| 265 | + if (!isCrossConnectLink(link)) { | ||
| 266 | + continue; | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + if (opticalSrcPort != null) { | ||
| 270 | + // opticalSrcPort!=null means src port was already found | ||
| 271 | + // in this case link.src() is optical layer, and link.dst() is packet layer | ||
| 272 | + | ||
| 273 | + // Check if types of src port and dst port matches | ||
| 274 | + Device srcDevice = checkNotNull(deviceService.getDevice(opticalSrcPort.deviceId()), | ||
| 275 | + "Unknown device ID"); | ||
| 276 | + Device dstDevice = checkNotNull(deviceService.getDevice(link.src().deviceId()), | ||
| 277 | + "Unknown device ID"); | ||
| 278 | + if (srcDevice.type() != dstDevice.type()) { | ||
| 279 | + log.error("Unsupported mix of cross connect points : {}, {}", | ||
| 280 | + srcDevice.type(), dstDevice.type()); | ||
| 213 | return null; | 281 | return null; |
| 214 | } | 282 | } |
| 215 | 283 | ||
| 216 | - OpticalConnectivity connectivity = createConnectivity(path, bandwidth, latency); | 284 | + // Update cross connect points map |
| 285 | + crossConnectPointMap.put(link.src(), link.dst()); | ||
| 286 | + | ||
| 287 | + // Add optical ports pair to list | ||
| 288 | + crossConnectPoints.add(Pair.of(opticalSrcPort, link.src())); | ||
| 289 | + | ||
| 290 | + // Reset flag parameter | ||
| 291 | + opticalSrcPort = null; | ||
| 292 | + } else { | ||
| 293 | + // opticalSrcPort==null means src port was not found yet | ||
| 294 | + // in this case link.src() is packet layer, and link.dst() is optical layer | ||
| 295 | + | ||
| 296 | + // Update cross connect points map | ||
| 297 | + crossConnectPointMap.put(link.dst(), link.src()); | ||
| 298 | + // Set opticalSrcPort to src of link (optical port) | ||
| 299 | + opticalSrcPort = link.dst(); | ||
| 300 | + } | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + // create intents from cross connect points | ||
| 304 | + List<Intent> intents = createIntents(crossConnectPoints); | ||
| 305 | + | ||
| 306 | + // create set of PacketLinkRealizedByOptical | ||
| 307 | + Set<PacketLinkRealizedByOptical> packetLinks = createPacketLinkSet(crossConnectPoints, | ||
| 308 | + intents, crossConnectPointMap); | ||
| 217 | 309 | ||
| 218 | - // create intents from cross connect points and set connectivity information | 310 | + // create OpticalConnectivity object and store information to distributed store |
| 219 | - List<Intent> intents = createIntents(xcPointPairs, connectivity); | 311 | + OpticalConnectivity connectivity = createConnectivity(path, bandwidth, latency, packetLinks); |
| 220 | 312 | ||
| 221 | // store cross connect port usage | 313 | // store cross connect port usage |
| 222 | path.links().stream().filter(this::isCrossConnectLink) | 314 | path.links().stream().filter(this::isCrossConnectLink) |
| 223 | - .forEach(usedCrossConnectLinks::add); | 315 | + .forEach(usedCrossConnectLinkSet::add); |
| 224 | 316 | ||
| 225 | // Submit the intents | 317 | // Submit the intents |
| 226 | for (Intent i : intents) { | 318 | for (Intent i : intents) { |
| ... | @@ -231,12 +323,16 @@ public class OpticalPathProvisioner | ... | @@ -231,12 +323,16 @@ public class OpticalPathProvisioner |
| 231 | return connectivity.id(); | 323 | return connectivity.id(); |
| 232 | } | 324 | } |
| 233 | 325 | ||
| 234 | - private OpticalConnectivity createConnectivity(Path path, Bandwidth bandwidth, Duration latency) { | 326 | + private OpticalConnectivity createConnectivity(Path path, Bandwidth bandwidth, Duration latency, |
| 327 | + Set<PacketLinkRealizedByOptical> links) { | ||
| 235 | OpticalConnectivityId id = OpticalConnectivityId.of(idCounter.getAndIncrement()); | 328 | OpticalConnectivityId id = OpticalConnectivityId.of(idCounter.getAndIncrement()); |
| 236 | - OpticalConnectivity connectivity = new OpticalConnectivity(id, path, bandwidth, latency); | 329 | + OpticalConnectivity connectivity = new OpticalConnectivity(id, path.links(), bandwidth, latency, |
| 330 | + links, Collections.emptySet()); | ||
| 331 | + | ||
| 332 | + links.forEach(l -> linkPathMap.put(l, connectivity)); | ||
| 237 | 333 | ||
| 238 | // store connectivity information | 334 | // store connectivity information |
| 239 | - connectivities.put(connectivity.id(), connectivity); | 335 | + connectivityMap.put(connectivity.id(), connectivity); |
| 240 | 336 | ||
| 241 | return connectivity; | 337 | return connectivity; |
| 242 | } | 338 | } |
| ... | @@ -244,7 +340,7 @@ public class OpticalPathProvisioner | ... | @@ -244,7 +340,7 @@ public class OpticalPathProvisioner |
| 244 | @Override | 340 | @Override |
| 245 | public boolean removeConnectivity(OpticalConnectivityId id) { | 341 | public boolean removeConnectivity(OpticalConnectivityId id) { |
| 246 | log.info("removeConnectivity({})", id); | 342 | log.info("removeConnectivity({})", id); |
| 247 | - OpticalConnectivity connectivity = connectivities.remove(id); | 343 | + Versioned<OpticalConnectivity> connectivity = connectivityMap.remove(id); |
| 248 | 344 | ||
| 249 | if (connectivity == null) { | 345 | if (connectivity == null) { |
| 250 | log.info("OpticalConnectivity with id {} not found.", id); | 346 | log.info("OpticalConnectivity with id {} not found.", id); |
| ... | @@ -252,7 +348,7 @@ public class OpticalPathProvisioner | ... | @@ -252,7 +348,7 @@ public class OpticalPathProvisioner |
| 252 | } | 348 | } |
| 253 | 349 | ||
| 254 | // TODO withdraw intent only if all of connectivities that use the optical path are withdrawn | 350 | // TODO withdraw intent only if all of connectivities that use the optical path are withdrawn |
| 255 | - connectivity.getRealizingLinks().forEach(l -> { | 351 | + connectivity.value().getRealizingLinks().forEach(l -> { |
| 256 | Intent intent = intentService.getIntent(l.realizingIntentKey()); | 352 | Intent intent = intentService.getIntent(l.realizingIntentKey()); |
| 257 | intentService.withdraw(intent); | 353 | intentService.withdraw(intent); |
| 258 | }); | 354 | }); |
| ... | @@ -262,98 +358,34 @@ public class OpticalPathProvisioner | ... | @@ -262,98 +358,34 @@ public class OpticalPathProvisioner |
| 262 | 358 | ||
| 263 | @Override | 359 | @Override |
| 264 | public Optional<List<Link>> getPath(OpticalConnectivityId id) { | 360 | public Optional<List<Link>> getPath(OpticalConnectivityId id) { |
| 265 | - OpticalConnectivity connectivity = connectivities.get(id); | 361 | + Versioned<OpticalConnectivity> connectivity = connectivityMap.get(id); |
| 266 | if (connectivity == null) { | 362 | if (connectivity == null) { |
| 267 | log.info("OpticalConnectivity with id {} not found.", id); | 363 | log.info("OpticalConnectivity with id {} not found.", id); |
| 268 | return Optional.empty(); | 364 | return Optional.empty(); |
| 269 | } | 365 | } |
| 270 | 366 | ||
| 271 | - return Optional.of(ImmutableList.copyOf(connectivity.links())); | 367 | + return Optional.of(ImmutableList.copyOf(connectivity.value().links())); |
| 272 | - } | ||
| 273 | - | ||
| 274 | - /** | ||
| 275 | - * Returns list of (optical, packet) pairs of cross connection points of missing optical path sections. | ||
| 276 | - * | ||
| 277 | - * Scans the given multi-layer path and looks for sections that use cross connect links. | ||
| 278 | - * The ingress and egress points in the optical layer are combined to the packet layer ports, and | ||
| 279 | - * are returned in a list. | ||
| 280 | - * | ||
| 281 | - * @param path the multi-layer path | ||
| 282 | - * @return List of cross connect link's (packet port, optical port) pairs | ||
| 283 | - */ | ||
| 284 | - private List<Pair<ConnectPoint, ConnectPoint>> getCrossConnectPoints(Path path) { | ||
| 285 | - List<Pair<ConnectPoint, ConnectPoint>> xcPointPairs = new LinkedList<>(); | ||
| 286 | - boolean scanning = false; | ||
| 287 | - | ||
| 288 | - for (Link link : path.links()) { | ||
| 289 | - if (!isCrossConnectLink(link)) { | ||
| 290 | - continue; | ||
| 291 | - } | ||
| 292 | - | ||
| 293 | - if (scanning) { | ||
| 294 | - // link.src() is packet, link.dst() is optical | ||
| 295 | - xcPointPairs.add(Pair.of(checkNotNull(link.src()), checkNotNull(link.dst()))); | ||
| 296 | - scanning = false; | ||
| 297 | - } else { | ||
| 298 | - // link.src() is optical, link.dst() is packet | ||
| 299 | - xcPointPairs.add(Pair.of(checkNotNull(link.dst()), checkNotNull(link.src()))); | ||
| 300 | - scanning = true; | ||
| 301 | - } | ||
| 302 | - } | ||
| 303 | - | ||
| 304 | - return xcPointPairs; | ||
| 305 | - } | ||
| 306 | - | ||
| 307 | - /** | ||
| 308 | - * Checks if optical cross connect points are of same type. | ||
| 309 | - * | ||
| 310 | - * @param xcPointPairs list of cross connection points | ||
| 311 | - * @return true if cross connect point pairs are of same type, false otherwise | ||
| 312 | - */ | ||
| 313 | - private boolean checkXcPoints(List<Pair<ConnectPoint, ConnectPoint>> xcPointPairs) { | ||
| 314 | - checkArgument(xcPointPairs.size() % 2 == 0); | ||
| 315 | - | ||
| 316 | - Iterator<Pair<ConnectPoint, ConnectPoint>> itr = xcPointPairs.iterator(); | ||
| 317 | - | ||
| 318 | - while (itr.hasNext()) { | ||
| 319 | - // checkArgument at start ensures we'll always have pairs of connect points | ||
| 320 | - Pair<ConnectPoint, ConnectPoint> src = itr.next(); | ||
| 321 | - Pair<ConnectPoint, ConnectPoint> dst = itr.next(); | ||
| 322 | - | ||
| 323 | - Device.Type srcType = deviceService.getDevice(src.getKey().deviceId()).type(); | ||
| 324 | - Device.Type dstType = deviceService.getDevice(dst.getKey().deviceId()).type(); | ||
| 325 | - | ||
| 326 | - // Only support connections between identical port types | ||
| 327 | - if (srcType != dstType) { | ||
| 328 | - log.warn("Unsupported mix of cross connect points : {}, {}", srcType, dstType); | ||
| 329 | - return false; | ||
| 330 | - } | ||
| 331 | - } | ||
| 332 | - | ||
| 333 | - return true; | ||
| 334 | } | 368 | } |
| 335 | 369 | ||
| 336 | /** | 370 | /** |
| 337 | * Scans the list of cross connection points and returns a list of optical connectivity intents. | 371 | * Scans the list of cross connection points and returns a list of optical connectivity intents. |
| 338 | - * During the process, store intent ID and its realizing link information to given connectivity object. | 372 | + * During the process, save information about packet links to given set. |
| 339 | * | 373 | * |
| 340 | - * @param xcPointPairs list of cross connection points | 374 | + * @param crossConnectPoints list of (src, dst) pair between which optical path will be set up |
| 341 | * @return list of optical connectivity intents | 375 | * @return list of optical connectivity intents |
| 342 | */ | 376 | */ |
| 343 | - private List<Intent> createIntents(List<Pair<ConnectPoint, ConnectPoint>> xcPointPairs, | 377 | + private List<Intent> createIntents(List<Pair<ConnectPoint, ConnectPoint>> crossConnectPoints) { |
| 344 | - OpticalConnectivity connectivity) { | ||
| 345 | - checkArgument(xcPointPairs.size() % 2 == 0); | ||
| 346 | - | ||
| 347 | List<Intent> intents = new LinkedList<>(); | 378 | List<Intent> intents = new LinkedList<>(); |
| 348 | - Iterator<Pair<ConnectPoint, ConnectPoint>> itr = xcPointPairs.iterator(); | 379 | + Iterator<Pair<ConnectPoint, ConnectPoint>> itr = crossConnectPoints.iterator(); |
| 349 | 380 | ||
| 350 | while (itr.hasNext()) { | 381 | while (itr.hasNext()) { |
| 351 | // checkArgument at start ensures we'll always have pairs of connect points | 382 | // checkArgument at start ensures we'll always have pairs of connect points |
| 352 | - Pair<ConnectPoint, ConnectPoint> src = itr.next(); | 383 | + Pair<ConnectPoint, ConnectPoint> next = itr.next(); |
| 353 | - Pair<ConnectPoint, ConnectPoint> dst = itr.next(); | 384 | + ConnectPoint src = next.getLeft(); |
| 385 | + ConnectPoint dst = next.getRight(); | ||
| 354 | 386 | ||
| 355 | - Port srcPort = deviceService.getPort(src.getKey().deviceId(), src.getKey().port()); | 387 | + Port srcPort = deviceService.getPort(src.deviceId(), src.port()); |
| 356 | - Port dstPort = deviceService.getPort(dst.getKey().deviceId(), dst.getKey().port()); | 388 | + Port dstPort = deviceService.getPort(dst.deviceId(), dst.port()); |
| 357 | 389 | ||
| 358 | if (srcPort instanceof OduCltPort && dstPort instanceof OduCltPort) { | 390 | if (srcPort instanceof OduCltPort && dstPort instanceof OduCltPort) { |
| 359 | OduCltPort srcOCPort = (OduCltPort) srcPort; | 391 | OduCltPort srcOCPort = (OduCltPort) srcPort; |
| ... | @@ -365,16 +397,12 @@ public class OpticalPathProvisioner | ... | @@ -365,16 +397,12 @@ public class OpticalPathProvisioner |
| 365 | // Create OTN circuit | 397 | // Create OTN circuit |
| 366 | OpticalCircuitIntent circuitIntent = OpticalCircuitIntent.builder() | 398 | OpticalCircuitIntent circuitIntent = OpticalCircuitIntent.builder() |
| 367 | .appId(appId) | 399 | .appId(appId) |
| 368 | - .src(src.getKey()) | 400 | + .src(src) |
| 369 | - .dst(dst.getKey()) | 401 | + .dst(dst) |
| 370 | .signalType(srcOCPort.signalType()) | 402 | .signalType(srcOCPort.signalType()) |
| 371 | .bidirectional(true) | 403 | .bidirectional(true) |
| 372 | .build(); | 404 | .build(); |
| 373 | intents.add(circuitIntent); | 405 | intents.add(circuitIntent); |
| 374 | - PacketLinkRealizedByOptical pLink = PacketLinkRealizedByOptical.create(src.getValue(), dst.getValue(), | ||
| 375 | - circuitIntent); | ||
| 376 | - connectivity.addRealizingLink(pLink); | ||
| 377 | - linkPathMap.put(pLink, connectivity); | ||
| 378 | } else if (srcPort instanceof OchPort && dstPort instanceof OchPort) { | 406 | } else if (srcPort instanceof OchPort && dstPort instanceof OchPort) { |
| 379 | OchPort srcOchPort = (OchPort) srcPort; | 407 | OchPort srcOchPort = (OchPort) srcPort; |
| 380 | OchPort dstOchPort = (OchPort) dstPort; | 408 | OchPort dstOchPort = (OchPort) dstPort; |
| ... | @@ -385,16 +413,12 @@ public class OpticalPathProvisioner | ... | @@ -385,16 +413,12 @@ public class OpticalPathProvisioner |
| 385 | // Create lightpath | 413 | // Create lightpath |
| 386 | OpticalConnectivityIntent opticalIntent = OpticalConnectivityIntent.builder() | 414 | OpticalConnectivityIntent opticalIntent = OpticalConnectivityIntent.builder() |
| 387 | .appId(appId) | 415 | .appId(appId) |
| 388 | - .src(src.getKey()) | 416 | + .src(src) |
| 389 | - .dst(dst.getKey()) | 417 | + .dst(dst) |
| 390 | .signalType(srcOchPort.signalType()) | 418 | .signalType(srcOchPort.signalType()) |
| 391 | .bidirectional(true) | 419 | .bidirectional(true) |
| 392 | .build(); | 420 | .build(); |
| 393 | intents.add(opticalIntent); | 421 | intents.add(opticalIntent); |
| 394 | - PacketLinkRealizedByOptical pLink = PacketLinkRealizedByOptical.create(src.getValue(), dst.getValue(), | ||
| 395 | - opticalIntent); | ||
| 396 | - connectivity.addRealizingLink(pLink); | ||
| 397 | - linkPathMap.put(pLink, connectivity); | ||
| 398 | } else { | 422 | } else { |
| 399 | log.warn("Unsupported cross connect point types {} {}", srcPort.type(), dstPort.type()); | 423 | log.warn("Unsupported cross connect point types {} {}", srcPort.type(), dstPort.type()); |
| 400 | return Collections.emptyList(); | 424 | return Collections.emptyList(); |
| ... | @@ -404,6 +428,36 @@ public class OpticalPathProvisioner | ... | @@ -404,6 +428,36 @@ public class OpticalPathProvisioner |
| 404 | return intents; | 428 | return intents; |
| 405 | } | 429 | } |
| 406 | 430 | ||
| 431 | + private Set<PacketLinkRealizedByOptical> createPacketLinkSet(List<Pair<ConnectPoint, ConnectPoint>> connectPoints, | ||
| 432 | + List<Intent> intents, | ||
| 433 | + Map<ConnectPoint, ConnectPoint> crossConnectPoints) { | ||
| 434 | + checkArgument(connectPoints.size() == intents.size()); | ||
| 435 | + | ||
| 436 | + Set<PacketLinkRealizedByOptical> pLinks = new HashSet<>(); | ||
| 437 | + | ||
| 438 | + Iterator<Pair<ConnectPoint, ConnectPoint>> xcPointsItr = connectPoints.iterator(); | ||
| 439 | + Iterator<Intent> intentItr = intents.iterator(); | ||
| 440 | + while (xcPointsItr.hasNext()) { | ||
| 441 | + Pair<ConnectPoint, ConnectPoint> xcPoints = xcPointsItr.next(); | ||
| 442 | + Intent intent = intentItr.next(); | ||
| 443 | + | ||
| 444 | + ConnectPoint packetSrc = checkNotNull(crossConnectPoints.get(xcPoints.getLeft())); | ||
| 445 | + ConnectPoint packetDst = checkNotNull(crossConnectPoints.get(xcPoints.getRight())); | ||
| 446 | + | ||
| 447 | + if (intent instanceof OpticalConnectivityIntent) { | ||
| 448 | + pLinks.add(PacketLinkRealizedByOptical.create(packetSrc, packetDst, | ||
| 449 | + (OpticalConnectivityIntent) intent)); | ||
| 450 | + } else if (intent instanceof OpticalCircuitIntent) { | ||
| 451 | + pLinks.add(PacketLinkRealizedByOptical.create(packetSrc, packetDst, | ||
| 452 | + (OpticalCircuitIntent) intent)); | ||
| 453 | + } else { | ||
| 454 | + log.warn("Unexpected intent type: {}", intent.getClass()); | ||
| 455 | + } | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + return pLinks; | ||
| 459 | + } | ||
| 460 | + | ||
| 407 | /** | 461 | /** |
| 408 | * Verifies if given device type is in packet layer, i.e., ROADM, OTN or ROADM_OTN device. | 462 | * Verifies if given device type is in packet layer, i.e., ROADM, OTN or ROADM_OTN device. |
| 409 | * | 463 | * |
| ... | @@ -444,18 +498,15 @@ public class OpticalPathProvisioner | ... | @@ -444,18 +498,15 @@ public class OpticalPathProvisioner |
| 444 | 498 | ||
| 445 | /** | 499 | /** |
| 446 | * Updates bandwidth resource of given connect point. | 500 | * Updates bandwidth resource of given connect point. |
| 501 | + * | ||
| 447 | * @param cp Connect point | 502 | * @param cp Connect point |
| 448 | * @param bandwidth New bandwidth | 503 | * @param bandwidth New bandwidth |
| 449 | */ | 504 | */ |
| 450 | private void updatePortBandwidth(ConnectPoint cp, Bandwidth bandwidth) { | 505 | private void updatePortBandwidth(ConnectPoint cp, Bandwidth bandwidth) { |
| 451 | - NodeId localNode = clusterService.getLocalNode().id(); | ||
| 452 | - NodeId sourceMaster = mastershipService.getMasterFor(cp.deviceId()); | ||
| 453 | - if (localNode.equals(sourceMaster)) { | ||
| 454 | log.debug("update Port {} Bandwidth {}", cp, bandwidth); | 506 | log.debug("update Port {} Bandwidth {}", cp, bandwidth); |
| 455 | BandwidthCapacity bwCapacity = networkConfigService.addConfig(cp, BandwidthCapacity.class); | 507 | BandwidthCapacity bwCapacity = networkConfigService.addConfig(cp, BandwidthCapacity.class); |
| 456 | bwCapacity.capacity(bandwidth).apply(); | 508 | bwCapacity.capacity(bandwidth).apply(); |
| 457 | } | 509 | } |
| 458 | - } | ||
| 459 | 510 | ||
| 460 | /** | 511 | /** |
| 461 | * Updates usage information of bandwidth based on connectivity which is established. | 512 | * Updates usage information of bandwidth based on connectivity which is established. |
| ... | @@ -487,6 +538,12 @@ public class OpticalPathProvisioner | ... | @@ -487,6 +538,12 @@ public class OpticalPathProvisioner |
| 487 | * @param connectivity Optical connectivity | 538 | * @param connectivity Optical connectivity |
| 488 | */ | 539 | */ |
| 489 | private void releaseBandwidthUsage(OpticalConnectivity connectivity) { | 540 | private void releaseBandwidthUsage(OpticalConnectivity connectivity) { |
| 541 | + if (connectivity.links().isEmpty()) { | ||
| 542 | + return; | ||
| 543 | + } | ||
| 544 | + | ||
| 545 | + // release resource only if this node is the master for link head device | ||
| 546 | + if (mastershipService.isLocalMaster(connectivity.links().get(0).src().deviceId())) { | ||
| 490 | OpticalConnectivityId connectivityId = connectivity.id(); | 547 | OpticalConnectivityId connectivityId = connectivity.id(); |
| 491 | 548 | ||
| 492 | log.debug("releasing bandwidth allocated to {}", connectivityId); | 549 | log.debug("releasing bandwidth allocated to {}", connectivityId); |
| ... | @@ -497,6 +554,7 @@ public class OpticalPathProvisioner | ... | @@ -497,6 +554,7 @@ public class OpticalPathProvisioner |
| 497 | } | 554 | } |
| 498 | log.debug("DONE releasing bandwidth for {}", connectivityId); | 555 | log.debug("DONE releasing bandwidth for {}", connectivityId); |
| 499 | } | 556 | } |
| 557 | + } | ||
| 500 | 558 | ||
| 501 | private class BandwidthLinkWeight implements LinkWeight { | 559 | private class BandwidthLinkWeight implements LinkWeight { |
| 502 | private Bandwidth bandwidth = null; | 560 | private Bandwidth bandwidth = null; |
| ... | @@ -515,7 +573,7 @@ public class OpticalPathProvisioner | ... | @@ -515,7 +573,7 @@ public class OpticalPathProvisioner |
| 515 | } | 573 | } |
| 516 | 574 | ||
| 517 | // Avoid cross connect links with used ports | 575 | // Avoid cross connect links with used ports |
| 518 | - if (isCrossConnectLink(l) && usedCrossConnectLinks.contains(l)) { | 576 | + if (isCrossConnectLink(l) && usedCrossConnectLinkSet.contains(l)) { |
| 519 | return -1.0; | 577 | return -1.0; |
| 520 | } | 578 | } |
| 521 | 579 | ||
| ... | @@ -592,18 +650,16 @@ public class OpticalPathProvisioner | ... | @@ -592,18 +650,16 @@ public class OpticalPathProvisioner |
| 592 | ConnectPoint packetSrc = e.getKey().src(); | 650 | ConnectPoint packetSrc = e.getKey().src(); |
| 593 | ConnectPoint packetDst = e.getKey().dst(); | 651 | ConnectPoint packetDst = e.getKey().dst(); |
| 594 | Bandwidth bw = e.getKey().bandwidth(); | 652 | Bandwidth bw = e.getKey().bandwidth(); |
| 653 | + | ||
| 654 | + // reflect modification only if packetSrc is local_ | ||
| 655 | + if (mastershipService.isLocalMaster(packetSrc.deviceId())) { | ||
| 595 | // Updates bandwidth of packet ports | 656 | // Updates bandwidth of packet ports |
| 596 | updatePortBandwidth(packetSrc, bw); | 657 | updatePortBandwidth(packetSrc, bw); |
| 597 | updatePortBandwidth(packetDst, bw); | 658 | updatePortBandwidth(packetDst, bw); |
| 598 | 659 | ||
| 599 | - OpticalConnectivity connectivity = e.getValue(); | 660 | + // Updates link status in distributed map |
| 600 | - connectivity.setLinkEstablished(packetSrc, packetDst); | 661 | + linkPathMap.computeIfPresent(e.getKey(), (link, connectivity) -> |
| 601 | - | 662 | + e.getValue().value().setLinkEstablished(packetSrc, packetDst, true)); |
| 602 | - if (e.getValue().isAllRealizingLinkEstablished()) { | ||
| 603 | - updateBandwidthUsage(connectivity); | ||
| 604 | - | ||
| 605 | - // Notifies listeners if all links are established | ||
| 606 | - post(new OpticalPathEvent(OpticalPathEvent.Type.PATH_INSTALLED, e.getValue().id())); | ||
| 607 | } | 663 | } |
| 608 | }); | 664 | }); |
| 609 | } | 665 | } |
| ... | @@ -633,23 +689,23 @@ public class OpticalPathProvisioner | ... | @@ -633,23 +689,23 @@ public class OpticalPathProvisioner |
| 633 | .forEach(e -> { | 689 | .forEach(e -> { |
| 634 | ConnectPoint packetSrc = e.getKey().src(); | 690 | ConnectPoint packetSrc = e.getKey().src(); |
| 635 | ConnectPoint packetDst = e.getKey().dst(); | 691 | ConnectPoint packetDst = e.getKey().dst(); |
| 692 | + | ||
| 693 | + // reflect modification only if packetSrc is local_ | ||
| 694 | + if (mastershipService.isLocalMaster(packetSrc.deviceId())) { | ||
| 636 | // Updates bandwidth of packet ports | 695 | // Updates bandwidth of packet ports |
| 637 | updatePortBandwidth(packetSrc, bw); | 696 | updatePortBandwidth(packetSrc, bw); |
| 638 | updatePortBandwidth(packetDst, bw); | 697 | updatePortBandwidth(packetDst, bw); |
| 639 | - OpticalConnectivity connectivity = e.getValue(); | ||
| 640 | - connectivity.setLinkRemoved(packetSrc, packetDst); | ||
| 641 | 698 | ||
| 642 | - // Notifies listeners if all links are gone | 699 | + // Updates link status in distributed map |
| 643 | - if (e.getValue().isAllRealizingLinkNotEstablished()) { | 700 | + linkPathMap.computeIfPresent(e.getKey(), (link, connectivity) -> |
| 644 | - releaseBandwidthUsage(connectivity); | 701 | + e.getValue().value().setLinkEstablished(packetSrc, packetDst, false)); |
| 645 | - post(new OpticalPathEvent(OpticalPathEvent.Type.PATH_REMOVED, e.getValue().id())); | ||
| 646 | } | 702 | } |
| 647 | }); | 703 | }); |
| 648 | } | 704 | } |
| 649 | 705 | ||
| 650 | private void removeXcLinkUsage(ConnectPoint cp) { | 706 | private void removeXcLinkUsage(ConnectPoint cp) { |
| 651 | Optional<Link> link = linkService.getLinks(cp).stream() | 707 | Optional<Link> link = linkService.getLinks(cp).stream() |
| 652 | - .filter(usedCrossConnectLinks::contains) | 708 | + .filter(usedCrossConnectLinkSet::contains) |
| 653 | .findAny(); | 709 | .findAny(); |
| 654 | 710 | ||
| 655 | if (!link.isPresent()) { | 711 | if (!link.isPresent()) { |
| ... | @@ -657,7 +713,7 @@ public class OpticalPathProvisioner | ... | @@ -657,7 +713,7 @@ public class OpticalPathProvisioner |
| 657 | return; | 713 | return; |
| 658 | } | 714 | } |
| 659 | 715 | ||
| 660 | - usedCrossConnectLinks.remove(link.get()); | 716 | + usedCrossConnectLinkSet.remove(link.get()); |
| 661 | } | 717 | } |
| 662 | } | 718 | } |
| 663 | 719 | ||
| ... | @@ -669,22 +725,60 @@ public class OpticalPathProvisioner | ... | @@ -669,22 +725,60 @@ public class OpticalPathProvisioner |
| 669 | switch (event.type()) { | 725 | switch (event.type()) { |
| 670 | case LINK_REMOVED: | 726 | case LINK_REMOVED: |
| 671 | Link link = event.subject(); | 727 | Link link = event.subject(); |
| 728 | + // updates linkPathMap only if src device of link is local | ||
| 729 | + if (!mastershipService.isLocalMaster(link.src().deviceId())) { | ||
| 730 | + return; | ||
| 731 | + } | ||
| 732 | + | ||
| 733 | + // find all packet links that correspond to removed link | ||
| 672 | Set<PacketLinkRealizedByOptical> pLinks = linkPathMap.keySet().stream() | 734 | Set<PacketLinkRealizedByOptical> pLinks = linkPathMap.keySet().stream() |
| 673 | .filter(l -> l.isBetween(link.src(), link.dst()) || l.isBetween(link.dst(), link.src())) | 735 | .filter(l -> l.isBetween(link.src(), link.dst()) || l.isBetween(link.dst(), link.src())) |
| 674 | .collect(Collectors.toSet()); | 736 | .collect(Collectors.toSet()); |
| 675 | 737 | ||
| 676 | pLinks.forEach(l -> { | 738 | pLinks.forEach(l -> { |
| 677 | - OpticalConnectivity c = linkPathMap.get(l); | 739 | + // remove found packet links from distributed store |
| 678 | - // Notifies listeners if all links are gone | 740 | + linkPathMap.computeIfPresent(l, (plink, conn) -> { |
| 679 | - if (c.isAllRealizingLinkNotEstablished()) { | 741 | + // Notifies listeners if all packet links are gone |
| 680 | - post(new OpticalPathEvent(OpticalPathEvent.Type.PATH_REMOVED, c.id())); | 742 | + if (conn.isAllRealizingLinkNotEstablished()) { |
| 743 | + post(new OpticalPathEvent(OpticalPathEvent.Type.PATH_REMOVED, conn.id())); | ||
| 681 | } | 744 | } |
| 682 | - linkPathMap.remove(l); | 745 | + return null; |
| 746 | + }); | ||
| 683 | }); | 747 | }); |
| 684 | default: | 748 | default: |
| 685 | break; | 749 | break; |
| 686 | } | 750 | } |
| 687 | } | 751 | } |
| 688 | } | 752 | } |
| 753 | + | ||
| 754 | + private class InternalStoreListener | ||
| 755 | + implements MapEventListener<PacketLinkRealizedByOptical, OpticalConnectivity> { | ||
| 756 | + | ||
| 757 | + @Override | ||
| 758 | + public void event(MapEvent<PacketLinkRealizedByOptical, OpticalConnectivity> event) { | ||
| 759 | + switch (event.type()) { | ||
| 760 | + case UPDATE: | ||
| 761 | + OpticalConnectivity oldConnectivity = event.oldValue().value(); | ||
| 762 | + OpticalConnectivity newConnectivity = event.newValue().value(); | ||
| 763 | + | ||
| 764 | + if (!oldConnectivity.isAllRealizingLinkEstablished() && | ||
| 765 | + newConnectivity.isAllRealizingLinkEstablished()) { | ||
| 766 | + // Notifies listeners if all links are established | ||
| 767 | + updateBandwidthUsage(newConnectivity); | ||
| 768 | + post(new OpticalPathEvent(OpticalPathEvent.Type.PATH_INSTALLED, newConnectivity.id())); | ||
| 769 | + } else if (!oldConnectivity.isAllRealizingLinkNotEstablished() && | ||
| 770 | + newConnectivity.isAllRealizingLinkNotEstablished()) { | ||
| 771 | + // Notifies listeners if all links are gone | ||
| 772 | + releaseBandwidthUsage(newConnectivity); | ||
| 773 | + post(new OpticalPathEvent(OpticalPathEvent.Type.PATH_REMOVED, newConnectivity.id())); | ||
| 774 | + } | ||
| 775 | + | ||
| 776 | + break; | ||
| 777 | + default: | ||
| 778 | + break; | ||
| 779 | + } | ||
| 780 | + } | ||
| 781 | + | ||
| 782 | + } | ||
| 689 | } | 783 | } |
| 690 | 784 | ... | ... |
| ... | @@ -33,9 +33,6 @@ public class PacketLinkRealizedByOptical { | ... | @@ -33,9 +33,6 @@ public class PacketLinkRealizedByOptical { |
| 33 | private final Bandwidth bandwidth; | 33 | private final Bandwidth bandwidth; |
| 34 | // TODO should be list of Intent Key? | 34 | // TODO should be list of Intent Key? |
| 35 | private final Key realizingIntentKey; | 35 | private final Key realizingIntentKey; |
| 36 | - // established=false represents that this (packet) link is expected to be | ||
| 37 | - // discovered after underlying (optical) path has been provisioned. | ||
| 38 | - private boolean established; | ||
| 39 | 36 | ||
| 40 | /** | 37 | /** |
| 41 | * Creates instance with specified parameters. | 38 | * Creates instance with specified parameters. |
| ... | @@ -51,7 +48,6 @@ public class PacketLinkRealizedByOptical { | ... | @@ -51,7 +48,6 @@ public class PacketLinkRealizedByOptical { |
| 51 | this.dst = dst; | 48 | this.dst = dst; |
| 52 | this.realizingIntentKey = realizingIntentKey; | 49 | this.realizingIntentKey = realizingIntentKey; |
| 53 | this.bandwidth = bandwidth; | 50 | this.bandwidth = bandwidth; |
| 54 | - this.established = false; | ||
| 55 | } | 51 | } |
| 56 | 52 | ||
| 57 | /** | 53 | /** |
| ... | @@ -129,24 +125,6 @@ public class PacketLinkRealizedByOptical { | ... | @@ -129,24 +125,6 @@ public class PacketLinkRealizedByOptical { |
| 129 | } | 125 | } |
| 130 | 126 | ||
| 131 | /** | 127 | /** |
| 132 | - * Returns whether packet link is realized or not. | ||
| 133 | - * | ||
| 134 | - * @return true if packet link is realized. false if not. | ||
| 135 | - */ | ||
| 136 | - public boolean isEstablished() { | ||
| 137 | - return established; | ||
| 138 | - } | ||
| 139 | - | ||
| 140 | - /** | ||
| 141 | - * Sets packet link to be established. | ||
| 142 | - * | ||
| 143 | - * @param established status of packet link | ||
| 144 | - */ | ||
| 145 | - public void setEstablished(boolean established) { | ||
| 146 | - this.established = established; | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | - /** | ||
| 150 | * Check if packet link is between specified two connect points. | 128 | * Check if packet link is between specified two connect points. |
| 151 | * | 129 | * |
| 152 | * @param src source connect point | 130 | * @param src source connect point |
| ... | @@ -157,4 +135,36 @@ public class PacketLinkRealizedByOptical { | ... | @@ -157,4 +135,36 @@ public class PacketLinkRealizedByOptical { |
| 157 | return (this.src.equals(src) && this.dst.equals(dst)); | 135 | return (this.src.equals(src) && this.dst.equals(dst)); |
| 158 | } | 136 | } |
| 159 | 137 | ||
| 138 | + @Override | ||
| 139 | + public boolean equals(Object o) { | ||
| 140 | + if (this == o) { | ||
| 141 | + return true; | ||
| 142 | + } | ||
| 143 | + if (o == null || getClass() != o.getClass()) { | ||
| 144 | + return false; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + PacketLinkRealizedByOptical that = (PacketLinkRealizedByOptical) o; | ||
| 148 | + | ||
| 149 | + if (!src.equals(that.src)) { | ||
| 150 | + return false; | ||
| 151 | + } | ||
| 152 | + if (!dst.equals(that.dst)) { | ||
| 153 | + return false; | ||
| 154 | + } | ||
| 155 | + if (!bandwidth.equals(that.bandwidth)) { | ||
| 156 | + return false; | ||
| 157 | + } | ||
| 158 | + return realizingIntentKey.equals(that.realizingIntentKey); | ||
| 159 | + | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + @Override | ||
| 163 | + public int hashCode() { | ||
| 164 | + int result = src.hashCode(); | ||
| 165 | + result = 31 * result + dst.hashCode(); | ||
| 166 | + result = 31 * result + bandwidth.hashCode(); | ||
| 167 | + result = 31 * result + realizingIntentKey.hashCode(); | ||
| 168 | + return result; | ||
| 169 | + } | ||
| 160 | } | 170 | } | ... | ... |
| ... | @@ -33,7 +33,7 @@ import java.util.Optional; | ... | @@ -33,7 +33,7 @@ import java.util.Optional; |
| 33 | public interface OpticalPathService extends ListenerService<OpticalPathEvent, OpticalPathListener> { | 33 | public interface OpticalPathService extends ListenerService<OpticalPathEvent, OpticalPathListener> { |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| 36 | - * Calculates optical path between connect points and sets up connectivity. | 36 | + * Calculates multi-layer path between connect points and sets up connectivity. |
| 37 | * | 37 | * |
| 38 | * @param ingress ingress port | 38 | * @param ingress ingress port |
| 39 | * @param egress egress port | 39 | * @param egress egress port |
| ... | @@ -45,9 +45,9 @@ public interface OpticalPathService extends ListenerService<OpticalPathEvent, Op | ... | @@ -45,9 +45,9 @@ public interface OpticalPathService extends ListenerService<OpticalPathEvent, Op |
| 45 | Bandwidth bandwidth, Duration latency); | 45 | Bandwidth bandwidth, Duration latency); |
| 46 | 46 | ||
| 47 | /** | 47 | /** |
| 48 | - * Sets up connectivity along given optical path. | 48 | + * Sets up connectivity along given multi-layer path including cross-connect links. |
| 49 | * | 49 | * |
| 50 | - * @param path path along which connectivity will be set up | 50 | + * @param path multi-layer path along which connectivity will be set up |
| 51 | * @param bandwidth required bandwidth. No bandwidth is assured if null. | 51 | * @param bandwidth required bandwidth. No bandwidth is assured if null. |
| 52 | * @param latency required latency. No latency is assured if null. | 52 | * @param latency required latency. No latency is assured if null. |
| 53 | * @return true if successful. false otherwise. | 53 | * @return true if successful. false otherwise. | ... | ... |
| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | 16 | ||
| 17 | package org.onosproject.newoptical; | 17 | package org.onosproject.newoptical; |
| 18 | 18 | ||
| 19 | +import com.google.common.collect.ImmutableSet; | ||
| 19 | import org.junit.After; | 20 | import org.junit.After; |
| 20 | import org.junit.Before; | 21 | import org.junit.Before; |
| 21 | import org.junit.Test; | 22 | import org.junit.Test; |
| ... | @@ -39,7 +40,9 @@ import org.onosproject.net.provider.ProviderId; | ... | @@ -39,7 +40,9 @@ import org.onosproject.net.provider.ProviderId; |
| 39 | import org.onosproject.newoptical.api.OpticalConnectivityId; | 40 | import org.onosproject.newoptical.api.OpticalConnectivityId; |
| 40 | 41 | ||
| 41 | import java.time.Duration; | 42 | import java.time.Duration; |
| 43 | +import java.util.Collections; | ||
| 42 | import java.util.List; | 44 | import java.util.List; |
| 45 | +import java.util.Set; | ||
| 43 | import java.util.stream.Collectors; | 46 | import java.util.stream.Collectors; |
| 44 | import java.util.stream.Stream; | 47 | import java.util.stream.Stream; |
| 45 | 48 | ||
| ... | @@ -94,10 +97,9 @@ public class OpticalConnectivityTest { | ... | @@ -94,10 +97,9 @@ public class OpticalConnectivityTest { |
| 94 | Link link2 = createLink(cp22, cp31); | 97 | Link link2 = createLink(cp22, cp31); |
| 95 | List<Link> links = Stream.of(link1, link2).collect(Collectors.toList()); | 98 | List<Link> links = Stream.of(link1, link2).collect(Collectors.toList()); |
| 96 | 99 | ||
| 97 | - Path path = new MockPath(cp12, cp31, links); | ||
| 98 | - | ||
| 99 | OpticalConnectivityId cid = OpticalConnectivityId.of(1L); | 100 | OpticalConnectivityId cid = OpticalConnectivityId.of(1L); |
| 100 | - OpticalConnectivity oc = new OpticalConnectivity(cid, path, bandwidth, latency); | 101 | + OpticalConnectivity oc = new OpticalConnectivity(cid, links, bandwidth, latency, |
| 102 | + Collections.emptySet(), Collections.emptySet()); | ||
| 101 | 103 | ||
| 102 | assertNotNull(oc); | 104 | assertNotNull(oc); |
| 103 | assertEquals(oc.id(), cid); | 105 | assertEquals(oc.id(), cid); |
| ... | @@ -133,8 +135,6 @@ public class OpticalConnectivityTest { | ... | @@ -133,8 +135,6 @@ public class OpticalConnectivityTest { |
| 133 | Link link6 = createLink(cp62, cp71); | 135 | Link link6 = createLink(cp62, cp71); |
| 134 | List<Link> links = Stream.of(link1, link2, link3, link4, link5, link6).collect(Collectors.toList()); | 136 | List<Link> links = Stream.of(link1, link2, link3, link4, link5, link6).collect(Collectors.toList()); |
| 135 | 137 | ||
| 136 | - Path path = new MockPath(cp12, cp71, links); | ||
| 137 | - | ||
| 138 | // Mocks 2 intents to create OduCtl connectivity | 138 | // Mocks 2 intents to create OduCtl connectivity |
| 139 | OpticalConnectivityIntent connIntent1 = createConnectivityIntent(cp21, cp32); | 139 | OpticalConnectivityIntent connIntent1 = createConnectivityIntent(cp21, cp32); |
| 140 | PacketLinkRealizedByOptical oduLink1 = PacketLinkRealizedByOptical.create(cp12, cp41, | 140 | PacketLinkRealizedByOptical oduLink1 = PacketLinkRealizedByOptical.create(cp12, cp41, |
| ... | @@ -144,29 +144,29 @@ public class OpticalConnectivityTest { | ... | @@ -144,29 +144,29 @@ public class OpticalConnectivityTest { |
| 144 | PacketLinkRealizedByOptical oduLink2 = PacketLinkRealizedByOptical.create(cp42, cp71, | 144 | PacketLinkRealizedByOptical oduLink2 = PacketLinkRealizedByOptical.create(cp42, cp71, |
| 145 | connIntent2); | 145 | connIntent2); |
| 146 | 146 | ||
| 147 | + Set<PacketLinkRealizedByOptical> plinks = ImmutableSet.of(oduLink1, oduLink2); | ||
| 148 | + | ||
| 147 | Bandwidth bandwidth = Bandwidth.bps(100); | 149 | Bandwidth bandwidth = Bandwidth.bps(100); |
| 148 | Duration latency = Duration.ofMillis(10); | 150 | Duration latency = Duration.ofMillis(10); |
| 149 | 151 | ||
| 150 | OpticalConnectivityId cid = OpticalConnectivityId.of(1L); | 152 | OpticalConnectivityId cid = OpticalConnectivityId.of(1L); |
| 151 | - OpticalConnectivity oc = new OpticalConnectivity(cid, path, bandwidth, latency); | 153 | + OpticalConnectivity oc1 = new OpticalConnectivity(cid, links, bandwidth, latency, |
| 152 | - | 154 | + plinks, Collections.emptySet()); |
| 153 | - oc.addRealizingLink(oduLink1); | ||
| 154 | - oc.addRealizingLink(oduLink2); | ||
| 155 | 155 | ||
| 156 | - assertTrue(oc.isAllRealizingLinkNotEstablished()); | 156 | + assertTrue(oc1.isAllRealizingLinkNotEstablished()); |
| 157 | - assertFalse(oc.isAllRealizingLinkEstablished()); | 157 | + assertFalse(oc1.isAllRealizingLinkEstablished()); |
| 158 | 158 | ||
| 159 | // Sets link realized by connIntent1 to be established | 159 | // Sets link realized by connIntent1 to be established |
| 160 | - oc.setLinkEstablished(cp12, cp41); | 160 | + OpticalConnectivity oc2 = oc1.setLinkEstablished(cp12, cp41, true); |
| 161 | 161 | ||
| 162 | - assertFalse(oc.isAllRealizingLinkNotEstablished()); | 162 | + assertFalse(oc2.isAllRealizingLinkNotEstablished()); |
| 163 | - assertFalse(oc.isAllRealizingLinkEstablished()); | 163 | + assertFalse(oc2.isAllRealizingLinkEstablished()); |
| 164 | 164 | ||
| 165 | // Sets link realized by connIntent2 to be established | 165 | // Sets link realized by connIntent2 to be established |
| 166 | - oc.setLinkEstablished(cp42, cp71); | 166 | + OpticalConnectivity oc3 = oc2.setLinkEstablished(cp42, cp71, true); |
| 167 | 167 | ||
| 168 | - assertFalse(oc.isAllRealizingLinkNotEstablished()); | 168 | + assertFalse(oc3.isAllRealizingLinkNotEstablished()); |
| 169 | - assertTrue(oc.isAllRealizingLinkEstablished()); | 169 | + assertTrue(oc3.isAllRealizingLinkEstablished()); |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | /** | 172 | /** |
| ... | @@ -196,8 +196,6 @@ public class OpticalConnectivityTest { | ... | @@ -196,8 +196,6 @@ public class OpticalConnectivityTest { |
| 196 | Link link6 = createLink(cp62, cp71); | 196 | Link link6 = createLink(cp62, cp71); |
| 197 | List<Link> links = Stream.of(link1, link2, link3, link4, link5, link6).collect(Collectors.toList()); | 197 | List<Link> links = Stream.of(link1, link2, link3, link4, link5, link6).collect(Collectors.toList()); |
| 198 | 198 | ||
| 199 | - Path path = new MockPath(cp12, cp71, links); | ||
| 200 | - | ||
| 201 | // Mocks 2 intents to create Och connectivity | 199 | // Mocks 2 intents to create Och connectivity |
| 202 | OpticalCircuitIntent circuitIntent1 = createCircuitIntent(cp21, cp32); | 200 | OpticalCircuitIntent circuitIntent1 = createCircuitIntent(cp21, cp32); |
| 203 | PacketLinkRealizedByOptical ochLink1 = PacketLinkRealizedByOptical.create(cp12, cp41, | 201 | PacketLinkRealizedByOptical ochLink1 = PacketLinkRealizedByOptical.create(cp12, cp41, |
| ... | @@ -207,29 +205,29 @@ public class OpticalConnectivityTest { | ... | @@ -207,29 +205,29 @@ public class OpticalConnectivityTest { |
| 207 | PacketLinkRealizedByOptical ochLink2 = PacketLinkRealizedByOptical.create(cp42, cp71, | 205 | PacketLinkRealizedByOptical ochLink2 = PacketLinkRealizedByOptical.create(cp42, cp71, |
| 208 | circuitIntent2); | 206 | circuitIntent2); |
| 209 | 207 | ||
| 208 | + Set<PacketLinkRealizedByOptical> plinks = ImmutableSet.of(ochLink1, ochLink2); | ||
| 209 | + | ||
| 210 | Bandwidth bandwidth = Bandwidth.bps(100); | 210 | Bandwidth bandwidth = Bandwidth.bps(100); |
| 211 | Duration latency = Duration.ofMillis(10); | 211 | Duration latency = Duration.ofMillis(10); |
| 212 | 212 | ||
| 213 | OpticalConnectivityId cid = OpticalConnectivityId.of(1L); | 213 | OpticalConnectivityId cid = OpticalConnectivityId.of(1L); |
| 214 | - OpticalConnectivity oc = new OpticalConnectivity(cid, path, bandwidth, latency); | 214 | + OpticalConnectivity oc1 = new OpticalConnectivity(cid, links, bandwidth, latency, |
| 215 | - | 215 | + plinks, Collections.emptySet()); |
| 216 | - oc.addRealizingLink(ochLink1); | ||
| 217 | - oc.addRealizingLink(ochLink2); | ||
| 218 | 216 | ||
| 219 | - assertTrue(oc.isAllRealizingLinkNotEstablished()); | 217 | + assertTrue(oc1.isAllRealizingLinkNotEstablished()); |
| 220 | - assertFalse(oc.isAllRealizingLinkEstablished()); | 218 | + assertFalse(oc1.isAllRealizingLinkEstablished()); |
| 221 | 219 | ||
| 222 | // Sets link realized by circuitIntent1 to be established | 220 | // Sets link realized by circuitIntent1 to be established |
| 223 | - oc.setLinkEstablished(cp12, cp41); | 221 | + OpticalConnectivity oc2 = oc1.setLinkEstablished(cp12, cp41, true); |
| 224 | 222 | ||
| 225 | - assertFalse(oc.isAllRealizingLinkNotEstablished()); | 223 | + assertFalse(oc2.isAllRealizingLinkNotEstablished()); |
| 226 | - assertFalse(oc.isAllRealizingLinkEstablished()); | 224 | + assertFalse(oc2.isAllRealizingLinkEstablished()); |
| 227 | 225 | ||
| 228 | // Sets link realized by circuitIntent2 to be established | 226 | // Sets link realized by circuitIntent2 to be established |
| 229 | - oc.setLinkEstablished(cp42, cp71); | 227 | + OpticalConnectivity oc3 = oc2.setLinkEstablished(cp42, cp71, true); |
| 230 | 228 | ||
| 231 | - assertFalse(oc.isAllRealizingLinkNotEstablished()); | 229 | + assertFalse(oc3.isAllRealizingLinkNotEstablished()); |
| 232 | - assertTrue(oc.isAllRealizingLinkEstablished()); | 230 | + assertTrue(oc3.isAllRealizingLinkEstablished()); |
| 233 | } | 231 | } |
| 234 | 232 | ||
| 235 | private ConnectPoint createConnectPoint(long devIdNum, long portIdNum) { | 233 | private ConnectPoint createConnectPoint(long devIdNum, long portIdNum) { | ... | ... |
| ... | @@ -21,9 +21,12 @@ import org.junit.After; | ... | @@ -21,9 +21,12 @@ import org.junit.After; |
| 21 | import org.junit.Before; | 21 | import org.junit.Before; |
| 22 | import org.junit.Test; | 22 | import org.junit.Test; |
| 23 | import org.onlab.packet.ChassisId; | 23 | import org.onlab.packet.ChassisId; |
| 24 | +import org.onlab.packet.IpAddress; | ||
| 24 | import org.onlab.util.Bandwidth; | 25 | import org.onlab.util.Bandwidth; |
| 25 | import org.onlab.util.Frequency; | 26 | import org.onlab.util.Frequency; |
| 26 | import org.onosproject.cluster.ClusterServiceAdapter; | 27 | import org.onosproject.cluster.ClusterServiceAdapter; |
| 28 | +import org.onosproject.cluster.ControllerNode; | ||
| 29 | +import org.onosproject.cluster.NodeId; | ||
| 27 | import org.onosproject.core.ApplicationId; | 30 | import org.onosproject.core.ApplicationId; |
| 28 | import org.onosproject.core.CoreServiceAdapter; | 31 | import org.onosproject.core.CoreServiceAdapter; |
| 29 | import org.onosproject.core.DefaultApplicationId; | 32 | import org.onosproject.core.DefaultApplicationId; |
| ... | @@ -44,12 +47,15 @@ import org.onosproject.net.Device; | ... | @@ -44,12 +47,15 @@ import org.onosproject.net.Device; |
| 44 | import org.onosproject.net.DeviceId; | 47 | import org.onosproject.net.DeviceId; |
| 45 | import org.onosproject.net.ElementId; | 48 | import org.onosproject.net.ElementId; |
| 46 | import org.onosproject.net.Link; | 49 | import org.onosproject.net.Link; |
| 50 | +import org.onosproject.net.MastershipRole; | ||
| 47 | import org.onosproject.net.OchSignal; | 51 | import org.onosproject.net.OchSignal; |
| 48 | import org.onosproject.net.OduSignalType; | 52 | import org.onosproject.net.OduSignalType; |
| 49 | import org.onosproject.net.Path; | 53 | import org.onosproject.net.Path; |
| 50 | import org.onosproject.net.Port; | 54 | import org.onosproject.net.Port; |
| 51 | import org.onosproject.net.PortNumber; | 55 | import org.onosproject.net.PortNumber; |
| 56 | +import org.onosproject.net.config.Config; | ||
| 52 | import org.onosproject.net.config.NetworkConfigServiceAdapter; | 57 | import org.onosproject.net.config.NetworkConfigServiceAdapter; |
| 58 | +import org.onosproject.net.config.basics.BandwidthCapacity; | ||
| 53 | import org.onosproject.net.device.DeviceServiceAdapter; | 59 | import org.onosproject.net.device.DeviceServiceAdapter; |
| 54 | import org.onosproject.net.intent.Intent; | 60 | import org.onosproject.net.intent.Intent; |
| 55 | import org.onosproject.net.intent.IntentEvent; | 61 | import org.onosproject.net.intent.IntentEvent; |
| ... | @@ -74,8 +80,20 @@ import org.onosproject.net.topology.PathServiceAdapter; | ... | @@ -74,8 +80,20 @@ import org.onosproject.net.topology.PathServiceAdapter; |
| 74 | import org.onosproject.newoptical.api.OpticalConnectivityId; | 80 | import org.onosproject.newoptical.api.OpticalConnectivityId; |
| 75 | import org.onosproject.newoptical.api.OpticalPathEvent; | 81 | import org.onosproject.newoptical.api.OpticalPathEvent; |
| 76 | import org.onosproject.newoptical.api.OpticalPathListener; | 82 | import org.onosproject.newoptical.api.OpticalPathListener; |
| 83 | +import org.onosproject.store.service.AsyncConsistentMap; | ||
| 84 | +import org.onosproject.store.service.AsyncDistributedSet; | ||
| 77 | import org.onosproject.store.service.AtomicCounter; | 85 | import org.onosproject.store.service.AtomicCounter; |
| 86 | +import org.onosproject.store.service.ConsistentMap; | ||
| 87 | +import org.onosproject.store.service.ConsistentMapAdapter; | ||
| 88 | +import org.onosproject.store.service.ConsistentMapBuilder; | ||
| 89 | +import org.onosproject.store.service.DistributedSet; | ||
| 90 | +import org.onosproject.store.service.DistributedSetAdapter; | ||
| 91 | +import org.onosproject.store.service.DistributedSetBuilder; | ||
| 92 | +import org.onosproject.store.service.MapEvent; | ||
| 93 | +import org.onosproject.store.service.MapEventListener; | ||
| 94 | +import org.onosproject.store.service.SetEventListener; | ||
| 78 | import org.onosproject.store.service.StorageServiceAdapter; | 95 | import org.onosproject.store.service.StorageServiceAdapter; |
| 96 | +import org.onosproject.store.service.Versioned; | ||
| 79 | 97 | ||
| 80 | import java.time.Duration; | 98 | import java.time.Duration; |
| 81 | import java.util.ArrayList; | 99 | import java.util.ArrayList; |
| ... | @@ -87,6 +105,8 @@ import java.util.List; | ... | @@ -87,6 +105,8 @@ import java.util.List; |
| 87 | import java.util.Map; | 105 | import java.util.Map; |
| 88 | import java.util.Optional; | 106 | import java.util.Optional; |
| 89 | import java.util.Set; | 107 | import java.util.Set; |
| 108 | +import java.util.concurrent.Executor; | ||
| 109 | +import java.util.function.BiFunction; | ||
| 90 | import java.util.stream.Collectors; | 110 | import java.util.stream.Collectors; |
| 91 | import java.util.stream.Stream; | 111 | import java.util.stream.Stream; |
| 92 | 112 | ||
| ... | @@ -155,6 +175,8 @@ public class OpticalPathProvisionerTest { | ... | @@ -155,6 +175,8 @@ public class OpticalPathProvisionerTest { |
| 155 | protected TestLinkService linkService; | 175 | protected TestLinkService linkService; |
| 156 | protected TestPathService pathService; | 176 | protected TestPathService pathService; |
| 157 | protected TestIntentService intentService; | 177 | protected TestIntentService intentService; |
| 178 | + protected TestMastershipService mastershipService; | ||
| 179 | + protected TestClusterService clusterService; | ||
| 158 | protected IdGenerator idGenerator; | 180 | protected IdGenerator idGenerator; |
| 159 | 181 | ||
| 160 | @Before | 182 | @Before |
| ... | @@ -188,14 +210,24 @@ public class OpticalPathProvisionerTest { | ... | @@ -188,14 +210,24 @@ public class OpticalPathProvisionerTest { |
| 188 | 210 | ||
| 189 | this.pathService = new TestPathService(); | 211 | this.pathService = new TestPathService(); |
| 190 | this.intentService = new TestIntentService(); | 212 | this.intentService = new TestIntentService(); |
| 213 | + this.mastershipService = new TestMastershipService(); | ||
| 214 | + this.clusterService = new TestClusterService(); | ||
| 215 | + | ||
| 216 | + mastershipService.setMastership(DEVICE1.id(), MastershipRole.MASTER); | ||
| 217 | + mastershipService.setMastership(DEVICE2.id(), MastershipRole.MASTER); | ||
| 218 | + mastershipService.setMastership(DEVICE3.id(), MastershipRole.MASTER); | ||
| 219 | + mastershipService.setMastership(DEVICE4.id(), MastershipRole.MASTER); | ||
| 220 | + mastershipService.setMastership(DEVICE5.id(), MastershipRole.MASTER); | ||
| 221 | + mastershipService.setMastership(DEVICE6.id(), MastershipRole.MASTER); | ||
| 222 | + mastershipService.setMastership(DEVICE7.id(), MastershipRole.MASTER); | ||
| 191 | 223 | ||
| 192 | this.target = new OpticalPathProvisioner(); | 224 | this.target = new OpticalPathProvisioner(); |
| 193 | target.coreService = new TestCoreService(); | 225 | target.coreService = new TestCoreService(); |
| 194 | target.intentService = this.intentService; | 226 | target.intentService = this.intentService; |
| 195 | target.pathService = this.pathService; | 227 | target.pathService = this.pathService; |
| 196 | target.linkService = this.linkService; | 228 | target.linkService = this.linkService; |
| 197 | - target.mastershipService = new TestMastershipService(); | 229 | + target.mastershipService = this.mastershipService; |
| 198 | - target.clusterService = new TestClusterService(); | 230 | + target.clusterService = this.clusterService; |
| 199 | target.storageService = new TestStorageService(); | 231 | target.storageService = new TestStorageService(); |
| 200 | target.deviceService = this.deviceService; | 232 | target.deviceService = this.deviceService; |
| 201 | target.networkConfigService = new TestNetworkConfigService(); | 233 | target.networkConfigService = new TestNetworkConfigService(); |
| ... | @@ -310,15 +342,16 @@ public class OpticalPathProvisionerTest { | ... | @@ -310,15 +342,16 @@ public class OpticalPathProvisionerTest { |
| 310 | } | 342 | } |
| 311 | 343 | ||
| 312 | /** | 344 | /** |
| 313 | - * Checks if PATH_INSTALLED event comes up after intent is installed. | 345 | + * Checks if PATH_INSTALLED event comes up after intent whose master is this node is installed. |
| 314 | */ | 346 | */ |
| 315 | @Test | 347 | @Test |
| 316 | - public void testInstalledEvent() { | 348 | + public void testInstalledEventLocal() { |
| 317 | Bandwidth bandwidth = Bandwidth.bps(100); | 349 | Bandwidth bandwidth = Bandwidth.bps(100); |
| 318 | Duration latency = Duration.ofMillis(10); | 350 | Duration latency = Duration.ofMillis(10); |
| 319 | 351 | ||
| 320 | OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency); | 352 | OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency); |
| 321 | 353 | ||
| 354 | + // notify all intents are installed | ||
| 322 | intentService.notifyInstalled(); | 355 | intentService.notifyInstalled(); |
| 323 | 356 | ||
| 324 | assertEquals(1, listener.events.size()); | 357 | assertEquals(1, listener.events.size()); |
| ... | @@ -327,26 +360,77 @@ public class OpticalPathProvisionerTest { | ... | @@ -327,26 +360,77 @@ public class OpticalPathProvisionerTest { |
| 327 | } | 360 | } |
| 328 | 361 | ||
| 329 | /** | 362 | /** |
| 363 | + * Checks if PATH_INSTALLED event comes up after intent whose master is remote node is installed. | ||
| 364 | + */ | ||
| 365 | + @Test | ||
| 366 | + public void testInstalledEventRemote() { | ||
| 367 | + // set the master for ingress device of intent to remote node | ||
| 368 | + mastershipService.setMastership(DEVICE2.id(), MastershipRole.NONE); | ||
| 369 | + | ||
| 370 | + Bandwidth bandwidth = Bandwidth.bps(100); | ||
| 371 | + Duration latency = Duration.ofMillis(10); | ||
| 372 | + | ||
| 373 | + OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency); | ||
| 374 | + | ||
| 375 | + // notify all intents are installed | ||
| 376 | + intentService.notifyInstalled(); | ||
| 377 | + | ||
| 378 | + // remote nodes must not receive event before distributed map is updated | ||
| 379 | + assertEquals(0, listener.events.size()); | ||
| 380 | + } | ||
| 381 | + | ||
| 382 | + /** | ||
| 330 | * Checks if PATH_REMOVED event comes up after packet link is removed. | 383 | * Checks if PATH_REMOVED event comes up after packet link is removed. |
| 331 | */ | 384 | */ |
| 332 | @Test | 385 | @Test |
| 333 | - public void testRemovedEvent() { | 386 | + public void testRemovedEventLocal() { |
| 334 | Bandwidth bandwidth = Bandwidth.bps(100); | 387 | Bandwidth bandwidth = Bandwidth.bps(100); |
| 335 | Duration latency = Duration.ofMillis(10); | 388 | Duration latency = Duration.ofMillis(10); |
| 336 | 389 | ||
| 337 | OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency); | 390 | OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency); |
| 338 | 391 | ||
| 392 | + // notify all intents are installed | ||
| 339 | intentService.notifyInstalled(); | 393 | intentService.notifyInstalled(); |
| 340 | 394 | ||
| 341 | target.removeConnectivity(cid); | 395 | target.removeConnectivity(cid); |
| 342 | 396 | ||
| 397 | + // notify all intents are withdrawn | ||
| 343 | intentService.notifyWithdrawn(); | 398 | intentService.notifyWithdrawn(); |
| 344 | 399 | ||
| 400 | + // must have received "INSTALLED" and "REMOVED" events | ||
| 345 | assertEquals(2, listener.events.size()); | 401 | assertEquals(2, listener.events.size()); |
| 402 | + assertEquals(OpticalPathEvent.Type.PATH_INSTALLED, listener.events.get(0).type()); | ||
| 403 | + assertEquals(cid, listener.events.get(0).subject()); | ||
| 346 | assertEquals(OpticalPathEvent.Type.PATH_REMOVED, listener.events.get(1).type()); | 404 | assertEquals(OpticalPathEvent.Type.PATH_REMOVED, listener.events.get(1).type()); |
| 347 | assertEquals(cid, listener.events.get(1).subject()); | 405 | assertEquals(cid, listener.events.get(1).subject()); |
| 348 | } | 406 | } |
| 349 | 407 | ||
| 408 | + | ||
| 409 | + /** | ||
| 410 | + * Checks if PATH_REMOVED event comes up after packet link is removed. | ||
| 411 | + */ | ||
| 412 | + @Test | ||
| 413 | + public void testRemovedEventRemote() { | ||
| 414 | + // set the master for ingress device of intent to remote node | ||
| 415 | + mastershipService.setMastership(DEVICE2.id(), MastershipRole.NONE); | ||
| 416 | + | ||
| 417 | + Bandwidth bandwidth = Bandwidth.bps(100); | ||
| 418 | + Duration latency = Duration.ofMillis(10); | ||
| 419 | + | ||
| 420 | + OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency); | ||
| 421 | + | ||
| 422 | + // notify all intents are installed | ||
| 423 | + intentService.notifyInstalled(); | ||
| 424 | + | ||
| 425 | + target.removeConnectivity(cid); | ||
| 426 | + | ||
| 427 | + // notify all intents are withdrawn | ||
| 428 | + intentService.notifyWithdrawn(); | ||
| 429 | + | ||
| 430 | + // remote nodes must not receive event before distributed map is updated | ||
| 431 | + assertEquals(0, listener.events.size()); | ||
| 432 | + } | ||
| 433 | + | ||
| 350 | private static ConnectPoint createConnectPoint(long devIdNum, long portIdNum) { | 434 | private static ConnectPoint createConnectPoint(long devIdNum, long portIdNum) { |
| 351 | return new ConnectPoint( | 435 | return new ConnectPoint( |
| 352 | deviceIdOf(devIdNum), | 436 | deviceIdOf(devIdNum), |
| ... | @@ -495,18 +579,192 @@ public class OpticalPathProvisionerTest { | ... | @@ -495,18 +579,192 @@ public class OpticalPathProvisionerTest { |
| 495 | } | 579 | } |
| 496 | 580 | ||
| 497 | private static class TestMastershipService extends MastershipServiceAdapter { | 581 | private static class TestMastershipService extends MastershipServiceAdapter { |
| 582 | + private Map<DeviceId, MastershipRole> mastershipMap = new HashMap<>(); | ||
| 583 | + | ||
| 584 | + public void setMastership(DeviceId deviceId, MastershipRole role) { | ||
| 585 | + mastershipMap.put(deviceId, role); | ||
| 586 | + } | ||
| 587 | + | ||
| 588 | + public void clear() { | ||
| 589 | + mastershipMap.clear(); | ||
| 590 | + } | ||
| 591 | + | ||
| 592 | + @Override | ||
| 593 | + public MastershipRole getLocalRole(DeviceId deviceId) { | ||
| 594 | + return mastershipMap.get(deviceId); | ||
| 595 | + } | ||
| 498 | 596 | ||
| 499 | } | 597 | } |
| 500 | 598 | ||
| 501 | private static class TestClusterService extends ClusterServiceAdapter { | 599 | private static class TestClusterService extends ClusterServiceAdapter { |
| 600 | + private NodeId nodeId; | ||
| 601 | + | ||
| 602 | + public void setLocalNode(String nodeIdStr) { | ||
| 603 | + nodeId = NodeId.nodeId(nodeIdStr); | ||
| 604 | + } | ||
| 605 | + | ||
| 606 | + @Override | ||
| 607 | + public ControllerNode getLocalNode() { | ||
| 608 | + return new ControllerNode() { | ||
| 609 | + @Override | ||
| 610 | + public NodeId id() { | ||
| 611 | + return nodeId; | ||
| 612 | + } | ||
| 502 | 613 | ||
| 614 | + @Override | ||
| 615 | + public IpAddress ip() { | ||
| 616 | + return null; | ||
| 617 | + } | ||
| 618 | + | ||
| 619 | + @Override | ||
| 620 | + public int tcpPort() { | ||
| 621 | + return 0; | ||
| 622 | + } | ||
| 623 | + }; | ||
| 624 | + } | ||
| 503 | } | 625 | } |
| 504 | 626 | ||
| 505 | private static class TestStorageService extends StorageServiceAdapter { | 627 | private static class TestStorageService extends StorageServiceAdapter { |
| 628 | + | ||
| 629 | + @Override | ||
| 630 | + public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() { | ||
| 631 | + ConsistentMapBuilder<K, V> builder = new ConsistentMapBuilder<K, V>() { | ||
| 632 | + @Override | ||
| 633 | + public AsyncConsistentMap<K, V> buildAsyncMap() { | ||
| 634 | + return null; | ||
| 635 | + } | ||
| 636 | + | ||
| 637 | + @Override | ||
| 638 | + public ConsistentMap<K, V> build() { | ||
| 639 | + return new TestConsistentMap<K, V>(); | ||
| 640 | + } | ||
| 641 | + }; | ||
| 642 | + | ||
| 643 | + return builder; | ||
| 644 | + } | ||
| 645 | + | ||
| 646 | + @Override | ||
| 647 | + public <E> DistributedSetBuilder<E> setBuilder() { | ||
| 648 | + DistributedSetBuilder<E> builder = new DistributedSetBuilder<E>() { | ||
| 649 | + @Override | ||
| 650 | + public AsyncDistributedSet<E> build() { | ||
| 651 | + return new DistributedSetAdapter<E>() { | ||
| 652 | + @Override | ||
| 653 | + public DistributedSet<E> asDistributedSet() { | ||
| 654 | + return new TestDistributedSet<E>(); | ||
| 655 | + } | ||
| 656 | + }; | ||
| 657 | + } | ||
| 658 | + }; | ||
| 659 | + | ||
| 660 | + return builder; | ||
| 661 | + } | ||
| 662 | + | ||
| 506 | @Override | 663 | @Override |
| 507 | public AtomicCounter getAtomicCounter(String name) { | 664 | public AtomicCounter getAtomicCounter(String name) { |
| 508 | return new MockAtomicCounter(); | 665 | return new MockAtomicCounter(); |
| 509 | } | 666 | } |
| 667 | + | ||
| 668 | + // Mock ConsistentMap that behaves as a HashMap | ||
| 669 | + class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { | ||
| 670 | + private Map<K, Versioned<V>> map = new HashMap<>(); | ||
| 671 | + private Map<MapEventListener<K, V>, Executor> listeners = new HashMap<>(); | ||
| 672 | + | ||
| 673 | + public void notifyListeners(MapEvent<K, V> event) { | ||
| 674 | + listeners.forEach((c, e) -> e.execute(() -> c.event(event))); | ||
| 675 | + } | ||
| 676 | + | ||
| 677 | + @Override | ||
| 678 | + public int size() { | ||
| 679 | + return map.size(); | ||
| 680 | + } | ||
| 681 | + | ||
| 682 | + @Override | ||
| 683 | + public Versioned<V> put(K key, V value) { | ||
| 684 | + Versioned<V> oldValue = map.get(key); | ||
| 685 | + Versioned<V> newValue = new Versioned<>(value, oldValue == null ? 0 : oldValue.version() + 1); | ||
| 686 | + map.put(key, newValue); | ||
| 687 | + notifyListeners(new MapEvent<>(name(), key, newValue, oldValue)); | ||
| 688 | + return newValue; | ||
| 689 | + } | ||
| 690 | + | ||
| 691 | + @Override | ||
| 692 | + public Versioned<V> get(K key) { | ||
| 693 | + return map.get(key); | ||
| 694 | + } | ||
| 695 | + | ||
| 696 | + @Override | ||
| 697 | + public Versioned<V> remove(K key) { | ||
| 698 | + Versioned<V> oldValue = map.remove(key); | ||
| 699 | + notifyListeners(new MapEvent<>(name(), key, oldValue, null)); | ||
| 700 | + return oldValue; | ||
| 701 | + } | ||
| 702 | + | ||
| 703 | + @Override | ||
| 704 | + public Versioned<V> computeIfPresent(K key, | ||
| 705 | + BiFunction<? super K, ? super V, ? extends V> remappingFunction) { | ||
| 706 | + Versioned<V> oldValue = map.get(key); | ||
| 707 | + Versioned<V> newValue = new Versioned<>(remappingFunction.apply(key, oldValue.value()), | ||
| 708 | + oldValue == null ? 0 : oldValue.version() + 1); | ||
| 709 | + map.put(key, newValue); | ||
| 710 | + notifyListeners(new MapEvent<>(name(), key, newValue, oldValue)); | ||
| 711 | + return newValue; | ||
| 712 | + } | ||
| 713 | + | ||
| 714 | + | ||
| 715 | + @Override | ||
| 716 | + public Set<Map.Entry<K, Versioned<V>>> entrySet() { | ||
| 717 | + return map.entrySet(); | ||
| 718 | + } | ||
| 719 | + | ||
| 720 | + @Override | ||
| 721 | + public Set<K> keySet() { | ||
| 722 | + return map.keySet(); | ||
| 723 | + } | ||
| 724 | + | ||
| 725 | + @Override | ||
| 726 | + public Collection<Versioned<V>> values() { | ||
| 727 | + return map.values(); | ||
| 728 | + } | ||
| 729 | + | ||
| 730 | + @Override | ||
| 731 | + public void clear() { | ||
| 732 | + map.clear(); | ||
| 733 | + } | ||
| 734 | + | ||
| 735 | + @Override | ||
| 736 | + public void addListener(MapEventListener<K, V> listener, Executor executor) { | ||
| 737 | + listeners.put(listener, executor); | ||
| 738 | + } | ||
| 739 | + | ||
| 740 | + @Override | ||
| 741 | + public void removeListener(MapEventListener<K, V> listener) { | ||
| 742 | + listeners.remove(listener); | ||
| 743 | + } | ||
| 744 | + } | ||
| 745 | + | ||
| 746 | + // Mock DistributedSet that behaves as a HashSet | ||
| 747 | + class TestDistributedSet<E> extends HashSet<E> implements DistributedSet<E> { | ||
| 748 | + | ||
| 749 | + @Override | ||
| 750 | + public void addListener(SetEventListener<E> listener) { | ||
| 751 | + } | ||
| 752 | + | ||
| 753 | + @Override | ||
| 754 | + public void removeListener(SetEventListener<E> listener) { | ||
| 755 | + } | ||
| 756 | + | ||
| 757 | + @Override | ||
| 758 | + public String name() { | ||
| 759 | + return null; | ||
| 760 | + } | ||
| 761 | + | ||
| 762 | + @Override | ||
| 763 | + public Type primitiveType() { | ||
| 764 | + return null; | ||
| 765 | + } | ||
| 766 | + } | ||
| 767 | + | ||
| 510 | } | 768 | } |
| 511 | 769 | ||
| 512 | private static class TestDeviceService extends DeviceServiceAdapter { | 770 | private static class TestDeviceService extends DeviceServiceAdapter { |
| ... | @@ -525,6 +783,25 @@ public class OpticalPathProvisionerTest { | ... | @@ -525,6 +783,25 @@ public class OpticalPathProvisionerTest { |
| 525 | } | 783 | } |
| 526 | 784 | ||
| 527 | private static class TestNetworkConfigService extends NetworkConfigServiceAdapter { | 785 | private static class TestNetworkConfigService extends NetworkConfigServiceAdapter { |
| 786 | + @Override | ||
| 787 | + @SuppressWarnings("unchecked") | ||
| 788 | + public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) { | ||
| 789 | + if (BandwidthCapacity.class.equals(configClass)) { | ||
| 790 | + return (C) new BandwidthCapacity() { | ||
| 791 | + @Override | ||
| 792 | + public void apply() { | ||
| 793 | + // do nothing | ||
| 794 | + } | ||
| 795 | + | ||
| 796 | + @Override | ||
| 797 | + public BandwidthCapacity capacity(Bandwidth bandwidth) { | ||
| 798 | + // do nothing | ||
| 799 | + return this; | ||
| 800 | + } | ||
| 801 | + }; | ||
| 802 | + } | ||
| 803 | + return null; | ||
| 804 | + } | ||
| 528 | 805 | ||
| 529 | } | 806 | } |
| 530 | 807 | ... | ... |
-
Please register or login to post a comment