Merge "Updated POM files and versions to SNAPSHOT"
authorGiovanni Meo <gmeo@cisco.com>
Mon, 6 May 2013 12:40:44 +0000 (12:40 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 6 May 2013 12:40:44 +0000 (12:40 +0000)
21 files changed:
opendaylight/clustering/integrationtest/pom.xml [new file with mode: 0644]
opendaylight/clustering/integrationtest/src/test/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusteringServicesIntegrationTest.java [new file with mode: 0644]
opendaylight/clustering/integrationtest/src/test/resources/logback.xml [new file with mode: 0644]
opendaylight/clustering/services_implementation/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManagerImpl.java
opendaylight/hosttracker/implementation/pom.xml
opendaylight/hosttracker/integrationtest/pom.xml
opendaylight/hosttracker/integrationtest/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerIntegrationTest.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/ITopologyServiceShimListener.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SwitchHandler.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServices.java
opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/Activator.java
opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java [new file with mode: 0644]
opendaylight/statisticsmanager/implementation/pom.xml
opendaylight/switchmanager/integrationtest/pom.xml [new file with mode: 0644]
opendaylight/switchmanager/integrationtest/src/test/java/org/opendaylight/controller/switchmanager/internal/SwitchmanagerIntegrationTest.java [new file with mode: 0644]
opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java
opendaylight/web/root/src/main/resources/js/open.js

diff --git a/opendaylight/clustering/integrationtest/pom.xml b/opendaylight/clustering/integrationtest/pom.xml
new file mode 100644 (file)
index 0000000..24a59d2
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>clustering.services.integrationtest</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.infinispan</groupId>
+      <artifactId>infinispan-core</artifactId>
+      <version>5.2.3.Final</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal.implementation</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+       <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services-implementation</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+  <properties>
+    <!-- Sonar jacoco plugin to get integration test coverage info -->
+    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+    <sonar.jacoco.reportPath>../implementation/target/jacoco.exec</sonar.jacoco.reportPath>
+    <sonar.jacoco.itReportPath>../implementaiton/target/jacoco-it.exec</sonar.jacoco.itReportPath>
+    <sonar.language>java</sonar.language>
+  </properties>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.jacoco</groupId>
+          <artifactId>jacoco-maven-plugin</artifactId>
+          <version>0.5.3.201107060350</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
+        <version>0.5.3.201107060350</version>
+        <configuration>
+          <destFile>../implementation/target/jacoco-it.exec</destFile>
+          <includes>org.opendaylight.controller.*</includes>
+        </configuration>
+        <executions>
+          <execution>
+            <id>pre-test</id>
+            <goals>
+              <goal>prepare-agent</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>post-test</id>
+            <configuration>
+              <skip>true</skip>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/clustering/integrationtest/src/test/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusteringServicesIntegrationTest.java b/opendaylight/clustering/integrationtest/src/test/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusteringServicesIntegrationTest.java
new file mode 100644 (file)
index 0000000..587a4cf
--- /dev/null
@@ -0,0 +1,235 @@
+package org.opendaylight.controller.clustering.services_implementation.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.systemPackages;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
+import java.net.InetAddress;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.inject.Inject;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.CacheListenerAddException;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.clustering.services.IClusterServices.cacheMode;
+import org.opendaylight.controller.clustering.services.IGetUpdates;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.util.PathUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(PaxExam.class)
+public class ClusteringServicesIntegrationTest {
+    private Logger log = LoggerFactory
+            .getLogger(ClusteringServicesIntegrationTest.class);
+    // get the OSGI bundle context
+    @Inject
+    private BundleContext bc;
+
+    private IClusterServices clusterServices = null;
+
+    // Configure the OSGi container
+    @Configuration
+    public Option[] config() {
+        return options(
+                //
+                systemProperty("logback.configurationFile").value(
+                        "file:" + PathUtils.getBaseDir()
+                                + "/src/test/resources/logback.xml"),
+                // To start OSGi console for inspection remotely
+                systemProperty("osgi.console").value("2401"),
+                // Set the systemPackages (used by clustering)
+                systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
+                // List framework bundles
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.console",
+                        "1.0.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.util",
+                        "1.0.400.v20120522-2049"),
+                mavenBundle("equinoxSDK381", "org.eclipse.osgi.services",
+                        "3.3.100.v20120522-1822"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds",
+                        "1.4.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command",
+                        "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime",
+                        "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell",
+                        "0.8.0.v201110170705"),
+                // List logger bundles
+                mavenBundle("org.slf4j", "slf4j-api", "1.7.2"),
+                mavenBundle("org.slf4j", "log4j-over-slf4j", "1.7.2"),
+                mavenBundle("ch.qos.logback", "logback-core", "1.0.9"),
+                mavenBundle("ch.qos.logback", "logback-classic", "1.0.9"),
+                // List all the bundles on which the test case depends
+                mavenBundle("org.opendaylight.controller",
+                        "clustering.services", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller",
+                        "clustering.services-implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "sal",
+                        "0.5.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller",
+                        "sal.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.jboss.spec.javax.transaction",
+                        "jboss-transaction-api_1.1_spec", "1.0.1.Final"),
+                mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
+                mavenBundle("org.apache.felix",
+                        "org.apache.felix.dependencymanager", "3.1.0"),
+                junitBundles());
+    }
+
+    private String stateToString(int state) {
+        switch (state) {
+        case Bundle.ACTIVE:
+            return "ACTIVE";
+        case Bundle.INSTALLED:
+            return "INSTALLED";
+        case Bundle.RESOLVED:
+            return "RESOLVED";
+        case Bundle.UNINSTALLED:
+            return "UNINSTALLED";
+        default:
+            return "Not CONVERTED";
+        }
+    }
+
+    @Before
+    public void areWeReady() {
+        assertNotNull(bc);
+        boolean debugit = false;
+        Bundle b[] = bc.getBundles();
+        for (int i = 0; i < b.length; i++) {
+            int state = b[i].getState();
+            if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
+                log.debug("Bundle:" + b[i].getSymbolicName() + " state:"
+                        + stateToString(state));
+                debugit = true;
+            }
+        }
+        if (debugit) {
+            log.debug("Do some debugging because some bundle is "
+                    + "unresolved");
+        }
+
+        // Assert if true, if false we are good to go!
+        assertFalse(debugit);
+
+        ServiceReference r = bc.getServiceReference(IClusterServices.class
+                .getName());
+        if (r != null) {
+            this.clusterServices = (IClusterServices) bc.getService(r);
+        }
+        assertNotNull(this.clusterServices);
+
+    }
+
+    @Test
+    public void clusterTest() throws CacheExistException, CacheConfigException,
+            CacheListenerAddException {
+
+        String container1 = "Container1";
+        String container2 = "Container2";
+        String cache1 = "Cache1";
+        String cache2 = "Cache2";
+        String cache3 = "Cache3";
+
+        HashSet<cacheMode> cacheModeSet = new HashSet<cacheMode>();
+        cacheModeSet.add(cacheMode.NON_TRANSACTIONAL);
+        ConcurrentMap cm11 = this.clusterServices.createCache(container1,
+                cache1, cacheModeSet);
+        assertNotNull(cm11);
+
+        assertNull(this.clusterServices.getCache(container2, cache2));
+        assertEquals(cm11, this.clusterServices.getCache(container1, cache1));
+
+        assertFalse(this.clusterServices.existCache(container2, cache2));
+        assertTrue(this.clusterServices.existCache(container1, cache1));
+
+        ConcurrentMap cm12 = this.clusterServices.createCache(container1,
+                cache2, cacheModeSet);
+        ConcurrentMap cm23 = this.clusterServices.createCache(container2,
+                cache3, cacheModeSet);
+
+        HashSet<String> cacheList = (HashSet<String>) this.clusterServices
+                .getCacheList(container1);
+        assertEquals(2, cacheList.size());
+        assertTrue(cacheList.contains(cache1));
+        assertTrue(cacheList.contains(cache2));
+        assertFalse(cacheList.contains(cache3));
+
+        assertNotNull(this.clusterServices.getCacheProperties(container1,
+                cache1));
+
+        HashSet<IGetUpdates<?, ?>> listeners = (HashSet<IGetUpdates<?, ?>>) this.clusterServices
+                .getListeners(container1, cache1);
+        assertEquals(0, listeners.size());
+
+        IGetUpdates<?, ?> getUpdate1 = new GetUpdates();
+        this.clusterServices.addListener(container1, cache1, getUpdate1);
+        listeners = (HashSet<IGetUpdates<?, ?>>) this.clusterServices
+                .getListeners(container1, cache1);
+        assertEquals(1, listeners.size());
+        this.clusterServices.addListener(container1, cache1, new GetUpdates());
+        listeners = (HashSet<IGetUpdates<?, ?>>) this.clusterServices
+                .getListeners(container1, cache1);
+        assertEquals(2, listeners.size());
+
+        listeners = (HashSet<IGetUpdates<?, ?>>) this.clusterServices
+                .getListeners(container2, cache3);
+        assertEquals(0, listeners.size());
+
+        this.clusterServices.removeListener(container1, cache1, getUpdate1);
+        listeners = (HashSet<IGetUpdates<?, ?>>) this.clusterServices
+                .getListeners(container1, cache1);
+        assertEquals(1, listeners.size());
+
+        InetAddress addr = this.clusterServices.getMyAddress();
+        assertNotNull(addr);
+
+        List<InetAddress> addrList = this.clusterServices
+                .getClusteredControllers();
+
+        this.clusterServices.destroyCache(container1, cache1);
+        assertFalse(this.clusterServices.existCache(container1, cache1));
+
+    }
+
+    private class GetUpdates implements IGetUpdates<Integer, String> {
+
+        @Override
+        public void entryCreated(Integer key, String containerName,
+                String cacheName, boolean originLocal) {
+            return;
+        }
+
+        @Override
+        public void entryUpdated(Integer key, String new_value,
+                String containerName, String cacheName, boolean originLocal) {
+            return;
+        }
+
+        @Override
+        public void entryDeleted(Integer key, String containerName,
+                String cacheName, boolean originLocal) {
+            return;
+        }
+    }
+}
diff --git a/opendaylight/clustering/integrationtest/src/test/resources/logback.xml b/opendaylight/clustering/integrationtest/src/test/resources/logback.xml
new file mode 100644 (file)
index 0000000..2d63ce5
--- /dev/null
@@ -0,0 +1,13 @@
+<configuration scan="true">
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+      </pattern>
+    </encoder>
+  </appender>
+
+  <root level="error">
+    <appender-ref ref="STDOUT" />
+  </root>
+</configuration>
index 80fc1c409957172d98b81866fcd991727cb9a4c3..ee2f65d2c8fb166fc85230ade455e6ecf496168f 100644 (file)
   <artifactId>clustering.services-implementation</artifactId>
   <version>0.4.0-SNAPSHOT</version>
   <packaging>bundle</packaging>
