/* * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.groupbasedpolicy.ip.sgt.distribution.service.impl; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.SxpConnectionAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.sxp.connection.fields.SxpConnection; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomains; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.connection.fields.ConnectionTimersBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.connections.fields.ConnectionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.connections.fields.connections.ConnectionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.protocol.rev141002.ConnectionMode; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class SxpCapableNodeListener implements DataTreeChangeListener<SxpConnection> { private String SXP_NODE_ID; private ListenerRegistration<SxpCapableNodeListener> listenerRegistration; private Map<InstanceIdentifier<Node>, String> sxpCapableNodes = new HashMap<>(); private DataBroker dataBroker; public SxpCapableNodeListener(DataBroker dataBroker, String sxpNodeId) { SXP_NODE_ID = sxpNodeId; this.dataBroker = dataBroker; DataTreeIdentifier<SxpConnection> iid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(NetworkTopology.class) .child(Topology.class) .child(Node.class) .augmentation(SxpConnectionAugmentation.class) .child(SxpConnection.class) .build()); listenerRegistration = dataBroker.registerDataTreeChangeListener(iid, this); } @Override public synchronized void onDataTreeChanged(Collection<DataTreeModification<SxpConnection>> changes) { changes.forEach((change) -> { InstanceIdentifier<Node> nodeIid = change.getRootPath().getRootIdentifier().firstIdentifierOf(Node.class); DataObjectModification<SxpConnection> rootNode = change.getRootNode(); String domainId = createDomainId(nodeIid); switch (rootNode.getModificationType()) { case DELETE: { removeSxpDomain(domainId); sxpCapableNodes.remove(nodeIid); break; } case WRITE: case SUBTREE_MODIFIED: { createSxpDomain(rootNode.getDataAfter(), domainId); sxpCapableNodes.put(nodeIid, domainId); break; } } }); } private String createDomainId(InstanceIdentifier<Node> nodeIid) { String topologyId = nodeIid.firstKeyOf(Topology.class).getTopologyId().getValue(); String nodeId = nodeIid.firstKeyOf(Node.class).getNodeId().getValue(); return topologyId + "/" + nodeId; } private void removeSxpDomain(String domainId) { InstanceIdentifier<SxpDomain> iid = sxpDomainIid(domainId); WriteTransaction wtx = dataBroker.newWriteOnlyTransaction(); wtx.delete(LogicalDatastoreType.CONFIGURATION, iid); wtx.submit(); } private void createSxpDomain(SxpConnection sxpData, String domainId) { IpAddress peerAddr = sxpData.getIpAddress(); PortNumber port = sxpData.getPortNumber(); String password = sxpData.getPassword(); InstanceIdentifier<SxpDomain> iid = sxpDomainIid(domainId); SxpDomain domain = new SxpDomainBuilder().setDomainName(domainId) .setConnections(new ConnectionsBuilder() .setConnection(Collections.singletonList(new ConnectionBuilder() .setPeerAddress(peerAddr) .setTcpPort(port) .setMode(ConnectionMode.Speaker) .setPassword(password) .setConnectionTimers(new ConnectionTimersBuilder().build()) .setDescription("Connection to " + domainId) .setVersion(sxpData.getVersion()) .build())) .build()) .build(); WriteTransaction wtx = dataBroker.newWriteOnlyTransaction(); wtx.merge(LogicalDatastoreType.CONFIGURATION, iid, domain); wtx.submit(); } private InstanceIdentifier<SxpDomain> sxpDomainIid(String domainId) { return InstanceIdentifier.builder(NetworkTopology.class) .child(Topology.class, new TopologyKey(new TopologyId(IpSgtDistributionServiceImpl.SXP_TOPOLOGY_ID))) .child(Node.class, new NodeKey(new NodeId(SXP_NODE_ID))) .augmentation(SxpNodeIdentity.class) .child(SxpDomains.class) .child(SxpDomain.class, new SxpDomainKey(domainId)) .build(); } synchronized String getDomainIdForPeer(InstanceIdentifier<Node> peer) { return sxpCapableNodes.get(peer); } void close() { listenerRegistration.close(); } }