aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/websocketmanager2/provider/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/websocketmanager2/provider/src/main')
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/Blueprint.java37
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManager.java140
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerProvider.java95
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/WebSocketManagerSocket.java216
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/AkkaConfig.java206
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/utils/UserScopes.java46
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager2/websocket/SyncWebSocketClient.java91
-rw-r--r--sdnr/wt/websocketmanager2/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml49
8 files changed, 880 insertions, 0 deletions
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>