diff options
Diffstat (limited to 'sdnr')
20 files changed, 1584 insertions, 0 deletions
diff --git a/sdnr/wt/pom.xml b/sdnr/wt/pom.xml index 9ec1ea449..59e23b3ae 100644 --- a/sdnr/wt/pom.xml +++ b/sdnr/wt/pom.xml @@ -38,6 +38,7 @@ <modules> <module>apigateway</module> <module>devicemodel</module> + <module>websocketmanager2</module> </modules> </project> diff --git a/sdnr/wt/websocketmanager2/feature/pom.xml b/sdnr/wt/websocketmanager2/feature/pom.xml new file mode 100644 index 000000000..cb0d617ca --- /dev/null +++ b/sdnr/wt/websocketmanager2/feature/pom.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + * ============LICENSE_START======================================================= + * ONAP : CCSDK.sdnr.wt.websocketmanager.feature + * ================================================================================ + * Copyright (C) 2018 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + +--> +<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> + + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>sdnr-wt-websocketmanager2-feature</artifactId> + <version>0.4.1-SNAPSHOT</version> + <packaging>feature</packaging> + <name>ccsdk-features-sdnr-wt :: ${project.artifactId} :: feature</name> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>1.2.1-SNAPSHOT</version> + <relativePath /> + </parent> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>mdsal-model-artifacts</artifactId> + <version>${odl.mdsal.model.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>mdsal-artifacts</artifactId> + <version>${odl.controller.mdsal.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-websocketmanager2-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-websocketmanager2-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/sdnr/wt/websocketmanager2/installer/pom.xml b/sdnr/wt/websocketmanager2/installer/pom.xml new file mode 100755 index 000000000..14c4022b8 --- /dev/null +++ b/sdnr/wt/websocketmanager2/installer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + * ============LICENSE_START======================================================= + * ONAP : CCSDK.sdnr.wt.websocketmanager.installer + * ================================================================================ + * Copyright (C) 2018 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + +--> +<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> + + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>sdnr-wt-websocketmanager2-installer</artifactId> + <version>0.4.1-SNAPSHOT</version> + <packaging>pom</packaging> + <name>ccsdk-features-sdnr-wt :: ${project.artifactId}</name> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>1.2.1-SNAPSHOT</version> + <relativePath /> + </parent> + + <properties> + <application.name>sdnr-wt-websocketmanager2</application.name> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>${application.name}-feature</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>${application.name}-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> +<!-- <execution> --> +<!-- <id>copy-dependencies</id> --> +<!-- <goals> --> +<!-- <goal>copy-dependencies</goal> --> +<!-- </goals> --> +<!-- <phase>prepare-package</phase> --> +<!-- <configuration> --> +<!-- <transitive>false</transitive> --> +<!-- <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> --> +<!-- <overWriteReleases>false</overWriteReleases> --> +<!-- <overWriteSnapshots>true</overWriteSnapshots> --> +<!-- <overWriteIfNewer>true</overWriteIfNewer> --> +<!-- <useRepositoryLayout>true</useRepositoryLayout> --> +<!-- <addParentPoms>false</addParentPoms> --> +<!-- <copyPom>false</copyPom> --> +<!-- <includeArtifactIds>${application.name}-model,${application.name}-provider,${application.name}</includeArtifactIds> --> +<!-- <scope>provided</scope> --> +<!-- </configuration> --> +<!-- </execution> --> + <execution> + <id>copy-nested-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>true</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/sdnr/wt/websocketmanager2/installer/src/assembly/assemble_mvnrepo_zip.xml b/sdnr/wt/websocketmanager2/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..c4eb9aa25 --- /dev/null +++ b/sdnr/wt/websocketmanager2/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/sdnr/wt/websocketmanager2/model/pom.xml b/sdnr/wt/websocketmanager2/model/pom.xml new file mode 100644 index 000000000..02b210cc8 --- /dev/null +++ b/sdnr/wt/websocketmanager2/model/pom.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + * ============LICENSE_START======================================================= + * ONAP : CCSDK.sdnr.wt.websocketmanager.model + * ================================================================================ + * Copyright (C) 2018 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + +--> +<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> + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>sdnr-wt-websocketmanager2-model</artifactId> + <version>0.4.1-SNAPSHOT</version> + <packaging>bundle</packaging> + <name>ccsdk-features-sdnr-wt :: ${project.artifactId}</name> + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>1.2.1-SNAPSHOT</version> + <relativePath /> + </parent> + <dependencies> + </dependencies> +</project> diff --git a/sdnr/wt/websocketmanager2/model/src/main/yang/websocketmanager.yang b/sdnr/wt/websocketmanager2/model/src/main/yang/websocketmanager.yang new file mode 100644 index 000000000..dd0297830 --- /dev/null +++ b/sdnr/wt/websocketmanager2/model/src/main/yang/websocketmanager.yang @@ -0,0 +1,38 @@ +module websocketmanager { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:websocketmanager"; + prefix "websocketmanager"; + + revision "2015-01-05" { + description "Initial revision of websocketmanager model"; + } + + rpc websocket-event { + input { + leaf nodeName { + type string; + } + + leaf eventType { + type string; + } + + leaf xmlEvent { + type string; + } + } + output { + leaf response { + type string; + } + } + } + + notification messagePushed { + leaf message { + type string; + } + + } +} + diff --git a/sdnr/wt/websocketmanager2/pom.xml b/sdnr/wt/websocketmanager2/pom.xml new file mode 100755 index 000000000..523c03ee4 --- /dev/null +++ b/sdnr/wt/websocketmanager2/pom.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + * ============LICENSE_START======================================================= + * ONAP : CCSDK.sdnr.wt.websocketmanager + * ================================================================================ + * Copyright (C) 2018 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + +--> +<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> + + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>sdnr-wt-websocketmanager2-top</artifactId> + <version>0.4.1-SNAPSHOT</version> + <packaging>pom</packaging> + <name>ccsdk-features-sdnr-wt :: ${project.artifactId}</name> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>1.2.1-SNAPSHOT</version> + <relativePath/> + </parent> + + <properties> + <feature-name>sdnr-wt-websocketmanager2</feature-name> + </properties> + + <modules> + <module>model</module> + <module>provider</module> + <module>feature</module> + <module>installer</module> + </modules> + +</project> diff --git a/sdnr/wt/websocketmanager2/provider/pom.xml b/sdnr/wt/websocketmanager2/provider/pom.xml new file mode 100644 index 000000000..4bf680599 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/pom.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============LICENSE_START======================================================= + ONAP : ccsdk feature sdnr wt websocketmanager2 ================================================================================ + Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All + rights reserved. ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); you may not + use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required + by applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. See the License for the specific + language governing permissions and limitations under the License. ============LICENSE_END========================================================= --> +<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> + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>sdnr-wt-websocketmanager2-provider</artifactId> + <version>0.4.1-SNAPSHOT</version> + <name>ccsdk-features-sdnr-wt :: ${project.artifactId}</name> + <packaging>bundle</packaging> + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>1.2.1-SNAPSHOT</version> + <relativePath></relativePath> + </parent> + <properties> + <maven.javadoc.skip>true</maven.javadoc.skip> + <checkstyle.skip>true</checkstyle.skip> + </properties> + <licenses> + <license> + <name>Apache License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0</url> + </license> + </licenses> + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-websocketmanager2-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty.websocket</groupId> + <artifactId>websocket-api</artifactId> + <version>9.3.21.v20170918</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty.websocket</groupId> + <artifactId>websocket-servlet</artifactId> + <version>9.3.21.v20170918</version> + </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-transport</artifactId> + </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-all</artifactId> + <!-- <version>${netty.version}</version> --> + </dependency> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + <dependency> + <groupId>com.typesafe.akka</groupId> + <artifactId>akka-actor_2.12</artifactId> + </dependency> + <dependency> + <groupId>com.typesafe.akka</groupId> + <artifactId>akka-cluster_2.12</artifactId> + </dependency> + <dependency> + <groupId>org.java-websocket</groupId> + <artifactId>Java-WebSocket</artifactId> + <version>1.3.8</version> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <!-- <version>2.23.4</version> --> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-api</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/Blueprint.java b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/Blueprint.java new file mode 100644 index 000000000..32d9d7a4b --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/Blueprint.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2; + +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; + +public abstract class Blueprint implements AutoCloseable { + + private RpcProviderRegistry rpcProviderRegistry = null; + + public abstract void init(); + + public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) { + this.rpcProviderRegistry = rpcProviderRegistry; + } + + public RpcProviderRegistry getRpcProviderRegistry() { + return this.rpcProviderRegistry; + } + + +} diff --git a/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManager.java b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManager.java new file mode 100644 index 000000000..18066128f --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManager.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2; + +import com.google.common.util.concurrent.ListenableFuture; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import org.eclipse.jetty.websocket.servlet.WebSocketServlet; +import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; +import org.json.JSONObject; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.WebSocketManagerSocket.EventInputCallback; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils.AkkaConfig; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils.AkkaConfig.ClusterConfig; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils.AkkaConfig.ClusterNodeInfo; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.websocket.SyncWebSocketClient; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketEventInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketEventOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketEventOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketmanagerService; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebSocketManager extends WebSocketServlet implements WebsocketmanagerService { + + private static final long serialVersionUID = -681665669062744439L; + + private static final Logger LOG = LoggerFactory.getLogger(WebSocketManager.class.getName()); + private static final String APPLICATION_NAME = WebSocketManager.class.getName(); + private static final int PORT = 8181; + private final EventInputCallback rpcEventInputCallback; + + /** + * timeout for websocket with no messages in ms + */ + private static final long IDLE_TIMEOUT = 5 * 60 * 1000L; + + private final ArrayList<URI> clusterNodeClients = new ArrayList<>(); + + public WebSocketManager() { + super(); + rpcEventInputCallback = message -> { + LOG.debug("onMessagePushed: " + message); + SyncWebSocketClient client; + for (URI clientURI : WebSocketManager.this.clusterNodeClients) { + client = new SyncWebSocketClient(clientURI); + LOG.debug("try to push message to " + client.getURI()); + client.openAndSendAndCloseSync(message); + } + }; + LOG.info("Create servlet for {}", APPLICATION_NAME); + } + + @Override + public void configure(WebSocketServletFactory factory) { + LOG.info("Configure provider for {}", APPLICATION_NAME); + // set a second timeout + factory.getPolicy().setIdleTimeout(IDLE_TIMEOUT); + factory.getPolicy().setMaxBinaryMessageSize(1); + factory.getPolicy().setMaxTextMessageSize(64 * 1024); + + // register Socket as the WebSocket to create on Upgrade + factory.register(WebSocketManagerSocket.class); + + AkkaConfig cfg = null; + try { + cfg = AkkaConfig.load(); + } catch (Exception e) { + LOG.warn("problem loading akka config: " + e.getMessage()); + } + if (cfg != null && cfg.isCluster()) { + this.initWSClients(cfg.getClusterConfig()); + } + } + + // ODL in Dublin version generates ListenableFuture that is child of Future. + @Override + public ListenableFuture<RpcResult<WebsocketEventOutput>> websocketEvent(WebsocketEventInput input) { + LOG.debug("Send message '{}'", input); + RpcResultBuilder<WebsocketEventOutput> result; + try { + WebsocketEventOutputBuilder outputBuilder = new WebsocketEventOutputBuilder(); + final String s = input.getXmlEvent(); + WebSocketManagerSocket.broadCast(input.getNodeName(), input.getEventType(), s); + outputBuilder.setResponse("OK"); + try { + JSONObject o = new JSONObject(); + o.put(WebSocketManagerSocket.KEY_NODENAME, input.getNodeName()); + o.put(WebSocketManagerSocket.KEY_EVENTTYPE, input.getEventType()); + o.put(WebSocketManagerSocket.KEY_XMLEVENT, input.getXmlEvent()); + this.rpcEventInputCallback.onMessagePushed(o.toString()); + } catch (Exception err) { + LOG.warn("problem pushing messsage to other nodes: " + err.getMessage()); + } + result = RpcResultBuilder.success(outputBuilder); + } catch (Exception e) { + LOG.warn("Socketproblem: {}", e); + result = RpcResultBuilder.failed(); + result.withError(ErrorType.APPLICATION, "Exception", e); + } + return result.buildFuture(); + } + + /********************************************************** + * Private functions + */ + + private void initWSClients(ClusterConfig clusterConfig) { + for (ClusterNodeInfo nodeConfig : clusterConfig.getSeedNodes()) { + if (clusterConfig.isMe(nodeConfig)) { + continue; + } + String url = String.format("ws://%s:%d/websocket", nodeConfig.getRemoteAddress(), PORT); + try { + LOG.debug("registering ws client for " + url); + clusterNodeClients.add(new URI(url)); + } catch (URISyntaxException e) { + LOG.warn("problem instantiating wsclient for url: " + url); + } + } + } +} diff --git a/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerProvider.java b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerProvider.java new file mode 100644 index 000000000..737fe5463 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerProvider.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2; + +import javax.servlet.ServletException; + +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketmanagerService; +import org.osgi.service.http.HttpService; +import org.osgi.service.http.NamespaceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebSocketManagerProvider extends Blueprint { + + private static final Logger LOG = LoggerFactory.getLogger(WebSocketManagerProvider.class); + private static final String APPLICATION_NAME = WebSocketManagerProvider.class.getName(); + private static final String ALIAS = "/websocket"; + + private WebSocketManager wsServlet = null; + private RpcRegistration<WebsocketmanagerService> websocketService = null; + + public WebSocketManagerProvider() { + LOG.info("Creating provider for {}", APPLICATION_NAME); + } + + @Override + public void init() { + LOG.info("Init provider for {}", APPLICATION_NAME); + RpcProviderRegistry rpcProviderRegistry = this.getRpcProviderRegistry(); + if (rpcProviderRegistry != null) { + if (wsServlet != null) { + this.websocketService = rpcProviderRegistry.addRpcImplementation(WebsocketmanagerService.class, + wsServlet); + } else { + LOG.error("wsServlet not provided"); + } + } else { + LOG.error("rpcProviderRegistry not provided"); + } + } + + @Override + public void close() throws Exception { + LOG.info("Close provider for {}", APPLICATION_NAME); + if (websocketService != null) { + websocketService.close(); + } + } + + public void onUnbindService(HttpService httpService) { + httpService.unregister(ALIAS); + wsServlet = null; + } + + public void onBindService(HttpService httpService) throws ServletException, NamespaceException { + if (httpService == null) { + LOG.warn("Unable to inject HttpService into DluxLoader. dlux modules won't work without httpService"); + } else { + + wsServlet = new WebSocketManager(); + httpService.registerServlet(ALIAS, wsServlet, null, null); + LOG.info("websocket servlet registered."); + if(this.websocketService==null) + this.init(); + else + LOG.info("websocketservice already initialized"); + } + + } + + public WebSocketManager getWsServlet() { + return wsServlet; + } + + public void setWsServlet(WebSocketManager wsServlet) { + this.wsServlet = wsServlet; + } +} diff --git a/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerSocket.java b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerSocket.java new file mode 100644 index 000000000..f445bcd23 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerSocket.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketAdapter; +import org.json.JSONObject; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils.UserScopes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebSocketManagerSocket extends WebSocketAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(WebSocketManagerSocket.class.getName()); + + public static final String MSG_KEY_DATA = "data"; + public static final String MSG_KEY_SCOPES = "scopes"; + public static final String MSG_KEY_PARAM = "param"; + public static final String MSG_KEY_VALUE = "value"; + public static final String MSG_KEY_SCOPE = "scope"; + + public static final String KEY_NODENAME = "nodename"; + public static final String KEY_EVENTTYPE = "eventtype"; + public static final String KEY_XMLEVENT = "xmlevent"; + + private static final Random RND = new Random(); + + + /** + * list of all sessionids + */ + private static final List<String> sessionIds = new ArrayList<>(); + /** + * map of sessionid <=> UserScopes + */ + private static final HashMap<String, UserScopes> userScopesList = new HashMap<>(); + /** + * map of class.hashCode <=> class + */ + private static final HashMap<String, WebSocketManagerSocket> clientList = new HashMap<>(); + private final String myUniqueSessionId; + + private Session session = null; + + public interface EventInputCallback { + void onMessagePushed(final String message) throws Exception; + } + + public WebSocketManagerSocket() { + this.myUniqueSessionId = _genSessionId(); + } + + @Override + protected void finalize() throws Throwable { + sessionIds.remove(this.myUniqueSessionId); + } + + private static String _genSessionId() { + String sid = String.valueOf(RND.nextLong()); + while (sessionIds.contains(sid)) { + sid = String.valueOf(RND.nextLong()); + } + sessionIds.add(sid); + return sid; + } + + @Override + public void onWebSocketText(String message) { + LOG.info(this.getRemoteAdr() + " has sent " + message); + if (!this.manageClientRequest(message)) { + this.manageClientRequest2(message); + } + + } + + @Override + public void onWebSocketBinary(byte[] payload, int offset, int len) { + + } + + @Override + public void onWebSocketConnect(Session sess) { + this.session = sess; + clientList.put(String.valueOf(this.hashCode()), this); + LOG.debug("client connected from " + this.getRemoteAdr()); + } + + @Override + public void onWebSocketClose(int statusCode, String reason) { + clientList.remove(String.valueOf(this.hashCode())); + LOG.debug("client disconnected from " + this.getRemoteAdr()); + } + + @Override + public void onWebSocketError(Throwable cause) { + + LOG.debug("error caused on " + this.getRemoteAdr() + " :" + cause.getMessage()); + // super.onWebSocketError(cause); + } + + private String getRemoteAdr() { + String adr = "unknown"; + try { + adr = this.session.getRemoteAddress().toString(); + } catch (Exception e) { + LOG.debug("error resolving adr: {}", e.getMessage()); + } + return adr; + } + + /** + * + * @param request is a json object + * {"data":"scopes","scopes":["scope1","scope2",...]} + * @return if handled + */ + private boolean manageClientRequest(String request) { + boolean ret = false; + try { + JSONObject jsonMessage = new JSONObject(request); + if (jsonMessage.has(MSG_KEY_DATA)) { + String data = jsonMessage.getString(MSG_KEY_DATA); + if (data.equals(MSG_KEY_SCOPES)) { + ret = true; + String sessionId = this.getSessionId(); + UserScopes clientDto = new UserScopes(); + clientDto.setScopes(jsonMessage.getJSONArray(MSG_KEY_SCOPES)); + userScopesList.put(sessionId, clientDto); + this.send( + "You are connected to the Opendaylight Websocket server and scopes are : " + request + ""); + } + } + } catch (Exception e) { + LOG.warn("problem set scope: " + e.getMessage()); + this.send("Your request to the Opendaylight Websocket server is >> " + request + + " << which failed because of following exception >> " + e.toString()); + } + return ret; + } + + /* + * broadcast message to all your clients + */ + private void manageClientRequest2(String request) { + try { + JSONObject o = new JSONObject(request); + if (o.has(KEY_NODENAME) && o.has(KEY_EVENTTYPE)) { + broadCast(o.getString(KEY_NODENAME), o.getString(KEY_EVENTTYPE), o.getString(KEY_XMLEVENT)); + } + } catch (Exception e) { + LOG.warn("handle ws request failed:" + e.getMessage()); + } + } + + private void send(String msg) { + try { + LOG.trace("sending {}", msg); + this.session.getRemote().sendString(msg); + } catch (Exception e) { + LOG.warn("problem sending message: " + e.getMessage()); + } + } + + private String getSessionId() { + return this.myUniqueSessionId; + } + + public static void broadCast(String nodeName, String eventType, String xmlEvent) { + if (clientList != null && clientList.size() > 0) { + for (Map.Entry<String, WebSocketManagerSocket> entry : clientList.entrySet()) { + WebSocketManagerSocket socket = entry.getValue(); + if (socket != null) { + try { + + UserScopes clientScopes = userScopesList.get(socket.getSessionId()); + if (clientScopes != null) { + if (clientScopes.hasScope(eventType)) { + socket.send(xmlEvent); + } else { + LOG.debug("client has not scope {}", eventType); + } + } else { + LOG.debug("no scopes for notifications registered"); + } + } catch (Exception ioe) { + LOG.warn(ioe.getMessage()); + } + } else { + LOG.debug("cannot broadcast. socket is null"); + } + } + } + } + +} diff --git a/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/AkkaConfig.java b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/AkkaConfig.java new file mode 100644 index 000000000..4381595a7 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/AkkaConfig.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.WebSocketManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; + +public class AkkaConfig{ + + private static final Logger LOG = LoggerFactory.getLogger(WebSocketManager.class.getName()); + + public static class ClusterNodeInfo + { + @Override + public String toString() { + return "ClusterNodeInfo [protocol=" + protocol + ", clusterName=" + clusterName + ", remoteAdr=" + remoteAdr + + ", port=" + port + "]"; + } + private final String protocol; + private final String clusterName; + private final String remoteAdr; + private final int port; + + public String getRemoteAddress() {return this.remoteAdr;} + public ClusterNodeInfo(String s) throws Exception + { + final String regex ="([a-z.]*):\\/\\/([a-zA-Z0-9-]*)@([a-zA-Z0-9.-]*):([0-9]*)"; + final Pattern pattern = Pattern.compile(regex); + final Matcher matcher = pattern.matcher(s); + if(!matcher.find()) { + throw new Exception("invalid seedNode format"); + } + this.protocol=matcher.group(1); + this.clusterName=matcher.group(2); + this.remoteAdr=matcher.group(3); + this.port=Integer.parseInt(matcher.group(4)); + } + } + public static class ClusterRoleInfo + { + @Override + public String toString() { + return "ClusterRoleInfo [Role=" + Role + ", Index=" + Index + "]"; + } + + private final String Role; + private final int Index; + public ClusterRoleInfo(String s) throws Exception { + final String regex = "([a-z]*)-([0-9]*)"; + final Pattern pattern = Pattern.compile(regex); + final Matcher matcher = pattern.matcher(s); + if(!matcher.find()) { + throw new Exception("invalid role format"); + } + this.Role=matcher.group(1); + this.Index=Integer.parseInt(matcher.group(2)); + } + + } + public static class ClusterConfig + { + @Override + public String toString() { + return "ClusterConfig [seedNodes=" + seedNodes + ", roles=" + roles + "]"; + } + private final List<ClusterNodeInfo> seedNodes; + private final List<ClusterRoleInfo> roles; + private final ClusterNodeInfo ismeInfo; + public ClusterConfig(Config o) throws Exception { + { + this.seedNodes = new ArrayList<>(); + List<String> a= o.getStringList("seed-nodes"); + for(int i=0;i<a.size();i++) + { + ClusterNodeInfo info=new ClusterNodeInfo(a.get(i)); + this.seedNodes.add(info); + } + this.roles=new ArrayList<>(); + a=o.getStringList("roles"); + for(int i=0;i<a.size();i++) + { + ClusterRoleInfo s=new ClusterRoleInfo(a.get(i)); + this.roles.add(s); + } + int idx=this.roles.get(0).Index-1; + if(idx>=0 && idx<this.seedNodes.size()) { + this.ismeInfo=this.seedNodes.get(idx); + } else { + this.ismeInfo=null; + } + } + + } + public boolean isCluster() { + return this.seedNodes!=null?this.seedNodes.size()>1:false; + } + public boolean isMe(ClusterNodeInfo i) { + return this.ismeInfo!=null?this.ismeInfo.equals(i):false; + } + public List<ClusterNodeInfo> getSeedNodes() { + return this.seedNodes; + } + } + + private static final String DEFAULT_FILENAME = "configuration/initial/akka.conf"; + private final File file; + private final String resourceFilename; + private final String fileContent; + private ClusterConfig cluserConfig; + public ClusterConfig getClusterConfig() {return this.cluserConfig;} + + private AkkaConfig(File file,boolean isResource) { + this.file=isResource?null:file; + this.fileContent=null; + this.resourceFilename=isResource?file.getName():null; + } + private AkkaConfig(String fileContent) { + this.file = null; + this.fileContent = fileContent; + this.resourceFilename = null; + } + + + @Override + public String toString() { + return "AkkaConfig [filename=" + file + ", cluserConfig=" + cluserConfig + "]"; + } + + private void loadFromFile() throws Exception { + Config cfg=null; + if(this.file!=null) { + cfg=ConfigFactory.parseFile(this.file); + } else if(this.fileContent!=null) { + cfg=ConfigFactory.parseString(this.fileContent); + } else if(this.resourceFilename!=null) { + cfg=ConfigFactory.parseResources(this.getClass(), this.resourceFilename); + } + + if(cfg!=null) { + this.cluserConfig=new ClusterConfig(cfg.getConfig("odl-cluster-data").getConfig("akka").getConfig("cluster")); + } else + { + LOG.warn("unable to parse config file"); + this.cluserConfig=null; + } + } + + public boolean isCluster() + { + return this.cluserConfig!=null?this.cluserConfig.isCluster():false; + } + public static AkkaConfig load() throws Exception + { + return load(DEFAULT_FILENAME); + } + + public static AkkaConfig load(String filename) throws Exception + { + return load(filename,false); + } + public static AkkaConfig load(String filename,boolean isResource) throws Exception + { + AkkaConfig cfg=new AkkaConfig(new File(filename),isResource); + cfg.loadFromFile(); + + return cfg; + } + public static AkkaConfig loadContent(String content) throws Exception + { + AkkaConfig cfg=new AkkaConfig(content); + cfg.loadFromFile(); + + return cfg; + } + + + + + + + +} diff --git a/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/UserScopes.java b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/UserScopes.java new file mode 100644 index 000000000..5dd503c73 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/UserScopes.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils; + +import org.json.JSONArray; + +public class UserScopes { + + private JSONArray scopes; + + /** + * + * @param jsonArray array of Strings + */ + public void setScopes(JSONArray jsonArray) { + this.scopes = jsonArray; + } + + public boolean hasScope(String scope) { + if (this.scopes == null) + return false; + for (int i = 0, l = this.scopes.length(); i < l; i++) { + if (this.scopes.get(i).toString().equals(scope)) { + return true; + } + } + + return false; + } + +} diff --git a/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/websocket/SyncWebSocketClient.java b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/websocket/SyncWebSocketClient.java new file mode 100644 index 000000000..0afe06e13 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/websocket/SyncWebSocketClient.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2.websocket; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SyncWebSocketClient extends WebSocketClient { + + private static final Logger LOG = LoggerFactory.getLogger(SyncWebSocketClient.class.getName()); + private String messageToSend; + + public SyncWebSocketClient(URI serverUri) { + super(serverUri); + } + + public SyncWebSocketClient(String uri) throws URISyntaxException { + this(new URI(uri)); + } + + @Override + public void onClose(int arg0, String arg1, boolean arg2) { + LOG.debug("socket closed: {} {} {}", arg0, arg1, arg2); + + } + + @Override + public void onError(Exception arg0) { + LOG.warn("error on socket: {}", arg0.getMessage()); + + } + + @Override + public void onMessage(String arg0) { + LOG.debug("received message: {}", arg0); + + } + + @Override + public void onOpen(ServerHandshake arg0) { + LOG.debug("socket opened"); + if (this.messageToSend != null) { + LOG.debug("try to send: " + this.messageToSend); + this.send(this.messageToSend); + this.messageToSend = null; + } + + } + + public void openAndSendAsync(String message) { + this.messageToSend = message; + this.connect(); + } + + public void openAndSendAndCloseSync(String message) { + try { + this.connectBlocking(); + } catch (InterruptedException e) { + LOG.warn("problem connecting:" + e.getMessage()); + Thread.currentThread().interrupt(); + } + this.send(message); + try { + this.closeBlocking(); + } catch (InterruptedException e) { + LOG.warn("problem disconnecting:" + e.getMessage()); + Thread.currentThread().interrupt(); + } + } + +} diff --git a/sdnr/wt/websocketmanager2/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml b/sdnr/wt/websocketmanager2/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml new file mode 100644 index 000000000..315921dbb --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================================== + ONAP : ccsdk feature sdnr wt + ================================================================================================= + Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + ================================================================================================= + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under the License + is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the License for the specific language governing permissions and limitations under + the License. + ============LICENSE_END========================================================================== +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + +<!-- <bean id="wsServlet" --> +<!-- class="org.onap.ccsdk.sdnr.wt.websocketmanager2.WebSocketManager"> --> +<!-- </bean> --> + + <reference id="rpcProviderRegistry" + interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" + odl:type="default" /> + + <bean id="provider" + class="org.onap.ccsdk.features.sdnr.wt.websocketmanager2.WebSocketManagerProvider" + init-method="init" destroy-method="close"> + <property name="rpcProviderRegistry" ref="rpcProviderRegistry" /> +<!-- <property name="wsServlet" ref="wsServlet" /> --> + </bean> + + <reference id="onBindService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"> + <reference-listener ref="provider" bind-method="onBindService" unbind-method="onUnbindService"/> + </reference> +<!-- <service --> +<!-- interface="org.eclipse.jetty.websocket.servlet.WebSocketServlet" --> +<!-- ref="wsServlet"> --> +<!-- <service-properties> --> +<!-- <entry key="alias" value="/websocket" /> --> +<!-- </service-properties> --> +<!-- </service> --> + +</blueprint> diff --git a/sdnr/wt/websocketmanager2/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/test/AkkaConfigTest.java b/sdnr/wt/websocketmanager2/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/test/AkkaConfigTest.java new file mode 100644 index 000000000..217088b33 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/test/AkkaConfigTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2.test; + +import static org.junit.Assert.*; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils.AkkaConfig; + +public class AkkaConfigTest { + + @Test + public void test() throws URISyntaxException, IOException { + + AkkaConfig config=null; + try { + //config = AkkaConfig.load("akka-singlenode.cfg", true); + config = AkkaConfig.loadContent(loadResourceContentAsString("akka-singlenode.cfg")); + } catch (Exception e) { + e.printStackTrace(); + fail("error loading singlenode config"); + } + assertEquals("no singlenode config detected",false,config.isCluster()); + assertEquals("more than one node detected",1,config.getClusterConfig().getSeedNodes().size()); + + try { + config = AkkaConfig.loadContent(loadResourceContentAsString("akka-cluster.cfg")); + } catch (Exception e) { + fail("error loading cluster config"); + } + assertEquals("no cluster config detected",true,config.isCluster()); + assertTrue("only one node detected",config.getClusterConfig().getSeedNodes().size()>1); + } + + private String loadResourceContentAsString(String resourceName) throws URISyntaxException, FileNotFoundException, IOException { + + StringBuilder sb = new StringBuilder(); + + ClassLoader classLoader = getClass().getClassLoader(); + File file = Paths.get(classLoader.getResource(resourceName).toURI()).toFile(); + try(BufferedReader br = new BufferedReader(new FileReader(file))) { + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + } + return sb.toString(); + } +} diff --git a/sdnr/wt/websocketmanager2/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/test/WebsocketServerConnectTest.java b/sdnr/wt/websocketmanager2/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/test/WebsocketServerConnectTest.java new file mode 100644 index 000000000..b380beca3 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/test/WebsocketServerConnectTest.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager2.test; + +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.WebSocketManager; + +public class WebsocketServerConnectTest { + + @Test + public void test() { + + WebSocketManager servlet =new WebSocketManager(); + + + + } +} diff --git a/sdnr/wt/websocketmanager2/provider/src/test/resources/akka-cluster.cfg b/sdnr/wt/websocketmanager2/provider/src/test/resources/akka-cluster.cfg new file mode 100644 index 000000000..465dcad83 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/test/resources/akka-cluster.cfg @@ -0,0 +1,49 @@ +odl-cluster-data { + akka { + remote { + artery { + enabled = off + canonical.hostname = "192.168.178.143" + canonical.port = 2550 + } + netty.tcp { + hostname = "192.168.178.143" + port = 2550 + } + # when under load we might trip a false positive on the failure detector + # transport-failure-detector { + # heartbeat-interval = 4 s + # acceptable-heartbeat-pause = 16s + # } + } + + cluster { + # Remove ".tcp" when using artery. + seed-nodes = ["akka.tcp://opendaylight-cluster-data@192.168.178.142:2550", + "akka.tcp://opendaylight-cluster-data@192.168.178.143:2550", + "akka.tcp://opendaylight-cluster-data@192.168.178.144:2550", + "akka.tcp://opendaylight-cluster-data@192.168.178.145:2550"] + + roles = ["member-2"] + + } + + persistence { + # By default the snapshots/journal directories live in KARAF_HOME. You can choose to put it somewhere else by + # modifying the following two properties. The directory location specified may be a relative or absolute path. + # The relative path is always relative to KARAF_HOME. + + # snapshot-store.local.dir = "target/snapshots" + # journal.leveldb.dir = "target/journal" + + journal { + leveldb { + # Set native = off to use a Java-only implementation of leveldb. + # Note that the Java-only version is not currently considered by Akka to be production quality. + + # native = off + } + } + } + } +} diff --git a/sdnr/wt/websocketmanager2/provider/src/test/resources/akka-singlenode.cfg b/sdnr/wt/websocketmanager2/provider/src/test/resources/akka-singlenode.cfg new file mode 100644 index 000000000..19e723319 --- /dev/null +++ b/sdnr/wt/websocketmanager2/provider/src/test/resources/akka-singlenode.cfg @@ -0,0 +1,48 @@ +odl-cluster-data { + akka { + remote { + artery { + enabled = off + canonical.hostname = "127.0.0.1" + canonical.port = 2550 + } + netty.tcp { + hostname = "127.0.0.1" + port = 2550 + } + # when under load we might trip a false positive on the failure detector + # transport-failure-detector { + # heartbeat-interval = 4 s + # acceptable-heartbeat-pause = 16s + # } + } + + cluster { + # Remove ".tcp" when using artery. + seed-nodes = ["akka.tcp://opendaylight-cluster-data@127.0.0.1:2550"] + + roles = [ + "member-1" + ] + + } + + persistence { + # By default the snapshots/journal directories live in KARAF_HOME. You can choose to put it somewhere else by + # modifying the following two properties. The directory location specified may be a relative or absolute path. + # The relative path is always relative to KARAF_HOME. + + # snapshot-store.local.dir = "target/snapshots" + # journal.leveldb.dir = "target/journal" + + journal { + leveldb { + # Set native = off to use a Java-only implementation of leveldb. + # Note that the Java-only version is not currently considered by Akka to be production quality. + + # native = off + } + } + } + } +} |