2 * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.nemo.intent.computation;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.List;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.CopyOnWriteArraySet;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
21 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
22 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
23 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.nemo.intent.IntentResolver;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalLinks;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalNodes;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPath;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPort;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;
34 import org.opendaylight.yangtools.concepts.ListenerRegistration;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * The virtual network mapping unit implements the following functions:
41 * (1) Automatically perform the virtual network mapping when the user's
42 * virtual network changed, which is subscribed from the data store.
43 * (2) Automatically perform the remapping for the virtual networks that
44 * are influenced by the changes of the underlying physical network
45 * which are also subscribed from the data store.
49 public class PNResourcesTracker {
50 private static final Logger log = LoggerFactory.getLogger(PNResourcesTracker.class);
52 private final ConcurrentHashMap<UserId, CopyOnWriteArraySet<String>/*physical resources*/> physicalResourceMap;
54 private final DataBroker dataBroker;
55 private final IntentResolver intentResolver;
58 * The registration for the physical node change listener.
60 private ListenerRegistration<?> physicalNodeChangeListenerReg;
63 * The registration for the physical link change listener.
65 private ListenerRegistration<?> physicalLinkChangeListenerReg;
67 public PNResourcesTracker(DataBroker dataBroker, IntentResolver intentResolver) {
70 this.dataBroker = dataBroker;
71 this.intentResolver = intentResolver;
72 physicalResourceMap = new ConcurrentHashMap<>();
74 InstanceIdentifier<PhysicalNode> nodeInstanceIdentifier = InstanceIdentifier
75 .builder(PhysicalNetwork.class)
76 .child(PhysicalNodes.class)
77 .child(PhysicalNode.class)
79 InstanceIdentifier<PhysicalLink> linkInstanceIdentifier = InstanceIdentifier
80 .builder(PhysicalNetwork.class)
81 .child(PhysicalLinks.class)
82 .child(PhysicalLink.class)
85 physicalNodeChangeListenerReg = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(
86 LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier), new PhysicalNodeChangeListener());
87 physicalLinkChangeListenerReg = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(
88 LogicalDatastoreType.OPERATIONAL, linkInstanceIdentifier), new PhysicalLinkChangeListener());
93 if(physicalLinkChangeListenerReg!=null){
94 physicalLinkChangeListenerReg.close();
96 if(physicalNodeChangeListenerReg!=null){
97 physicalNodeChangeListenerReg.close();
99 physicalResourceMap.clear();
101 protected synchronized void resetResource(UserId userId) {
102 physicalResourceMap.remove(userId);
105 protected void addPhysicalNode(UserId userId, PhysicalNode physicalNode) {
106 addPhysicalResource(userId, physicalNode.getKey().toString());
109 protected void addPhysicalPort(UserId userId, PhysicalPort physicalPort) {
110 addPhysicalResource(userId, physicalPort.getKey().toString());
113 protected void addPhysicalPath(UserId userId, PhysicalPath physicalPath) {
114 List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink>
115 physicalLinkList = physicalPath.getPhysicalLink();
116 for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.path.instance.PhysicalLink physicalLink :
118 addPhysicalResource(userId, physicalLink.getKey().toString());
122 private synchronized void addPhysicalResource(UserId userId, String resourceId) {
123 if (!physicalResourceMap.containsKey(userId)) {
124 physicalResourceMap.put(userId, new CopyOnWriteArraySet<String>());
126 physicalResourceMap.get(userId).add(resourceId);
129 private synchronized void physicalResourceDown(String resourceId) {
130 Map<UserId, CopyOnWriteArraySet<String>> tmpMap = new HashMap<>(physicalResourceMap);
131 for (UserId userId : tmpMap.keySet()) {
132 Set<String> physicalResources = tmpMap.get(userId);
133 if (physicalResources.contains(resourceId)) {
134 physicalResourceMap.remove(userId);
136 log.info("Physical network changed and affected the virtual network of " +
137 "user {}, start remapping.", userId.getValue());
139 intentResolver.resolveIntent(userId);
140 } catch (Exception e) {
141 // TODO Auto-generated catch block
142 log.error("Exception:",e);
149 * A listener to ch ange events related to physical nodes being
150 * added, removed or updated.
154 private class PhysicalNodeChangeListener implements DataTreeChangeListener<PhysicalNode> {
155 private void handleNodeUpdate(PhysicalNode originNode, PhysicalNode currentNode) {
156 log.debug("Handle node {} update.", originNode.getNodeId().getValue());
157 List<PhysicalPort> originPorts = originNode.getPhysicalPort();
158 List<PhysicalPort> currentPorts = currentNode.getPhysicalPort() == null ? new ArrayList<>() : currentNode.getPhysicalPort();
159 if (originPorts != null) {
160 for (PhysicalPort physicalPort : originPorts) {
161 if (!currentPorts.contains(physicalPort)) {
162 log.debug("Physical port {} removed.", physicalPort.getPortId().getValue());
163 physicalResourceDown(physicalPort.getKey().toString());
170 public void onDataTreeChanged(Collection<DataTreeModification<PhysicalNode>> changes) {
171 for (DataTreeModification<PhysicalNode> change: changes) {
172 DataObjectModification<PhysicalNode> rootNode = change.getRootNode();
173 PhysicalNode originalNode = rootNode.getDataBefore();
174 switch (rootNode.getModificationType()) {
176 if (originalNode != null) {
177 handleNodeUpdate(originalNode, rootNode.getDataAfter());
181 String resourceId = originalNode.getKey().toString();
182 log.debug("Physical node {} removed.", resourceId);
183 physicalResourceDown(resourceId);
193 * A listener to change events related to physical links being
194 * added, removed or updated.
198 private class PhysicalLinkChangeListener implements DataTreeChangeListener<PhysicalLink> {
199 private void handleLinkUpdate(PhysicalLink originLink, PhysicalLink currentLink) {
200 log.debug("Handle physical link {} update.", originLink.getLinkId().getValue());
205 public void onDataTreeChanged(Collection<DataTreeModification<PhysicalLink>> changes) {
206 for (DataTreeModification<PhysicalLink> change: changes) {
207 DataObjectModification<PhysicalLink> rootNode = change.getRootNode();
208 PhysicalLink originalLink = rootNode.getDataBefore();
209 switch (rootNode.getModificationType()) {
211 if (originalLink != null) {
212 handleLinkUpdate(originalLink, rootNode.getDataAfter());
216 String resourceId = originalLink.getKey().toString();
217 log.debug("Physical link {} removed.", resourceId);
218 physicalResourceDown(resourceId);