--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.opendaylight</artifactId>
+ <version>1.4.2-SNAPSHOT</version>
+ <relativePath>../../opendaylight/commons/opendaylight</relativePath>
+ </parent>
+ <artifactId>extras-features</artifactId>
+ <packaging>kar</packaging>
+ <name>${project.artifactId}</name>
+ <description>Base Features POM</description>
+ <properties>
+ <features.file>features.xml</features.file>
+ <netty3.version>3.9.2.Final</netty3.version>
+ </properties>
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.karaf.tooling</groupId>
+ <artifactId>karaf-maven-plugin</artifactId>
+ <version>${karaf.version}</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>features-create-kar</id>
+ <goals>
+ <goal>features-create-kar</goal>
+ </goals>
+ <configuration>
+ <featuresFile>${project.build.directory}/classes/${features.file}</featuresFile>
+ </configuration>
+ </execution>
+ </executions>
+ <!-- There is no useful configuration for the kar mojo. The features-generate-descriptor mojo configuration may be useful -->
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<features name="extras-features-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
+
+ <feature name="osgi-compendium" description="OSGi compendium feature" version="${osgi.version}" resolver="(obr)">
+ <bundle start-level="10">mvn:org.osgi/org.osgi.compendium/${osgi.compendium.version}</bundle>
+ </feature>
+
+ <feature name="odl-extras-scala" description="Scala Runtime for OpenDaylight" version="${scala.version}" resolver="(obr)" start-level="10">
+ <bundle>mvn:org.scala-lang/scala-library/${scala.version}.${scala.micro.version}</bundle>
+ <bundle>mvn:org.scala-lang/scala-reflect/${scala.version}.${scala.micro.version}</bundle>
+ </feature>
+
+ <feature name="odl-extras-akka-system" description="Akka Actor Framework System Bundles" version="${akka.version}" resolver="(obr)" start-level="15">
+ <feature version="${scala.version}">odl-extras-scala</feature>
+ <bundle dependency="true">mvn:com.typesafe/config/${typesafe.config.version}</bundle>
+ <bundle dependency="true">mvn:com.typesafe.akka/akka-actor_${scala.version}/${akka.version}</bundle>
+ <bundle dependency="true">mvn:com.typesafe.akka/akka-slf4j_${scala.version}/${akka.version}</bundle>
+ <bundle>mvn:com.typesafe.akka/akka-osgi_${scala.version}/${akka.version}</bundle>
+ </feature>
+
+ <feature name="odl-extras-akka-clustering" description="Akka Clustering Support" version="${akka.version}" resolver="(obr)" start-level="20">
+ <feature version="${akka.version}">odl-extras-akka-system</feature>
+ <bundle dependency="true">wrap:mvn:org.uncommons.maths/uncommons-maths/${uncommons.maths.version}</bundle>
+ <bundle dependency="true">mvn:com.google.protobuf/protobuf-java/${protobuf.version}</bundle>
+ <bundle dependency="true">wrap:mvn:io.netty/netty/${netty3.version}</bundle>
+ <bundle>mvn:com.typesafe.akka/akka-remote_${scala.version}/${akka.version}</bundle>
+ <bundle>mvn:com.typesafe.akka/akka-cluster_${scala.version}/${akka.version}</bundle>
+ </feature>
+
+ <feature name='odl-extras-leveldb' description='LevelDB feature' version='0.7' resolver='(obr)'>
+ <bundle start-level="20">wrap:mvn:org.iq80.leveldb/leveldb/${leveldb.version}</bundle>
+ <bundle start-level="20">wrap:mvn:org.fusesource.leveldbjni/leveldbjni-all/${leveldbjni.version}</bundle>
+ </feature>
+</features>
<properties>
- <akka.version>2.3.2</akka.version>
+ <akka.version>2.3.4</akka.version>
<aopalliance.version>1.0.0</aopalliance.version>
<appauth.version>0.4.2-SNAPSHOT</appauth.version>
<archetype-app-northbound>0.0.1-SNAPSHOT</archetype-app-northbound>
<compiler.version>2.3.2</compiler.version>
<commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
<concepts.version>0.5.2-SNAPSHOT</concepts.version>
+ <concurrentlinkedhashmap.version>1.4</concurrentlinkedhashmap.version>
<config.version>0.2.5-SNAPSHOT</config.version>
<configuration.implementation.version>0.4.3-SNAPSHOT</configuration.implementation.version>
<configuration.version>0.4.3-SNAPSHOT</configuration.version>
<karaf.branding.version>1.0.0-SNAPSHOT</karaf.branding.version>
<karaf.shell.version>3.0.0</karaf.shell.version>
<karaf.version>3.0.1</karaf.version>
+ <leveldb.version>0.7</leveldb.version>
+ <leveldbjni.version>1.8</leveldbjni.version>
<lifecycle.mapping.version>1.0.0</lifecycle.mapping.version>
<logback.version>1.0.9</logback.version>
<logging.bridge.version>0.4.2-SNAPSHOT</logging.bridge.version>
<maven.plugin.api.version>3.0.5</maven.plugin.api.version>
+ <mimepull.version>1.9.4</mimepull.version>
<mdsal.version>1.1-SNAPSHOT</mdsal.version>
<netconf.version>0.2.5-SNAPSHOT</netconf.version>
<networkconfig.bridgedomain.northbound.version>0.0.3-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
<northbound.jolokia.version>1.4.2-SNAPSHOT</northbound.jolokia.version>
<opendaylight-l2-types.version>2013.08.27.4-SNAPSHOT</opendaylight-l2-types.version>
<osgi-brandfragment.web.version>0.0.2-SNAPSHOT</osgi-brandfragment.web.version>
+ <parboiled.version>1.1.6</parboiled.version>
+ <parboiled.scala.version>1.1.6</parboiled.scala.version>
<propertymavenplugin.version>1.0-alpha-2</propertymavenplugin.version>
+ <protobuf.version>2.5.0</protobuf.version>
<protocol-framework.version>0.5.0-SNAPSHOT</protocol-framework.version>
<protocol_plugins.openflow.version>0.4.2-SNAPSHOT</protocol_plugins.openflow.version>
<protocol_plugins.stub.version>0.4.2-SNAPSHOT</protocol_plugins.stub.version>
<samples.loadbalancer.northbound.version>0.4.2-SNAPSHOT</samples.loadbalancer.northbound.version>
<samples.simpleforwarding.version>0.4.2-SNAPSHOT</samples.simpleforwarding.version>
<sanitytest.version>0.4.2-SNAPSHOT</sanitytest.version>
- <scala.version>2.11</scala.version>
+ <scala.version>2.10</scala.version>
+ <scala.micro.version>4</scala.micro.version>
<security.version>0.4.2-SNAPSHOT</security.version>
+ <shapeless.version>1.2.4</shapeless.version>
<sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
<sonar.branch>${user.name}-private-view</sonar.branch>
<sonar.host.url>https://sonar.opendaylight.org/</sonar.host.url>
<spring-security-karaf.version>3.1.4.RELEASE</spring-security-karaf.version>
<spring-security.version>3.1.3.RELEASE</spring-security.version>
<spring.version>3.1.3.RELEASE</spring.version>
+ <sonar.skippedModules>org.openflow.openflowj,net.sf.jung2</sonar.skippedModules>
<statistics.northbound.version>0.4.2-SNAPSHOT</statistics.northbound.version>
<statisticsmanager.implementation.version>0.4.2-SNAPSHOT</statisticsmanager.implementation.version>
<statisticsmanager.version>0.5.1-SNAPSHOT</statisticsmanager.version>
<topology.web.version>0.4.2-SNAPSHOT</topology.web.version>
<topologymanager.version>0.4.2-SNAPSHOT</topologymanager.version>
<troubleshoot.web.version>0.4.2-SNAPSHOT</troubleshoot.web.version>
+ <typesafe.config.version>1.2.0</typesafe.config.version>
+ <uncommons.maths.version>1.2.2</uncommons.maths.version>
<usermanager.implementation.version>0.4.2-SNAPSHOT</usermanager.implementation.version>
<usermanager.northbound.version>0.0.2-SNAPSHOT</usermanager.northbound.version>
<usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
</dependency>
<!-- scope is compile so all features (there is only one) are installed
into startup.properties and the feature repo itself is not installed -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>extras-features</artifactId>
+ <version>${project.version}</version>
+ <type>kar</type>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-features</artifactId>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-base</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-management</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-service</artifactId>
lisp.mappingOverwrite = true
# Enable the Solicit-Map-Request (SMR) mechanism
lisp.smr = false
+
+#RESTConf websocket listen port (default is 8181)
+restconf.websocket.port=8181
<appender-ref ref="opendaylight.log"/>
</logger>
+ <!-- BGPCEP plugin -->
+ <logger name="org.opendaylight.protocol" level="INFO"/>
+ <logger name="org.opendaylight.bgpcep" level="INFO"/>
+
<!-- To debug MD-SAL schema loading issues, uncomment this -->
<!--logger name="org.opendaylight.yangtools.yang.parser.impl.util.URLSchemaContextResolver" level="DEBUG"/>
<logger name="org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl" level="TRACE"/-->
+++ /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.model</groupId>
- <artifactId>model-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
- </parent>
- <artifactId>model-flow-management</artifactId>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>model-flow-base</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>model-inventory</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>opendaylight-l2-types</artifactId>
- </dependency>
- </dependencies>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-</project>
+++ /dev/null
-module flow-management {
- namespace "urn:opendaylight:flow:config";
- prefix flow-cfg;
-
- import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
- import opendaylight-flow-types {prefix flow;}
-
- revision "2013-08-19" {
- description "Initial revision of flow service";
- }
-
-
- grouping flow-entry {
- leaf node {
- type inv:node-ref;
- }
- uses flow:flow;
- }
-
- container flows {
- list flow {
- key "node id";
-
- leaf id {
- type uint32;
- }
- uses flow-entry;
- }
- }
-}
+++ /dev/null
-module group-management {
- namespace "urn:opendaylight:group:config";
- prefix group-cfg;
-
- import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
- import opendaylight-group-types {prefix group;}
-
- revision "2013-10-24" {
- description "Initial revision of group service";
- }
-
- grouping group-entry {
- leaf node {
- type inv:node-ref;
- }
- uses group:group;
- }
-
- container groups {
- list group {
- key "id node";
-
- leaf id {
- type uint32;
- }
-
- uses group-entry;
- }
- }
-}
+++ /dev/null
-module meter-management {
- namespace "urn:opendaylight:meter:config";
- prefix meter-cfg;
-
- import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
- import opendaylight-meter-types {prefix meter;}
-
- revision "2013-10-24" {
- description "Initial revision of meter service";
- }
-
- grouping meter-entry {
- leaf node {
- type inv:node-ref;
- }
- uses meter:meter;
- }
-
- container meters {
- list meter {
- key "id node";
-
- leaf id {
- type uint32;
- }
-
- uses meter-entry;
- }
- }
-}
+++ /dev/null
-module port-management {
- namespace "urn:opendaylight:port:config";
- prefix port-cfg;
-
- import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
- import opendaylight-port-types {prefix port;}
-
- revision "2013-10-24" {
- description "Initial revision of port service";
- }
-
- grouping port-entry {
- leaf node {
- type inv:node-ref;
- }
- uses port:port-mod;
- }
-
- container ports {
- list port {
- key "id node";
-
- leaf id {
- type uint32;
- }
-
- uses port-entry;
- }
- }
-}
+++ /dev/null
-module queue-management {
- namespace "urn:opendaylight:queue:config";
- prefix queue-cfg;
-
- import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
-
- import opendaylight-queue-types {prefix queue; revision-date "2013-09-25";}
-
-
- revision "2013-10-24" {
- description "Initial revision of queue service";
- }
-
- grouping queue-entry {
- leaf node {
- type inv:node-connector-ref;
-
- }
- uses queue:queue-config-request;
- }
-
- container queues {
- list queue {
- key "id node";
-
- leaf id {
- type uint32;
- }
-
- uses queue-entry;
- }
- }
-}
+++ /dev/null
-module table-management {
- namespace "urn:opendaylight:table:config";
- prefix table-cfg;
-
- import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
- import opendaylight-table-types {prefix table;}
-
- revision "2013-10-24" {
- description "Initial revision of table service";
- }
-
- grouping table-entry {
-
- leaf node {
- type inv:node-ref;
- }
-
- uses table:table-features;
- }
-
- container tables {
- list table {
- key "id node";
-
- leaf id {
- type uint32;
- }
-
- uses table-entry;
- }
- }
-}
<module>model-flow-base</module>
<module>model-flow-service</module>
<module>model-flow-statistics</module>
- <module>model-flow-management</module>
<module>model-topology</module>
</modules>
@Override
public void start(BundleContext context) throws Exception {
+ String websocketPortStr = context.getProperty(WebSocketServer.WEBSOCKET_SERVER_CONFIG_PROPERTY);
+ int websocketPort = (websocketPortStr != null && !"".equals(websocketPortStr))
+ ? Integer.parseInt(websocketPortStr) : WebSocketServer.DEFAULT_PORT;
bundleContext = context;
- brokerServiceTrancker = new ServiceTracker<>(context, Broker.class, this);
- brokerServiceTrancker.open();
- webSocketServerThread = new Thread(new WebSocketServer());
+ webSocketServerThread = new Thread(WebSocketServer.createInstance(websocketPort));
webSocketServerThread.setName("Web socket server");
webSocketServerThread.start();
+ brokerServiceTrancker = new ServiceTracker<>(context, Broker.class, this);
+ brokerServiceTrancker.open();
}
@Override
broker.registerToListenDataChanges(listener);
final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
- UriBuilder port = uriBuilder.port(WebSocketServer.PORT);
+ UriBuilder port = uriBuilder.port(WebSocketServer.getInstance().getPort());
final URI uriToWebsocketServer = port.replacePath(streamName).build();
return Response.status(Status.OK).location(uriToWebsocketServer).build();
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+
/**
- * {@link WebSocketServer} is responsible to start and stop web socket server at
- * {@link #PORT}.
+ * {@link WebSocketServer} is responsible to start and stop web socket server
*/
public class WebSocketServer implements Runnable {
private static final Logger logger = LoggerFactory
.getLogger(WebSocketServer.class);
-
- public static final int PORT = 8181;
+ public static final String WEBSOCKET_SERVER_CONFIG_PROPERTY = "restconf.websocket.port";
+ public static final int DEFAULT_PORT = 8181;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
+ private static WebSocketServer singleton = null;
+ private int port = DEFAULT_PORT;
+
+ private WebSocketServer(int port) {
+ this.port = port;
+ }
+
+ /**
+ * Create instance of {@link WebSocketServer}
+ * @param port TCP port used for this server
+ * @return instance of {@link WebSocketServer}
+ */
+ public static WebSocketServer createInstance(int port) {
+ if(singleton != null) {
+ throw new IllegalStateException("createInstance() has already been called");
+ }
+ if(port < 1024) {
+ throw new IllegalArgumentException("Privileged port (below 1024) is not allowed");
+ }
+ singleton = new WebSocketServer(port);
+ return singleton;
+ }
+
+ /**
+ * Return websocket TCP port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Get instance of {@link WebSocketServer} created by {@link #createInstance(int)}
+ * @return instance of {@link WebSocketServer}
+ */
+ public static WebSocketServer getInstance() {
+ Preconditions.checkNotNull(singleton,
+ "createInstance() must be called prior to getInstance()");
+ return singleton;
+ }
+
+ /**
+ * Destroy this already created instance
+ */
+ public static void destroyInstance() {
+ if(singleton == null) {
+ throw new IllegalStateException(
+ "createInstance() must be called prior to destroyInstance()");
+ }
+ getInstance().stop();
+ }
@Override
public void run() {
.channel(NioServerSocketChannel.class)
.childHandler(new WebSocketServerInitializer());
- Channel ch = b.bind(PORT).sync().channel();
- logger.info("Web socket server started at port {}.", PORT);
+ Channel ch = b.bind(port).sync().channel();
+ logger.info("Web socket server started at port {}.", port);
ch.closeFuture().sync();
} catch (InterruptedException e) {
<module>features/base</module>
<module>features/controller</module>
<module>features/adsal</module>
+ <module>features/extras</module>
<module>opendaylight/dummy-console</module>
<module>opendaylight/karaf-branding</module>
<module>opendaylight/distribution/opendaylight-karaf</module>