-
+  <properties>
+    <!-- Sonar properties using jacoco to retrieve integration test results -->
+    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
+    <sonar.jacoco.Reportpath>target/jacoco.exec</sonar.jacoco.Reportpath>
+    <sonar.jacoco.itReportPath>target/jacoco-it.exec</sonar.jacoco.itReportPath>
+    <sonar.language>java</sonar.language>
+  </properties>
   <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.jacoco</groupId>
+          <artifactId>jacoco-maven-plugin</artifactId>
+          <version>0.5.3.201107060350</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
     <plugins>
       <plugin>
        <groupId>org.apache.felix</groupId>
          </instructions>
        </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
+        <configuration>
+          <includes>org.opendaylight.controller.*</includes>
+        </configuration>
+        <executions>
+          <execution>
+            <id>pre-test</id>
+            <goals>
+              <goal>prepare-agent</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>post-test</id>
+            <phase>test</phase>
+            <goals>
+              <goal>report</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>      
     </plugins>
   </build>
   <dependencies>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.0-SNAPSHOT</version>
+      <version>0.4.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index c26b38843b29833f3633e822c7ef86d45b531ef6..986f074fa35286967c45205029eaa5a61f545eae 100644 (file)
@@ -34,6 +34,7 @@
     <module>../../forwarding/staticrouting</module>
     <module>../../clustering/services</module>
     <module>../../clustering/services_implementation</module>
+    <module>../../clustering/integrationtest</module>
     <module>../../clustering/stub</module>
     <module>../../clustering/test</module>
     <module>../../configuration/api</module>
@@ -50,6 +51,7 @@
     <module>../../containermanager/implementation</module>
     <module>../../switchmanager/api</module>
     <module>../../switchmanager/implementation</module>
+    <module>../../switchmanager/integrationtest</module>
     <module>../../statisticsmanager/api</module>
     <module>../../statisticsmanager/implementation</module>
     <module>../../statisticsmanager/integrationtest</module>
