From f86bc4b0383cb4d1f4d91326a45a85a35e162c32 Mon Sep 17 00:00:00 2001 From: Paul Dennehy Date: Tue, 25 Sep 2018 17:50:05 +0100 Subject: [PATCH] Fixing code as part of dmaap-775 Change-Id: I5217bab4076ca2a93cf4c83e71fdaa46e4ce788e Signed-off-by: Paul Dennehy Issue-ID: DMAAP-775 --- .../onap/dmaap/datarouter/provisioning/Poker.java | 647 +++++++++++---------- .../datarouter/provisioning/PublishServlet.java | 406 ++++++------- .../dmaap/datarouter/provisioning/utils/DB.java | 50 +- 3 files changed, 569 insertions(+), 534 deletions(-) diff --git a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/Poker.java b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/Poker.java index 563e6f7f..193485e6 100644 --- a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/Poker.java +++ b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/Poker.java @@ -1,323 +1,324 @@ -/******************************************************************************* - * ============LICENSE_START================================================== - * * org.onap.dmaap - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ - -package org.onap.dmaap.datarouter.provisioning; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.TreeSet; - -import org.apache.log4j.Logger; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.onap.dmaap.datarouter.provisioning.beans.EgressRoute; -import org.onap.dmaap.datarouter.provisioning.beans.Feed; -import org.onap.dmaap.datarouter.provisioning.beans.Group; -import org.onap.dmaap.datarouter.provisioning.beans.IngressRoute; -import org.onap.dmaap.datarouter.provisioning.beans.NetworkRoute; -import org.onap.dmaap.datarouter.provisioning.beans.Parameters; -import org.onap.dmaap.datarouter.provisioning.beans.Subscription; -import org.onap.dmaap.datarouter.provisioning.utils.*; - -/** - * This class handles the two timers (described in R1 Design Notes), and takes care of issuing the GET to each node of - * the URL to "poke". - * - * @author Robert Eby - * @version $Id: Poker.java,v 1.11 2014/01/08 16:13:47 eby Exp $ - */ -public class Poker extends TimerTask { - - /** - * Template used to generate the URL to issue the GET against - */ - private static final String POKE_URL_TEMPLATE = "http://%s/internal/fetchProv"; - - private static final Object lock = new Object(); - - /** - * This is a singleton -- there is only one Poker object in the server - */ - private static Poker poker; - - /** - * Get the singleton Poker object. - * - * @return the Poker - */ - public static synchronized Poker getPoker() { - if (poker == null) { - poker = new Poker(); - } - return poker; - } - - private long timer1; - private long timer2; - private String thisPod; // DNS name of this machine - private Logger logger; - private String provString; - - private Poker() { - timer1 = timer2 = 0; - Timer rolex = new Timer(); - logger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal"); - try { - thisPod = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - thisPod = "*UNKNOWN*"; // not a major problem - } - provString = buildProvisioningString(); - - rolex.scheduleAtFixedRate(this, 0L, 1000L); // Run once a second to check the timers - } - - /** - * This method sets the two timers described in the design notes. - * - * @param t1 the first timer controls how long to wait after a provisioning request before poking each node This - * timer can be reset if it has not "gone off". - * @param t2 the second timer set the outer bound on how long to wait. It cannot be reset. - */ - public void setTimers(long t1, long t2) { - synchronized (lock) { - if (timer1 == 0 || t1 > timer1) { - timer1 = t1; - } - if (timer2 == 0) { - timer2 = t2; - } - } - if (logger.isDebugEnabled()) { - logger.debug("Poker timers set to " + timer1 + " and " + timer2); - } - - - } - - /** - * Return the last provisioning string built. - * - * @return the last provisioning string built. - */ - public String getProvisioningString() { - return provString; - } - - /** - * The method to run at the predefined interval (once per second). This method checks to see if either of the two - * timers has expired, and if so, will rebuild the provisioning string, and poke all the nodes and other PODs. The - * timers are then reset to 0. - */ - @Override - public void run() { - try { - if (timer1 > 0) { - long now = System.currentTimeMillis(); - boolean fire = false; - synchronized (lock) { - if (now > timer1 || now > timer2) { - timer1 = timer2 = 0; - fire = true; - } - } - if (fire) { - pokeNodes(); - } - } - } catch (Exception e) { - logger.warn("PROV0020: Caught exception in Poker: " + e); - e.printStackTrace(); - } - } - - private void pokeNodes() { - // Rebuild the prov string - provString = buildProvisioningString(); - // Only the active POD should poke nodes, etc. - boolean active = SynchronizerTask.getSynchronizer().isActive(); - if (active) { - // Poke all the DR nodes - for (String n : BaseServlet.getNodes()) { - pokeNode(n); - } - // Poke the pod that is not us - for (String n : BaseServlet.getPods()) { - if (n.length() > 0 && !n.equals(thisPod)) { - pokeNode(n); - } - } - } - } - - private void pokeNode(final String nodename) { - logger.debug("PROV0012 Poking node " + nodename + " ..."); - String nodeUrl = String.format(POKE_URL_TEMPLATE, nodename + ":" + DB.HTTP_PORT); - Runnable r = () -> { - try { - URL url = new URL(nodeUrl); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setConnectTimeout(60000); //Fixes for Itrack DATARTR-3, poke timeout - conn.connect(); - conn.getContentLength(); // Force the GET through - conn.disconnect(); - } catch (MalformedURLException e) { - logger.warn("PROV0013 MalformedURLException Error poking node at " + nodeUrl + " : " + e.getMessage()); - } catch (IOException e) { - logger.warn("PROV0013 IOException Error poking node at " + nodeUrl + " : " + e.getMessage()); - } - }; - r.run(); - } - - private String buildProvisioningString() { - StringBuilder sb = new StringBuilder("{\n"); - - // Append Feeds to the string - String pfx = "\n"; - sb.append("\"feeds\": ["); - for (Feed f : Feed.getAllFeeds()) { - sb.append(pfx); - sb.append(f.asJSONObject().toString()); - pfx = ",\n"; - } - sb.append("\n],\n"); - - //Append groups to the string - Rally:US708115 - 1610 - pfx = "\n"; - sb.append("\"groups\": ["); - for (Group s : Group.getAllgroups()) { - sb.append(pfx); - sb.append(s.asJSONObject().toString()); - pfx = ",\n"; - } - sb.append("\n],\n"); - - // Append Subscriptions to the string - pfx = "\n"; - sb.append("\"subscriptions\": ["); - for (Subscription s : Subscription.getAllSubscriptions()) { - sb.append(pfx); - if (s != null) { - sb.append(s.asJSONObject().toString()); - } - pfx = ",\n"; - } - sb.append("\n],\n"); - - // Append Parameters to the string - pfx = "\n"; - sb.append("\"parameters\": {"); - Map props = Parameters.getParameters(); - Set ivals = new HashSet(); - String intv = props.get("_INT_VALUES"); - if (intv != null) { - ivals.addAll(Arrays.asList(intv.split("\\|"))); - } - for (String key : new TreeSet(props.keySet())) { - String v = props.get(key); - sb.append(pfx); - sb.append(" \"").append(key).append("\": "); - if (ivals.contains(key)) { - // integer value - sb.append(v); - } else if (key.endsWith("S")) { - // Split and append array of strings - String[] pp = v.split("\\|"); - String p2 = ""; - sb.append("["); - for (String t : pp) { - sb.append(p2).append("\"").append(quote(t)).append("\""); - p2 = ","; - } - sb.append("]"); - } else { - sb.append("\"").append(quote(v)).append("\""); - } - pfx = ",\n"; - } - sb.append("\n},\n"); - - // Append Routes to the string - pfx = "\n"; - sb.append("\"ingress\": ["); - for (IngressRoute in : IngressRoute.getAllIngressRoutes()) { - sb.append(pfx); - sb.append(in.asJSONObject().toString()); - pfx = ",\n"; - } - sb.append("\n],\n"); - - pfx = "\n"; - sb.append("\"egress\": {"); - for (EgressRoute eg : EgressRoute.getAllEgressRoutes()) { - sb.append(pfx); - String t = eg.asJSONObject().toString(); - t = t.substring(1, t.length() - 1); - sb.append(t); - pfx = ",\n"; - } - sb.append("\n},\n"); - - pfx = "\n"; - sb.append("\"routing\": ["); - for (NetworkRoute ne : NetworkRoute.getAllNetworkRoutes()) { - sb.append(pfx); - sb.append(ne.asJSONObject().toString()); - pfx = ",\n"; - } - sb.append("\n]"); - sb.append("\n}"); - - // Convert to string and verify it is valid JSON - String tempProvString = sb.toString(); - try { - new JSONObject(new JSONTokener(tempProvString)); - } catch (JSONException e) { - logger.warn("PROV0016: Possible invalid prov string: " + e); - } - return tempProvString; - } - - private String quote(String s) { - StringBuilder sb = new StringBuilder(); - for (char ch : s.toCharArray()) { - if (ch == '\\' || ch == '"') { - sb.append('\\'); - } - sb.append(ch); - } - return sb.toString(); - } -} +/******************************************************************************* + * ============LICENSE_START================================================== + * * org.onap.dmaap + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ + +package org.onap.dmaap.datarouter.provisioning; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import java.util.TreeSet; +import org.apache.log4j.Logger; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.onap.dmaap.datarouter.provisioning.beans.EgressRoute; +import org.onap.dmaap.datarouter.provisioning.beans.Feed; +import org.onap.dmaap.datarouter.provisioning.beans.Group; +import org.onap.dmaap.datarouter.provisioning.beans.IngressRoute; +import org.onap.dmaap.datarouter.provisioning.beans.NetworkRoute; +import org.onap.dmaap.datarouter.provisioning.beans.Parameters; +import org.onap.dmaap.datarouter.provisioning.beans.Subscription; +import org.onap.dmaap.datarouter.provisioning.utils.DB; + +/** + * This class handles the two timers (described in R1 Design Notes), and takes care of issuing the GET to each node of + * the URL to "poke". + * + * @author Robert Eby + * @version $Id: Poker.java,v 1.11 2014/01/08 16:13:47 eby Exp $ + */ +public class Poker extends TimerTask { + + /** + * Template used to generate the URL to issue the GET against + */ + private static final String POKE_URL_TEMPLATE = "http://%s/internal/fetchProv"; + + private static final Object lock = new Object(); + + /** + * This is a singleton -- there is only one Poker object in the server + */ + private static Poker poker; + private long timer1; + private long timer2; + private String thisPod; // DNS name of this machine + private Logger logger; + private String provString; + + private Poker() { + timer1 = timer2 = 0; + Timer rolex = new Timer(); + logger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal"); + try { + thisPod = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + thisPod = "*UNKNOWN*"; // not a major problem + logger.info("UnknownHostException: Setting thisPod to \"*UNKNOWN*\""); + } + provString = buildProvisioningString(); + + rolex.scheduleAtFixedRate(this, 0L, 1000L); // Run once a second to check the timers + } + + /** + * Get the singleton Poker object. + * + * @return the Poker + */ + public static synchronized Poker getPoker() { + if (poker == null) { + poker = new Poker(); + } + return poker; + } + + /** + * This method sets the two timers described in the design notes. + * + * @param t1 the first timer controls how long to wait after a provisioning request before poking each node This + * timer can be reset if it has not "gone off". + * @param t2 the second timer set the outer bound on how long to wait. It cannot be reset. + */ + public void setTimers(long t1, long t2) { + synchronized (lock) { + if (timer1 == 0 || t1 > timer1) { + timer1 = t1; + } + if (timer2 == 0) { + timer2 = t2; + } + } + if (logger.isDebugEnabled()) { + logger.debug("Poker timers set to " + timer1 + " and " + timer2); + } + + + } + + /** + * Return the last provisioning string built. + * + * @return the last provisioning string built. + */ + public String getProvisioningString() { + return provString; + } + + /** + * The method to run at the predefined interval (once per second). This method checks to see if either of the two + * timers has expired, and if so, will rebuild the provisioning string, and poke all the nodes and other PODs. The + * timers are then reset to 0. + */ + @Override + public void run() { + try { + if (timer1 > 0) { + long now = System.currentTimeMillis(); + boolean fire = false; + synchronized (lock) { + if (now > timer1 || now > timer2) { + timer1 = timer2 = 0; + fire = true; + } + } + if (fire) { + pokeNodes(); + } + } + } catch (Exception e) { + logger.warn("PROV0020: Caught exception in Poker: " + e); + } + } + + private void pokeNodes() { + // Rebuild the prov string + provString = buildProvisioningString(); + // Only the active POD should poke nodes, etc. + boolean active = SynchronizerTask.getSynchronizer().isActive(); + if (active) { + // Poke all the DR nodes + for (String n : BaseServlet.getNodes()) { + pokeNode(n); + } + // Poke the pod that is not us + for (String n : BaseServlet.getPods()) { + if (n.length() > 0 && !n.equals(thisPod)) { + pokeNode(n); + } + } + } + } + + private void pokeNode(final String nodename) { + logger.debug("PROV0012 Poking node " + nodename + " ..."); + String nodeUrl = String.format(POKE_URL_TEMPLATE, nodename + ":" + DB.getHttpPort()); + Runnable r = () -> { + try { + URL url = new URL(nodeUrl); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(60000); //Fixes for Itrack DATARTR-3, poke timeout + conn.connect(); + conn.getContentLength(); // Force the GET through + conn.disconnect(); + } catch (MalformedURLException e) { + logger.warn( + "PROV0013 MalformedURLException Error poking node at " + nodeUrl + " : " + e + .getMessage()); + } catch (IOException e) { + logger.warn("PROV0013 IOException Error poking node at " + nodeUrl + " : " + e + .getMessage()); + } + }; + r.run(); + } + + private String buildProvisioningString() { + StringBuilder sb = new StringBuilder("{\n"); + + // Append Feeds to the string + String pfx = "\n"; + sb.append("\"feeds\": ["); + for (Feed f : Feed.getAllFeeds()) { + sb.append(pfx); + sb.append(f.asJSONObject().toString()); + pfx = ",\n"; + } + sb.append("\n],\n"); + + //Append groups to the string - Rally:US708115 - 1610 + pfx = "\n"; + sb.append("\"groups\": ["); + for (Group s : Group.getAllgroups()) { + sb.append(pfx); + sb.append(s.asJSONObject().toString()); + pfx = ",\n"; + } + sb.append("\n],\n"); + + // Append Subscriptions to the string + pfx = "\n"; + sb.append("\"subscriptions\": ["); + for (Subscription s : Subscription.getAllSubscriptions()) { + sb.append(pfx); + if (s != null) { + sb.append(s.asJSONObject().toString()); + } + pfx = ",\n"; + } + sb.append("\n],\n"); + + // Append Parameters to the string + pfx = "\n"; + sb.append("\"parameters\": {"); + Map props = Parameters.getParameters(); + Set ivals = new HashSet(); + String intv = props.get("_INT_VALUES"); + if (intv != null) { + ivals.addAll(Arrays.asList(intv.split("\\|"))); + } + for (String key : new TreeSet(props.keySet())) { + String v = props.get(key); + sb.append(pfx); + sb.append(" \"").append(key).append("\": "); + if (ivals.contains(key)) { + // integer value + sb.append(v); + } else if (key.endsWith("S")) { + // Split and append array of strings + String[] pp = v.split("\\|"); + String p2 = ""; + sb.append("["); + for (String t : pp) { + sb.append(p2).append("\"").append(quote(t)).append("\""); + p2 = ","; + } + sb.append("]"); + } else { + sb.append("\"").append(quote(v)).append("\""); + } + pfx = ",\n"; + } + sb.append("\n},\n"); + + // Append Routes to the string + pfx = "\n"; + sb.append("\"ingress\": ["); + for (IngressRoute in : IngressRoute.getAllIngressRoutes()) { + sb.append(pfx); + sb.append(in.asJSONObject().toString()); + pfx = ",\n"; + } + sb.append("\n],\n"); + + pfx = "\n"; + sb.append("\"egress\": {"); + for (EgressRoute eg : EgressRoute.getAllEgressRoutes()) { + sb.append(pfx); + String t = eg.asJSONObject().toString(); + t = t.substring(1, t.length() - 1); + sb.append(t); + pfx = ",\n"; + } + sb.append("\n},\n"); + + pfx = "\n"; + sb.append("\"routing\": ["); + for (NetworkRoute ne : NetworkRoute.getAllNetworkRoutes()) { + sb.append(pfx); + sb.append(ne.asJSONObject().toString()); + pfx = ",\n"; + } + sb.append("\n]"); + sb.append("\n}"); + + // Convert to string and verify it is valid JSON + String tempProvString = sb.toString(); + try { + new JSONObject(new JSONTokener(tempProvString)); + } catch (JSONException e) { + logger.warn("PROV0016: Possible invalid prov string: " + e); + } + return tempProvString; + } + + private String quote(String s) { + StringBuilder sb = new StringBuilder(); + for (char ch : s.toCharArray()) { + if (ch == '\\' || ch == '"') { + sb.append('\\'); + } + sb.append(ch); + } + return sb.toString(); + } +} diff --git a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/PublishServlet.java b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/PublishServlet.java index 4cefdf1e..07285950 100644 --- a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/PublishServlet.java +++ b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/PublishServlet.java @@ -1,197 +1,209 @@ -/******************************************************************************* - * ============LICENSE_START================================================== - * * org.onap.dmaap - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ - - -package org.onap.dmaap.datarouter.provisioning; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord; -import org.onap.dmaap.datarouter.provisioning.beans.Feed; -import org.onap.dmaap.datarouter.provisioning.beans.IngressRoute; -import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs; -import org.onap.dmaap.datarouter.provisioning.utils.*; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -/** - * This servlet handles redirects for the <publishURL> on the provisioning server, - * which is generated by the provisioning server to handle a particular subscriptions to a feed. - * See the File Publishing and Delivery API document for details on how these methods - * should be invoked. - * - * @author Robert Eby - * @version $Id: PublishServlet.java,v 1.8 2014/03/12 19:45:41 eby Exp $ - */ -@SuppressWarnings("serial") -public class PublishServlet extends BaseServlet { - private int next_node; - private String provstring; - private List irt; - //Adding EELF Logger Rally:US664892 - private static EELFLogger eelflogger = EELFManager.getInstance().getLogger("org.onap.dmaap.datarouter.provisioning.PublishServlet"); - private static final Object lock = new Object(); - - - @Override - public void init(ServletConfig config) throws ServletException { - super.init(config); - next_node = 0; - provstring = ""; - irt = new ArrayList(); - - } - @Override - public void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException { - setIpAndFqdnForEelf("doDelete"); - eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER),getIdFromPath(req)+""); - redirect(req, resp); - } - @Override - public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - setIpAndFqdnForEelf("doGet"); - eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER),getIdFromPath(req)+""); - redirect(req, resp); - } - @Override - public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException { - setIpAndFqdnForEelf("doPut"); - eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER),getIdFromPath(req)+""); - redirect(req, resp); - } - @Override - public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { - setIpAndFqdnForEelf("doPost"); - eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER)); - redirect(req, resp); - - } - private void redirect(HttpServletRequest req, HttpServletResponse resp) { - try { - String[] nodes = getNodes(); - if (nodes == null || nodes.length == 0) { - resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "There are no nodes defined in the DR network."); - } else { - EventLogRecord elr = new EventLogRecord(req); - int feedid = checkPath(req); - if (feedid < 0) { - String message = (feedid == -1) - ? "Invalid request - Missing or bad feed number." - : "Invalid request - Missing file ID."; - elr.setMessage(message); - elr.setResult(HttpServletResponse.SC_NOT_FOUND); - eventlogger.info(elr); - - resp.sendError(HttpServletResponse.SC_NOT_FOUND, message); - } else { - // Generate new URL - String nextnode = getRedirectNode(feedid, req); - nextnode = nextnode + ":" + DB.HTTPS_PORT; - String newurl = "https://" + nextnode + "/publish" + req.getPathInfo(); - String qs = req.getQueryString(); - if (qs != null) - newurl += "?" + qs; - - // Log redirect in event log - String message = "Redirected to: " + newurl; - elr.setMessage(message); - elr.setResult(HttpServletResponse.SC_MOVED_PERMANENTLY); - eventlogger.info(elr); - - resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); - resp.setHeader("Location", newurl); - } - } - } catch (IOException ioe) { - intlogger.error("IOException" + ioe.getMessage()); - - } - } - private String getRedirectNode(int feedid, HttpServletRequest req) { - // Check to see if the IRT needs to be updated - Poker p = Poker.getPoker(); - String s = p.getProvisioningString(); - synchronized (lock) { - if (irt == null || (s.length() != provstring.length()) || !s.equals(provstring)) { - // Provisioning string has changed -- update the IRT - provstring = s; - JSONObject jo = new JSONObject(new JSONTokener(provstring)); - JSONArray ja = jo.getJSONArray("ingress"); - List newlist = new ArrayList(); - for (int i = 0; i < ja.length(); i++) { - IngressRoute iroute = new IngressRoute(ja.getJSONObject(i)); - newlist.add(iroute); - } - irt = newlist; - } - } - - // Look in IRT for next node - for (IngressRoute route : irt) { - if (route.matches(feedid, req)) { - // pick a node at random from the list - Collection nodes = route.getNodes(); - String[] arr = nodes.toArray(new String[0]); - long id = System.currentTimeMillis() % arr.length; - String node = arr[(int) id]; - intlogger.info("Redirecting to "+node+" because of route "+route); - return node; - } - } - - // No IRT rule matches, do round robin of all active nodes - String[] nodes = getNodes(); - if (next_node >= nodes.length) // The list of nodes may have grown/shrunk - next_node = 0; - return nodes[next_node++]; - } - private int checkPath(HttpServletRequest req) { - String path = req.getPathInfo(); - if (path == null || path.length() < 2) - return -1; - path = path.substring(1); - int ix = path.indexOf('/'); - if (ix < 0 || ix == path.length()-1) - return -2; - try { - int feedid = Integer.parseInt(path.substring(0, ix)); - if (!Feed.isFeedValid(feedid)) - return -1; - return feedid; - } catch (NumberFormatException e) { - return -1; - } - } -} +/******************************************************************************* + * ============LICENSE_START================================================== + * * org.onap.dmaap + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ + + +package org.onap.dmaap.datarouter.provisioning; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord; +import org.onap.dmaap.datarouter.provisioning.beans.Feed; +import org.onap.dmaap.datarouter.provisioning.beans.IngressRoute; +import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs; +import org.onap.dmaap.datarouter.provisioning.utils.DB; + +/** + * This servlet handles redirects for the <publishURL> on the provisioning server, which is generated by the + * provisioning server to handle a particular subscriptions to a feed. See the File Publishing and Delivery API + * document for details on how these methods should be invoked. + * + * @author Robert Eby + * @version $Id: PublishServlet.java,v 1.8 2014/03/12 19:45:41 eby Exp $ + */ +@SuppressWarnings("serial") +public class PublishServlet extends BaseServlet { + + private int next_node; + private String provstring; + private List irt; + //Adding EELF Logger Rally:US664892 + private static EELFLogger eelflogger = EELFManager.getInstance() + .getLogger("org.onap.dmaap.datarouter.provisioning.PublishServlet"); + private static final Object lock = new Object(); + + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + next_node = 0; + provstring = ""; + irt = new ArrayList(); + + } + + @Override + public void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException { + setIpAndFqdnForEelf("doDelete"); + eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + ""); + redirect(req, resp); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + setIpAndFqdnForEelf("doGet"); + eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + ""); + redirect(req, resp); + } + + @Override + public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException { + setIpAndFqdnForEelf("doPut"); + eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF_AND_FEEDID, req.getHeader(BEHALF_HEADER), getIdFromPath(req) + ""); + redirect(req, resp); + } + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + setIpAndFqdnForEelf("doPost"); + eelflogger.info(EelfMsgs.MESSAGE_WITH_BEHALF, req.getHeader(BEHALF_HEADER)); + redirect(req, resp); + + } + + private void redirect(HttpServletRequest req, HttpServletResponse resp) { + try { + String[] nodes = getNodes(); + if (nodes == null || nodes.length == 0) { + resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, + "There are no nodes defined in the DR network."); + } else { + EventLogRecord elr = new EventLogRecord(req); + int feedid = checkPath(req); + if (feedid < 0) { + String message = (feedid == -1) + ? "Invalid request - Missing or bad feed number." + : "Invalid request - Missing file ID."; + elr.setMessage(message); + elr.setResult(HttpServletResponse.SC_NOT_FOUND); + eventlogger.info(elr); + + resp.sendError(HttpServletResponse.SC_NOT_FOUND, message); + } else { + // Generate new URL + String nextnode = getRedirectNode(feedid, req); + nextnode = nextnode + ":" + DB.getHttpsPort(); + String newurl = "https://" + nextnode + "/publish" + req.getPathInfo(); + String qs = req.getQueryString(); + if (qs != null) { + newurl += "?" + qs; + } + + // Log redirect in event log + String message = "Redirected to: " + newurl; + elr.setMessage(message); + elr.setResult(HttpServletResponse.SC_MOVED_PERMANENTLY); + eventlogger.info(elr); + + resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); + resp.setHeader("Location", newurl); + } + } + } catch (IOException ioe) { + intlogger.error("IOException" + ioe.getMessage()); + + } + } + + private String getRedirectNode(int feedid, HttpServletRequest req) { + // Check to see if the IRT needs to be updated + Poker p = Poker.getPoker(); + String s = p.getProvisioningString(); + synchronized (lock) { + if (irt == null || (s.length() != provstring.length()) || !s.equals(provstring)) { + // Provisioning string has changed -- update the IRT + provstring = s; + JSONObject jo = new JSONObject(new JSONTokener(provstring)); + JSONArray ja = jo.getJSONArray("ingress"); + List newlist = new ArrayList(); + for (int i = 0; i < ja.length(); i++) { + IngressRoute iroute = new IngressRoute(ja.getJSONObject(i)); + newlist.add(iroute); + } + irt = newlist; + } + } + + // Look in IRT for next node + for (IngressRoute route : irt) { + if (route.matches(feedid, req)) { + // pick a node at random from the list + Collection nodes = route.getNodes(); + String[] arr = nodes.toArray(new String[0]); + long id = System.currentTimeMillis() % arr.length; + String node = arr[(int) id]; + intlogger.info("Redirecting to " + node + " because of route " + route); + return node; + } + } + + // No IRT rule matches, do round robin of all active nodes + String[] nodes = getNodes(); + if (next_node >= nodes.length) // The list of nodes may have grown/shrunk + { + next_node = 0; + } + return nodes[next_node++]; + } + + private int checkPath(HttpServletRequest req) { + String path = req.getPathInfo(); + if (path == null || path.length() < 2) { + return -1; + } + path = path.substring(1); + int ix = path.indexOf('/'); + if (ix < 0 || ix == path.length() - 1) { + return -2; + } + try { + int feedid = Integer.parseInt(path.substring(0, ix)); + if (!Feed.isFeedValid(feedid)) { + return -1; + } + return feedid; + } catch (NumberFormatException e) { + return -1; + } + } +} diff --git a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DB.java b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DB.java index 7f0d56b7..1952f946 100644 --- a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DB.java +++ b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/DB.java @@ -24,12 +24,25 @@ package org.onap.dmaap.datarouter.provisioning.utils; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.NoSuchElementException; +import java.util.Properties; +import java.util.Queue; +import java.util.Set; import org.apache.log4j.Logger; -import java.io.*; -import java.sql.*; -import java.util.*; - /** * Load the DB JDBC driver, and manage a simple pool of connections to the DB. * @@ -38,7 +51,8 @@ import java.util.*; */ public class DB { - private static Logger intlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal"); + private static Logger intlogger = Logger + .getLogger("org.onap.dmaap.datarouter.provisioning.internal"); private static String DB_URL; private static String DB_LOGIN; @@ -46,12 +60,12 @@ public class DB { private static Properties props; private static final Queue queue = new LinkedList<>(); - public static String HTTPS_PORT; - public static String HTTP_PORT; + private static String HTTPS_PORT; + private static String HTTP_PORT; /** * Construct a DB object. If this is the very first creation of this object, it will load a copy of the properties - * for the server, and attempt to load the JDBC driver for the database. If a fatal error occurs (e.g. either the + * for the server, and attempt to load the JDBC driver for the database. If a fatal error occurs (e.g. either the * properties file or the DB driver is missing), the JVM will exit. */ public DB() { @@ -70,11 +84,9 @@ public class DB { Class.forName(DB_DRIVER); } catch (IOException e) { intlogger.fatal("PROV9003 Opening properties: " + e.getMessage()); - e.printStackTrace(); System.exit(1); } catch (ClassNotFoundException e) { intlogger.fatal("PROV9004 cannot find the DB driver: " + e); - e.printStackTrace(); System.exit(1); } } @@ -111,8 +123,7 @@ public class DB { if (++n >= 3) { throw sqlEx; } - } - finally { + } finally { if (connection != null && !connection.isValid(1)) { connection.close(); connection = null; @@ -151,6 +162,15 @@ public class DB { return retroFit1(); } + + public static String getHttpsPort() { + return HTTPS_PORT; + } + + public static String getHttpPort() { + return HTTP_PORT; + } + /** * Retrofit 1 - Make sure the expected tables are in DB and are initialized. Uses sql_init_01.sql to setup the DB. * @@ -175,7 +195,8 @@ public class DB { runInitScript(connection, 1); } } catch (SQLException e) { - intlogger.fatal("PROV9000: The database credentials are not working: " + e.getMessage()); + intlogger + .fatal("PROV9000: The database credentials are not working: " + e.getMessage()); return false; } finally { if (connection != null) { @@ -210,7 +231,8 @@ public class DB { /** * Initialize the tables by running the initialization scripts located in the directory specified by the property - * org.onap.dmaap.datarouter.provserver.dbscripts. Scripts have names of the form sql_init_NN.sql + * org.onap.dmaap.datarouter.provserver.dbscripts. Scripts have names of the form + * sql_init_NN.sql * * @param connection a DB connection * @param scriptId the number of the sql_init_NN.sql script to run -- 2.16.6