Replace depreciated MDSAL interfaces
[ccsdk/features.git] / sdnr / wt / websocketmanager2 / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / websocketmanager2 / WebSocketManagerSocket.java
1 /*******************************************************************************
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.websocketmanager2;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.Random;
26 import java.util.Set;
27
28 import org.eclipse.jetty.websocket.api.Session;
29 import org.eclipse.jetty.websocket.api.WebSocketAdapter;
30 import org.json.JSONObject;
31 import org.onap.ccsdk.features.sdnr.wt.websocketmanager2.utils.UserScopes;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 public class WebSocketManagerSocket extends WebSocketAdapter {
36
37     private static final Logger LOG = LoggerFactory.getLogger(WebSocketManagerSocket.class.getName());
38     public static final String MSG_KEY_DATA = "data";
39     public static final String MSG_KEY_SCOPES = "scopes";
40     public static final String MSG_KEY_PARAM = "param";
41     public static final String MSG_KEY_VALUE = "value";
42     public static final String MSG_KEY_SCOPE = "scope";
43
44     public static final String KEY_NODENAME = "nodename";
45     public static final String KEY_EVENTTYPE = "eventtype";
46     public static final String KEY_XMLEVENT = "xmlevent";
47
48     private static final Random RND = new Random();
49
50
51     /**
52      * list of all sessionids
53      */
54     private static final List<String> sessionIds = new ArrayList<>();
55     /**
56      * map of sessionid <=> UserScopes
57      */
58     private static final HashMap<String, UserScopes> userScopesList = new HashMap<>();
59     /**
60      * map of class.hashCode <=> class
61      */
62     private static final HashMap<String, WebSocketManagerSocket> clientList = new HashMap<>();
63     private final String myUniqueSessionId;
64
65     private Session session = null;
66
67     public interface EventInputCallback {
68         void onMessagePushed(final String message) throws Exception;
69     }
70
71     public WebSocketManagerSocket() {
72         this.myUniqueSessionId = _genSessionId();
73     }
74
75     @Override
76     protected void finalize() throws Throwable {
77         sessionIds.remove(this.myUniqueSessionId);
78     }
79
80     private static String _genSessionId() {
81         String sid = String.valueOf(RND.nextLong());
82         while (sessionIds.contains(sid)) {
83             sid = String.valueOf(RND.nextLong());
84         }
85         sessionIds.add(sid);
86         return sid;
87     }
88
89     @Override
90     public void onWebSocketText(String message) {
91         LOG.info("{} has sent {}",this.getRemoteAdr(), message);
92         if (!this.manageClientRequest(message)) {
93             this.manageClientRequest2(message);
94         }
95     }
96
97     @Override
98     public void onWebSocketBinary(byte[] payload, int offset, int len) {
99         LOG.debug("Binary not supported");
100     }
101
102     @Override
103     public void onWebSocketConnect(Session sess) {
104         this.session = sess;
105         clientList.put(String.valueOf(this.hashCode()), this);
106         LOG.debug("client connected from " + this.getRemoteAdr());
107     }
108
109     @Override
110     public void onWebSocketClose(int statusCode, String reason) {
111         clientList.remove(String.valueOf(this.hashCode()));
112         LOG.debug("client disconnected from " + this.getRemoteAdr());
113     }
114
115     @Override
116     public void onWebSocketError(Throwable cause) {
117         LOG.debug("error caused on " + this.getRemoteAdr() + " :" + cause.getMessage());
118         // super.onWebSocketError(cause);
119     }
120
121     private String getRemoteAdr() {
122         String adr = "unknown";
123         try {
124             adr = this.session.getRemoteAddress().toString();
125         } catch (Exception e) {
126             LOG.debug("error resolving adr: {}", e.getMessage());
127         }
128         return adr;
129     }
130
131     /**
132      *
133      * @param request is a json object
134      *                {"data":"scopes","scopes":["scope1","scope2",...]}
135      * @return if handled
136      */
137     private boolean manageClientRequest(String request) {
138         boolean ret = false;
139         try {
140             JSONObject jsonMessage = new JSONObject(request);
141             if (jsonMessage.has(MSG_KEY_DATA)) {
142                 String data = jsonMessage.getString(MSG_KEY_DATA);
143                 if (data.equals(MSG_KEY_SCOPES)) {
144                     ret = true;
145                     String sessionId = this.getSessionId();
146                     UserScopes clientDto = new UserScopes();
147                     clientDto.setScopes(jsonMessage.getJSONArray(MSG_KEY_SCOPES));
148                     userScopesList.put(sessionId, clientDto);
149                     this.send(
150                             "You are connected to the Opendaylight Websocket server and scopes are : " + request + "");
151                 }
152             }
153         } catch (Exception e) {
154             LOG.warn("problem set scope: " + e.getMessage());
155             this.send("Your request to the Opendaylight Websocket server is >> " + request
156                     + " << which failed because of following exception >> " + e.toString());
157         }
158         return ret;
159     }
160
161     /*
162      * broadcast message to all your clients
163      */
164     private void manageClientRequest2(String request) {
165         try {
166             JSONObject o = new JSONObject(request);
167             if (o.has(KEY_NODENAME) && o.has(KEY_EVENTTYPE)) {
168                 this.sendToAll(o.getString(KEY_NODENAME), o.getString(KEY_EVENTTYPE), o.getString(KEY_XMLEVENT));
169             }
170         } catch (Exception e) {
171             LOG.warn("handle ws request failed:" + e.getMessage());
172         }
173     }
174
175     public void send(String msg) {
176         try {
177             LOG.trace("sending {}", msg);
178             this.session.getRemote().sendString(msg);
179         } catch (Exception e) {
180             LOG.warn("problem sending message: " + e.getMessage());
181         }
182     }
183      public String getSessionId() {
184         return this.myUniqueSessionId;
185     }
186
187     private void sendToAll(String nodeName, String eventType, String xmlEvent) {
188         if (clientList.size() > 0) {
189             for (Map.Entry<String, WebSocketManagerSocket> entry : clientList.entrySet()) {
190                 WebSocketManagerSocket socket = entry.getValue();
191                 if (socket != null) {
192                     try {
193                         UserScopes clientScopes = userScopesList.get(socket.getSessionId());
194                         if (clientScopes != null) {
195                             if (clientScopes.hasScope(eventType)) {
196                                 socket.send(xmlEvent);
197                             } else {
198                                 LOG.debug("client has not scope {}", eventType);
199                             }
200                         } else {
201                             LOG.debug("no scopes for notifications registered");
202                         }
203                     } catch (Exception ioe) {
204                         LOG.warn(ioe.getMessage());
205                     }
206                 } else {
207                     LOG.debug("cannot broadcast. socket is null");
208                 }
209             }
210         }
211     }
212     public static void broadCast(String nodeName, String eventType, String xmlEvent) {
213         if(clientList.size()>0) {
214             Set<Entry<String, WebSocketManagerSocket>> e = clientList.entrySet();
215             WebSocketManagerSocket s = e.iterator().next().getValue();
216             if(s!=null)
217             {
218                 s.sendToAll(nodeName, eventType, xmlEvent);
219             }
220         }
221     }
222
223 }