index 110d3381df8fa13100ab42d29ca2f954ba31ddb8..eee08d3a09db224a7ace5793cbbb597b32a5c2fb 100644 (file)
@@ -604,9 +604,9 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager,
     private Status addEntriesInternal(FlowEntryInstall entry, boolean async) {
         // Install the flow on the network node
         Status status = (async)?
-                programmer.addFlow(entry.getNode(), entry.getInstall()
-                        .getFlow()) :
                 programmer.addFlowAsync(entry.getNode(), entry.getInstall()
+                        .getFlow()) :
+                programmer.addFlow(entry.getNode(), entry.getInstall()
                             .getFlow());
 
 
index 402dfe32e350cd6486d9ca6cc36665e9bd2c746e..e7788d999ab42482b767e6ab812567fa7c60f7c0 100644 (file)
@@ -18,7 +18,7 @@
                <!-- Sonar properties using jacoco to retrieve integration test results -->
                <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
                <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
-               <sonar.jacoco.Reportpath>target/jacobo.exec</sonar.jacoco.Reportpath>
+               <sonar.jacoco.Reportpath>target/jacoco.exec</sonar.jacoco.Reportpath>
                <sonar.jacoco.itReportPath>target/jacoco-it.exec</sonar.jacoco.itReportPath>
                <sonar.language>java</sonar.language>
        </properties>
index 0d2d18ca2784edc3dee2830c20a20f2d6ccb43fa..d68189ad0f47e1d096eb1b9d09ec21d9080837fb 100644 (file)
@@ -59,7 +59,7 @@
  \r
        <dependency>\r
       <groupId>org.opendaylight.controller</groupId>\r
-      <artifactId>clustering.services-implementation</artifactId>\r
+      <artifactId>clustering.stub</artifactId>\r
       <version>0.4.0-SNAPSHOT</version>\r
     </dependency>\r
 \r
index fb5367c528654bd3dbf412cf13f346bc00690dd8..c5407794d25abf8cc0f6d846f96d6346c92edda8 100644 (file)
@@ -121,7 +121,7 @@ public class HostTrackerIntegrationTest {
                mavenBundle("org.opendaylight.controller",\r
                         "clustering.services", "0.4.0-SNAPSHOT"),\r
                mavenBundle("org.opendaylight.controller",\r
-                        "clustering.services-implementation", "0.4.0-SNAPSHOT"),\r
+                        "clustering.stub", "0.4.0-SNAPSHOT"),\r
 \r
                 // needed by forwardingrulesmanager\r
                 mavenBundle("org.opendaylight.controller", "switchmanager",\r
index 0c30c80f0df48fe4a5ca35fee756cdd7f698a464..e90823726c926d70304666055445b06df7ee4558 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -9,11 +8,13 @@
 
 package org.opendaylight.controller.protocol_plugin.openflow;
 
+import java.util.List;
 import java.util.Set;
 
 import org.opendaylight.controller.sal.core.Edge;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 
 /**
  * The Interface provides Edge updates to the topology listeners
@@ -21,18 +22,17 @@ import org.opendaylight.controller.sal.core.UpdateType;
 public interface ITopologyServiceShimListener {
     /**
      * Called to update on Edge in the topology graph
-     *
-     * @param edge                     {@link org.opendaylight.controller.sal.core.Edge} being updated
-     * @param type             {@link org.opendaylight.controller.sal.core.UpdateType}
-     * @param props            set of {@link org.opendaylight.controller.sal.core.Property} like
-     *                                                 {@link org.opendaylight.controller.sal.core.Bandwidth} and/or
-     *                                                 {@link org.opendaylight.controller.sal.core.Latency} etc.
+     * 
+     * @param topoedgeupdateList
+     *            List of topoedgeupdates Each topoedgeupdate includes edge, its
+     *            Properties ( BandWidth and/or Latency etc) and update type.
      */
-    public void edgeUpdate(Edge edge, UpdateType type, Set<Property> props);
+    public void edgeUpdate(List<TopoEdgeUpdate> topoedgeupdateList);
 
     /**
-     * Called when an Edge utilization is above the safe threshold configured
-     * on the controller
+     * Called when an Edge utilization is above the safe threshold configured on
+     * the controller
+     * 
      * @param {@link org.opendaylight.controller.sal.core.Edge}
      */
     public void edgeOverUtilized(Edge edge);
@@ -40,7 +40,7 @@ public interface ITopologyServiceShimListener {
     /**
      * Called when the Edge utilization is back to normal, below the safety
      * threshold level configured on the controller
-     *
+     * 
      * @param {@link org.opendaylight.controller.sal.core.Edge}
      */
     public void edgeUtilBackToNormal(Edge edge);
index 5c51cc5862d5f4c391cd956c1c8b59e1f03059ce..9a05c3f4f100c46b2c357f59ae6256f4e497f491 100644 (file)
@@ -207,7 +207,6 @@ public class SwitchHandler implements ISwitch {
         }
         executor.shutdown();
 
-        selector = null;
         msgReadWriteService = null;
 
         if (switchHandlerThread != null) {
@@ -313,7 +312,9 @@ public class SwitchHandler implements ISwitch {
         List<OFMessage> msgs = null;
 
         try {
-            msgs = msgReadWriteService.readMessages();
+            if (msgReadWriteService != null) {
+                msgs = msgReadWriteService.readMessages();
+            }
         } catch (Exception e) {
             reportError(e);
         }
index af502a2177d12c89101ca5b2363f90a9eeabe4da..873b53ff65aa23ececb17d733d64fb438f3f6098 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.controller.protocol_plugin.openflow.internal;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -44,6 +45,7 @@ import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.State;
 import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.discovery.IDiscoveryService;
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 
 /**
@@ -52,8 +54,8 @@ import org.opendaylight.controller.sal.utils.GlobalConstants;
  * container configurations.
  */
 public class TopologyServiceShim implements IDiscoveryService,
-               IContainerListener, CommandProvider, IRefreshInternalProvider,
-               IInventoryShimExternalListener {
+        IContainerListener, CommandProvider, IRefreshInternalProvider,
+        IInventoryShimExternalListener {
     protected static final Logger logger = LoggerFactory
             .getLogger(TopologyServiceShim.class);
     private ConcurrentMap<String, ITopologyServiceShimListener> topologyServiceShimListeners = new ConcurrentHashMap<String, ITopologyServiceShimListener>();
@@ -76,19 +78,31 @@ public class TopologyServiceShim implements IDiscoveryService,
 
     class NotifyEntry {
         String container;
-        Pair<Edge, Set<Property>> edgeProps;
-        UpdateType type;
+        List<TopoEdgeUpdate> teuList;
 
-        NotifyEntry(String container, Pair<Edge, Set<Property>> edgeProps,
-                UpdateType type) {
+        public NotifyEntry(String container, TopoEdgeUpdate teu) {
             this.container = container;
-            this.edgeProps = edgeProps;
-            this.type = type;
+            this.teuList = new ArrayList<TopoEdgeUpdate>();
+            if (teu != null) {
+                this.teuList.add(teu);
+            }
+        }
+
+        public NotifyEntry(String container, List<TopoEdgeUpdate> teuList) {
+            this.container = container;
+            this.teuList = new ArrayList<TopoEdgeUpdate>();
+            if (teuList != null) {
+                this.teuList.addAll(teuList);
+            }
         }
     }
 
     class TopologyNotify implements Runnable {
         private final BlockingQueue<NotifyEntry> notifyQ;
+        private NotifyEntry entry;
+        private Map<String, List<TopoEdgeUpdate>> teuMap = new HashMap<String, List<TopoEdgeUpdate>>();
+        private List<TopoEdgeUpdate> teuList;
+        private boolean notifyListeners;
 
         TopologyNotify(BlockingQueue<NotifyEntry> notifyQ) {
             this.notifyQ = notifyQ;
@@ -97,22 +111,37 @@ public class TopologyServiceShim implements IDiscoveryService,
         public void run() {
             while (true) {
                 try {
-                    NotifyEntry entry = notifyQ.take();
-
-                    ITopologyServiceShimListener topologServiceShimListener = topologyServiceShimListeners
-                            .get(entry.container);
-                    topologServiceShimListener.edgeUpdate(
-                            entry.edgeProps.getLeft(), entry.type,
-                            entry.edgeProps.getRight());
+                    teuMap.clear();
+                    notifyListeners = false;
+                    while (!notifyQ.isEmpty()) {
+                        entry = notifyQ.take();
+                        teuList = teuMap.get(entry.container);
+                        if (teuList == null) {
+                            teuList = new ArrayList<TopoEdgeUpdate>();
+                        }
+                        // group all the updates together
+                        teuList.addAll(entry.teuList);
+                        teuMap.put(entry.container, teuList);
+                        notifyListeners = true;
+                    }
+                    
+                    if (notifyListeners) {
+                        for (String container : teuMap.keySet()) {
+                            // notify the listener
+                            topologyServiceShimListeners.get(container)
+                                    .edgeUpdate(teuMap.get(container));
+                        }
+                    }
 
-                    entry = null;
+                    Thread.sleep(100);
                 } catch (InterruptedException e1) {
-                    logger.warn("TopologyNotify interrupted {}", e1.getMessage());
+                    logger.warn("TopologyNotify interrupted {}",
+                            e1.getMessage());
                     if (shuttingDown) {
                         return;
                     }
                 } catch (Exception e2) {
-                    logger.error("",e2);
+                    logger.error("", e2);
                 }
             }
         }
@@ -165,7 +194,7 @@ public class TopologyServiceShim implements IDiscoveryService,
                         return;
                     }
                 } catch (Exception e2) {
-                    logger.error("",e2);
+                    logger.error("", e2);
                 }
             }
         }
@@ -353,7 +382,8 @@ public class TopologyServiceShim implements IDiscoveryService,
                 && this.topologyServiceShimListeners.get(containerName).equals(
                         s)) {
             this.topologyServiceShimListeners.remove(containerName);
-            logger.trace("Removed topologyServiceShimListener for container: {}",
+            logger.trace(
+                    "Removed topologyServiceShimListener for container: {}",
                     containerName);
         }
     }
@@ -370,6 +400,7 @@ public class TopologyServiceShim implements IDiscoveryService,
 
     private void removeNodeConnector(String container,
             NodeConnector nodeConnector) {
+        List<TopoEdgeUpdate> teuList = new ArrayList<TopoEdgeUpdate>();
         Map<NodeConnector, Pair<Edge, Set<Property>>> edgePropsMap = edgeMap
                 .get(container);
         if (edgePropsMap == null) {
@@ -381,7 +412,8 @@ public class TopologyServiceShim implements IDiscoveryService,
         if (edgeProps == null) {
             return;
         }
-        notifyEdge(container, edgeProps.getLeft(), UpdateType.REMOVED, null);
+        teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), null,
+                UpdateType.REMOVED));
 
         // Remove edge in another direction
         edgeProps = edgePropsMap
@@ -389,52 +421,130 @@ public class TopologyServiceShim implements IDiscoveryService,
         if (edgeProps == null) {
             return;
         }
-        notifyEdge(container, edgeProps.getLeft(), UpdateType.REMOVED, null);
+        teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), null,
+                UpdateType.REMOVED));
+
+        // Update in one shot
+        notifyEdge(container, teuList);
     }
 
