Add collaboration feature
[sdc.git] / openecomp-be / lib / openecomp-sdc-notification-lib / openecomp-sdc-notification-websocket / src / main / java / org / openecomp / sdc / notification / websocket / NotificationWebsocketHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.notification.websocket;
22
23 import com.google.gson.Gson;
24 import org.openecomp.sdc.logging.api.Logger;
25 import org.openecomp.sdc.logging.api.LoggerFactory;
26 import org.openecomp.sdc.notification.types.NotificationsStatusDto;
27 import org.openecomp.sdc.notification.workers.NotificationWorker;
28 import org.springframework.http.HttpHeaders;
29 import org.springframework.web.socket.CloseStatus;
30 import org.springframework.web.socket.TextMessage;
31 import org.springframework.web.socket.WebSocketSession;
32 import org.springframework.web.socket.handler.TextWebSocketHandler;
33
34 import java.io.IOException;
35 import java.util.Objects;
36 import java.util.Optional;
37 import java.util.UUID;
38 import java.util.function.Consumer;
39
40 public class NotificationWebsocketHandler extends TextWebSocketHandler {
41
42         private static final String USER_ID_HEADER_PARAM = "USER_ID";
43         private static final String LAST_DELIVERED_QUERY_PARAM = "LAST_DELIVERED_EVENT_ID";
44         private static final String COOKIE = "Cookie";
45         private static Logger LOGGER = LoggerFactory.getLogger(NotificationWebsocketHandler.class);
46         private NotificationWorker worker;
47
48         public NotificationWebsocketHandler(NotificationWorker worker) {
49                 super();
50                 this.worker = Objects.requireNonNull(worker, "NotificationWorker object is not initialized.");
51         }
52
53         @Override
54     public void afterConnectionEstablished(WebSocketSession session) throws Exception {
55         super.afterConnectionEstablished(session);
56
57                 String ownerId = getOwnerId(session);
58                 if (ownerId == null) {
59                         return;
60                 }
61                 UUID lastDelivered = getLastEventId(session);
62
63                 Consumer<NotificationsStatusDto> notesProcessor = (notes) -> notifyReceiver(session, notes);
64
65                 worker.register(ownerId, lastDelivered, notesProcessor);
66     }
67
68         @Override
69     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
70                 String ownerId = getOwnerId(session);
71                 if (ownerId != null) {
72                         worker.unregister(ownerId);
73                 }
74             super.afterConnectionClosed(session, status);
75     }
76
77         private void notifyReceiver(WebSocketSession session, NotificationsStatusDto notificationsStatusDto) {
78
79                 try {
80                         session.sendMessage(new TextMessage(new Gson().toJson(notificationsStatusDto)));
81                 } catch (IOException e) {
82                         LOGGER.error("IO Exception during Receiver notification.", e);
83                 }
84         }
85
86     private String getOwnerId(WebSocketSession session) {
87
88         HttpHeaders handshakeHeaders = session.getHandshakeHeaders();
89         if (handshakeHeaders.containsKey(COOKIE)) {
90                         String[] cookies = handshakeHeaders.get(COOKIE).get(0).split("; ");
91                         Optional<String> cookie = extractValue(cookies, USER_ID_HEADER_PARAM);
92                         if (cookie.isPresent()) {
93                                 return cookie.get();
94                         }
95                 }
96
97                 LOGGER.error("No " + USER_ID_HEADER_PARAM + " specified in the session cookies.");
98                 return null;
99     }
100
101     private UUID getLastEventId(WebSocketSession session) {
102
103         String uriQuery = session.getUri().getQuery();
104         if (uriQuery != null) {
105
106             String[] queries = uriQuery.split("; ");
107             Optional<String> paramValue = extractValue(queries, LAST_DELIVERED_QUERY_PARAM);
108             if (paramValue.isPresent()) {
109                 return UUID.fromString(paramValue.get());
110             }
111         }
112
113         LOGGER.warn("No " + LAST_DELIVERED_QUERY_PARAM + " specified in the request URI.");
114         return null;
115     }
116
117         private Optional<String> extractValue(String[] pairs, String name) {
118
119                 for (String nameValuePair : pairs) {
120
121             String[] value = nameValuePair.split("=");
122             if (value[0].equals(name)) {
123                 return Optional.of(value[1]);
124             }
125         }
126
127                 return Optional.empty();
128         }
129
130 }