/* * Copyright © 2015 Yale University 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.alto.basic.endpointcostservice.suportservice.impl; import org.opendaylight.alto.basic.endpointcostservice.suportservice.exception.ReadDataFailedException; import org.opendaylight.alto.basic.endpointcostservice.suportservice.service.LinkService; import org.opendaylight.alto.basic.endpointcostservice.suportservice.service.NetworkElementService; import org.opendaylight.alto.basic.endpointcostservice.suportservice.service.NetworkFlowCapableNodeService; import org.opendaylight.alto.basic.endpointcostservice.suportservice.service.NetworkHostNodeService; import org.opendaylight.alto.basic.endpointcostservice.helper.DataStoreHelper; import org.opendaylight.alto.basic.endpointcostservice.util.InstanceIdentifierUtils; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostNode; 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.topology.Link; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class NetworkElementImpl implements NetworkElementService, DataChangeListener, AutoCloseable { private static final Logger log = LoggerFactory .getLogger(NetworkElementImpl.class); private static final int CPUS = Runtime.getRuntime().availableProcessors(); private ExecutorService exec = Executors.newFixedThreadPool(CPUS); private DataBroker dataBroker; private ListenerRegistration<DataChangeListener> hostNodeListRegistration; private ListenerRegistration<DataChangeListener> linkListRegistration; private NetworkHostNodeService hostNodeService; private LinkService linkService; private NetworkFlowCapableNodeService flowCapableNodeService; public NetworkElementImpl(DataBroker dataBroker) { this.dataBroker = dataBroker; this.linkService = new LinkServiceImpl(); this.hostNodeService = new NetworkHostNodeImpl(); this.flowCapableNodeService = new NetworkFlowCapableNodeImpl(dataBroker); registerAsDataChangeListener(); } public void registerAsDataChangeListener() { addExistingNodes(); registerHostNodeListener(); registerLinkListener(); } private void addExistingNodes() { try { Topology topology = DataStoreHelper.readOperational(this.dataBroker, InstanceIdentifierUtils.TOPOLOGY); addExistingHostNodes(topology); addExistingLinks(topology); } catch (ReadDataFailedException e) { e.printMessage("Read topology failed"); e.printStackTrace(); } } private void addExistingHostNodes(Topology topology) { log.info("Topology Null Check: " + (topology == null)); List<Node> nodeList = topology.getNode(); log.info("Node List Null Check: " + (nodeList == null)); if (topology != null && nodeList != null) { for (int i = 0; i < nodeList.size(); ++i) { Node node = nodeList.get(i); HostNode hostNode = node.getAugmentation(HostNode.class); log.info("Processing node " + i + ", " + hostNode); hostNodeService.addHostNode(hostNode); } } } private void addExistingLinks(Topology topology) { log.info("Topology Null Check: " + (topology == null)); List<Link> linkList = topology.getLink(); log.info("Link List Null Check: " + (linkList == null)); if (topology != null && linkList != null) { for (int i = 0; i < linkList.size(); i++) { Link link = linkList.get(i); log.info("Processing link " + i + ", " + link.getLinkId().getValue()); linkService.addLink(link); } } } @Override public void close() throws Exception { this.hostNodeListRegistration.close(); this.linkListRegistration.close(); } @Override public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) { exec.submit(new Runnable() { @Override public void run() { if (change == null) { log.info("In onDataChanged: Change event is null."); return; } onDataUpdated(change); onDataCreated(change); onDataDeleted(change); } private void onDataUpdated( AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) { Map<InstanceIdentifier<?>, DataObject> updatedData = change .getUpdatedData(); if (updatedData.size() > 0) { log.info("In onDataUpdated"); processUpdatedOrCreatedData(updatedData); } } private void onDataCreated( AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) { Map<InstanceIdentifier<?>, DataObject> createdData = change .getCreatedData(); if (createdData.size() > 0) { log.info("In onDataCreated"); processUpdatedOrCreatedData(createdData); } } private void processUpdatedOrCreatedData( Map<InstanceIdentifier<?>, DataObject> data) { for (Map.Entry<InstanceIdentifier<?>, DataObject> entrySet : data .entrySet()) { final DataObject dataObject = entrySet.getValue(); if (dataObject instanceof HostNode) { log.info("Mapping host nodes to switch"); hostNodeService.addHostNode((HostNode) dataObject); } else if (dataObject instanceof Link) { log.info("Updating Links"); linkService.addLink((Link) dataObject); } } } private void onDataDeleted( AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) { Map<InstanceIdentifier<?>, DataObject> originalData = change .getOriginalData(); Set<InstanceIdentifier<?>> deletedData = change .getRemovedPaths(); if (deletedData.size() > 0) { log.info("In onDataDeleted"); processDeletedData(originalData, deletedData); } } private void processDeletedData( Map<InstanceIdentifier<?>, DataObject> originalData, Set<InstanceIdentifier<?>> deletedData) { for (InstanceIdentifier<?> iid : deletedData) { if (iid.getTargetType().equals(HostNode.class)) { hostNodeService.deleteHostNode((HostNode) originalData.get(iid)); } else if (iid.getTargetType().equals(Link.class)) { linkService.deleteLink((Link) originalData.get(iid)); } } } }); } @Override public LinkService getLinkService() { return linkService; } @Override public NetworkHostNodeService getHostNodeService() { return hostNodeService; } @Override public NetworkFlowCapableNodeService getFlowCapableNodeService() { return flowCapableNodeService; } private void registerHostNodeListener() { this.hostNodeListRegistration = this.dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, InstanceIdentifierUtils.HOSTNODE, this, AsyncDataBroker.DataChangeScope.BASE); } private void registerLinkListener() { this.linkListRegistration = this.dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,InstanceIdentifierUtils.LINK,this, AsyncDataBroker.DataChangeScope.BASE); } }