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