-    private void notifyEdge(String container, Edge edge, UpdateType type,
-            Set<Property> props) {
+    /**
+     * Update local cache and return true if it needs to notify upper layer
+     * Topology listeners.
+     * 
+     * @param container
+     *            The network container
+     * @param edge
+     *            The edge
+     * @param type
+     *            The update type
+     * @param props
+     *            The edge properties
+     * @return true if it needs to notify upper layer Topology listeners
+     */
+    private boolean updateLocalEdgeMap(String container, Edge edge,
+            UpdateType type, Set<Property> props) {
         ConcurrentMap<NodeConnector, Pair<Edge, Set<Property>>> edgePropsMap = edgeMap
                 .get(container);
         NodeConnector src = edge.getTailNodeConnector();
         Pair<Edge, Set<Property>> edgeProps = new ImmutablePair<Edge, Set<Property>>(
                 edge, props);
+        boolean rv = false;
 
         switch (type) {
         case ADDED:
         case CHANGED:
             if (edgePropsMap == null) {
                 edgePropsMap = new ConcurrentHashMap<NodeConnector, Pair<Edge, Set<Property>>>();
+                rv = true;
             } else {
                 if (edgePropsMap.containsKey(src)
                         && edgePropsMap.get(src).equals(edgeProps)) {
-                    // Entry already exists. Return here.
-                    return;
+                    // Entry already exists. No update.
+                    rv = false;
+                } else {
+                    rv = true;
                 }
             }
-            edgePropsMap.put(src, edgeProps);
-            edgeMap.put(container, edgePropsMap);
+            if (rv) {
+                edgePropsMap.put(src, edgeProps);
+                edgeMap.put(container, edgePropsMap);
+            }
             break;
         case REMOVED:
-            if (edgePropsMap != null) {
+            if ((edgePropsMap != null) && edgePropsMap.containsKey(src)) {
                 edgePropsMap.remove(src);
                 if (edgePropsMap.isEmpty()) {
                     edgeMap.remove(container);
                 } else {
                     edgeMap.put(container, edgePropsMap);
                 }
+                rv = true;
             }
             break;
         default:
-            logger.debug("notifyEdge: invalid {} for Edge {} in container {}",
-                    type, edge, container);
+            logger.debug(
+                    "notifyLocalEdgeMap: invalid {} for Edge {} in container {}",
+                    new Object[] { type.getName(), edge, container });
+        }
+
+        if (rv) {
+            logger.debug(
+                    "notifyLocalEdgeMap: {} for Edge {} in container {}",
+                    new Object[] { type.getName(), edge, container });
+        }
+        
+        return rv;
+    }
+
+    private void notifyEdge(String container, Edge edge, UpdateType type,
+            Set<Property> props) {
+        boolean notifyListeners;
+        
+        // Update local cache
+        notifyListeners = updateLocalEdgeMap(container, edge, type, props);
+
+        // Prepare to update TopologyService
+        if (notifyListeners) {
+            notifyQ.add(new NotifyEntry(container, new TopoEdgeUpdate(edge, props,
+                    type)));
+            logger.debug("notifyEdge: {} Edge {} in container {}", 
+                    new Object[] { type.getName(), edge, container });
+        }
+    }
+
+    private void notifyEdge(String container, List<TopoEdgeUpdate> etuList) {
+        if (etuList == null) {
             return;
         }
 
-        notifyQ.add(new NotifyEntry(container, edgeProps, type));
+        Edge edge;
+        UpdateType type;
+        List<TopoEdgeUpdate> etuNotifyList = new ArrayList<TopoEdgeUpdate>();
+        boolean notifyListeners = false, rv;
+
+        for (TopoEdgeUpdate etu : etuList) {
+            edge = etu.getEdge();
+            type = etu.getUpdateType();
+
+            // Update local cache
+            rv = updateLocalEdgeMap(container, edge, type, etu.getProperty());
+            if (rv) {
+                if (!notifyListeners) {
+                    notifyListeners = true;
+                }
+                etuNotifyList.add(etu);
+                logger.debug(
+                        "notifyEdge(TopoEdgeUpdate): {} Edge {} in container {}",
+                        new Object[] { type.getName(), edge, container });
+            }
+        }
 
-        logger.debug("notifyEdge: {} Edge {} in container {}",
-                type, edge, container);
+        // Prepare to update TopologyService
+        if (notifyListeners) {
+            notifyQ.add(new NotifyEntry(container, etuNotifyList));
+            logger.debug("notifyEdge(TopoEdgeUpdate): add notifyQ");
+        }
     }
 
     @Override
@@ -572,9 +682,12 @@ public class TopologyServiceShim implements IDiscoveryService,
             }
 
             long bw = 0;
-            for (Property prop : edgeProps.getRight()) {
-                if (prop.getName().equals(Bandwidth.BandwidthPropName)) {
-                    bw = ((Bandwidth) prop).getValue();
+            Set<Property> props = edgeProps.getRight();
+            if (props != null) {
+                for (Property prop : props) {
+                    if (prop.getName().equals(Bandwidth.BandwidthPropName)) {
+                        bw = ((Bandwidth) prop).getValue();
+                    }
                 }
             }
             count++;
@@ -638,14 +751,18 @@ public class TopologyServiceShim implements IDiscoveryService,
             return;
         }
         int i = 0;
+        List<TopoEdgeUpdate> teuList = new ArrayList<TopoEdgeUpdate>();
         for (Pair<Edge, Set<Property>> edgeProps : edgePropMap.values()) {
             if (edgeProps != null) {
                 i++;
+                teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), edgeProps
+                        .getRight(), UpdateType.ADDED));
                 logger.trace("Add edge {}", edgeProps.getLeft());
-                topologServiceShimListener.edgeUpdate(edgeProps.getLeft(),
-                        UpdateType.ADDED, edgeProps.getRight());
             }
         }
