2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.unimgr.mef.netvirt;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
21 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
22 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni;
24 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.UniBuilder;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.PhysicalLayersBuilder;
26 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.LinksBuilder;
27 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
28 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.LinkBuilder;
29 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.Interface;
30 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.InterfaceBuilder;
31 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.config.rev150710.ElanConfig;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.config.rev150710.ElanConfigBuilder;
39 import org.opendaylight.yangtools.concepts.ListenerRegistration;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 import com.google.common.util.concurrent.CheckedFuture;
46 public class NodeConnectorListener extends UnimgrDataTreeChangeListener<FlowCapableNodeConnector> {
48 private static final Logger log = LoggerFactory.getLogger(NodeConnectorListener.class);
49 private static boolean generateMac = false;
50 private final UniPortManager uniPortManager;
51 private ListenerRegistration<NodeConnectorListener> nodeConnectorListenerRegistration;
53 public NodeConnectorListener(final DataBroker dataBroker, final UniPortManager uniPortManager, final boolean generateMac) {
55 this.uniPortManager = uniPortManager;
56 NodeConnectorListener.generateMac = generateMac;
60 public void registerListener() {
62 final DataTreeIdentifier<FlowCapableNodeConnector> dataTreeIid = new DataTreeIdentifier<>(
63 LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
64 nodeConnectorListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
65 log.info("NodeConnectorListener created and registered");
67 configIntegrationBridge();
68 } catch (final Exception e) {
69 log.error("Node connector listener registration failed !", e);
70 throw new IllegalStateException("Node connector listener registration failed.", e);
74 @SuppressWarnings("deprecation")
75 private InstanceIdentifier<FlowCapableNodeConnector> getInstanceIdentifier() {
76 return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
77 .augmentation(FlowCapableNodeConnector.class);
81 public void close() throws Exception {
82 nodeConnectorListenerRegistration.close();
86 public void add(DataTreeModification<FlowCapableNodeConnector> newDataObject) {
87 if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
88 log.info("node connector {} created", newDataObject.getRootNode().getIdentifier());
89 addFlowCapableNodeConnector(newDataObject);
94 public void remove(DataTreeModification<FlowCapableNodeConnector> removedDataObject) {
95 if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
96 log.info("node connector {} deleted", removedDataObject.getRootNode().getIdentifier());
97 removeFlowCapableNodeConnector(removedDataObject);
102 public void update(DataTreeModification<FlowCapableNodeConnector> modifiedDataObject) {
103 if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
104 log.info("node connector {} updated", modifiedDataObject.getRootNode().getIdentifier());
105 updateFlowCapableNodeConnector(modifiedDataObject);
109 private void addFlowCapableNodeConnector(DataTreeModification<FlowCapableNodeConnector> newDataObject) {
111 FlowCapableNodeConnector data = newDataObject.getRootNode().getDataAfter();
113 String dpnFromNodeConnectorId = getDpnIdFromNodeConnector(newDataObject);
115 handleNodeConnectorAdded(dataBroker, dpnFromNodeConnectorId, data);
116 } catch (final Exception e) {
117 log.error("Add node connector failed !", e);
121 private void removeFlowCapableNodeConnector(DataTreeModification<FlowCapableNodeConnector> removedDataObject) {
123 FlowCapableNodeConnector data = removedDataObject.getRootNode().getDataBefore();
125 String dpnFromNodeConnectorId = getDpnIdFromNodeConnector(removedDataObject);
127 handleNodeConnectorRemoved(dataBroker, dpnFromNodeConnectorId, data);
128 } catch (final Exception e) {
129 log.error("Remove node connector failed !", e);
133 private void updateFlowCapableNodeConnector(DataTreeModification<FlowCapableNodeConnector> modifiedDataObject) {
135 FlowCapableNodeConnector original = modifiedDataObject.getRootNode().getDataBefore();
136 FlowCapableNodeConnector update = modifiedDataObject.getRootNode().getDataAfter();
138 String dpnFromNodeConnectorId = getDpnIdFromNodeConnector(modifiedDataObject);
140 handleNodeConnectorUpdated(dataBroker, dpnFromNodeConnectorId, original, update);
141 } catch (final Exception e) {
142 log.error("Update node connector failed !", e);
146 @SuppressWarnings("deprecation")
147 private String getDpnIdFromNodeConnector(DataTreeModification<FlowCapableNodeConnector> newDataObject) {
148 InstanceIdentifier<FlowCapableNodeConnector> key = newDataObject.getRootPath().getRootIdentifier();
149 NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
151 String dpnFromNodeConnectorId = getDpnFromNodeConnectorId(nodeConnectorId);
152 return dpnFromNodeConnectorId;
155 @SuppressWarnings("deprecation")
156 private static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
158 * NodeConnectorId is of form 'openflow:dpnid:portnum'
160 String[] split = portId.getValue().split(IfmConstants.OF_URI_SEPARATOR);
164 private void handleNodeConnectorAdded(DataBroker dataBroker, String dpnId, FlowCapableNodeConnector nodeConnector) {
166 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
168 log.info("Adding mef uni/device interface {} with device {}", nodeConnector.getName(), dpnId);
170 String uniName = MefInterfaceUtils.getDeviceInterfaceName(dpnId, nodeConnector.getName());
171 InstanceIdentifier<Interface> interfacePath = MefInterfaceUtils.getDeviceInterfaceInstanceIdentifier(dpnId,
173 InterfaceBuilder interfaceBuilder = new InterfaceBuilder();
174 interfaceBuilder.setPhy(new Identifier45(uniName));
175 Interface deviceInterface = interfaceBuilder.build();
176 tx.merge(LogicalDatastoreType.OPERATIONAL, interfacePath, deviceInterface, true);
178 InstanceIdentifier<Uni> uniPath = MefInterfaceUtils.getUniInstanceIdentifier(uniName);
179 UniBuilder uniBuilder = new UniBuilder();
180 uniBuilder.setUniId(new Identifier45(uniName));
181 uniBuilder.setMacAddress(nodeConnector.getHardwareAddress());
183 PhysicalLayersBuilder physicalLayersBuilder = new PhysicalLayersBuilder();
184 LinksBuilder linksBuilder = new LinksBuilder();
185 List<Link> links = new ArrayList<>();
186 LinkBuilder linkBuilder = new LinkBuilder();
187 linkBuilder.setDevice(new Identifier45(dpnId));
188 linkBuilder.setInterface(uniName);
189 links.add(linkBuilder.build());
190 linksBuilder.setLink(links);
191 physicalLayersBuilder.setLinks(linksBuilder.build());
192 uniBuilder.setPhysicalLayers(physicalLayersBuilder.build());
193 Uni uni = uniBuilder.build();
194 tx.merge(LogicalDatastoreType.OPERATIONAL, uniPath, uni, true);
196 CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
199 } catch (InterruptedException | ExecutionException e) {
200 log.error("Error writing to datastore (path, data) : ({}, {}), ({}, {})", interfacePath, deviceInterface,
202 throw new RuntimeException(e.getMessage());
205 // Reply UNI port configuration
206 uniPortManager.updateOperUni(uni.getUniId().getValue());
209 private void handleNodeConnectorRemoved(DataBroker dataBroker, String dpnId,
210 FlowCapableNodeConnector nodeConnector) {
212 String uniName = MefInterfaceUtils.getDeviceInterfaceName(dpnId, nodeConnector.getName());
213 InstanceIdentifier<Interface> interfacePath = MefInterfaceUtils.getDeviceInterfaceInstanceIdentifier(dpnId,
215 if (MefInterfaceUtils.getInterface(dataBroker, dpnId, uniName, LogicalDatastoreType.OPERATIONAL) != null) {
216 MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, interfacePath);
219 // Reply UNI port configuration
220 uniPortManager.removeUniPorts(uniName);
221 InstanceIdentifier<Uni> uniPath = MefInterfaceUtils.getUniInstanceIdentifier(uniName);
222 if (MefInterfaceUtils.getUni(dataBroker, uniName, LogicalDatastoreType.OPERATIONAL) != null) {
223 MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, uniPath);
227 private void handleNodeConnectorUpdated(DataBroker dataBroker, String dpnFromNodeConnectorId,
228 FlowCapableNodeConnector original, FlowCapableNodeConnector update) {
232 private void configIntegrationBridge() {
233 if (generateMac == true) {// default for netvirt
237 ElanConfigBuilder elanConfigBuilder = new ElanConfigBuilder();
238 elanConfigBuilder.setIntBridgeGenMac(false);
239 InstanceIdentifier<ElanConfig> id = InstanceIdentifier.builder(ElanConfig.class).build();
241 MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, id, elanConfigBuilder.build());