--- /dev/null
+<?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>
--- /dev/null
+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;
+ }
+ }
+}
--- /dev/null
+<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>
<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>
<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>
<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>
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());
<!-- 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>
\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
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
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
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
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);
/**
* 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);
}
executor.shutdown();
- selector = null;
msgReadWriteService = null;
if (switchHandlerThread != null) {
List<OFMessage> msgs = null;
try {
- msgs = msgReadWriteService.readMessages();
+ if (msgReadWriteService != null) {
+ msgs = msgReadWriteService.readMessages();
+ }
} catch (Exception e) {
reportError(e);
}
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;
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;
/**
* 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>();
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;
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);
}
}
}
return;
}
} catch (Exception e2) {
- logger.error("",e2);
+ logger.error("", e2);
}
}
}
&& this.topologyServiceShimListeners.get(containerName).equals(
s)) {
this.topologyServiceShimListeners.remove(containerName);
- logger.trace("Removed topologyServiceShimListener for container: {}",
+ logger.trace(
+ "Removed topologyServiceShimListener for container: {}",
containerName);
}
}
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) {
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
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
}
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++;
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);
}
if (conList != null) {
containers.addAll(conList);
}
-
+
switch (type) {
case ADDED:
break;
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;
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;
}
@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);
}
}
* Object
*/
public Object[] getImplementations() {
- Object[] res = { ReadService.class };
+ Object[] res = { ReadService.class, InventoryService.class };
return res;
}
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);
+ }
+ }
}
--- /dev/null
+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;
+ }
+
+
+}
<!-- 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>
--- /dev/null
+<?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>
--- /dev/null
+
+/*
+ * 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)));
+ }
+}
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),
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;
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
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"
},
address : {
root : "/admin",
- users : "/users"
+ users : "/users",
+ password : '/admin/users/password/'
},
modal : {
initialize : function(callback) {
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,
});
});
+ // 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) {
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);
},
body : function() {
var $p = $(document.createElement('p'));
- $p.append("Remove user?");
+ $p.append('Select an action');
return $p;
},
},
'#' + 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'
$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 = {
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 = {
});
/** MAIN PAGE LOAD */
-one.main.menu.load();
\ No newline at end of file
+one.main.menu.load();