9f9dc37e41fd7c28e5caf32ca35e38fb07a763d8
[policy/engine.git] / PolicyEngineAPI / src / main / java / org / onap / policy / std / AutoClientEnd.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * PolicyEngineAPI
4  * ================================================================================
5  * Copyright (C) 2017-2018 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.onap.policy.std;
22
23 import java.net.URI;
24 import javax.websocket.ClientEndpoint;
25 import org.java_websocket.client.WebSocketClient;
26 import org.java_websocket.handshake.ServerHandshake;
27 import org.onap.policy.api.NotificationHandler;
28 import org.onap.policy.api.NotificationScheme;
29 import org.onap.policy.api.NotificationType;
30 import org.onap.policy.api.PDPNotification;
31 import org.onap.policy.common.logging.flexlogger.FlexLogger;
32 import org.onap.policy.common.logging.flexlogger.Logger;
33 import org.onap.policy.xacml.api.XACMLErrorConstants;
34
35 @ClientEndpoint
36 public class AutoClientEnd extends WebSocketClient {
37     private static StdPDPNotification notification = null;
38     private static StdPDPNotification oldNotification = null;
39     private static AutoClientEnd client = null;
40     private static NotificationScheme scheme = null;
41     private static NotificationHandler handler = null;
42     private static String url = null;
43     private static boolean status = false;
44     private static boolean stop = false;
45     private static boolean message = false;
46     private static boolean error = false;
47     private static Logger logger = FlexLogger.getLogger(AutoClientEnd.class.getName());
48
49     private AutoClientEnd(URI serverUri) {
50         super(serverUri);
51     }
52
53     @Override
54     public void onMessage(String msg) {
55         logger.info("Received Auto Notification from : " + getURI() + ", Notification: " + msg);
56         AutoClientEnd.message = true;
57         try {
58             AutoClientEnd.notification = NotificationUnMarshal.notificationJSON(msg);
59         } catch (Exception e) {
60             logger.error("PE500 " + e);
61         }
62         try {
63             NotificationStore.recordNotification(notification);
64         } catch (Exception e) {
65             logger.error(e);
66         }
67         if (AutoClientEnd.oldNotification != AutoClientEnd.notification) {
68             AutoClientEnd.oldNotification = AutoClientEnd.notification;
69             callHandler();
70         }
71
72         AutoClientEnd.message = false;
73     }
74
75     @Override
76     public void onClose(int code, String reason, boolean remote) {
77         logger.info("AutoClientEnd disconnected from: " + getURI() + "; Code: " + code + ", reason :  " + reason);
78         if (!AutoClientEnd.stop && !AutoClientEnd.message) {
79             // This Block of code is executed if there is any Network Failure or
80             // if the Notification is Down.
81             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Disconnected from Notification Server");
82             AutoClientEnd.client = null;
83             AutoClientEnd.status = false;
84             // Try to connect Back to available PDP.
85             AutoClientEnd.error = true;
86             start(url);
87         }
88         AutoClientEnd.message = false;
89     }
90
91     @Override
92     public void onError(Exception ex) {
93         logger.error("XACMLErrorConstants.ERROR_PROCESS_FLOW + Error connecting to: " + getURI()
94                 + ", Exception occured ...\n" + ex);
95         // trying to Restart by self.
96         stop();
97         if (AutoClientEnd.url != null) {
98             AutoClientEnd.client = null;
99             AutoClientEnd.status = false;
100             AutoClientEnd.error = true;
101             AutoClientEnd.start(AutoClientEnd.url);
102         }
103     }
104
105     @Override
106     public void onOpen(ServerHandshake arg0) {
107         logger.info("Auto Notification Session Started... " + getURI());
108     }
109
110     /**
111      * Sets the auto.
112      *
113      * @param scheme the scheme
114      * @param handler the handler
115      */
116     public static void setAuto(NotificationScheme scheme, NotificationHandler handler) {
117         logger.info("Auto Notification setAuto, scheme: " + scheme);
118         AutoClientEnd.scheme = scheme;
119         AutoClientEnd.handler = handler;
120     }
121
122     public static void setScheme(NotificationScheme scheme) {
123         AutoClientEnd.scheme = scheme;
124     }
125
126     public static boolean getStatus() {
127         return AutoClientEnd.status;
128     }
129
130     public static String getUrl() {
131         return AutoClientEnd.url;
132     }
133
134     /**
135      * Start.
136      *
137      * @param url the url
138      */
139     public static void start(String url) {
140         AutoClientEnd.url = url;
141
142         if (scheme == null || handler == null || !(scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS)
143                 || scheme.equals(NotificationScheme.AUTO_NOTIFICATIONS)) || AutoClientEnd.client != null) {
144             return;
145         }
146
147         if (url.contains("https")) {
148             url = url.replaceAll("https", "wss");
149         } else {
150             url = url.replaceAll("http", "ws");
151         }
152
153         // Stop and Start needs to be done.
154         try {
155             logger.info("Starting Auto Notification with the PDP server : " + url);
156             client = new AutoClientEnd(new URI(url + "notifications"));
157             client.connect();
158             status = true;
159             if (error) {
160                 // will not trigger. leave it in to later add checks
161                 // The URL's will be in Sync according to design Spec.
162                 ManualClientEnd.start(AutoClientEnd.url);
163                 StdPDPNotification notification = NotificationStore.getDeltaNotification(
164                         (StdPDPNotification) ManualClientEnd.result(NotificationScheme.MANUAL_ALL_NOTIFICATIONS));
165                 if (notification.getNotificationType() != null && oldNotification != notification) {
166                     oldNotification = notification;
167                     AutoClientEnd.notification = notification;
168                     callHandler();
169                 }
170                 error = false;
171             }
172         } catch (Exception e) {
173             logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
174             client = null;
175             status = false;
176             changeUrl();
177         }
178     }
179
180     private static void changeUrl() {
181         // Change the PDP if it is not Up.
182         StdPolicyEngine.rotatePDPList();
183         start(StdPolicyEngine.getPDPURL());
184     }
185
186     /**
187      * Stop the websocket connection.
188      */
189     public static void stop() {
190         if (client == null) {
191             return;
192         }
193         logger.info("\n Closing Auto Notification WebSocket Connection.. ");
194         stop = true;
195         try {
196             client.closeBlocking();
197         } catch (InterruptedException e) {
198             logger.info("\n Error Closing Auto Notification WebSocket Connection.. InterruptedException");
199         }
200         logger.info("\n Closed the Auto Notification WebSocket Connection.. ");
201         client = null;
202         status = false;
203         stop = false;
204     }
205
206     private static void callHandler() {
207         if (handler == null || scheme == null) {
208             return;
209         }
210         if (scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS)) {
211             boolean removed = false;
212             boolean updated = false;
213             if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) {
214                 removed = true;
215                 notification.setNotificationType(NotificationType.REMOVE);
216             }
217             if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) {
218                 updated = true;
219                 notification.setNotificationType(NotificationType.UPDATE);
220             }
221             if (removed && updated) {
222                 notification.setNotificationType(NotificationType.BOTH);
223             }
224             try {
225                 handler.notificationReceived(notification);
226             } catch (Exception e) {
227                 logger.error("Error in Clients Handler Object : ", e);
228             }
229         } else if (scheme.equals(NotificationScheme.AUTO_NOTIFICATIONS)) {
230             PDPNotification newNotification = MatchStore.checkMatch(notification);
231             if (newNotification.getNotificationType() != null) {
232                 try {
233                     handler.notificationReceived(newNotification);
234                 } catch (Exception e) {
235                     logger.error("Error in Clients Handler Object : ", e);
236                 }
237             }
238         }
239     }
240 }