+        if (i > 0) {
+            topologServiceShimListener.edgeUpdate(teuList);
+        }
         logger.debug("Sent {} updates", i);
     }
 
@@ -663,7 +780,7 @@ public class TopologyServiceShim implements IDiscoveryService,
         if (conList != null) {
             containers.addAll(conList);
         }
-        
+
         switch (type) {
         case ADDED:
             break;
index c0b296345e261e18c6a0d0e3c58816183c734331..b23737c52037058d246d18bad2acd32caf52abc6 100644 (file)
@@ -10,9 +10,6 @@ package org.opendaylight.controller.protocol_plugin.openflow.internal;
 
 import java.util.Dictionary;
 import java.util.List;
-import java.util.Set;
-import java.util.ArrayList;
-
 import org.apache.felix.dm.Component;
 import org.opendaylight.controller.protocol_plugin.openflow.IRefreshInternalProvider;
 import org.opendaylight.controller.protocol_plugin.openflow.ITopologyServiceShimListener;
@@ -20,8 +17,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.opendaylight.controller.sal.core.Edge;
-import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.topology.IPluginInTopologyService;
 import org.opendaylight.controller.sal.topology.IPluginOutTopologyService;
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
@@ -130,11 +125,8 @@ public class TopologyServices implements ITopologyServiceShimListener,
     }
 
     @Override
-    public void edgeUpdate(Edge edge, UpdateType type, Set<Property> props) {
+    public void edgeUpdate(List<TopoEdgeUpdate> topoedgeupdateList) {
         if (this.salTopoService != null) {
-            List<TopoEdgeUpdate> topoedgeupdateList = new ArrayList<TopoEdgeUpdate>();
-            TopoEdgeUpdate teu = new TopoEdgeUpdate(edge, props, type);
-            topoedgeupdateList.add(teu);
             this.salTopoService.edgeUpdate(topoedgeupdateList);
         }
     }
index ad447b9584c79284bad5a03ad64ab07c8e7e91ce..cf93fb0a37fb1381716934da2220d6df7eba456c 100644 (file)
@@ -58,7 +58,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      *         Object
      */
     public Object[] getImplementations() {
-        Object[] res = { ReadService.class };
+        Object[] res = { ReadService.class, InventoryService.class };
         return res;
     }
 
@@ -86,6 +86,14 @@ public class Activator extends ComponentActivatorAbstractBase {
             props.put("protocolPluginType", Node.NodeIDType.OPENFLOW);
             c.setInterface(IPluginInReadService.class.getName(), props);
         }
-    }
 
+        if (imp.equals(InventoryService.class)) {
+            // export the service to be used by SAL
+            Dictionary<String, Object> props = new Hashtable<String, Object>();
+            // Set the protocolPluginType property which will be used
+            // by SAL
+            props.put("protocolPluginType", Node.NodeIDType.OPENFLOW);
+            c.setInterface(IPluginInInventoryService.class.getName(), props);
+        }
+    }
 }
