Committed by
Gerrit Code Review
ACTN TE Topology APP Implementation. Function of the implementation:
- receives multiple TE topologies from SB provider, and merge into one native TE topology - store both original, received TE topologies and the native topology in TE topology data store - provide APIs for NB APP to retreive and display the TE topologies. Change-Id: Id0b2f3433966694fcf197cc0b8ad19a063e92f36
Showing
5 changed files
with
828 additions
and
0 deletions
1 | +/* | ||
2 | + * Copyright 2016 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.tetopology.management.impl; | ||
17 | + | ||
18 | +import static org.slf4j.LoggerFactory.getLogger; | ||
19 | + | ||
20 | +import java.util.List; | ||
21 | +import java.lang.annotation.ElementType; | ||
22 | +import java.math.BigDecimal; | ||
23 | +import java.math.BigInteger; | ||
24 | +import java.util.ArrayList; | ||
25 | +import java.util.Map; | ||
26 | + | ||
27 | +import org.apache.felix.scr.annotations.Activate; | ||
28 | +import org.apache.felix.scr.annotations.Component; | ||
29 | +import org.apache.felix.scr.annotations.Deactivate; | ||
30 | +import org.apache.felix.scr.annotations.Reference; | ||
31 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
32 | +import org.apache.felix.scr.annotations.Service; | ||
33 | +import org.onlab.packet.IpAddress; | ||
34 | +import org.onlab.util.KryoNamespace; | ||
35 | +import org.onosproject.store.AbstractStore; | ||
36 | +import org.onosproject.store.serializers.KryoNamespaces; | ||
37 | +import org.onosproject.store.service.ConsistentMap; | ||
38 | +import org.onosproject.store.service.MapEvent; | ||
39 | +import org.onosproject.store.service.MapEventListener; | ||
40 | +import org.onosproject.store.service.Serializer; | ||
41 | +import org.onosproject.store.service.StorageService; | ||
42 | +import org.onosproject.tetopology.management.api.KeyId; | ||
43 | +import org.onosproject.tetopology.management.api.Network; | ||
44 | +import org.onosproject.tetopology.management.api.Networks; | ||
45 | +import org.onosproject.tetopology.management.api.TeTopologyEvent; | ||
46 | +import org.onosproject.tetopology.management.api.TeTopologyId; | ||
47 | +import org.onosproject.tetopology.management.api.TeTopologyType; | ||
48 | +import org.onosproject.tetopology.management.api.link.AsNumber; | ||
49 | +import org.onosproject.tetopology.management.api.link.DefaultNetworkLink; | ||
50 | +import org.onosproject.tetopology.management.api.link.ExternalDomain; | ||
51 | +import org.onosproject.tetopology.management.api.link.TeIpv4; | ||
52 | +import org.onosproject.tetopology.management.api.link.TeIpv6; | ||
53 | +import org.onosproject.tetopology.management.api.link.Label; | ||
54 | +import org.onosproject.tetopology.management.api.link.LinkProtectionType; | ||
55 | +import org.onosproject.tetopology.management.api.link.NetworkLink; | ||
56 | +import org.onosproject.tetopology.management.api.link.NetworkLinkKey; | ||
57 | +import org.onosproject.tetopology.management.api.link.PathElement; | ||
58 | +import org.onosproject.tetopology.management.api.link.TeLink; | ||
59 | +import org.onosproject.tetopology.management.api.link.TeLinkAccessType; | ||
60 | +import org.onosproject.tetopology.management.api.link.UnderlayBackupPath; | ||
61 | +import org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath; | ||
62 | +import org.onosproject.tetopology.management.api.link.UnnumberedLink; | ||
63 | +import org.onosproject.tetopology.management.api.link.UnreservedBandwidth; | ||
64 | +import org.onosproject.tetopology.management.api.node.ConnectivityMatrix; | ||
65 | +import org.onosproject.tetopology.management.api.node.DefaultNetworkNode; | ||
66 | +import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint; | ||
67 | +import org.onosproject.tetopology.management.api.node.InterfaceSwitchingCapability; | ||
68 | +import org.onosproject.tetopology.management.api.node.NetworkNode; | ||
69 | +import org.onosproject.tetopology.management.api.node.NetworkNodeKey; | ||
70 | +import org.onosproject.tetopology.management.api.node.TeNetworkTopologyId; | ||
71 | +import org.onosproject.tetopology.management.api.node.TeNode; | ||
72 | +import org.onosproject.tetopology.management.api.node.TeStatus; | ||
73 | +import org.onosproject.tetopology.management.api.node.TeTerminationPoint; | ||
74 | +import org.onosproject.tetopology.management.api.node.TerminationCapability; | ||
75 | +import org.onosproject.tetopology.management.api.node.TerminationPoint; | ||
76 | +import org.onosproject.tetopology.management.api.node.TerminationPointKey; | ||
77 | +import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint; | ||
78 | +import org.onosproject.tetopology.management.api.TeTopologyStore; | ||
79 | +import org.onosproject.tetopology.management.api.TeTopologyStoreDelegate; | ||
80 | +import org.onosproject.tetopology.management.api.DefaultNetwork; | ||
81 | +import org.onosproject.tetopology.management.api.DefaultNetworks; | ||
82 | +import org.onosproject.tetopology.management.api.InternalTeNetwork; | ||
83 | +import org.slf4j.Logger; | ||
84 | + | ||
85 | +/** | ||
86 | + * Implementation of the IETF network store. | ||
87 | + */ | ||
88 | +@Component(immediate = true) | ||
89 | +@Service | ||
90 | +public class DistributedTeTopologyStore | ||
91 | + extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate> | ||
92 | + implements TeTopologyStore { | ||
93 | + | ||
94 | + private final Logger log = getLogger(getClass()); | ||
95 | + | ||
96 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
97 | + protected StorageService storageService; | ||
98 | + | ||
99 | + // Track networks by network key | ||
100 | + private ConsistentMap<KeyId, InternalTeNetwork> networkIdNetworkConsistentMap; | ||
101 | + private Map<KeyId, InternalTeNetwork> networkIdNetworkMap; | ||
102 | + | ||
103 | + // Listener for network events | ||
104 | + private final MapEventListener<KeyId, InternalTeNetwork> networkMapListener = new InternalNetworkMapListener(); | ||
105 | + | ||
106 | + private static final Serializer NETWORK_SERIALIZER = Serializer | ||
107 | + .using(new KryoNamespace.Builder().register(KryoNamespaces.API) | ||
108 | + .register(KeyId.class) | ||
109 | + .register(InternalTeNetwork.class) | ||
110 | + .register(TeTopologyId.class) | ||
111 | + .register(DefaultNetwork.class) | ||
112 | + .register(DefaultNetworks.class) | ||
113 | + .register(InternalTeNetwork.class) | ||
114 | + .register(Network.class) | ||
115 | + .register(Networks.class) | ||
116 | + .register(TeTopologyType.class) | ||
117 | + .register(TeIpv4.class) | ||
118 | + .register(NetworkLinkKey.class) | ||
119 | + .register(NetworkLink.class) | ||
120 | + .register(PathElement.class) | ||
121 | + .register(TeLink.class) | ||
122 | + .register(UnderlayBackupPath.class) | ||
123 | + .register(UnderlayPrimaryPath.class) | ||
124 | + .register(UnnumberedLink.class) | ||
125 | + .register(UnreservedBandwidth.class) | ||
126 | + .register(InterfaceSwitchingCapability.class) | ||
127 | + .register(NetworkNode.class) | ||
128 | + .register(TeNode.class) | ||
129 | + .register(TerminationPoint.class) | ||
130 | + .register(TeTerminationPoint.class) | ||
131 | + .register(TerminationCapability.class) | ||
132 | + .register(TeStatus.class) | ||
133 | + .register(TunnelTerminationPoint.class) | ||
134 | + .register(DefaultNetworkLink.class) | ||
135 | + .register(DefaultNetworkNode.class) | ||
136 | + .register(DefaultTerminationPoint.class) | ||
137 | + .register(TerminationPointKey.class) | ||
138 | + .register(TeNetworkTopologyId.class) | ||
139 | + .register(NetworkNodeKey.class) | ||
140 | + .register(ConnectivityMatrix.class) | ||
141 | + .register(TeTopologyId.class) | ||
142 | + .register(TeLinkAccessType.class) | ||
143 | + .register(BigInteger.class) | ||
144 | + .register(String.class) | ||
145 | + .register(Long.class) | ||
146 | + .register(Boolean.class) | ||
147 | + .register(BigDecimal.class) | ||
148 | + .register(Short.class) | ||
149 | + .register(IpAddress.class) | ||
150 | + .register(Integer.class) | ||
151 | + .register(ExternalDomain.class) | ||
152 | + .register(ElementType.class) | ||
153 | + .register(LinkProtectionType.class) | ||
154 | + .register(Label.class) | ||
155 | + .register(TeIpv6.class) | ||
156 | + .register(AsNumber.class) | ||
157 | + .build()); | ||
158 | + | ||
159 | + /** | ||
160 | + * Distributed network store service activate method. | ||
161 | + */ | ||
162 | + @Activate | ||
163 | + public void activate() { | ||
164 | + log.info("TE topology store is activated"); | ||
165 | + networkIdNetworkConsistentMap = storageService.<KeyId, InternalTeNetwork>consistentMapBuilder() | ||
166 | + .withSerializer(NETWORK_SERIALIZER) | ||
167 | + .withName("networkId-network") | ||
168 | + .withRelaxedReadConsistency() | ||
169 | + .build(); | ||
170 | + networkIdNetworkConsistentMap.addListener(networkMapListener); | ||
171 | + networkIdNetworkMap = networkIdNetworkConsistentMap.asJavaMap(); | ||
172 | + | ||
173 | + log.info("Started"); | ||
174 | + } | ||
175 | + | ||
176 | + /** | ||
177 | + * Distributed network store service deactivate method. | ||
178 | + */ | ||
179 | + @Deactivate | ||
180 | + public void deactivate() { | ||
181 | + networkIdNetworkConsistentMap.removeListener(networkMapListener); | ||
182 | + log.info("Stopped"); | ||
183 | + } | ||
184 | + | ||
185 | + @Override | ||
186 | + public List<InternalTeNetwork> getNetworks(TeTopologyType type) { | ||
187 | + List<InternalTeNetwork> networks = new ArrayList<>(); | ||
188 | + | ||
189 | + for (Map.Entry<KeyId, InternalTeNetwork> entry:networkIdNetworkMap.entrySet()) { | ||
190 | + KeyId networkId = entry.getKey(); | ||
191 | + InternalTeNetwork network = entry.getValue(); | ||
192 | + | ||
193 | + if (network.getTeTopologyType() == type || | ||
194 | + type == TeTopologyType.ANY) { | ||
195 | + networks.add(network); | ||
196 | + } | ||
197 | + } | ||
198 | + | ||
199 | + return networks; | ||
200 | + } | ||
201 | + | ||
202 | + @Override | ||
203 | + public InternalTeNetwork getNetwork(KeyId networkId) { | ||
204 | + return networkIdNetworkMap.get(networkId); | ||
205 | + } | ||
206 | + | ||
207 | + @Override | ||
208 | + public void updateNetwork(InternalTeNetwork network) { | ||
209 | + //TODO - check the validity of the network before updating | ||
210 | + log.info("network = {}", network); | ||
211 | + networkIdNetworkMap.put(network.networkId(), network); | ||
212 | + } | ||
213 | + | ||
214 | + @Override | ||
215 | + public void removeNetwork(KeyId networkId) { | ||
216 | + networkIdNetworkMap.remove(networkId); | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * Listener class to map listener map events to the network events. | ||
221 | + */ | ||
222 | + private class InternalNetworkMapListener implements MapEventListener<KeyId, InternalTeNetwork> { | ||
223 | + @Override | ||
224 | + public void event(MapEvent<KeyId, InternalTeNetwork> event) { | ||
225 | + TeTopologyEvent.Type type = null; | ||
226 | + TeTopologyEvent topologyEvent = null; | ||
227 | + switch (event.type()) { | ||
228 | + case INSERT: | ||
229 | + type = TeTopologyEvent.Type.NETWORK_ADDED; | ||
230 | + // Need to check if nodes/links are already in, otherwise errors | ||
231 | + topologyEvent = new TeTopologyEvent(type, event.newValue().value()); | ||
232 | + break; | ||
233 | + case UPDATE: | ||
234 | + // Need to check what attributes change, and coordinate with other Node/Link events. | ||
235 | + if ((event.oldValue().value() != null) && (event.newValue().value() == null)) { | ||
236 | + type = TeTopologyEvent.Type.NETWORK_REMOVED; | ||
237 | + topologyEvent = new TeTopologyEvent(type, event.oldValue().value()); | ||
238 | + } else { | ||
239 | + type = TeTopologyEvent.Type.NETWORK_UPDATED; | ||
240 | + topologyEvent = new TeTopologyEvent(type, event.newValue().value()); | ||
241 | + } | ||
242 | + break; | ||
243 | + case REMOVE: | ||
244 | + type = TeTopologyEvent.Type.NETWORK_REMOVED; | ||
245 | + topologyEvent = new TeTopologyEvent(type, event.oldValue().value()); | ||
246 | + break; | ||
247 | + default: | ||
248 | + log.error("Unsupported event type: {}", event.type()); | ||
249 | + } | ||
250 | + log.info("Event type {}, Event {}", type, topologyEvent); | ||
251 | + if (topologyEvent != null) { | ||
252 | + notifyDelegate(topologyEvent); | ||
253 | + } | ||
254 | + } | ||
255 | + } | ||
256 | + | ||
257 | +} | ||
258 | + |
apps/tetopology/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyIdConfig.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016 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.tetopology.management.impl; | ||
17 | + | ||
18 | +import org.onosproject.core.ApplicationId; | ||
19 | +import org.onosproject.incubator.net.config.basics.ConfigException; | ||
20 | +import org.onosproject.net.config.Config; | ||
21 | +import org.onosproject.tetopology.management.api.TeTopologyId; | ||
22 | + | ||
23 | +/** | ||
24 | + * Configuration for TE Topology Identifiers. | ||
25 | + */ | ||
26 | +public class TeTopologyIdConfig extends Config<ApplicationId> { | ||
27 | + public static final String CONFIG_VALUE_ERROR = "Error parsing config value"; | ||
28 | + private static final String PROVIDER_ID = "provider-id"; | ||
29 | + private static final String CLIENT_ID = "client-id"; | ||
30 | + private static final String TOPOLOGY_ID = "topology-id"; | ||
31 | + | ||
32 | + /** | ||
33 | + * Generates TE topology identifier. | ||
34 | + * | ||
35 | + * @return encoded TE topology identifier | ||
36 | + * @throws ConfigException if the parameters are not correctly configured | ||
37 | + * or conversion of the parameters fails | ||
38 | + */ | ||
39 | + public TeTopologyId getTeTopologyId() throws ConfigException { | ||
40 | + try { | ||
41 | + long providerId = object.path(PROVIDER_ID).asLong(); | ||
42 | + long clientId = object.path(CLIENT_ID).asLong(); | ||
43 | + String topologyId = object.path(TOPOLOGY_ID).asText(); | ||
44 | + | ||
45 | + return new TeTopologyId(providerId, clientId, topologyId); | ||
46 | + | ||
47 | + } catch (IllegalArgumentException e) { | ||
48 | + throw new ConfigException(CONFIG_VALUE_ERROR, e); | ||
49 | + } | ||
50 | + } | ||
51 | +} |
apps/tetopology/src/main/java/org/onosproject/tetopology/management/impl/TeTopologyManager.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016 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.tetopology.management.impl; | ||
17 | + | ||
18 | +import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED; | ||
19 | +import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED; | ||
20 | +import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; | ||
21 | + | ||
22 | +import java.util.ArrayList; | ||
23 | +import java.util.List; | ||
24 | +import java.util.Collection; | ||
25 | + | ||
26 | +import org.apache.felix.scr.annotations.Activate; | ||
27 | +import org.apache.felix.scr.annotations.Component; | ||
28 | +import org.apache.felix.scr.annotations.Deactivate; | ||
29 | +import org.apache.felix.scr.annotations.Reference; | ||
30 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
31 | +import org.apache.felix.scr.annotations.Service; | ||
32 | +import org.onlab.packet.Ip4Address; | ||
33 | +import org.onosproject.core.ApplicationId; | ||
34 | +import org.onosproject.core.CoreService; | ||
35 | +import org.onosproject.incubator.net.config.basics.ConfigException; | ||
36 | +import org.onosproject.net.DeviceId; | ||
37 | +import org.onosproject.net.MastershipRole; | ||
38 | +import org.onosproject.net.PortNumber; | ||
39 | +import org.onosproject.net.config.ConfigFactory; | ||
40 | +import org.onosproject.net.config.NetworkConfigEvent; | ||
41 | +import org.onosproject.net.config.NetworkConfigListener; | ||
42 | +import org.onosproject.net.config.NetworkConfigRegistry; | ||
43 | +import org.onosproject.net.device.DeviceProvider; | ||
44 | +import org.onosproject.net.device.DeviceProviderRegistry; | ||
45 | +import org.onosproject.net.device.DeviceProviderService; | ||
46 | +import org.onosproject.net.device.DeviceService; | ||
47 | +import org.onosproject.net.link.LinkProvider; | ||
48 | +import org.onosproject.net.link.LinkProviderRegistry; | ||
49 | +import org.onosproject.net.link.LinkProviderService; | ||
50 | +import org.onosproject.net.link.LinkService; | ||
51 | +import org.onosproject.net.provider.AbstractListenerProviderRegistry; | ||
52 | +import org.onosproject.net.provider.AbstractProviderService; | ||
53 | +import org.onosproject.net.provider.ProviderId; | ||
54 | +import org.onosproject.tetopology.management.api.DefaultNetwork; | ||
55 | +import org.onosproject.tetopology.management.api.DefaultNetworks; | ||
56 | +import org.onosproject.tetopology.management.api.InternalTeNetwork; | ||
57 | +import org.onosproject.tetopology.management.api.KeyId; | ||
58 | +import org.onosproject.tetopology.management.api.Network; | ||
59 | +import org.onosproject.tetopology.management.api.Networks; | ||
60 | +import org.onosproject.tetopology.management.api.TeTopologyEvent; | ||
61 | +import org.onosproject.tetopology.management.api.TeTopologyId; | ||
62 | +import org.onosproject.tetopology.management.api.TeTopologyListener; | ||
63 | +import org.onosproject.tetopology.management.api.TeTopologyProvider; | ||
64 | +import org.onosproject.tetopology.management.api.TeTopologyProviderRegistry; | ||
65 | +import org.onosproject.tetopology.management.api.TeTopologyProviderService; | ||
66 | +import org.onosproject.tetopology.management.api.TeTopologyService; | ||
67 | +import org.onosproject.tetopology.management.api.TeTopologyStore; | ||
68 | +import org.onosproject.tetopology.management.api.TeTopologyStoreDelegate; | ||
69 | +import org.onosproject.tetopology.management.api.TeTopologyType; | ||
70 | +import org.onosproject.tetopology.management.api.link.DefaultNetworkLink; | ||
71 | +import org.onosproject.tetopology.management.api.link.NetworkLink; | ||
72 | +import org.onosproject.tetopology.management.api.link.NetworkLinkKey; | ||
73 | +import org.onosproject.tetopology.management.api.node.ConnectivityMatrix; | ||
74 | +import org.onosproject.tetopology.management.api.node.DefaultNetworkNode; | ||
75 | +import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint; | ||
76 | +import org.onosproject.tetopology.management.api.node.NetworkNode; | ||
77 | +import org.onosproject.tetopology.management.api.node.NetworkNodeKey; | ||
78 | +import org.onosproject.tetopology.management.api.node.TeNode; | ||
79 | +import org.onosproject.tetopology.management.api.node.TerminationPoint; | ||
80 | +import org.onosproject.tetopology.management.api.node.TerminationPointKey; | ||
81 | +import org.slf4j.Logger; | ||
82 | +import org.slf4j.LoggerFactory; | ||
83 | + | ||
84 | +import com.google.common.collect.Lists; | ||
85 | + | ||
86 | +/** | ||
87 | + * Implementation of the topology management service. | ||
88 | + */ | ||
89 | +@Component(immediate = true) | ||
90 | +@Service | ||
91 | +public class TeTopologyManager | ||
92 | + extends AbstractListenerProviderRegistry<TeTopologyEvent, TeTopologyListener, | ||
93 | + TeTopologyProvider, TeTopologyProviderService> | ||
94 | + implements TeTopologyService, TeTopologyProviderRegistry, DeviceProvider, LinkProvider { | ||
95 | + private static final String APP_NAME = "org.onosproject.tetopology"; | ||
96 | + private static final String IETF_TE_TOPOLOGY_MANAGER = "ietf-te-topology-manager"; | ||
97 | + private static final String PROVIDER = "org.onosproject.provider.ietfte.objects"; | ||
98 | + private static final long MY_PROVIDER_ID = 0x0a0a0a0aL; | ||
99 | + private static final long DEFAUL_CLIENT_ID = 0x00L; | ||
100 | + private static final String MY_NATIVE_TOPOLOGY_ID = "onos-sc-topo-1"; | ||
101 | + private static final TeTopologyId DEFAULT_TOPOLOGY_ID = new TeTopologyId(MY_PROVIDER_ID, | ||
102 | + DEFAUL_CLIENT_ID, | ||
103 | + MY_NATIVE_TOPOLOGY_ID); | ||
104 | + //teTopologyId is configurable from Network Config | ||
105 | + private TeTopologyId teTopologyId = DEFAULT_TOPOLOGY_ID; | ||
106 | + | ||
107 | + private static final Ip4Address NEW_TE_NODE_ID_START = Ip4Address.valueOf("1.1.1.1"); | ||
108 | + private static final Ip4Address NEW_TE_NODE_ID_END = Ip4Address.valueOf("1.1.250.250"); | ||
109 | + private static final String MDSC_URI_PREFIX = "MDSC"; | ||
110 | + private static Ip4Address newTeNodeId = NEW_TE_NODE_ID_START; | ||
111 | + | ||
112 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
113 | + | ||
114 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
115 | + protected CoreService coreService; | ||
116 | + | ||
117 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
118 | + protected NetworkConfigRegistry cfgService; | ||
119 | + | ||
120 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
121 | + protected DeviceService deviceService; | ||
122 | + | ||
123 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
124 | + protected LinkService linkService; | ||
125 | + | ||
126 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
127 | + protected DeviceProviderRegistry deviceProviderRegistry; | ||
128 | + | ||
129 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
130 | + protected LinkProviderRegistry linkProviderRegistry; | ||
131 | + | ||
132 | + //Only network level data is stored in this subsystem. | ||
133 | + //Link and Device details is stored in Link and Device subsystems. | ||
134 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
135 | + public TeTopologyStore store; | ||
136 | + | ||
137 | + //private TeTopologyStoreDelegate delegate = this::post; | ||
138 | + private final TeTopologyStoreDelegate delegate = new InternalStoreDelegate(); | ||
139 | + | ||
140 | + private final ConfigFactory<ApplicationId, TeTopologyIdConfig> factory = | ||
141 | + new ConfigFactory<ApplicationId, TeTopologyIdConfig>(APP_SUBJECT_FACTORY, | ||
142 | + TeTopologyIdConfig.class, | ||
143 | + "teTopologyId", | ||
144 | + true) { | ||
145 | + @Override | ||
146 | + public TeTopologyIdConfig createConfig() { | ||
147 | + return new TeTopologyIdConfig(); | ||
148 | + } | ||
149 | + }; | ||
150 | + private final NetworkConfigListener cfgLister = new InternalConfigListener(); | ||
151 | + private ApplicationId appId; | ||
152 | + | ||
153 | + private DeviceProviderService deviceProviderService; | ||
154 | + private LinkProviderService linkProviderService; | ||
155 | + | ||
156 | + /** | ||
157 | + * Activation helper function. | ||
158 | + */ | ||
159 | + public void activateBasics() { | ||
160 | + store.setDelegate(delegate); | ||
161 | + eventDispatcher.addSink(TeTopologyEvent.class, listenerRegistry); | ||
162 | + } | ||
163 | + | ||
164 | + /** | ||
165 | + * Deactivation helper function. | ||
166 | + */ | ||
167 | + public void deactivateBasics() { | ||
168 | + store.unsetDelegate(delegate); | ||
169 | + eventDispatcher.removeSink(TeTopologyEvent.class); | ||
170 | + } | ||
171 | + | ||
172 | + @Activate | ||
173 | + public void activate() { | ||
174 | + activateBasics(); | ||
175 | + appId = coreService.registerApplication(APP_NAME); | ||
176 | + cfgService.registerConfigFactory(factory); | ||
177 | + cfgService.addListener(cfgLister); | ||
178 | + | ||
179 | + deviceProviderService = deviceProviderRegistry.register(this); | ||
180 | + linkProviderService = linkProviderRegistry.register(this); | ||
181 | + | ||
182 | + //TODO: Needs to add the event listener into LINK and Device subsystem | ||
183 | + | ||
184 | + log.info("Started"); | ||
185 | + } | ||
186 | + | ||
187 | + @Deactivate | ||
188 | + public void deactivate() { | ||
189 | + deactivateBasics(); | ||
190 | + | ||
191 | + cfgService.removeListener(cfgLister); | ||
192 | + cfgService.unregisterConfigFactory(factory); | ||
193 | + | ||
194 | + deviceProviderRegistry.unregister(this); | ||
195 | + linkProviderRegistry.unregister(this); | ||
196 | + | ||
197 | + //TODO: Needs to remove the event listener from LINK and Device subsystem | ||
198 | + | ||
199 | + log.info("Stopped"); | ||
200 | + } | ||
201 | + | ||
202 | + @Override | ||
203 | + public Networks getNetworks() { | ||
204 | + // return a list of the native networks | ||
205 | + List<InternalTeNetwork> teNetworks = store.getNetworks(TeTopologyType.NATIVE); | ||
206 | + | ||
207 | + List<Network> defaultNetworks = new ArrayList<>(); | ||
208 | + for (InternalTeNetwork teNetwork : teNetworks) { | ||
209 | + defaultNetworks.add(teNetwork); | ||
210 | + } | ||
211 | + | ||
212 | + return (new DefaultNetworks(defaultNetworks)); | ||
213 | + } | ||
214 | + | ||
215 | + @Override | ||
216 | + public Network getNetwork(KeyId networkId) { | ||
217 | + return new DefaultNetwork(store.getNetwork(networkId)); | ||
218 | + } | ||
219 | + | ||
220 | + @Override | ||
221 | + public void updateNetwork(Network network) { | ||
222 | + store.updateNetwork(new InternalTeNetwork(TeTopologyType.CONFIGURED, new DefaultNetwork(network))); | ||
223 | + //TODO: Need to update nodes and links to Device/Link subsystems. | ||
224 | + } | ||
225 | + | ||
226 | + @Override | ||
227 | + public void removeNetwork(KeyId networkId) { | ||
228 | + store.removeNetwork(networkId); | ||
229 | + } | ||
230 | + | ||
231 | + @Override | ||
232 | + protected TeTopologyProviderService createProviderService(TeTopologyProvider provider) { | ||
233 | + return new InternalTopologyProviderService(provider); | ||
234 | + } | ||
235 | + | ||
236 | + private class InternalTopologyProviderService | ||
237 | + extends AbstractProviderService<TeTopologyProvider> | ||
238 | + implements TeTopologyProviderService { | ||
239 | + | ||
240 | + protected InternalTopologyProviderService(TeTopologyProvider provider) { | ||
241 | + super(provider); | ||
242 | + } | ||
243 | + | ||
244 | + @Override | ||
245 | + public void networkUpdated(Network network) { | ||
246 | + // Store received network data into the local TE topology data store | ||
247 | + InternalTeNetwork teNetwork = new InternalTeNetwork(TeTopologyType.SUBORDINATE, network); | ||
248 | + store.updateNetwork(teNetwork); | ||
249 | + | ||
250 | + // let's do it here for now | ||
251 | + mergeNetworks(); | ||
252 | + | ||
253 | + //TODO: Store node and link in Device/Link subsystem | ||
254 | + //deviceProviderService.deviceConnected(arg0, arg1); | ||
255 | + //linkProviderService.linkDetected(arg0); | ||
256 | + } | ||
257 | + | ||
258 | + @Override | ||
259 | + public void networkRemoved(KeyId networkId) { | ||
260 | + store.removeNetwork(networkId); | ||
261 | + } | ||
262 | + | ||
263 | + @Override | ||
264 | + public void linkUpdated(NetworkLinkKey linkKey, NetworkLink link) { | ||
265 | + // Need to check if this is a new link | ||
266 | + | ||
267 | + //deviceProviderService.deviceConnected(arg0, arg1); | ||
268 | + } | ||
269 | + | ||
270 | + @Override | ||
271 | + public void linkRemoved(NetworkLinkKey linkKey) { | ||
272 | + // No action is required (TODO: Auto-generated method stub) | ||
273 | + } | ||
274 | + | ||
275 | + @Override | ||
276 | + public void nodeUpdated(NetworkNodeKey nodeKey, NetworkNode node) { | ||
277 | + // Need to check if this is a new node | ||
278 | + | ||
279 | + // No action is required (TODO: Auto-generated method stub) | ||
280 | + } | ||
281 | + | ||
282 | + @Override | ||
283 | + public void nodeRemoved(NetworkNodeKey nodeKey) { | ||
284 | + // No action is required (TODO: Auto-generated method stub) | ||
285 | + } | ||
286 | + | ||
287 | + @Override | ||
288 | + public void terminationPointUpdated(TerminationPointKey terminationPointKey, | ||
289 | + TerminationPoint terminationPoint) { | ||
290 | + // No action is required (TODO: Auto-generated method stub) | ||
291 | + } | ||
292 | + | ||
293 | + @Override | ||
294 | + public void terminationPointRemoved(TerminationPointKey terminationPointKey) { | ||
295 | + // No action is required (TODO: Auto-generated method stub) | ||
296 | + } | ||
297 | + | ||
298 | + } | ||
299 | + | ||
300 | + private class InternalStoreDelegate implements TeTopologyStoreDelegate { | ||
301 | + @Override | ||
302 | + public void notify(TeTopologyEvent event) { | ||
303 | + if (event != null) { | ||
304 | + //post(event); | ||
305 | + processEvent(event); | ||
306 | + } | ||
307 | + } | ||
308 | + } | ||
309 | + | ||
310 | + private void processEvent(TeTopologyEvent event) { | ||
311 | + log.info("ProcessEvent {}", event.type().toString()); | ||
312 | + | ||
313 | + //TODO - partial merge when network is updated | ||
314 | + if (event.type() == TeTopologyEvent.Type.NETWORK_ADDED) { | ||
315 | + // move network merging to networkUpdated() | ||
316 | + //mergeNetworks(); | ||
317 | + } | ||
318 | + | ||
319 | + //TODO: Merge node and links from Device/Links subsytems if required. | ||
320 | + | ||
321 | + post(event); | ||
322 | + } | ||
323 | + | ||
324 | + private void mergeNetworks() { | ||
325 | + /* | ||
326 | + * Merge all subordinate TE topologies, create a simple merged native topology | ||
327 | + * and store it in the topology store. | ||
328 | + */ | ||
329 | + /* TODO - generate new id based on its provider id + network id */ | ||
330 | + KeyId newNetworkId = KeyId.keyId(Long.toString(teTopologyId.providerId()) + "-" + teTopologyId.topologyId()); | ||
331 | + store.removeNetwork(newNetworkId); | ||
332 | + /* create list of links, nodes and termination points */ | ||
333 | + List<NetworkLink> allLinks = new ArrayList<>(); | ||
334 | + List<NetworkNode> allNodes = new ArrayList<>(); | ||
335 | + List<KeyId> allSupportingNetworkIds = new ArrayList<>(); | ||
336 | + | ||
337 | + /* translate keys for links/nodes/tps */ | ||
338 | + List<InternalTeNetwork> subordNetworks = store.getNetworks(TeTopologyType.SUBORDINATE); | ||
339 | + for (InternalTeNetwork network : subordNetworks) { | ||
340 | + allSupportingNetworkIds.add(network.networkId()); | ||
341 | + | ||
342 | + /* create and add new nodes */ | ||
343 | + List<NetworkNode> nodes = network.getNodes(); | ||
344 | + for (NetworkNode node : nodes) { | ||
345 | + | ||
346 | + KeyId newNodeId = KeyId.keyId(MDSC_URI_PREFIX + node.nodeId()); | ||
347 | + TeNode newTeNode = null; | ||
348 | + TeNode origTeNode = node.getTe(); | ||
349 | + if (origTeNode != null) { | ||
350 | + newTeNode = new TeNode(origTeNode.teNodeId()); | ||
351 | + newTeNode.setName(origTeNode.name()); | ||
352 | + newTeNode.setAdminStatus(origTeNode.adminStatus()); | ||
353 | + newTeNode.setOpStatus(origTeNode.opStatus()); | ||
354 | + newTeNode.setAbstract(origTeNode.isAbstract()); | ||
355 | + List<ConnectivityMatrix> newConnMatrices = new ArrayList<>(); | ||
356 | + | ||
357 | + for (ConnectivityMatrix conn : origTeNode.connectivityMatrices()) { | ||
358 | + KeyId tpId = conn.from().tpId(); | ||
359 | + KeyId newFromTpId = KeyId.keyId(MDSC_URI_PREFIX + tpId); | ||
360 | + TerminationPointKey newFrom = new TerminationPointKey(newNetworkId, newNodeId, newFromTpId); | ||
361 | + | ||
362 | + tpId = conn.to().tpId(); | ||
363 | + KeyId newToTpId = KeyId.keyId(MDSC_URI_PREFIX + tpId); | ||
364 | + TerminationPointKey newTo = new TerminationPointKey(newNetworkId, newNodeId, newToTpId); | ||
365 | + ConnectivityMatrix newConnMatrix = | ||
366 | + new ConnectivityMatrix(conn.id(), newFrom, newTo, conn.isAllowed()); | ||
367 | + newConnMatrices.add(newConnMatrix); | ||
368 | + } | ||
369 | + newTeNode.setConnectivityMatrices(newConnMatrices); | ||
370 | + newTeNode.setUnderlayTopology(origTeNode.underlayTopology()); | ||
371 | + newTeNode.setTunnelTerminationPoints(origTeNode.tunnelTerminationPoints()); | ||
372 | + } | ||
373 | + List<NetworkNodeKey> supportingNodes = Lists.newArrayList(); | ||
374 | + supportingNodes.add(new NetworkNodeKey(network.networkId(), node.nodeId())); | ||
375 | + DefaultNetworkNode newNode = | ||
376 | + new DefaultNetworkNode(newNodeId, supportingNodes, newTeNode); | ||
377 | + List<TerminationPoint> newTps = Lists.newArrayList(); | ||
378 | + | ||
379 | + List<TerminationPoint> origTps = node.getTerminationPoints(); | ||
380 | + if (nonEmpty(origTps)) { | ||
381 | + for (TerminationPoint tp : origTps) { | ||
382 | + DefaultTerminationPoint newTp = | ||
383 | + new DefaultTerminationPoint(KeyId.keyId(MDSC_URI_PREFIX + tp.id())); | ||
384 | + List<TerminationPointKey> supportTps = Lists.newArrayList(); | ||
385 | + supportTps.add(new TerminationPointKey(network.networkId(), node.nodeId(), tp.id())); | ||
386 | + newTp.setSupportingTpIds(supportTps); | ||
387 | + newTps.add(newTp); | ||
388 | + } | ||
389 | + } | ||
390 | + newNode.setTerminationPoints(newTps); | ||
391 | + allNodes.add(newNode); | ||
392 | + } | ||
393 | + | ||
394 | + /* create and add new links */ | ||
395 | + List<NetworkLink> links = network.getLinks(); | ||
396 | + if (nonEmpty(links)) { | ||
397 | + for (NetworkLink link : links) { | ||
398 | + KeyId newLinkId = KeyId.keyId(MDSC_URI_PREFIX + link.linkId()); | ||
399 | + KeyId k = link.getSource().nodeId(); | ||
400 | + KeyId newSourceNodeId = | ||
401 | + KeyId.keyId(MDSC_URI_PREFIX + k); | ||
402 | + k = link.getSource().tpId(); | ||
403 | + KeyId newSourceNodeTpId = | ||
404 | + KeyId.keyId(MDSC_URI_PREFIX + k); | ||
405 | + k = link.getDestination().nodeId(); | ||
406 | + KeyId newDestNodeId = | ||
407 | + KeyId.keyId(MDSC_URI_PREFIX + k); | ||
408 | + k = link.getDestination().tpId(); | ||
409 | + KeyId newDestNodeTpId = | ||
410 | + KeyId.keyId(MDSC_URI_PREFIX + k); | ||
411 | + TerminationPointKey newSourceNodeTp = | ||
412 | + new TerminationPointKey(newNetworkId, newSourceNodeId, newSourceNodeTpId); | ||
413 | + TerminationPointKey newDestNodeTp = | ||
414 | + new TerminationPointKey(newNetworkId, newDestNodeId, newDestNodeTpId); | ||
415 | + | ||
416 | + DefaultNetworkLink newLink = new DefaultNetworkLink(newLinkId); | ||
417 | + newLink.setSource(newSourceNodeTp); | ||
418 | + newLink.setDestination(newDestNodeTp); | ||
419 | + List<NetworkLinkKey> supportLinks = Lists.newArrayList(); | ||
420 | + supportLinks.add(new NetworkLinkKey(network.networkId(), link.linkId())); | ||
421 | + newLink.setSupportingLinkIds(supportLinks); | ||
422 | + newLink.setTe(link.getTe()); | ||
423 | + | ||
424 | + allLinks.add(newLink); | ||
425 | + } | ||
426 | + } | ||
427 | + } | ||
428 | + | ||
429 | + /* save generated native TE network into the store */ | ||
430 | + if (allNodes.size() > 0) { | ||
431 | + //TeTopologyId newTopoId = new TeTopologyId(MY_PROVIDER_ID, 0L, NATIVE_TOPOLOGY_ID); | ||
432 | + DefaultNetwork nativeDefaultNetwork = | ||
433 | + new DefaultNetwork(newNetworkId, allSupportingNetworkIds, allNodes, allLinks, teTopologyId, true); | ||
434 | + InternalTeNetwork newTeNetwork = new InternalTeNetwork(TeTopologyType.NATIVE, nativeDefaultNetwork); | ||
435 | + store.updateNetwork(newTeNetwork); | ||
436 | + } | ||
437 | + } | ||
438 | + | ||
439 | + @Override | ||
440 | + public ProviderId id() { | ||
441 | + return new ProviderId(IETF_TE_TOPOLOGY_MANAGER, PROVIDER); | ||
442 | + } | ||
443 | + | ||
444 | + private class InternalConfigListener implements NetworkConfigListener { | ||
445 | + | ||
446 | + @Override | ||
447 | + public void event(NetworkConfigEvent event) { | ||
448 | + try { | ||
449 | + teTopologyId = cfgService.getConfig(appId, TeTopologyIdConfig.class).getTeTopologyId(); | ||
450 | + } catch (ConfigException e) { | ||
451 | + log.error("Configuration error {}", e); | ||
452 | + } | ||
453 | + log.info("new teTopologyId is {}", teTopologyId); | ||
454 | + } | ||
455 | + | ||
456 | + @Override | ||
457 | + public boolean isRelevant(NetworkConfigEvent event) { | ||
458 | + return event.configClass().equals(TeTopologyIdConfig.class) && | ||
459 | + (event.type() == CONFIG_ADDED || | ||
460 | + event.type() == CONFIG_UPDATED); | ||
461 | + } | ||
462 | + } | ||
463 | + | ||
464 | + @Override | ||
465 | + public void changePortState(DeviceId arg0, PortNumber arg1, boolean arg2) { | ||
466 | + // TODO: This will be implemented if required. | ||
467 | + } | ||
468 | + | ||
469 | + @Override | ||
470 | + public boolean isReachable(DeviceId arg0) { | ||
471 | + // TODO: This will be implemented if required. | ||
472 | + return false; | ||
473 | + } | ||
474 | + | ||
475 | + @Override | ||
476 | + public void roleChanged(DeviceId arg0, MastershipRole arg1) { | ||
477 | + // TODO: This will be implemented if required. | ||
478 | + } | ||
479 | + | ||
480 | + @Override | ||
481 | + public void triggerProbe(DeviceId arg0) { | ||
482 | + // TODO: This will be implemented if required. | ||
483 | + } | ||
484 | + | ||
485 | + private Ip4Address assignTeNodeId() { | ||
486 | + int value = newTeNodeId.toInt(); | ||
487 | + | ||
488 | + if (value >= NEW_TE_NODE_ID_END.toInt()) { | ||
489 | + value = NEW_TE_NODE_ID_START.toInt(); | ||
490 | + } | ||
491 | + return Ip4Address.valueOf(value); | ||
492 | + } | ||
493 | + | ||
494 | + private static boolean nonEmpty(Collection<?> c) { | ||
495 | + return c != null && !c.isEmpty(); | ||
496 | + } | ||
497 | +} |
apps/tetopology/src/main/java/org/onosproject/tetopology/management/impl/package-info.java
0 → 100644
1 | +/** | ||
2 | + * Copyright 2016 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 | + | ||
17 | +/** | ||
18 | + * TE Topology Management implementation. | ||
19 | + */ | ||
20 | +package org.onosproject.tetopology.management.impl; |
-
Please register or login to post a comment