package org.opendaylight.alto.provider;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.logging.Level;
import org.opendaylight.controller.config.yang.config.alto_provider.impl.AltoProviderRuntimeMXBean;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
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.alto.rev150404.AltoServiceService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.FilteredCostMapServiceInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.FilteredCostMapServiceOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.FilteredNetworkMapServiceInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.FilteredNetworkMapServiceOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.Resources;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.input.CostType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.input.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.EndpointCostService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.EndpointCostServiceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.EndpointCostMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.EndpointCostMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.EndpointCostMapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.Meta;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.MetaBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.endpoint.cost.map.DstCosts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.endpoint.cost.map.DstCostsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.Constraint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.CostMetric;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.CostMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostNode;////////////////////////////////////
+import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.host.AttachmentPoints;
+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.TpId;
+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.Link;
+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.opendaylight.alto.costdefault.rev150507.DstCosts1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.costdefault.rev150507.DstCosts1Builder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.SparseMultigraph;
+import edu.uci.ics.jung.graph.util.EdgeType;
public class AltoProvider implements
AltoServiceService, DataChangeListener,
private static final Logger log = LoggerFactory.getLogger(AltoProvider.class);
+ private ListenerRegistration<DataChangeListener> hostNodeListerRegistration;
+
+ private ListenerRegistration<DataChangeListener> linkListerRegistration;
+ private Map<String, String> ipSwitchIdMap = null;
+ Graph<NodeId, Link> networkGraph = null;
+ Set<String> linkAdded = new HashSet<>();
+ DijkstraShortestPath<NodeId, Link> shortestPath = null;
+
public static final InstanceIdentifier<Resources> ALTO_IID
= InstanceIdentifier.builder(Resources.class).build();
private final ExecutorService executor;
public AltoProvider() {
+ this.ipSwitchIdMap = new HashMap<String, String>();
this.executor = Executors.newFixedThreadPool(1);
+ //////////////////////////////////////////////////////////////
}
public void setDataProvider(final DataBroker salDataProvider) {
log.info(this.getClass().getName() + " data provider initiated");
}
+ public void registerAsDataChangeListener() {
+ InstanceIdentifier<HostNode> hostNodes = InstanceIdentifier
+ .builder(NetworkTopology.class)//
+ .child(Topology.class,
+ new TopologyKey(new TopologyId("flow:1")))//
+ .child(Node.class).augmentation(HostNode.class).build();
+ this.hostNodeListerRegistration = dataProvider
+ .registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ hostNodes, this, DataChangeScope.BASE);
+
+ InstanceIdentifier<Link> links = InstanceIdentifier
+ .builder(NetworkTopology.class)//
+ .child(Topology.class,
+ new TopologyKey(new TopologyId("flow:1")))//
+ .child(Link.class).build();
+ this.linkListerRegistration = dataProvider.registerDataChangeListener(
+ LogicalDatastoreType.OPERATIONAL, links, this,
+ DataChangeScope.BASE);
+
+ InstanceIdentifier<Topology> topology = InstanceIdentifier
+ .builder(NetworkTopology.class)//
+ .child(Topology.class,
+ new TopologyKey(new TopologyId("flow:1"))).build();
+
+ ReadOnlyTransaction newReadOnlyTransaction = dataProvider
+ .newReadOnlyTransaction();
+
+ ListenableFuture<Optional<Topology>> dataFuture = newReadOnlyTransaction
+ .read(LogicalDatastoreType.OPERATIONAL, topology);
+ try {
+ Topology get = dataFuture.get().get();
+ //log.trace("test " + get);
+ } catch (InterruptedException | ExecutionException ex) {
+ java.util.logging.Logger.getLogger(AltoProvider.class.getName())
+ .log(Level.SEVERE, null, ex);
+ }
+ Futures.addCallback(dataFuture,
+ new FutureCallback<Optional<Topology>>() {
+ @Override
+ public void onSuccess(final Optional<Topology> result) {
+ if (result.isPresent()) {
+ log.trace("Processing NEW NODE? " + result.get());
+ processTopology(result.get());
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable arg0) {
+ }
+ });
+ }
+
+ public synchronized void addLinks(List<Link> links) {
+ if (links == null || links.isEmpty()) {
+ log.info("In addLinks: No link added as links is null or empty.");
+ return;
+ }
+
+ if (networkGraph == null) {
+ networkGraph = new SparseMultigraph<>();
+ }
+
+ for (Link link : links) {
+ if (linkAlreadyAdded(link)) {
+ continue;
+ }
+ NodeId sourceNodeId = link.getSource().getSourceNode();
+ NodeId destinationNodeId = link.getDestination().getDestNode();
+ networkGraph.addVertex(sourceNodeId);
+ networkGraph.addVertex(destinationNodeId);
+ networkGraph.addEdge(link, sourceNodeId, destinationNodeId,
+ EdgeType.UNDIRECTED);
+ }
+
+ if (shortestPath == null) {
+ shortestPath = new DijkstraShortestPath<>(networkGraph);
+ } else {
+ shortestPath.reset();
+ }
+ }
+
+ private boolean linkAlreadyAdded(Link link) {
+ String linkAddedKey = null;
+ if (link.getDestination().getDestTp().hashCode() > link.getSource()
+ .getSourceTp().hashCode()) {
+ linkAddedKey = link.getSource().getSourceTp().getValue()
+ + link.getDestination().getDestTp().getValue();
+ } else {
+ linkAddedKey = link.getDestination().getDestTp().getValue()
+ + link.getSource().getSourceTp().getValue();
+ }
+ if (linkAdded.contains(linkAddedKey)) {
+ return true;
+ } else {
+ linkAdded.add(linkAddedKey);
+ return false;
+ }
+ }
+
+ public void processTopology(Topology topology) {
+ List<Node> nodeList = topology.getNode();
+ for (int i = 0; i < nodeList.size(); ++i) {
+ Node node = nodeList.get(i);
+ HostNode hostNode = node.getAugmentation(HostNode.class);
+ log.info("process node "+i+hostNode);
+ processNode(hostNode);
+ }
+ List<Link> linkList = topology.getLink();
+ addLinks(linkList);
+ }
+
+ private void deleteHostNode(HostNode hostNode) {
+ List<AttachmentPoints> attachmentPoints = hostNode
+ .getAttachmentPoints();
+
+ TpId tpId = attachmentPoints.get(0).getTpId();
+ String tpIdString = tpId.getValue();
+
+ String ipv4String = hostNode.getAddresses().get(0).getIp()
+ .getIpv4Address().getValue();
+
+ this.ipSwitchIdMap.remove(ipv4String);
+ }
+
+ private void processNode(HostNode hostNode) {
+ if(hostNode==null)return;
+ List<AttachmentPoints> attachmentPoints = hostNode
+ .getAttachmentPoints();
+
+ TpId tpId = attachmentPoints.get(0).getTpId();
+ String tpIdString = tpId.getValue();
+
+ String ipv4String = hostNode.getAddresses().get(0).getIp()
+ .getIpv4Address().getValue();
+
+ this.ipSwitchIdMap.put(ipv4String, tpIdString);
+ }
+
+
@Override
public void onDataChanged(
final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- DataObject dataObject = change.getUpdatedSubtree();
- if (dataObject instanceof Resources) {
- Resources altoResources = (Resources) dataObject;
- log.info("onDataChanged - new ALTO config: {}", altoResources);
- }
+// DataObject dataObject = change.getUpdatedSubtree();
+// if (dataObject instanceof Resources) {
+// Resources altoResources = (Resources) dataObject;
+// log.info("onDataChanged - new ALTO config: {}", altoResources);
+ log.info("in Data Changed");
+ if (change == null) {
+ log.info("In onDataChanged: No processing done as change even is null.");
+ return;
+ }
+ Map<InstanceIdentifier<?>, DataObject> updatedData = change
+ .getUpdatedData();
+ Map<InstanceIdentifier<?>, DataObject> createdData = change
+ .getCreatedData();
+ Map<InstanceIdentifier<?>, DataObject> originalData = change
+ .getOriginalData();
+ Set<InstanceIdentifier<?>> deletedData = change.getRemovedPaths();
+
+ for (InstanceIdentifier<?> iid : deletedData) {
+ log.info("delete Data");
+ if (iid.getTargetType().equals(HostNode.class)) {
+ log.info("delete hostnode");
+ HostNode node = ((HostNode) originalData.get(iid));
+ deleteHostNode(node);
+ } else if (iid.getTargetType().equals(Link.class)) {
+ // TODO performance improvement here
+ log.info("delete edge");
+ String linkAddedKey = null;
+ Link link = (Link) originalData.get(iid);
+ if (link.getDestination().getDestTp().hashCode() > link.getSource()
+ .getSourceTp().hashCode()) {
+ linkAddedKey = link.getSource().getSourceTp().getValue()
+ + link.getDestination().getDestTp().getValue();
+ } else {
+ linkAddedKey = link.getDestination().getDestTp().getValue()
+ + link.getSource().getSourceTp().getValue();
+ }
+ if (linkAdded.contains(linkAddedKey)) {
+ linkAdded.remove(linkAddedKey);
+ }
+ networkGraph.removeEdge((Link) originalData.get(iid));
+ shortestPath.reset();
+ shortestPath = new DijkstraShortestPath<>(networkGraph);
+ }
+ }
+
+ for (Map.Entry<InstanceIdentifier<?>, DataObject> entrySet : updatedData
+ .entrySet()) {
+ log.info("update hostnode data");
+ InstanceIdentifier<?> iiD = entrySet.getKey();
+ final DataObject dataObject = entrySet.getValue();
+ if (dataObject instanceof HostNode) {
+ processNode((HostNode) dataObject);
+ }
+ }
+
+ for (Map.Entry<InstanceIdentifier<?>, DataObject> entrySet : createdData
+ .entrySet()) {
+ InstanceIdentifier<?> iiD = entrySet.getKey();
+ final DataObject dataObject = entrySet.getValue();
+ if (dataObject instanceof HostNode) {
+ log.info("update HostNode");
+ processNode((HostNode) dataObject);
+ } else if (dataObject instanceof Link) {
+ log.info("update link");
+ Link link = (Link) dataObject;
+ if (!linkAlreadyAdded(link)) {
+ NodeId sourceNodeId = link.getSource().getSourceNode();
+ NodeId destinationNodeId = link.getDestination()
+ .getDestNode();
+ networkGraph.addVertex(sourceNodeId);
+ networkGraph.addVertex(destinationNodeId);
+ networkGraph.addEdge(link, sourceNodeId, destinationNodeId,
+ EdgeType.UNDIRECTED);
+ log.info("update link in networkGraph");
+ shortestPath.reset();
+ shortestPath = new DijkstraShortestPath<>(networkGraph);
+ }
+ }
+ }
+
+
}
+ public List<EndpointCostMap> hopcountNumerical(List<TypedEndpointAddress> srcs, List<TypedEndpointAddress> dsts) {
+
+ List<EndpointCostMap> result = new ArrayList<EndpointCostMap>();
+ for (int i = 0; i < srcs.size(); ++i) {
+ TypedEndpointAddress teaSrc = srcs.get(i);
+ String ipv4SrcString = teaSrc.getTypedIpv4Address().getValue()
+ .substring(5);
+ log.info("ipv4SrcString:"+ipv4SrcString);
+ String tpIdSrc = this.ipSwitchIdMap.get(ipv4SrcString);
+ String[] tempi = tpIdSrc.split(":");
+ String swSrcId = tempi[0] + ":" + tempi[1];
+ log.info("swSrcId:"+swSrcId);
+ List<DstCosts> dstCostsList = new ArrayList<DstCosts>();
+
+ for (int j = 0; j < dsts.size(); ++j) {
+ TypedEndpointAddress teaDst = dsts.get(j);
+ String ipv4DstString = teaDst.getTypedIpv4Address().getValue()
+ .substring(5);
+ String tpIdDst = this.ipSwitchIdMap.get(ipv4DstString);
+ String[] tempj = tpIdDst.split(":");
+ String swDstId = tempj[0] + ":" + tempj[1];
+
+ NodeId srcNodeId = new NodeId(swSrcId);
+ NodeId dstNodeId = new NodeId(swDstId);
+ log.info("caculate shortest path");
+ Number number = shortestPath.getDistance(srcNodeId, dstNodeId);
+ DstCosts1 dst1 = null;
+ if (number!=null) {
+ dst1 = new DstCosts1Builder().setCostDefault(number.intValue()).build();
+ }
+ else {
+ dst1 = new DstCosts1Builder().setCostDefault(Integer.MAX_VALUE).build();
+ }
+ DstCosts dstCost = new DstCostsBuilder()
+ .addAugmentation(DstCosts1.class, dst1).setDst(teaDst)
+ .build();
+ dstCostsList.add(dstCost);
+ }
+ EndpointCostMap ecp = new EndpointCostMapBuilder().setSrc(teaSrc)
+ .setDstCosts(dstCostsList)
+ .setKey(new EndpointCostMapKey(teaSrc)).build();
+ result.add(ecp);
+ }
+ return result;
+ }
+
@Override
public Future<RpcResult<EndpointCostServiceOutput>> endpointCostService(
EndpointCostServiceInput input) {
- // TODO Auto-generated method stub
- return null;
+/* // TODO Auto-generated method stub
+
+ return null;*/
+ log.info("all input:"+input);
+ log.info("start rpc");
+ CostType costTypeInput = null;
+ List<Constraint> constraintsInput = null;
+ Endpoints endpointsInput = null;
+
+ RpcResultBuilder<EndpointCostServiceOutput> endpointCostServiceBuilder = null;
+
+ EndpointCostServiceOutput output = null;
+ //EndpointCostServiceOutputBuilder outputBuilder = null;
+
+ if ((costTypeInput = input.getCostType()) == null) {
+ endpointCostServiceBuilder = RpcResultBuilder.<EndpointCostServiceOutput>failed().withError(ErrorType.APPLICATION, "Invalid cost-type value ", "Argument can not be null.");
+ }
+ else {
+ log.info("costTypeInput: "+costTypeInput);
+ if ((endpointsInput = input.getEndpoints()) == null) {
+ endpointCostServiceBuilder = RpcResultBuilder.<EndpointCostServiceOutput>failed().withError(ErrorType.APPLICATION, "Invalid endpoints value ", "Argument can not be null.");
+ }
+ else {
+ log.info("costMetric: "+costTypeInput.getCostMetric());
+ Endpoints endpoints = input.getEndpoints();
+ List<TypedEndpointAddress> srcs = endpoints.getSrcs();
+ List<TypedEndpointAddress> dsts = endpoints.getDsts();
+ //judge whether srcs or dsts are discovered
+ boolean srcDstFoundFlag = true;
+ for (int i = 0; i < srcs.size(); ++i) {
+ TypedEndpointAddress teaSrc = srcs.get(i);
+ String ipv4SrcString = teaSrc.getTypedIpv4Address().getValue()
+ .substring(5);
+ log.info("parsed ipv4SrcString:"+ipv4SrcString);
+ if (this.ipSwitchIdMap.get(ipv4SrcString) == null) {
+ endpointCostServiceBuilder = RpcResultBuilder.<EndpointCostServiceOutput>failed().withError(ErrorType.APPLICATION, "Invalid endpoints value ", "IP can not be found.");
+ srcDstFoundFlag = false;
+ }
+ }
+ for (int j = 0; j < dsts.size(); ++j) {
+ TypedEndpointAddress teaDst = dsts.get(j);
+ String ipv4DstString = teaDst.getTypedIpv4Address().getValue()
+ .substring(5);
+ log.info("parsed ipv4DstString:"+ipv4DstString);
+ if (this.ipSwitchIdMap.get(ipv4DstString) == null) {
+ endpointCostServiceBuilder = RpcResultBuilder.<EndpointCostServiceOutput>failed().withError(ErrorType.APPLICATION, "Invalid endpoints value ", "IP can not be found.");
+ srcDstFoundFlag = false;
+ }
+ }
+ CostMetric costMetric = costTypeInput.getCostMetric();
+ CostMode costMode = costTypeInput.getCostMode();
+ log.info("costmetric string:888"+costMetric.getString());
+ log.info("costmode string:888"+costMode);
+ if (srcDstFoundFlag && costMode.equals(CostMode.Numerical) && (costMetric.getEnumeration() == CostMetric.Enumeration.Hopcount || costMetric.getString().equals("hopcount"))){
+ log.info("in hopcount");
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.meta.CostType costType = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.meta.CostTypeBuilder()
+ .setCostMetric(costMetric)
+ .setCostMode(costMode).build();
+ Meta meta = new MetaBuilder().setCostType(costType).build();
+ List<EndpointCostMap> ecmList = hopcountNumerical(srcs, dsts);
+ EndpointCostService ecs = new EndpointCostServiceBuilder().setMeta(meta).setEndpointCostMap(ecmList).build();
+
+ if ((output = new EndpointCostServiceOutputBuilder().setEndpointCostService(ecs).build()) != null) {
+ log.info("output valid");
+ endpointCostServiceBuilder = RpcResultBuilder.success(output);
+ }
+ else {
+ endpointCostServiceBuilder = RpcResultBuilder.<EndpointCostServiceOutput>failed().withError(ErrorType.APPLICATION, "Invalid output value", "Output is null.");
+ }
+ return Futures.immediateFuture(endpointCostServiceBuilder.build());
+
+ }
+
+ }
+ }
+ return Futures.immediateFuture(RpcResultBuilder.<EndpointCostServiceOutput>failed().withError(ErrorType.APPLICATION, "Invalid output value", "Output is null.").build());
+
}
@Override
@Override
public void close() throws ExecutionException, InterruptedException {
- executor.shutdown();
+ this.hostNodeListerRegistration.close();
+ this.linkListerRegistration.close();
+ this.ipSwitchIdMap.clear();
+ executor.shutdown();
if (dataProvider != null) {
WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
tx.delete(LogicalDatastoreType.CONFIGURATION, ALTO_IID);
--- /dev/null
+/**
+ * Copyright (c) 2014 André Martins, Colin Dixon, Evan Zeller 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.provider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+//import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.Addresses;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.AddressesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.EndpointCostMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.EndpointCostMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.endpoint.cost.map.DstCosts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.endpoint.cost.map.DstCostsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.costdefault.rev150507.DstCosts1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.costdefault.rev150507.DstCosts1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedIpv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.host.AttachmentPoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.host.AttachmentPointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId;
+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.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Destination;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Source;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.SourceBuilder;
+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.TopologyBuilder;
+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.LinkBuilder;
+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.NodeBuilder;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.mock;
+
+public class AltoProviderTest {
+
+ private AltoProvider altoProvider;
+ private Addresses addrs;
+ private DataBroker dataBroker;
+ private IpAddress ipAddress;
+ private MacAddress mac;
+
+
+ @Before
+ public void init(){
+ dataBroker = mock(DataBroker.class);
+ altoProvider = new AltoProvider();
+ }
+
+ @Test
+ public void onProcessTopology() throws Exception {
+ IpAddress ipAddress1 = new IpAddress(new Ipv4Address("10.0.0.1"));
+ MacAddress mac1 = new MacAddress("00:00:00:00:00:01");
+ Addresses addrs1 = new AddressesBuilder().setIp(ipAddress1).setMac(mac1).build();
+ List<Addresses> addrsList1 = new ArrayList<Addresses>();
+ addrsList1.add(addrs1);
+
+ AttachmentPoints ap1 = new AttachmentPointsBuilder().setTpId(new TpId("openflow:1:1")).build();
+ List<AttachmentPoints> apList1 = new ArrayList<AttachmentPoints>();
+ apList1.add(ap1);
+ HostNode hostNode1 = new HostNodeBuilder().setAddresses(addrsList1).setAttachmentPoints(apList1).build();
+
+ IpAddress ipAddress2 = new IpAddress(new Ipv4Address("10.0.0.2"));
+ MacAddress mac2 = new MacAddress("00:00:00:00:00:02");
+ Addresses addrs2 = new AddressesBuilder().setIp(ipAddress2).setMac(mac2).build();
+ List<Addresses> addrsList2 = new ArrayList<Addresses>();
+ addrsList2.add(addrs2);
+
+ AttachmentPoints ap2 = new AttachmentPointsBuilder().setTpId(new TpId("openflow:2:1")).build();
+ List<AttachmentPoints> apList2 = new ArrayList<AttachmentPoints>();
+ apList2.add(ap2);
+ HostNode hostNode2 = new HostNodeBuilder().setAddresses(addrsList2).setAttachmentPoints(apList2).build();
+
+
+ Node node1 = new NodeBuilder().addAugmentation(HostNode.class, hostNode1).build();
+ Node node2 = new NodeBuilder().addAugmentation(HostNode.class, hostNode2).build();
+
+ Node sw1 = new NodeBuilder().setNodeId(new NodeId("openflow:1")).build();
+ Node sw2 = new NodeBuilder().setNodeId(new NodeId("openflow:2")).build();
+ Node sw3 = new NodeBuilder().setNodeId(new NodeId("openflow:3")).build();
+
+ Destination SW1_2 = new DestinationBuilder().setDestNode(new NodeId("openflow:1"))
+ .setDestTp(new TpId("openflow:1:2")).build();
+ Source SW3_1 = new SourceBuilder().setSourceNode(new NodeId("openflow:3"))
+ .setSourceTp(new TpId("openflow:3:1")).build();
+ Link l1 = new LinkBuilder().setLinkId(new LinkId("link1"))
+ .setDestination(SW1_2)
+ .setSource(SW3_1).build();
+
+ Destination SW1_3 = new DestinationBuilder().setDestNode(new NodeId("openflow:1"))
+ .setDestTp(new TpId("openflow:1:3")).build();
+ Source SW2_2 = new SourceBuilder().setSourceNode(new NodeId("openflow:2"))
+ .setSourceTp(new TpId("openflow:2:2")).build();
+ Link l2 = new LinkBuilder().setLinkId(new LinkId("link2"))
+ .setDestination(SW1_3)
+ .setSource(SW2_2).build();
+
+ Destination SW3_2 = new DestinationBuilder().setDestNode(new NodeId("openflow:3"))
+ .setDestTp(new TpId("openflow:3:2")).build();
+ Source SW2_3 = new SourceBuilder().setSourceNode(new NodeId("openflow:2"))
+ .setSourceTp(new TpId("openflow:2:3")).build();
+ Link l3 = new LinkBuilder().setLinkId(new LinkId("link3"))
+ .setDestination(SW3_2)
+ .setSource(SW2_3).build();
+
+ List<Node> nodeList = new ArrayList<Node>();
+ nodeList.add(node1);
+ nodeList.add(node2);
+ nodeList.add(sw1);
+ nodeList.add(sw2);
+ nodeList.add(sw3);
+
+ List<Link> linkList = new ArrayList<Link>();
+ linkList.add(l1);
+ linkList.add(l2);
+ linkList.add(l3);
+
+ Topology topology = new TopologyBuilder().setTopologyId(new TopologyId("flow:1"))
+ .setLink(linkList)
+ .setNode(nodeList).build();
+
+ altoProvider.processTopology(topology);
+
+ TypedIpv4Address ipv4_1 = new TypedIpv4Address("ipv4:10.0.0.1");
+ TypedEndpointAddress tea1 = new TypedEndpointAddress(ipv4_1);
+
+ List<TypedEndpointAddress> teaList1 = new ArrayList<TypedEndpointAddress>();
+ teaList1.add(tea1);
+
+ TypedIpv4Address ipv4_2 = new TypedIpv4Address("ipv4:10.0.0.2");
+ TypedEndpointAddress tea2 = new TypedEndpointAddress(ipv4_2);
+
+ List<TypedEndpointAddress> teaList2 = new ArrayList<TypedEndpointAddress>();
+ teaList2.add(tea2);
+
+ DstCosts1 dc1 = new DstCosts1Builder().setCostDefault(1).build();
+ DstCosts dc = new DstCostsBuilder().setDst(tea2).addAugmentation(DstCosts1.class, dc1).build();
+
+ List<DstCosts> dcList = new ArrayList<DstCosts>();
+ dcList.add(dc);
+
+ EndpointCostMap ecp = new EndpointCostMapBuilder().setSrc(tea1).setDstCosts(dcList).build();
+ List<EndpointCostMap> ecpList = new ArrayList<EndpointCostMap>();
+ ecpList.add(ecp);
+
+ Assert.assertEquals(altoProvider.hopcountNumerical(teaList1, teaList2), ecpList);
+ }
+
+}