--- /dev/null
+/*
+ * 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();
+ }
+}