diff --git a/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java b/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/InventoryService.java
new file mode 100644 (file)
index 0000000..54b4ea1
--- /dev/null
@@ -0,0 +1,141 @@
+package org.opendaylight.controller.protocol_plugins.stub.internal;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.opendaylight.controller.sal.core.Actions;
+import org.opendaylight.controller.sal.core.Bandwidth;
+import org.opendaylight.controller.sal.core.Buffers;
+import org.opendaylight.controller.sal.core.Capabilities;
+import org.opendaylight.controller.sal.core.Capabilities.CapabilitiesType;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.State;
+import org.opendaylight.controller.sal.core.Tables;
+import org.opendaylight.controller.sal.core.TimeStamp;
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+
+/**
+ * Stub Implementation for IPluginInReadService used by SAL
+ *
+ *
+ */
+public class InventoryService implements IPluginInInventoryService {
+    private static final Logger logger = LoggerFactory
+            .getLogger(InventoryService.class);
+
+    private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in global container only
+    private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in global container only
+
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init() {
+        nodeProps = new ConcurrentHashMap<Node, Map<String, Property>>();
+        nodeConnectorProps = new ConcurrentHashMap<NodeConnector, Map<String, Property>>();
+
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     *
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+    void stop() {
+    }
+
+    /**
+     * Retrieve nodes from openflow
+     */
+    @Override
+    public ConcurrentMap<Node, Map<String, Property>> getNodeProps() {
+
+        //  setup nodeProps
+        Map<String, Property> propMap = new HashMap<String, Property>();
+
+        Tables t = new Tables((byte)1);
+        propMap.put(Tables.TablesPropName, t);
+        Capabilities c = new Capabilities((int)3);
+        propMap.put(Capabilities.CapabilitiesPropName, c);
+        Actions a = new Actions((int)2);
+        propMap.put(Actions.ActionsPropName, a);
+        Buffers b = new Buffers((int)1);
+        propMap.put(Buffers.BuffersPropName, b);
+        Long connectedSinceTime = 100000L;
+        TimeStamp timeStamp = new TimeStamp(connectedSinceTime,
+                "connectedSince");
+        propMap.put(TimeStamp.TimeStampPropName, timeStamp);
+
+        // setup property map for all nodes
+        Node node;
+        node = NodeCreator.createOFNode(2L);
+        nodeProps.put(node, propMap);
+
+        return nodeProps;
+    }
+
+    /**
+     * Retrieve nodeConnectors from openflow
+     */
+    @Override
+    public ConcurrentMap<NodeConnector, Map<String, Property>> getNodeConnectorProps(
+            Boolean refresh) {
+
+        //  setup nodeConnectorProps
+        Map<String, Property> ncPropMap = new HashMap<String, Property>();
+        Capabilities cap = new Capabilities
+                (CapabilitiesType.FLOW_STATS_CAPABILITY.getValue());
+        ncPropMap.put(Capabilities.CapabilitiesPropName, cap);
+        Bandwidth bw = new Bandwidth (Bandwidth.BW1Gbps);
+        ncPropMap.put(Bandwidth.BandwidthPropName, bw);
+        State st = new State (State.EDGE_UP);
+        ncPropMap.put(State.StatePropName, st);
+
+        // setup property map for all node connectors
+        NodeConnector nc = NodeConnectorCreator.createOFNodeConnector
+                ((short)2, NodeCreator.createOFNode(3L));
+        nodeConnectorProps.put(nc, ncPropMap);
+
+        return nodeConnectorProps;
+    }
+
+
+}
index 311204b5456b9fca09568f06aabec88eb716c9ec..fdc2efa5c207baf25b7bfe8ca90ae24ce53768c7 100644 (file)
@@ -16,7 +16,7 @@
     <!-- Sonar properties using jacoco to retrieve integration test results -->
     <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
     <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
-    <sonar.jacoco.Reportpath>target/jacobo.exec</sonar.jacoco.Reportpath>
+    <sonar.jacoco.Reportpath>target/jacoco.exec</sonar.jacoco.Reportpath>
     <sonar.jacoco.itReportPath>target/jacoco-it.exec</sonar.jacoco.itReportPath>
     <sonar.language>java</sonar.language>
   </properties>
       <version>0.4.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/opendaylight/switchmanager/integrationtest/pom.xml b/opendaylight/switchmanager/integrationtest/pom.xml
new file mode 100644 (file)
index 0000000..bdf00f4
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>commons.opendaylight</artifactId>
+    <version>1.4.0-SNAPSHOT</version>
+    <relativePath>../../../opendaylight/commons/opendaylight</relativePath>
+  </parent>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>switchmanager.integrationtest</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>switchmanager</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+      <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>switchmanager.implementation</artifactId>
+         <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+     <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+     <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal.implementation</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager.implementation</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.stub</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>configuration</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>configuration.implementation</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>protocol_plugins.stub</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+  <properties>
+    <!-- Sonar jacoco plugin to get integration test coverage info -->
+    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+    <sonar.jacoco.reportPath>../implementation/target/jacoco.exec</sonar.jacoco.reportPath>
+    <sonar.jacoco.itReportPath>../implementaiton/target/jacoco-it.exec</sonar.jacoco.itReportPath>
+    <sonar.language>java</sonar.language>
+  </properties>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.jacoco</groupId>
+          <artifactId>jacoco-maven-plugin</artifactId>
+          <version>0.5.3.201107060350</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
+        <version>0.5.3.201107060350</version>
+        <configuration>
+          <destFile>../implementation/target/jacoco-it.exec</destFile>
+          <includes>org.opendaylight.controller.*</includes>
+        </configuration>
+        <executions>
+          <execution>
+            <id>pre-test</id>
+            <goals>
+              <goal>prepare-agent</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>post-test</id>
+            <configuration>
+              <skip>true</skip>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/opendaylight/switchmanager/integrationtest/src/test/java/org/opendaylight/controller/switchmanager/internal/SwitchmanagerIntegrationTest.java b/opendaylight/switchmanager/integrationtest/src/test/java/org/opendaylight/controller/switchmanager/internal/SwitchmanagerIntegrationTest.java
new file mode 100644 (file)
index 0000000..450a717
--- /dev/null
@@ -0,0 +1,230 @@
+
+/*
+ * Copyright (c) 2013 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.controller.switchmanager.internal;
+
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Bundle;
+import javax.inject.Inject;
+
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.After;
+import org.junit.runner.RunWith;
+import org.opendaylight.controller.sal.core.Actions;
+import org.opendaylight.controller.sal.core.Bandwidth;
+import org.opendaylight.controller.sal.core.Buffers;
+import org.opendaylight.controller.sal.core.Capabilities;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.State;
+import org.opendaylight.controller.sal.core.TimeStamp;
+import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.Capabilities.CapabilitiesType;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.opendaylight.controller.sal.utils.NodeCreator;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
+import org.opendaylight.controller.switchmanager.*;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
+
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.util.Filter;
+import org.osgi.framework.BundleContext;
+import static org.junit.Assert.*;
+import org.ops4j.pax.exam.junit.Configuration;
+import static org.ops4j.pax.exam.CoreOptions.*;
+
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.util.PathUtils;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+@RunWith(PaxExam.class)
+public class SwitchmanagerIntegrationTest {
+    private Logger log = LoggerFactory
+            .getLogger(SwitchmanagerIntegrationTest.class);
+    // get the OSGI bundle context
+    @Inject
+    private BundleContext bc;
+
+    private ISwitchManager switchManager = null;
+
+    // Configure the OSGi container
+    @Configuration
+    public Option[] config() {
+        return options(
+                systemProperty("logback.configurationFile").value(
+                        "file:" + PathUtils.getBaseDir()
+                                + "/src/test/resources/logback.xml"),
+                // To start OSGi console for inspection remotely
+                systemProperty("osgi.console").value("2401"),
+                // Set the systemPackages (used by clustering)
+                systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
+                // List framework bundles
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.console",
+                        "1.0.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.util",
+                        "1.0.400.v20120522-2049"),
+                mavenBundle("equinoxSDK381", "org.eclipse.osgi.services",
+                        "3.3.100.v20120522-1822"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds",
+                        "1.4.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command",
+                        "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime",
+                        "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell",
+                        "0.8.0.v201110170705"),
+                // List logger bundles
+                mavenBundle("org.slf4j", "slf4j-api", "1.7.2"),
+                mavenBundle("org.slf4j", "log4j-over-slf4j", "1.7.2"),
+                mavenBundle("ch.qos.logback", "logback-core", "1.0.9"),
+                mavenBundle("ch.qos.logback", "logback-classic", "1.0.9"),
+
+                mavenBundle("org.opendaylight.controller", "switchmanager",
+                        "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "switchmanager.implementation",
+                        "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "sal",
+                        "0.5.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "sal.implementation",
+                        "0.4.0-SNAPSHOT"),
+               mavenBundle("org.opendaylight.controller", "containermanager",
+                        "0.4.0-SNAPSHOT"),
+               mavenBundle("org.opendaylight.controller", "containermanager.implementation",
+                       "0.4.0-SNAPSHOT"),
+               mavenBundle("org.opendaylight.controller", "clustering.services",
+                       "0.4.0-SNAPSHOT"),
+               mavenBundle("org.opendaylight.controller", "clustering.stub",
+                       "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "configuration",
+                        "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "configuration.implementation", 
+                        "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller",
+                        "protocol_plugins.stub", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.jboss.spec.javax.transaction",
+                        "jboss-transaction-api_1.1_spec", "1.0.1.Final"),
+                mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
+                mavenBundle("org.apache.felix",
+                        "org.apache.felix.dependencymanager", "3.1.0"),
+                junitBundles());
+    }
+
+    private String stateToString(int state) {
+        switch (state) {
+        case Bundle.ACTIVE:
+            return "ACTIVE";
+        case Bundle.INSTALLED:
+            return "INSTALLED";
+        case Bundle.RESOLVED:
+            return "RESOLVED";
+        case Bundle.UNINSTALLED:
+            return "UNINSTALLED";
+        default:
+            return "Not CONVERTED";
+        }
+    }
+
+    @Before
+    public void areWeReady() {
+        assertNotNull(bc);
+        boolean debugit = false;
+        Bundle b[] = bc.getBundles();
+        for (int i = 0; i < b.length; i++) {
+            int state = b[i].getState();
+            if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
+                log.debug("Bundle:" + b[i].getSymbolicName() + " state:"
+                        + stateToString(state));
+                debugit = true;
+            }
+        }
+        if (debugit) {
+            log.debug("Do some debugging because some bundle is "
+                    + "unresolved");
+        }
+
+        // Assert if true, if false we are good to go!
+        assertFalse(debugit);
+
+         // Now lets create a hosttracker for testing purpose
+         ServiceReference s = bc
+             .getServiceReference(ISwitchManager.class.getName());
+         if (s != null) {
+                 this.switchManager = (ISwitchManager)bc.getService(s);
+         }
+
+         // If StatisticsManager is null, cannot run tests.
+         assertNotNull(this.switchManager);
+    }
+
+
+    @Test
+    public void testNodeProp() throws UnknownHostException {
+        assertNotNull(this.switchManager);
+
+        Node node = NodeCreator.createOFNode((long)2);
+        Map<String, Property> propMap = this.switchManager.getNodeProps(node);
+        Assert.assertFalse(propMap.isEmpty());
+
+        Assert.assertTrue(this.switchManager.getNodeProp
+                (node, Capabilities.CapabilitiesPropName)
+                .equals(new Capabilities((int)3)));
+        Assert.assertTrue(this.switchManager.getNodeProp
+                (node, Actions.ActionsPropName)
+                .equals(new Actions((int)2)));
+        Assert.assertTrue(this.switchManager.getNodeProp
+                (node, Buffers.BuffersPropName)
+                .equals(new Buffers((int)1)));
+        Assert.assertTrue(this.switchManager.getNodeProp
+                (node, TimeStamp.TimeStampPropName)
+                .equals(new TimeStamp(100000L, "connectedSince")));
+    }
+
+    @Test
+    public void testNodeConnectorProp() throws UnknownHostException {
+        assertNotNull(this.switchManager);
+
+        NodeConnector nc = NodeConnectorCreator.createOFNodeConnector
+                ((short)2, NodeCreator.createOFNode((long)3));
+        Map<String, Property> propMap = this.switchManager.getNodeConnectorProps(nc);
+        Assert.assertFalse(propMap.isEmpty());
+
+        Assert.assertTrue(this.switchManager.getNodeConnectorProp
+                (nc, Capabilities.CapabilitiesPropName)
+                .equals(new Capabilities
+                        (CapabilitiesType.FLOW_STATS_CAPABILITY.getValue())));
+        Assert.assertTrue(this.switchManager.getNodeConnectorProp
+                (nc, Bandwidth.BandwidthPropName)
+                .equals(new Bandwidth (Bandwidth.BW1Gbps)));
+        Assert.assertTrue(this.switchManager.getNodeConnectorProp
+                (nc, State.StatePropName)
+                .equals(new State (State.EDGE_UP)));
+    }
+}
index 4c31dee54225f0350bb3568ddea671ec787571fa..c7ba7aab1e4b258706c82055e99a81f4edf14aaa 100644 (file)
@@ -125,10 +125,13 @@ public class Devices implements IDaylightWeb {
                     String nodeConnectorName = (ncName != null) ? ncName.getValue()
                             : "";
                     nodeConnectorName += " ("+nodeConnector.getID()+")";
-                    if (portStatus.getValue() == Config.ADMIN_UP) {
-                        nodeConnectorName = "<span style='color:green;'>"+nodeConnectorName+"</span>";
-                    } else if (portStatus.getValue() == Config.ADMIN_DOWN) {
-                        nodeConnectorName = "<span style='color:red;'>"+nodeConnectorName+"</span>";
+                    
+                    if (portStatus != null) {
+                        if (portStatus.getValue() == Config.ADMIN_UP) {
+                            nodeConnectorName = "<span style='color:green;'>"+nodeConnectorName+"</span>";
+                        } else if (portStatus.getValue() == Config.ADMIN_DOWN) {
+                            nodeConnectorName = "<span style='color:red;'>"+nodeConnectorName+"</span>";
+                        }
                     }
                     
                     portList.put(Short.parseShort(nodeConnectorNumberToStr),
index 1ab8dff116aff1f176f168d66ae979de83e35dec..7c45bb8cee04433502b3ad5e3567f8d211c87428 100644 (file)
@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletRequest;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.controller.usermanager.internal.UserConfig;
 import org.springframework.stereotype.Controller;
@@ -94,6 +95,31 @@ public class DaylightWebAdmin {
 
         return userManager.removeLocalUser(userName).getDescription();
     }
+    
+    @RequestMapping(value = "/users/password/{username}", method = RequestMethod.POST)
+    @ResponseBody
+    public Status changePassword(@PathVariable("username") String username, HttpServletRequest request,
+            @RequestParam("currentPassword") String currentPassword, @RequestParam("newPassword") String newPassword) {
+        String user = request.getUserPrincipal().getName();
+        
+        IUserManager userManager = (IUserManager) ServiceHelper
+                .getGlobalInstance(IUserManager.class, this);
+        if (userManager == null) {
+            return new Status(StatusCode.GONE, "User Manager not found");
+        }
+        
+        if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
+            return new Status(StatusCode.FORBIDDEN, "Operation not permitted");
+        }
+        
+        if (newPassword.isEmpty()) {
+            return new Status(StatusCode.BADREQUEST, "Empty passwords not allowed");
+        }
+        
+        Status status = userManager.changeLocalUserPassword(user, currentPassword, newPassword);
+        
+        return status;
+    }
 
     /**
      * Is the operation permitted for the given level
index 629d5bbaacffcb42d510d1f8ca56614398d57a30..dda63be90e35f35f35e9d7a1944b6af1d1b71980 100644 (file)
@@ -124,13 +124,25 @@ one.main.admin = {
                 form : {
                     name : "one_main_admin_id_modal_add_form_name",
                     role : "one_main_admin_id_modal_add_form_role",
-                    password : "one_main_admin_id_modal_add_form_password"
+                    password : "one_main_admin_id_modal_add_form_password",
+                                       verify : "one_main_admin_id_modal_add_form_verify"
                 }
             },
             remove : {
                 user : "one_main_admin_id_modal_remove_user",
-                close : "one_main_admin_id_modal_remove_close"
-            }
+                close : "one_main_admin_id_modal_remove_close",
+                               password : 'one_main_admin_id_modal_remove_password'
+            },
+                       password : {
+                               modal : 'one_main_admin_id_modal_password_modal',
+                               submit : 'one_main_admin_id_modal_password_submit',
+                               cancel : 'one_main_admin_id_modal_password_cancel',
+                               form : {
+                                       old : 'one_main_admin_id_modal_password_form_old',
+                                       set : 'one_main_admin_id_modal_password_form_new',
+                                       verify : 'one_main_admin_id_modal_password_form_verify'
+                               }
+                       }
         },
         add : {
             user : "one_main_admin_id_add_user"
@@ -138,7 +150,8 @@ one.main.admin = {
     },
     address : {
         root : "/admin",
-        users : "/users"
+        users : "/users",
+               password : '/admin/users/password/'
     },
     modal : {
         initialize : function(callback) {
@@ -239,7 +252,7 @@ one.main.admin = {
     remove : {
         modal : {
             initialize : function(id) {
-                var h3 = "Remove User";
+                var h3 = "Edit User";
                 var footer = one.main.admin.remove.footer();
                 var $body = one.main.admin.remove.body();
                 var $modal = one.lib.modal.spawn(one.main.admin.id.modal.user,
@@ -278,6 +291,13 @@ one.main.admin = {
                                                     });
                                 });
 
+                               // change password binding
+                               $('#' + one.main.admin.id.modal.remove.password, $modal).click(function() {
+                                       one.main.admin.password.initialize(id, function() {
+                                               $modal.modal('hide');
+                                       });
+                               });
+
                 $modal.modal();
             },
             ajax : function(id, callback) {
@@ -297,6 +317,11 @@ one.main.admin = {
             var $removeButton = one.lib.dashlet.button.button(removeButton);
             footer.push($removeButton);
 
+                       var change = one.lib.dashlet.button.single('Change Password',
+                                       one.main.admin.id.modal.remove.password, 'btn-success', '');
+                       var $change = one.lib.dashlet.button.button(change);
+                       footer.push($change);
+
             var closeButton = one.lib.dashlet.button.single("Close",
                     one.main.admin.id.modal.remove.close, "", "");
             var $closeButton = one.lib.dashlet.button.button(closeButton);
@@ -306,7 +331,7 @@ one.main.admin = {
         },
         body : function() {
             var $p = $(document.createElement('p'));
-            $p.append("Remove user?");
+            $p.append('Select an action');
             return $p;
         },
     },
@@ -364,6 +389,13 @@ one.main.admin = {
                         '#' + one.main.admin.id.modal.add.form.role).find(
                         'option:selected').attr('value');
 
+                               // password check
+                               var verify = $('#'+one.main.admin.id.modal.add.form.verify).val();
+                               if (user.password != verify) {
+                                       alert('Passwords do not match');
+                                       return false;
+                               }
+
                 var resource = {};
                 resource['json'] = JSON.stringify(user);
                 resource['action'] = 'add'
@@ -391,6 +423,12 @@ one.main.admin = {
             $input.attr('id', one.main.admin.id.modal.add.form.password);
             $input.attr('type', 'password');
             $fieldset.append($label).append($input);
+                       // password verify
+                       var $label = one.lib.form.label('Verify Password');
+                       var $input = one.lib.form.input('Verify Password');
+                       $input.attr('id', one.main.admin.id.modal.add.form.verify);
+                       $input.attr('type', 'password');
+                       $fieldset.append($label).append($input);
             // roles
             var $label = one.lib.form.label('Roles');
             var options = {
@@ -418,7 +456,96 @@ one.main.admin = {
 
             return footer;
         }
-    }
+    },
+       password : {
+               initialize : function(id, successCallback) {
+                       var h3 = 'Change Password';
+                       var footer = one.main.admin.password.footer();
+                       var $body = one.main.admin.password.body(id);;
+                       var $modal = one.lib.modal.spawn(one.main.admin.id.modal.password.modal,
+                               h3, $body, footer);
+
+                       // cancel binding
+                       $('#'+one.main.admin.id.modal.password.cancel, $modal).click(function() {
+                               $modal.modal('hide');
+                       });
+
+                       // change password binding
+                       $('#'+one.main.admin.id.modal.password.submit, $modal).click(function() {
+                               one.main.admin.password.submit(id, $modal, function(result) {
+                                       if (result.code == 'SUCCESS') {
+                                               $modal.modal('hide');
+                                               successCallback();
+                                       } else {
+                                               alert(result.code+': '+result.description);
+                                       }
+                               });
+                       });
+
+                       $modal.modal();
+               },
+               submit : function(id, $modal, callback) {
+                       var resource = {};
+                       resource.newPassword = $('#'+one.main.admin.id.modal.password.form.set, $modal).val();
+
+                       // verify password
+                       var verify = $('#'+one.main.admin.id.modal.password.form.verify, $modal).val();
+                       if (verify != resource.newPassword) {
+                               alert('Passwords do not match');
+                               return false;
+                       }
+
+                       resource.currentPassword = $('#'+one.main.admin.id.modal.password.form.old, $modal).val();
+
+                       $.post(one.main.admin.address.password+id, resource, function(data) {
+                               callback(data);
+                       });
+               },
+               body : function(id) {
+                       var $form = $(document.createElement('form'));
+                       var $fieldset = $(document.createElement('fieldset'));
+                       // user
+                       var $label = one.lib.form.label('Username');
+                       var $input = one.lib.form.input('');
+                       $input.attr('disabled', 'disabled');
+                       $input.val(id);
+                       $fieldset.append($label)
+                               .append($input);
+                       // old password
+            var $label = one.lib.form.label('Old Password');
+            var $input = one.lib.form.input('Old Password');
+            $input.attr('id', one.main.admin.id.modal.password.form.old);
+            $input.attr('type', 'password');
+            $fieldset.append($label).append($input);
+                       // new password
+            var $label = one.lib.form.label('New Password');
+            var $input = one.lib.form.input('New Password');
+            $input.attr('id', one.main.admin.id.modal.password.form.set);
+            $input.attr('type', 'password');
+            $fieldset.append($label).append($input);
+                       // verify new password
+                       var $label = one.lib.form.label('Verify Password');
+                       var $input = one.lib.form.input('Verify Password');
+                       $input.attr('id', one.main.admin.id.modal.password.form.verify);
+                       $input.attr('type', 'password');
+                       $fieldset.append($label).append($input);
+                       // return
+                       $form.append($fieldset);
+                       return $form;
+               },
+               footer : function() {
+                       var footer = [];
+                       var submit = one.lib.dashlet.button.single('Submit',
+                               one.main.admin.id.modal.password.submit, 'btn-primary', '');
+                       var $submit = one.lib.dashlet.button.button(submit);
+                       footer.push($submit);
+                       var cancel = one.lib.dashlet.button.single('Cancel',
+                               one.main.admin.id.modal.password.cancel, '', '');
+                       var $cancel = one.lib.dashlet.button.button(cancel);
+                       footer.push($cancel);
+                       return footer;
+               }
+       }
 }
 
 one.main.dashlet = {
@@ -478,4 +605,4 @@ $.ajaxSetup({
 });
 
 /** MAIN PAGE LOAD */
-one.main.menu.load();
\ No newline at end of file
+one.main.menu.load();