implement ecs in alto-provider 04/20004/1
authorroot <dongs2011@gmail.com>
Mon, 11 May 2015 09:31:22 +0000 (05:31 -0400)
committerroot <dongs2011@gmail.com>
Mon, 11 May 2015 09:31:52 +0000 (05:31 -0400)
Change-Id: Iec7294bb1fbb6c0d33223a139d158a67b00840e9
Signed-off-by: root <dongs2011@gmail.com>
alto-model/src/main/yang/alto-cost-default.yang [new file with mode: 0644]
alto-provider/pom.xml
alto-provider/src/main/java/org/opendaylight/alto/provider/AltoProvider.java
alto-provider/src/main/java/org/opendaylight/controller/config/yang/config/alto_provider/impl/AltoProviderModule.java
alto-provider/src/test/java/org/opendaylight/alto/provider/AltoProviderTest.java [new file with mode: 0644]
features/pom.xml
features/src/main/resources/features.xml
pom.xml

diff --git a/alto-model/src/main/yang/alto-cost-default.yang b/alto-model/src/main/yang/alto-cost-default.yang
new file mode 100644 (file)
index 0000000..2ce4722
--- /dev/null
@@ -0,0 +1,17 @@
+module alto-cost-default {
+    namespace "urn:opendaylight:alto:costdefault";
+    prefix "alto-cost-default";
+
+    import alto-service {prefix alto-restconf;}
+
+    revision 2015-05-07 {
+        description
+            "augment default cost in alto-service-types";
+    }
+
+    augment "/alto-restconf:endpoint-cost-service/alto-restconf:output/alto-restconf:endpoint-cost-service/alto-restconf:endpoint-cost-map/alto-restconf:dst-costs" {
+        leaf cost-default {
+            type int32;
+        }
+    }
+}
index cc95f660e6ebabdc8778d35c62f47ff7c151a61d..273af201a33aa7f16022eb78c5238f457d5427a6 100644 (file)
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>${mdsal.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.l2switch.addresstracker</groupId>
+            <artifactId>addresstracker-model</artifactId>
+            <version>${l2switch.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.l2switch.hosttracker</groupId>
+            <artifactId>hosttracker-model</artifactId>
+            <version>${l2switch.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-topology</artifactId>
+            <version>${ietf.topology.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.thirdparty</groupId>
+            <artifactId>net.sf.jung2</artifactId>
+            <version>2.0.1</version>
+        </dependency>
   </dependencies>
 
   <build>
index afed2ec16070f146c43bf508ec85f11809469f8e..b4c7dd131c5206855afe6fe8658f1d8199733547 100644 (file)
@@ -1,32 +1,79 @@
 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,
@@ -34,6 +81,14 @@ public class AltoProvider implements
 
     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();
 
@@ -41,7 +96,9 @@ public class AltoProvider implements
     private final ExecutorService executor;
 
     public AltoProvider() {
+       this.ipSwitchIdMap = new HashMap<String, String>();
         this.executor = Executors.newFixedThreadPool(1);
+        //////////////////////////////////////////////////////////////
     }
 
     public void setDataProvider(final DataBroker salDataProvider) {
@@ -49,21 +106,357 @@ public class AltoProvider implements
         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
@@ -82,7 +475,10 @@ public class AltoProvider implements
 
     @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);
index f023a0bff0774ae886550a164e09233fcefaf5f4..1d516c87b9d0a2de3c3dddf37bcb93d0fa86f5ff 100644 (file)
@@ -41,6 +41,9 @@ public class AltoProviderModule extends AbstractAltoProviderModule {
             dataBrokerService.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, AltoProvider.ALTO_IID, altoProvider, DataChangeScope.SUBTREE);
         final AltoProviderRuntimeRegistration runtimeReg = getRootRuntimeBeanRegistratorWrapper().register(altoProvider);
 
+        altoProvider.registerAsDataChangeListener();
+        log.info("provider success");
+
         final class AutoCloseableAlto implements AutoCloseable {
             @Override
             public void close() throws Exception {
diff --git a/alto-provider/src/test/java/org/opendaylight/alto/provider/AltoProviderTest.java b/alto-provider/src/test/java/org/opendaylight/alto/provider/AltoProviderTest.java
new file mode 100644 (file)
index 0000000..07d6943
--- /dev/null
@@ -0,0 +1,169 @@
+/**
+ * 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);  
+  }
+
+}
index d40df36eb4f6d8bef27101ae99ee42f026af1c5d..91d13167b77680ef04eb392538f42330750e47e6 100644 (file)
@@ -122,6 +122,36 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpcore-osgi</artifactId>
     </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>${mdsal.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.l2switch.addresstracker</groupId>
+            <artifactId>addresstracker-model</artifactId>
+            <version>${l2switch.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.l2switch.hosttracker</groupId>
+            <artifactId>hosttracker-model</artifactId>
+            <version>${l2switch.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-topology</artifactId>
+            <version>${ietf.topology.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.thirdparty</groupId>
+            <artifactId>net.sf.jung2</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+
   </dependencies>
 
   <build>
index 578e5b4fc94812ac5e1b79407661e77a4c1bd966..90db26ba0161206c69e456c0181a8cafc504a4f3 100644 (file)
@@ -41,6 +41,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <feature name='odl-alto-provider' version='${project.version}' description='OpenDaylight :: alto :: Provider'>
     <feature version='${project.version}'>odl-alto-model</feature>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+    <feature version='${l2switch.version}'>odl-l2switch-hosttracker</feature>
+    <feature version='${l2switch.version}'>odl-l2switch-addresstracker</feature>
     <configfile finalname="etc/opendaylight/karaf/03-alto.xml">mvn:org.opendaylight.alto/alto-config/${project.version}/xml/config</configfile>
     <bundle>mvn:org.opendaylight.alto/alto-provider/${project.version}</bundle>
   </feature>
diff --git a/pom.xml b/pom.xml
index a0b317e370e95761f15449752779d1951869774a..e59bb9ad931221cab558984458f346ab7cb8ee52 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>odlparent</artifactId>
-    <version>1.6.0-SNAPSHOT</version>
-    <relativePath></relativePath>
+    <version>1.5.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
   <groupId>org.opendaylight.alto</groupId>
@@ -22,6 +22,7 @@
     <module>alto-model</module>
     <module>alto-config</module> <!-- required by alto-manager -->
     <module>alto-provider</module>
+    <module>alto-hosttracker</module>
     <module>features</module>
     <module>alto-commons</module>
     <module>alto-manager</module>
@@ -61,6 +62,8 @@
     <controller.commons.northbound.version> <!-- required by alto-northbound -->
       0.5.0-SNAPSHOT
     </controller.commons.northbound.version>
+    <l2switch.version>0.2.0-SNAPSHOT</l2switch.version>
+    <ietf.topology.version>2013.10.21.7-SNAPSHOT</ietf.topology.version>
   </properties>
 
   <dependencyManagement>
     </dependencies>
   </dependencyManagement>
 
-  <repositories>
-
-    <!-- OpenDayLight Repo Mirror -->
-    <!-- NOTE: URLs need to be hardcoded in the repository section because we have
-         parent poms that do NOT exist in this project and thus need to be pulled
-         down from the repository. To override these URLs you should use the
-         mirror section in your local settings.xml file. -->
-    <repository>
-      <releases>
-        <enabled>true</enabled>
-        <updatePolicy>never</updatePolicy>
-      </releases>
-      <snapshots>
-        <enabled>false</enabled>
-      </snapshots>
-      <id>opendaylight-mirror</id>
-      <name>opendaylight-mirror</name>
-      <url>http://nexus.opendaylight.org/content/groups/public/</url>
-    </repository>
-    <!-- OpenDayLight Snapshot artifact -->
-    <repository>
-      <releases>
-        <enabled>false</enabled>
-      </releases>
-      <snapshots>
-        <enabled>true</enabled>
-      </snapshots>
-      <id>opendaylight-snapshot</id>
-      <name>opendaylight-snapshot</name>
-      <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
-    </repository>
-  </repositories>
-
   <build>
     <pluginManagement>
       <plugins>