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