datarouter-prov code clean - remove tabs
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / Poker.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 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  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24 package org.onap.dmaap.datarouter.provisioning;
25
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.net.HttpURLConnection;
30 import java.net.InetAddress;
31 import java.net.MalformedURLException;
32 import java.net.URL;
33 import java.net.UnknownHostException;
34 import java.util.Arrays;
35 import java.util.HashSet;
36 import java.util.Map;
37 import java.util.Properties;
38 import java.util.Set;
39 import java.util.Timer;
40 import java.util.TimerTask;
41 import java.util.TreeSet;
42
43 import javax.servlet.ServletException;
44
45 import org.apache.log4j.Logger;
46 import org.json.JSONException;
47 import org.json.JSONObject;
48 import org.json.JSONTokener;
49 import org.onap.dmaap.datarouter.provisioning.beans.EgressRoute;
50 import org.onap.dmaap.datarouter.provisioning.beans.Feed;
51 import org.onap.dmaap.datarouter.provisioning.beans.Group;
52 import org.onap.dmaap.datarouter.provisioning.beans.IngressRoute;
53 import org.onap.dmaap.datarouter.provisioning.beans.NetworkRoute;
54 import org.onap.dmaap.datarouter.provisioning.beans.Parameters;
55 import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
56 import org.onap.dmaap.datarouter.provisioning.utils.*;
57
58 /**
59  * This class handles the two timers (described in R1 Design Notes), and takes care of issuing
60  * the GET to each node of the URL to "poke".
61  *
62  * @author Robert Eby
63  * @version $Id: Poker.java,v 1.11 2014/01/08 16:13:47 eby Exp $
64  */
65 public class Poker extends TimerTask {
66     /** Template used to generate the URL to issue the GET against */
67     public static final String POKE_URL_TEMPLATE = "http://%s/internal/fetchProv";
68
69
70
71
72     /** This is a singleton -- there is only one Poker object in the server */
73     private static Poker p;
74
75     /**
76      * Get the singleton Poker object.
77      * @return the Poker
78      */
79     public static synchronized Poker getPoker() {
80         if (p == null)
81             p = new Poker();
82         return p;
83     }
84
85     private long timer1;
86     private long timer2;
87     private Timer rolex;
88     private String this_pod;        // DNS name of this machine
89     private Logger logger;
90     private String provstring;
91
92     private Poker() {
93         timer1 = timer2 = 0;
94         rolex = new Timer();
95         logger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");
96         try {
97             this_pod = InetAddress.getLocalHost().getHostName();
98         } catch (UnknownHostException e) {
99             this_pod = "*UNKNOWN*";    // not a major problem
100         }
101         provstring = buildProvisioningString();
102
103         rolex.scheduleAtFixedRate(this, 0L, 1000L);    // Run once a second to check the timers
104     }
105
106     /**
107      * This method sets the two timers described in the design notes.
108      * @param t1 the first timer controls how long to wait after a provisioning request before poking each node
109      *   This timer can be reset if it has not "gone off".
110      * @param t2 the second timer set the outer bound on how long to wait.  It cannot be reset.
111      */
112     public void setTimers(long t1, long t2) {
113         synchronized (this_pod) {
114             if (timer1 == 0 || t1 > timer1)
115                 timer1 = t1;
116             if (timer2 == 0)
117                 timer2 = t2;
118         }
119         if (logger.isDebugEnabled())
120             logger.debug("Poker timers set to " + timer1 + " and " + timer2);
121
122
123     }
124
125     /**
126      * Return the last provisioning string built.
127      * @return the last provisioning string built.
128      */
129     public String getProvisioningString() {
130         return provstring;
131     }
132
133     /**
134      * The method to run at the predefined interval (once per second).  This method checks
135      * to see if either of the two timers has expired, and if so, will rebuild the provisioning
136      * string, and poke all the nodes and other PODs.  The timers are then reset to 0.
137      */
138     @Override
139     public void run() {
140         try {
141             if (timer1 > 0) {
142                 long now = System.currentTimeMillis();
143                 boolean fire = false;
144                 synchronized (this_pod) {
145                     if (now > timer1 || now > timer2) {
146                         timer1 = timer2 = 0;
147                         fire = true;
148                     }
149                 }
150                 if (fire) {
151                     // Rebuild the prov string
152                     provstring = buildProvisioningString();
153
154                     // Only the active POD should poke nodes, etc.
155                     boolean active = SynchronizerTask.getSynchronizer().isActive();
156                     if (active) {
157                         // Poke all the DR nodes
158                         for (String n : BaseServlet.getNodes()) {
159                             pokeNode(n);
160                         }
161                         // Poke the pod that is not us
162                         for (String n : BaseServlet.getPods()) {
163                             if (n.length() > 0 && !n.equals(this_pod))
164                                 pokeNode(n);
165                         }
166                     }
167                 }
168             }
169         } catch (Exception e) {
170             logger.warn("PROV0020: Caught exception in Poker: "+e);
171             e.printStackTrace();
172         }
173     }
174     private void pokeNode(final String nodename) {
175         logger.debug("PROV0012 Poking node " + nodename + " ...");
176         Runnable r = new Runnable() {
177             @Override
178             public void run() {
179
180                 try {
181                     String u = String.format(POKE_URL_TEMPLATE, nodename+":"+DB.HTTP_PORT);
182                     URL url = new URL(u);
183                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
184                     conn.setConnectTimeout(60000);    //Fixes for Itrack DATARTR-3, poke timeout
185                     conn.connect();
186                     conn.getContentLength();    // Force the GET through
187                     conn.disconnect();
188                 } catch (MalformedURLException e) {
189                     logger.warn("PROV0013 MalformedURLException Error poking node "+nodename+": " + e.getMessage());
190                 } catch (IOException e) {
191                     logger.warn("PROV0013 IOException Error poking node "+nodename+": " + e.getMessage());
192                 }
193             }
194         };
195 //        Thread t = new Thread(r);
196 //        t.start();
197         r.run();
198     }
199     @SuppressWarnings("unused")
200     private String buildProvisioningString() {
201         StringBuilder sb = new StringBuilder("{\n");
202
203         // Append Feeds to the string
204         String pfx = "\n";
205         sb.append("\"feeds\": [");
206         for (Feed f : Feed.getAllFeeds()) {
207             sb.append(pfx);
208             sb.append(f.asJSONObject().toString());
209             pfx = ",\n";
210         }
211         sb.append("\n],\n");
212
213         //Append groups to the string - Rally:US708115  - 1610
214         pfx = "\n";
215         sb.append("\"groups\": [");
216         for (Group s : Group.getAllgroups()) {
217             sb.append(pfx);
218             sb.append(s.asJSONObject().toString());
219             pfx = ",\n";
220         }
221         sb.append("\n],\n");
222
223
224         // Append Subscriptions to the string
225         pfx = "\n";
226         sb.append("\"subscriptions\": [");
227         for (Subscription s : Subscription.getAllSubscriptions()) {
228             sb.append(pfx);
229             if(s!=null)
230             sb.append(s.asJSONObject().toString());
231             pfx = ",\n";
232         }
233         sb.append("\n],\n");
234
235         // Append Parameters to the string
236         pfx = "\n";
237         sb.append("\"parameters\": {");
238         Map<String,String> props = Parameters.getParameters();
239         Set<String> ivals = new HashSet<String>();
240         String intv = props.get("_INT_VALUES");
241         if (intv != null)
242             ivals.addAll(Arrays.asList(intv.split("\\|")));
243         for (String key : new TreeSet<String>(props.keySet())) {
244             String v = props.get(key);
245             sb.append(pfx);
246             sb.append("  \"").append(key).append("\": ");
247             if (ivals.contains(key)) {
248                 // integer value
249                 sb.append(v);
250             } else if (key.endsWith("S")) {
251                 // Split and append array of strings
252                 String[] pp = v.split("\\|");
253                 String p2 = "";
254                 sb.append("[");
255                 for (String t : pp) {
256                     sb.append(p2).append("\"").append(quote(t)).append("\"");
257                     p2 = ",";
258                 }
259                 sb.append("]");
260             } else {
261                 sb.append("\"").append(quote(v)).append("\"");
262             }
263             pfx = ",\n";
264         }
265         sb.append("\n},\n");
266
267         // Append Routes to the string
268         pfx = "\n";
269         sb.append("\"ingress\": [");
270         for (IngressRoute in : IngressRoute.getAllIngressRoutes()) {
271             sb.append(pfx);
272             sb.append(in.asJSONObject().toString());
273             pfx = ",\n";
274         }
275         sb.append("\n],\n");
276
277         pfx = "\n";
278         sb.append("\"egress\": {");
279         for (EgressRoute eg : EgressRoute.getAllEgressRoutes()) {
280             sb.append(pfx);
281             String t = eg.asJSONObject().toString();
282             t = t.substring(1, t.length()-1);
283             sb.append(t);
284             pfx = ",\n";
285         }
286         sb.append("\n},\n");
287
288         pfx = "\n";
289         sb.append("\"routing\": [");
290         for (NetworkRoute ne : NetworkRoute.getAllNetworkRoutes()) {
291             sb.append(pfx);
292             sb.append(ne.asJSONObject().toString());
293             pfx = ",\n";
294         }
295         sb.append("\n]");
296         sb.append("\n}");
297
298         // Convert to string and verify it is valid JSON
299         String provstring = sb.toString();
300         try {
301             new JSONObject(new JSONTokener(provstring));
302         } catch (JSONException e) {
303             logger.warn("PROV0016: Possible invalid prov string: "+e);
304         }
305         return provstring;
306     }
307     private String quote(String s) {
308         StringBuilder sb = new StringBuilder();
309         for (char ch : s.toCharArray()) {
310             if (ch == '\\' || ch == '"') {
311                 sb.append('\\');
312             }
313             sb.append(ch);
314         }
315         return sb.toString();
316     }
317 }