<configuration>
<instructions>
<Import-Package>
+ org.opendaylight.controller.configuration,
org.opendaylight.controller.containermanager,
org.opendaylight.controller.sal.authorization,
org.opendaylight.controller.sal.utils,
</build>
<dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
+import org.opendaylight.controller.configuration.ConfigurationObject;
import org.opendaylight.controller.containermanager.IContainerAuthorization;
import org.opendaylight.controller.sal.authorization.AppRoleLevel;
import org.opendaylight.controller.sal.authorization.IResourceAuthorization;
*/
public abstract class Authorization<T> implements IResourceAuthorization {
private static final Logger logger = LoggerFactory.getLogger(Authorization.class);
- private static final String namesRegex = "^[a-zA-Z0-9]+[{\\.|\\_|\\-}[a-zA-Z0-9]]*$";
+ private static final String namesRegex = ConfigurationObject.getRegularExpression();
/*
* The configured resource groups
*/
--- /dev/null
+<?xml version="1.0"?>
+<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>config-subsystem</artifactId>
+ <version>0.2.4-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>config-module-archetype</artifactId>
+ <name>config-module-archetype</name>
+ <description>Archetype for new module managed by configuration subsystem</description>
+
+</project>
--- /dev/null
+<archetype>
+ <id>config-module-archetype</id>
+
+ <allowPartial>true</allowPartial>
+
+ <requiredProperties>
+ <requiredProperty key="module-name">
+ </requiredProperty>
+ <requiredProperty key="module-name-java-prefix">
+ </requiredProperty>
+ <requiredProperty key="module-implementation-name">
+ <defaultValue>impl</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="config-api-yang-revision">
+ <defaultValue>2013-04-05</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="config-api-version">
+ <defaultValue>0.2.4-SNAPSHOT</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="yang-maven-plugin-version">
+ <defaultValue>0.6.2-SNAPSHOT</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="revision">
+ <defaultValue>2014-01-31</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="service-java-class">
+ <defaultValue>java.lang.AutoCloseable</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="maven-bundle-plugin-version">
+ <defaultValue>2.4.0</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="yang-namespace-mapping-from">
+ <defaultValue>urn:opendaylight:params:xml:ns:yang:controller</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="yang-namespace-mapping-to">
+ <defaultValue>org.opendaylight.controller.config.yang</defaultValue>
+ </requiredProperty>
+
+ </requiredProperties>
+
+ <fileSets>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/yang</directory>
+ </fileSet>
+ </fileSets>
+</archetype>
--- /dev/null
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>${groupId}</groupId>
+ <artifactId>${artifactId}</artifactId>
+ <version>${version}</version>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
+ <config.version>${config-api-version}</config.version>
+ <maven.bundle.version>${maven-bundle-plugin-version}</maven.bundle.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>${yang-maven-plugin-version}</version>
+ <executions>
+ <execution>
+ <id>config</id>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ </codeGeneratorClass>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+ <additionalConfiguration>
+ <namespaceToPackage1>
+ ${yang-namespace-mapping-from}==${yang-namespace-mapping-to}
+ </namespaceToPackage1>
+ </additionalConfiguration>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-jmx-generator-plugin</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${jmxGeneratorPath}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${maven.bundle.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ <Export-Package>
+ ${yang-namespace-mapping-to}.${module-name},
+ </Export-Package>
+ <Import-Package>
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+
+ </plugins>
+ </build>
+</project>
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module ${module-name}-${module-implementation-name} {
+
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:${module-name}:${module-implementation-name}";
+ prefix "${module-name}-${module-implementation-name}";
+
+ import config { prefix config; revision-date ${config-api-yang-revision}; }
+ import ${module-name} { prefix ${module-name}; revision-date ${revision}; }
+
+ description
+ "This module contains the base YANG definitions for
+ ${module-name} ${module-implementation-name} implementation.";
+
+ revision "${revision}" {
+ description
+ "Initial revision.";
+ }
+
+ // This is the definition of a service implementation
+ identity ${module-name}-${module-implementation-name} {
+ base config:module-type;
+ config:provided-service ${module-name}:${module-name};
+ config:java-name-prefix ${module-name-java-prefix};
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case ${module-name}-${module-implementation-name} {
+ when "/config:modules/config:module/config:type = '${module-name}-${module-implementation-name}'";
+
+ leaf simple-attribute {
+ type uint32;
+ }
+
+ container dto-attribute {
+ leaf inner-attribute {
+ type string;
+ }
+ }
+
+ // Dependency attribute demonstration, the config:required-identity points to a service type
+ // In this case it is the same service type as this implementation provides: ${module-name}
+ container dependency-attribute {
+ uses config:service-ref {
+ refine type {
+ mandatory false;
+ config:required-identity ${module-name}:${module-name};
+ }
+ }
+ }
+
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module ${module-name} {
+
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:${module-name}";
+ prefix "${module-name}";
+
+ import config { prefix config; revision-date ${config-api-yang-revision}; }
+
+ description
+ "This module contains the base YANG definitions for
+ ${module-name} services.";
+
+ revision "${revision}" {
+ description
+ "Initial revision.";
+ }
+
+ // This is the definition of a service
+ identity ${module-name} {
+
+ base "config:service-type";
+
+ // TODO modify the java class
+ config:java-class " ${service-java-class}";
+ }
+}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<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">
+<!-- vi: set et smarttab sw=4 tabstop=4: --><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>
<module>yang-test-plugin</module>
<module>shutdown-api</module>
<module>shutdown-impl</module>
+ <module>config-module-archetype</module>
</modules>
<profiles>
</goals>
</pluginExecutionFilter>
<action>
- <ignore />
+ <ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</plugins>
</pluginManagement>
</build>
-</project>
+</project>
\ No newline at end of file
</dependency>
</dependencies>
+
+
<build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>
+ org.opendaylight.controller
+ </groupId>
+ <artifactId>
+ yang-test-plugin
+ </artifactId>
+ <versionRange>
+ [0.2.3,)
+ </versionRange>
+ <goals>
+ <goal>
+ delete-sources
+ </goal>
+ <goal>
+ process-sources
+ </goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore/>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
<plugins>
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
public abstract class ConfigurationObject implements Serializable {
private static final long serialVersionUID = 1L;
- private static final String DEFAULT_REGEX = "^[\\w-\\+\\*\\/\\.\\(\\)\\[\\]\\@]{1,256}$";
+ private static final String DEFAULT_REGEX = "^[\\w-=\\+\\*\\/\\.\\(\\)\\[\\]\\@\\|\\:]{1,256}$";
private static final String REGEX_PROP_NAME = "resourceNameRegularExpression";
private static String regex;
* resource name regular expression, false otherwise
*/
protected boolean isValidResourceName(String name) {
- return (name != null) ? name.matches(regex) : false;
+ return name != null && name.matches(regex);
}
/**
for (FlowEntryInstall installEntry : toInstallSafe) {
// Install and update database
- Status ret = addEntriesInternal(installEntry, async);
+ Status ret = addEntryInternal(installEntry, async);
if (ret.isSuccess()) {
oneSucceded = true;
}
// Install new entries
for (FlowEntryInstall newEntry : toInstallSafe) {
- succeeded = this.addEntriesInternal(newEntry, async);
+ succeeded = this.addEntryInternal(newEntry, async);
}
} else {
/*
/**
* This is the function that modifies the final container flows merged
* entries on the network node and update the database. It expects that all
- * the validity checks are passed
+ * the validity checks are passed.
+ * This function is supposed to be called only on the controller on which
+ * the IFRM call is executed.
*
* @param currentEntries
* @param newEntries
* contain the unique id assigned to this request
*/
private Status modifyEntryInternal(FlowEntryInstall currentEntries, FlowEntryInstall newEntries, boolean async) {
+ Status status = new Status(StatusCode.UNDEFINED);
FlowEntryDistributionOrderFutureTask futureStatus =
distributeWorkOrder(currentEntries, newEntries, UpdateType.CHANGED);
if (futureStatus != null) {
- Status retStatus = new Status(StatusCode.UNDEFINED);
try {
- retStatus = futureStatus.get();
- if (retStatus.getCode()
+ status = futureStatus.get();
+ if (status.getCode()
.equals(StatusCode.TIMEOUT)) {
// A timeout happened, lets cleanup the workMonitor
workMonitor.remove(futureStatus.getOrder());
} catch (ExecutionException e) {
log.error("", e);
}
- return retStatus;
} else {
// Modify the flow on the network node
- Status status = async ? programmer.modifyFlowAsync(currentEntries.getNode(), currentEntries.getInstall()
- .getFlow(), newEntries.getInstall()
- .getFlow()) : programmer.modifyFlow(currentEntries.getNode(), currentEntries.getInstall()
- .getFlow(), newEntries.getInstall()
- .getFlow());
+ status = modifyEntryInHw(currentEntries, newEntries, async);
+ }
- if (!status.isSuccess()) {
- log.trace("SDN Plugin failed to program the flow: {}. The failure is: {}", newEntries.getInstall(),
- status.getDescription());
- return status;
- }
+ if (!status.isSuccess()) {
+ log.trace("{} SDN Plugin failed to program the flow: {}. The failure is: {}",
+ (futureStatus != null) ? "Remote" : "Local", newEntries.getInstall(), status.getDescription());
+ return status;
+ }
- log.trace("Modified {} => {}", currentEntries.getInstall(), newEntries.getInstall());
+ log.trace("Modified {} => {}", currentEntries.getInstall(), newEntries.getInstall());
- // Update DB
- newEntries.setRequestId(status.getRequestId());
- updateSwViews(currentEntries, false);
- updateSwViews(newEntries, true);
+ // Update DB
+ newEntries.setRequestId(status.getRequestId());
+ updateSwViews(currentEntries, false);
+ updateSwViews(newEntries, true);
- return status;
- }
+ return status;
+ }
+
+ private Status modifyEntryInHw(FlowEntryInstall currentEntries, FlowEntryInstall newEntries, boolean async) {
+ return async ? programmer.modifyFlowAsync(currentEntries.getNode(), currentEntries.getInstall().getFlow(),
+ newEntries.getInstall().getFlow()) : programmer.modifyFlow(currentEntries.getNode(), currentEntries
+ .getInstall().getFlow(), newEntries.getInstall().getFlow());
}
/**
* This is the function that removes the final container flows merged entry
* from the network node and update the database. It expects that all the
* validity checks are passed
+ * This function is supposed to be called only on the controller on which
+ * the IFRM call is executed.
*
* @param entry
* the flow entry to remove
* contain the unique id assigned to this request
*/
private Status removeEntryInternal(FlowEntryInstall entry, boolean async) {
+ Status status = new Status(StatusCode.UNDEFINED);
FlowEntryDistributionOrderFutureTask futureStatus = distributeWorkOrder(entry, null, UpdateType.REMOVED);
if (futureStatus != null) {
- Status retStatus = new Status(StatusCode.UNDEFINED);
try {
- retStatus = futureStatus.get();
- if (retStatus.getCode()
- .equals(StatusCode.TIMEOUT)) {
+ status = futureStatus.get();
+ if (status.getCode().equals(StatusCode.TIMEOUT)) {
// A timeout happened, lets cleanup the workMonitor
workMonitor.remove(futureStatus.getOrder());
}
} catch (ExecutionException e) {
log.error("", e);
}
- return retStatus;
} else {
// Mark the entry to be deleted (for CC just in case we fail)
entry.toBeDeleted();
// Remove from node
- Status status = async ? programmer.removeFlowAsync(entry.getNode(), entry.getInstall()
- .getFlow()) : programmer.removeFlow(entry.getNode(), entry.getInstall()
- .getFlow());
-
- if (!status.isSuccess()) {
- log.trace("SDN Plugin failed to remove the flow: {}. The failure is: {}", entry.getInstall(),
- status.getDescription());
- return status;
- }
- log.trace("Removed {}", entry.getInstall());
-
- // Update DB
- updateSwViews(entry, false);
+ status = removeEntryInHw(entry, async);
+ }
+ if (!status.isSuccess()) {
+ log.trace("{} SDN Plugin failed to remove the flow: {}. The failure is: {}",
+ (futureStatus != null) ? "Remote" : "Local", entry.getInstall(), status.getDescription());
return status;
}
+
+ log.trace("Removed {}", entry.getInstall());
+
+ // Update DB
+ updateSwViews(entry, false);
+
+ return status;
+ }
+
+ private Status removeEntryInHw(FlowEntryInstall entry, boolean async) {
+ return async ? programmer.removeFlowAsync(entry.getNode(), entry.getInstall().getFlow()) : programmer
+ .removeFlow(entry.getNode(), entry.getInstall().getFlow());
}
/**
* on the network node and updates the database. It expects that all the
* validity and conflict checks are passed. That means it does not check
* whether this flow would conflict or overwrite an existing one.
+ * This function is supposed to be called only on the controller on which
+ * the IFRM call is executed.
*
* @param entry
* the flow entry to install
* @return the status of this request. In case of asynchronous call, it will
* contain the unique id assigned to this request
*/
- private Status addEntriesInternal(FlowEntryInstall entry, boolean async) {
+ private Status addEntryInternal(FlowEntryInstall entry, boolean async) {
+ Status status = new Status(StatusCode.UNDEFINED);
FlowEntryDistributionOrderFutureTask futureStatus = distributeWorkOrder(entry, null, UpdateType.ADDED);
if (futureStatus != null) {
- Status retStatus = new Status(StatusCode.UNDEFINED);
try {
- retStatus = futureStatus.get();
- if (retStatus.getCode()
- .equals(StatusCode.TIMEOUT)) {
+ status = futureStatus.get();
+ if (status.getCode().equals(StatusCode.TIMEOUT)) {
// A timeout happened, lets cleanup the workMonitor
workMonitor.remove(futureStatus.getOrder());
}
} catch (ExecutionException e) {
log.error("", e);
}
- return retStatus;
} else {
- // Install the flow on the network node
- Status status = async ? programmer.addFlowAsync(entry.getNode(), entry.getInstall()
- .getFlow()) : programmer.addFlow(entry.getNode(), entry.getInstall()
- .getFlow());
+ status = addEntryInHw(entry, async);
+ }
- if (!status.isSuccess()) {
- log.trace("SDN Plugin failed to program the flow: {}. The failure is: {}", entry.getInstall(),
- status.getDescription());
- return status;
- }
+ if (!status.isSuccess()) {
+ log.trace("{} SDN Plugin failed to program the flow: {}. The failure is: {}",
+ (futureStatus != null) ? "Remote" : "Local", entry.getInstall(), status.getDescription());
+ return status;
+ }
+
+ log.trace("Added {}", entry.getInstall());
- log.trace("Added {}", entry.getInstall());
+ // Update DB
+ entry.setRequestId(status.getRequestId());
+ updateSwViews(entry, true);
- // Update DB
- entry.setRequestId(status.getRequestId());
- updateSwViews(entry, true);
+ return status;
+ }
- return status;
- }
+ private Status addEntryInHw(FlowEntryInstall entry, boolean async) {
+ // Install the flow on the network node
+ return async ? programmer.addFlowAsync(entry.getNode(), entry.getInstall().getFlow()) : programmer.addFlow(
+ entry.getNode(), entry.getInstall().getFlow());
}
/**
FlowEntryInstall feiNew = workOrder.get(fe);
switch (fe.getUpType()) {
case ADDED:
- gotStatus = addEntriesInternal(feiCurrent, false);
+ gotStatus = addEntryInHw(feiCurrent, false);
break;
case CHANGED:
- gotStatus = modifyEntryInternal(feiCurrent, feiNew, false);
+ gotStatus = modifyEntryInHw(feiCurrent, feiNew, false);
break;
case REMOVED:
- gotStatus = removeEntryInternal(feiCurrent, false);
+ gotStatus = removeEntryInHw(feiCurrent, false);
break;
}
// Remove the Order
public static ListenerAdapter createListener(InstanceIdentifier path, String streamName) {
ListenerAdapter listener = new ListenerAdapter(path, streamName);
- lock.lock();
- listenersByInstanceIdentifier.put(path, listener);
- listenersByStreamName.put(streamName, listener);
- lock.unlock();
+ try {
+ lock.lock();
+ listenersByInstanceIdentifier.put(path, listener);
+ listenersByStreamName.put(streamName, listener);
+ } finally {
+ lock.unlock();
+ }
return listener;
}
} catch (Exception e) {
}
}
- lock.lock();
- listenersByStreamName = new ConcurrentHashMap<>();
- listenersByInstanceIdentifier = new ConcurrentHashMap<>();
- lock.unlock();
+ try {
+ lock.lock();
+ listenersByStreamName = new ConcurrentHashMap<>();
+ listenersByInstanceIdentifier = new ConcurrentHashMap<>();
+ } finally {
+ lock.unlock();
+ }
}
public static void removeListenerIfNoSubscriberExists(ListenerAdapter listener) {
listener.close();
} catch (Exception e) {
}
- lock.lock();
- listenersByInstanceIdentifier.remove(listener.getPath());
- listenersByStreamName.remove(listener).getStreamName();
- lock.unlock();
+ try {
+ lock.lock();
+ listenersByInstanceIdentifier.remove(listener.getPath());
+ listenersByStreamName.remove(listener.getStreamName());
+ } finally {
+ lock.unlock();
+ }
}
}
+++ /dev/null
-/*
- * Copyright (c) 2014 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.sal.restconf.iml.varioustests;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.w3c.dom.Document;
-
-
-public class VariousTest {
-
- @Ignore
- @Test
- public void test() {
- String[] split = "/something:dfsa/s:sda".split("/");
- System.out.println(split.length);
- for (String str : split) {
- System.out.println(">"+str+"<");
- }
-
- }
-
- @Test
- public void loadXml() {
- TestUtils.readInputToCnSn("/varioustest/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE);
-// TestUtils.normalizeCompositeNode(compositeNode, modules, schemaNodePath)
- }
-
- @Test
- public void buildXml() {
-// Document doc;
-// doc.createElementNS(namespaceURI, qualifiedName)
- }
-
-
-}
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
import java.net.URI;
import org.slf4j.Logger;
clientChannel.writeAndFlush(new PingWebSocketFrame(Unpooled.copiedBuffer(new byte[]{1, 2, 3, 4, 5, 6})));
}
- public void close() throws InterruptedException {
- clientChannel.writeAndFlush(new CloseWebSocketFrame());
+ public void close(String reasonText) throws InterruptedException {
+ CloseWebSocketFrame closeWebSocketFrame = new CloseWebSocketFrame(1000,reasonText);
+ clientChannel.writeAndFlush(closeWebSocketFrame);
// WebSocketClientHandler will close the connection when the server
// responds to the CloseWebSocketFrame.
if (args.length > 0) {
uri = new URI(args[0]);
} else {
- uri = new URI("http://192.168.11.1:8181/opendaylight-inventory:nodes");
+ uri = new URI("http://192.168.1.101:8181/opendaylight-inventory:nodes");
}
IClientMessageCallback messageCallback = new ClientMessageCallback();
WebSocketClient webSocketClient = new WebSocketClient(uri, messageCallback);
webSocketClient.connect();
+
+ while (true) {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ String input = br.readLine();
+ if (input.equals("q")) {
+ System.out.print("Would you like to close stream? (Y = yes, empty = yes)\n");
+ input = br.readLine();
+ if (input.equals("yes") || input.isEmpty()) {
+ webSocketClient.close("opendaylight-inventory:nodes");
+ break;
+ }
+ }
+ }
}
private static class ClientMessageCallback implements IClientMessageCallback {
@Override
public void onMessageReceived(Object message) {
- logger.info("received message {}", ((TextWebSocketFrame)message).text());
+ if (message instanceof TextWebSocketFrame) {
+ logger.info("received message {}"+ ((TextWebSocketFrame)message).text());
+ }
}
}
}
gatewayIPAssigned = false;
dnsNameservers = new ArrayList<String>();
- allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();
- hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();
- try {
- SubnetUtils util = new SubnetUtils(cidr);
- SubnetInfo info = util.getInfo();
- if (gatewayIP == null) {
- gatewayIP = info.getLowAddress();
- }
- if (allocationPools.size() < 1) {
- NeutronSubnet_IPAllocationPool source =
- new NeutronSubnet_IPAllocationPool(info.getLowAddress(),
- info.getHighAddress());
- allocationPools = source.splitPool(gatewayIP);
+ if (hostRoutes == null) {
+ hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();
+ }
+ if (allocationPools == null) {
+ allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();
+ try {
+ SubnetUtils util = new SubnetUtils(cidr);
+ SubnetInfo info = util.getInfo();
+ if (gatewayIP == null) {
+ gatewayIP = info.getLowAddress();
+ }
+ if (allocationPools.size() < 1) {
+ NeutronSubnet_IPAllocationPool source =
+ new NeutronSubnet_IPAllocationPool(info.getLowAddress(),
+ info.getHighAddress());
+ allocationPools = source.splitPool(gatewayIP);
+ }
+ } catch (Exception e) {
+ return false;
}
- } catch (Exception e) {
- return false;
}
return true;
}
.getLogger(Controller.class);
private ControllerIO controllerIO;
private Thread switchEventThread;
+ private volatile boolean shutdownSwitchEventThread;// default to false
private ConcurrentHashMap<Long, ISwitch> switches;
private PriorityBlockingQueue<SwitchEvent> switchEvents;
// only 1 message listener per OFType
while (true) {
try {
+ if(shutdownSwitchEventThread) {
+ // break out of the infinite loop
+ // if you are shutting down
+ logger.info("Switch Event Thread is shutting down");
+ break;
+ }
SwitchEvent ev = switchEvents.take();
SwitchEvent.SwitchEventType eType = ev.getEventType();
ISwitch sw = ev.getSwitch();
logger.error("Unknown switch event {}", eType.ordinal());
}
} catch (InterruptedException e) {
- switchEvents.clear();
- return;
+ // nothing to do except retry
+ } catch (Exception e) {
+ // log the exception and retry
+ logger.warn("Exception in Switch Event Thread is {}" ,e);
}
}
+ switchEvents.clear();
}
-
}
/**
((SwitchHandler) entry.getValue()).stop();
it.remove();
}
+ shutdownSwitchEventThread = true;
switchEventThread.interrupt();
try {
controllerIO.shutDown();
@Override
public void nodeFlowStatisticsUpdated(Node node, List<FlowOnNode> flowStatsList) {
- List<FlowOnNode> currentStat = this.flowStatistics.get(node);
- // Update cache only if changed to avoid unnecessary cache sync operations
- if (! flowStatsList.equals(currentStat)){
- this.flowStatistics.put(node, flowStatsList);
- }
+ // No equality check because duration fields change constantly
+ this.flowStatistics.put(node, flowStatsList);
}
@Override
}
private Status validateNodeId() {
- if (nodeId == null || nodeId.isEmpty()) {
- return new Status(StatusCode.BADREQUEST, "NodeId cannot be empty");
+ if (!isValidResourceName(nodeId)) {
+ return new Status(StatusCode.BADREQUEST, "Invalid NodeId");
}
return new Status(StatusCode.SUCCESS);
}