From e0194fbb1f8291ca0c23cc68840097b8d33670e5 Mon Sep 17 00:00:00 2001 From: koblosz Date: Tue, 22 May 2018 17:13:35 +0200 Subject: Refactor DmaapPropertyReader Issue-ID: DCAEGEN2-522 Signed-off-by: KOBLOSZ SANDRA Change-Id: I2d9928ff3ffeda0e204480f13e8c8bf91bddf912 --- .../java/org/onap/dcae/commonFunction/AnyNode.java | 188 +++++++++++++ .../commonFunction/CambriaPublisherFactory.java | 19 +- .../dcae/commonFunction/DmaapPropertyReader.java | 302 ++++++++------------- 3 files changed, 306 insertions(+), 203 deletions(-) create mode 100644 src/main/java/org/onap/dcae/commonFunction/AnyNode.java (limited to 'src/main/java/org/onap/dcae/commonFunction') diff --git a/src/main/java/org/onap/dcae/commonFunction/AnyNode.java b/src/main/java/org/onap/dcae/commonFunction/AnyNode.java new file mode 100644 index 00000000..b09a17a0 --- /dev/null +++ b/src/main/java/org/onap/dcae/commonFunction/AnyNode.java @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2018 Nokia Networks 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========================================================= + */ +package org.onap.dcae.commonFunction; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** + * This class is a wrapper for 2 most used entities of org.json lib: JSONArray and JSONObject and + * comprises utility methods for fast access of json structures without need to explicitly coerce between them. + * While using this, bear in mind it does not contain exception handling - it is assumed that when using, the parsed json structure is known. + * + * @author koblosz + */ +public class AnyNode { + private static final Logger LOGGER = LoggerFactory.getLogger(AnyNode.class); + private Object obj; + + /** + * @param filePath + * @return + * @throws IOException + */ + public static AnyNode parse(String filePath) throws IOException { + try (FileReader fr = new FileReader(filePath)) { + JSONTokener tokener = new JSONTokener(fr); + return new AnyNode(new JSONObject(tokener)); + } catch (FileNotFoundException | JSONException e1) { + LOGGER.error("Could not find or parse file under path %s due to: %s", filePath, e1.toString()); + e1.printStackTrace(); + throw e1; + } + } + + /** + * Returns keyset of underlying object. It is assumed that underlying object is of type org.json.JSONObject. + * + * @return Set of string keys present in underlying JSONObject + */ + public Set getKeys() { + return asJsonObject().keySet(); + } + + /** + * Returns value associated with specified key wrapped with AnyValue object. It is assumed that this is of type org.json.JSONObject. + * + * @param key A key string + * @return The AnyNode object associated with given key. + */ + public AnyNode get(String key) { + return new AnyNode(asJsonObject().get(key)); + } + + /** + * Returns value under specified index wrapped with AnyValue object. It is assumed that this is of type org.json.JSONArray. + * + * @param idx An index of JSONArray + * @return The AnyNode object associated with given index. + */ + public AnyNode get(int idx) { + return new AnyNode(asJsonArray().get(idx)); + } + + /** + * Returns int assuming this can be coerced to int. + */ + public int asInt() { + return (int) this.obj; + } + + /** + * Returns string representation of this. If it happens to have null, the value is treated as org.json.JSONObject.NULL and "null" string is returned then. + * + * @return A String + */ + public String asString() { + return this.obj != JSONObject.NULL ? (String) this.obj : JSONObject.NULL.toString(); + } + + public String toString() { + return this.obj.toString(); + } + + /** + * Converts underlying object to String-to-Object map. It is assumed that underlying object is of type org.json.JSONObject. + * + * @return A map. + */ + public Map asRawMap() { + return asJsonObject().toMap(); + } + + /** + * Returns optional of object under specified key, wrapped with AnyNode object. If underlying object is not of type org.json.JSONObject, then Optional.empty will be returned. + * + * @param key A key string + */ + public Optional getAsOptional(String key) { + AnyNode result = null; + try { + result = get(key); + } catch (JSONException ex) { + } + return Optional.ofNullable(result); + } + + public JSONObject asJsonObject() { + return (JSONObject) this.obj; + } + + /** + * Converts underlying object to map representation with map values wrapped with AnyNode object. It is assumed that underlying object is of type org.json.JSONObject. + */ + public Map asMap() { + Map map = new HashMap<>(); + getKeys().forEach(key -> map.put(key, get(key))); + return map; + } + + /** + * Converts underlying object to map representation with map values wrapped with AnyNode object. It is assumed that underlying object is of type org.json.JSONObject. + */ + public java.util.List asList() { + return asStream().collect(Collectors.toList()); + } + + /** + * Converts this object to stream of underlying objects wrapped with AnyNode class. It is assumed that this is of type JSONArray. + */ + public Stream asStream() { + return StreamSupport.stream(((JSONArray) this.obj).spliterator(), false).map(AnyNode::new); + } + + /** + * Checks if specified key is present in this. It is assumed that this is of type JSONObject. + */ + public boolean hasKey(String key) { + return getAsOptional(key).isPresent(); + } + + /** + * Returns empty AnyNode (with null inside) + */ + public static AnyNode nullValue() { + return new AnyNode(JSONObject.NULL.toString()); + } + + private JSONArray asJsonArray() { + return (JSONArray) this.obj; + } + + private AnyNode(Object object) { + this.obj = object; + } + +} diff --git a/src/main/java/org/onap/dcae/commonFunction/CambriaPublisherFactory.java b/src/main/java/org/onap/dcae/commonFunction/CambriaPublisherFactory.java index 35d3e317..41230a14 100644 --- a/src/main/java/org/onap/dcae/commonFunction/CambriaPublisherFactory.java +++ b/src/main/java/org/onap/dcae/commonFunction/CambriaPublisherFactory.java @@ -23,6 +23,8 @@ import com.att.nsa.cambria.client.CambriaBatchingPublisher; import com.att.nsa.cambria.client.CambriaClientBuilders; import java.net.MalformedURLException; import java.security.GeneralSecurityException; +import java.util.Map; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,21 +35,18 @@ class CambriaPublisherFactory { public CambriaBatchingPublisher createCambriaPublisher(String streamId) throws MalformedURLException, GeneralSecurityException { String authpwd = null; - String ueburl = DmaapPropertyReader.getInstance(CommonStartup.cambriaConfigFile).dmaap_hash - .get(streamId + ".cambria.url"); + DmaapPropertyReader reader = DmaapPropertyReader.getInstance(CommonStartup.cambriaConfigFile); + Map dmaapProperties = reader.getDmaapProperties(); + String ueburl = dmaapProperties.get(streamId + ".cambria.url"); if (ueburl == null) { - ueburl = DmaapPropertyReader.getInstance(CommonStartup.cambriaConfigFile).dmaap_hash - .get(streamId + ".cambria.hosts"); + ueburl = dmaapProperties.get(streamId + ".cambria.hosts"); } - String topic = DmaapPropertyReader.getInstance(CommonStartup.cambriaConfigFile) - .getKeyValue(streamId + ".cambria.topic"); - String authuser = DmaapPropertyReader.getInstance(CommonStartup.cambriaConfigFile) - .getKeyValue(streamId + ".basicAuthUsername"); + String topic = reader.getKeyValue(streamId + ".cambria.topic"); + String authuser = reader.getKeyValue(streamId + ".basicAuthUsername"); if (authuser != null) { - authpwd = DmaapPropertyReader.getInstance(CommonStartup.cambriaConfigFile).dmaap_hash - .get(streamId + ".basicAuthPassword"); + authpwd = dmaapProperties.get(streamId + ".basicAuthPassword"); } if ((authuser != null) && (authpwd != null)) { diff --git a/src/main/java/org/onap/dcae/commonFunction/DmaapPropertyReader.java b/src/main/java/org/onap/dcae/commonFunction/DmaapPropertyReader.java index dabd2b15..c0659aa6 100644 --- a/src/main/java/org/onap/dcae/commonFunction/DmaapPropertyReader.java +++ b/src/main/java/org/onap/dcae/commonFunction/DmaapPropertyReader.java @@ -20,204 +20,120 @@ package org.onap.dcae.commonFunction; -import java.io.FileNotFoundException; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.FileReader; + import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Set; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonIOException; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; +import java.util.Objects; +import java.util.stream.Collectors; public class DmaapPropertyReader { - private static final String HOST_URL = " HOST-URL:"; - private static final String TOPIC = "TOPIC:"; - private static final String CAMBRIA_URL = "cambria.url"; - private static final String CAMBRIA_HOSTS = "cambria.hosts"; - private static final String PWD = " PWD:"; - private static final String USER = " USER:"; - private static final String BASIC_AUTH_PASSWORD = "basicAuthPassword"; - private static final String BASIC_AUTH_USER_NAME = "basicAuthUsername"; - private static DmaapPropertyReader instance = null; - - private static final Logger log = LoggerFactory.getLogger(DmaapPropertyReader.class); - - public HashMap dmaap_hash = new HashMap<>(); - - public DmaapPropertyReader(String CambriaConfigFile) { - - FileReader fr = null; - try { - JsonElement root = null; - fr = new FileReader(CambriaConfigFile); - root = new JsonParser().parse(fr); - - // Check if dmaap config is handled by legacy controller/service - // manager - if (root.getAsJsonObject().has("channels")) { - JsonArray jsonObject = (JsonArray) root.getAsJsonObject().get("channels"); - - for (int i = 0; i < jsonObject.size(); i++) { - log.debug(TOPIC + jsonObject.get(i).getAsJsonObject().get("cambria.topic") + HOST_URL - + jsonObject.get(i).getAsJsonObject().get(CAMBRIA_URL) + " HOSTS:" - + jsonObject.get(i).getAsJsonObject().get(CAMBRIA_HOSTS) + PWD - + jsonObject.get(i).getAsJsonObject().get(BASIC_AUTH_PASSWORD) + USER - + jsonObject.get(i).getAsJsonObject().get(BASIC_AUTH_USER_NAME) + " NAME:" - + jsonObject.get(i).getAsJsonObject().get("name")); - - String convertedname = jsonObject.get(i).getAsJsonObject().get("name").toString().replace("\"", ""); - dmaap_hash.put(convertedname + ".cambria.topic", - jsonObject.get(i).getAsJsonObject().get("cambria.topic").toString().replace("\"", "")); - - if (jsonObject.get(i).getAsJsonObject().get(CAMBRIA_HOSTS) != null) { - dmaap_hash.put(convertedname + ".cambria.hosts", - jsonObject.get(i).getAsJsonObject().get(CAMBRIA_HOSTS).toString().replace("\"", "")); - } - if (jsonObject.get(i).getAsJsonObject().get(CAMBRIA_URL) != null) { - dmaap_hash.put(convertedname + ".cambria.url", - jsonObject.get(i).getAsJsonObject().get(CAMBRIA_URL).toString().replace("\"", "")); - } - if (jsonObject.get(i).getAsJsonObject().get(BASIC_AUTH_PASSWORD) != null) { - dmaap_hash.put(convertedname + ".basicAuthPassword", jsonObject.get(i).getAsJsonObject() - .get(BASIC_AUTH_PASSWORD).toString().replace("\"", "")); - } - if (jsonObject.get(i).getAsJsonObject().get(BASIC_AUTH_USER_NAME) != null) { - dmaap_hash.put(convertedname + ".basicAuthUsername", jsonObject.get(i).getAsJsonObject() - .get(BASIC_AUTH_USER_NAME).toString().replace("\"", "")); - } - - } - } else { - - // Handing new format from controllergen2/config_binding_service - JsonObject jsonObject = root.getAsJsonObject(); - Set> entries = jsonObject.entrySet(); - - for (Map.Entry entry : entries) { - - JsonElement topicurl = entry.getValue().getAsJsonObject().get("dmaap_info").getAsJsonObject() - .get("topic_url"); - String[] urlParts = dmaapUrlSplit(topicurl.toString().replace("\"", "")); - - String mrTopic = null; - String mrUrl = null; - String[] hostport = null; - String username = null; - String userpwd = null; - - try { - - if (null != urlParts) { - mrUrl = urlParts[2]; - - // DCAE internal dmaap topic convention - if ("events".equals(urlParts[3])) { - mrTopic = urlParts[4]; - } else { - // ONAP dmaap topic convention - mrTopic = urlParts[3]; - hostport = mrUrl.split(":"); - } - - } - } catch (NullPointerException e) { - System.out.println("NullPointerException"); - e.getMessage(); - } - - if (entry.getValue().getAsJsonObject().has("aaf_username")) { - username = entry.getValue().getAsJsonObject().get("aaf_username").toString().replace("\"", ""); - } - if (entry.getValue().getAsJsonObject().has("aaf_password")) { - userpwd = entry.getValue().getAsJsonObject().get("aaf_password").toString().replace("\"", ""); - } - if (hostport == null) { - log.debug(TOPIC + mrTopic + HOST_URL + mrUrl + PWD + userpwd + USER + username); - } else { - log.debug(TOPIC + mrTopic + HOST_URL + mrUrl + " HOSTS:" + hostport[0] + PWD - + userpwd + USER + username + " NAME:" + entry.getKey()); - } - - dmaap_hash.put(entry.getKey() + ".cambria.topic", mrTopic); - - if (!(hostport == null)) { - dmaap_hash.put(entry.getKey() + ".cambria.hosts", hostport[0]); - } - - if (!(mrUrl == null)) { - dmaap_hash.put(entry.getKey() + ".cambria.url", mrUrl); - } - - if (!(username == null)) { - dmaap_hash.put(entry.getKey() + ".basicAuthUsername", username); - } - - if (!(userpwd == null)) { - dmaap_hash.put(entry.getKey() + ".basicAuthPassword", userpwd); - } - - } - - } - - } catch (JsonIOException | JsonSyntaxException | - - FileNotFoundException e1) { - e1.printStackTrace(); - log.error("Problem loading Dmaap Channel configuration file: " + e1.toString()); - } finally { - if (fr != null) { - try { - fr.close(); - } catch (IOException e) { - log.error("Error closing file reader stream : " + e.toString()); - } - } - } - - } - - /*** - * Dmaap url structure pub - https://:/events/ - * .., sub - https://: - * /events/../G1/u1"; - * - * Onap url structure pub - http://:/. - * , - */ - - private String[] dmaapUrlSplit(String dmUrl) { - String[] multUrls = dmUrl.split(","); - - StringBuffer newUrls = new StringBuffer(); - String[] urlParts = null; - for (int i = 0; i < multUrls.length; i++) { - urlParts = multUrls[i].split("/"); - if (i == 0) { - newUrls = newUrls.append(urlParts[2]); - } else { - newUrls = newUrls.append(",").append(urlParts[2]); - } - } - return urlParts; - } - - public static synchronized DmaapPropertyReader getInstance(String channelConfig) { - if (instance == null) { - instance = new DmaapPropertyReader(channelConfig); - } - return instance; - } - - public String getKeyValue(String hashKey) { - return this.dmaap_hash.get(hashKey); - } -} + + private static final Logger log = LoggerFactory.getLogger(DmaapPropertyReader.class); + private static final String CAMBRIA_TOPIC_KEY = "cambria.topic"; + private static final String CAMBRIA_HOSTS_KEY = "cambria.hosts"; + private static final String CAMBRIA_URL_KEY = "cambria.url"; + private static final List LEGACY_CHANNEL_MANDATORY_PARAMS = Lists.newArrayList(CAMBRIA_TOPIC_KEY, CAMBRIA_HOSTS_KEY, CAMBRIA_URL_KEY, "basicAuthPassword", "basicAuthUsername"); + private static DmaapPropertyReader instance = null; + private final Map dmaapProperties; + + public DmaapPropertyReader(String cambriaConfigFilePath) { + this.dmaapProperties = DmaapPropertyReader.getProcessedDmaapProperties(cambriaConfigFilePath); + } + + public Map getDmaapProperties() { + return dmaapProperties; + } + + public static synchronized DmaapPropertyReader getInstance(String channelConfig) { + if (instance == null) { + instance = new DmaapPropertyReader(channelConfig); + } + return instance; + } + + public String getKeyValue(String hashKey) { + return dmaapProperties.get(hashKey); + } + + private static Map getProcessedDmaapProperties(String configFilePath) { + Map transformedDmaapProperties = new HashMap<>(); + try { + AnyNode root = AnyNode.parse(configFilePath); + if (root.hasKey("channels")) { // Check if dmaap config is handled by legacy controller/service/manager + transformedDmaapProperties = getLegacyDmaapPropertiesWithChannels(root.get("channels")); + } else {//Handing new format from controllergen2/config_binding_service + transformedDmaapProperties = getDmaapPropertiesWithInfoData(root); + } + } catch (IOException e) { + e.printStackTrace(); + } + return transformedDmaapProperties; + } + + private static Map getLegacyDmaapPropertiesWithChannels(AnyNode channelsNode) { + return channelsNode.asList().stream() + .map(DmaapPropertyReader::getTransformedMandatoryChannelProperties) + .flatMap(m -> m.entrySet().stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + private static Map getTransformedMandatoryChannelProperties(AnyNode channel) { + String prefix = channel.get("name").asString() + "."; + return channel.asMap().entrySet().stream().filter(el -> LEGACY_CHANNEL_MANDATORY_PARAMS.contains(el.getKey()) && !Objects.equals(el.getKey(), "name")) + .collect(Collectors.toMap(k -> prefix + k.getKey(), v -> v.getValue().asString().replace("\"", ""))); + } + + private static Map getDmaapPropertiesWithInfoData(AnyNode root) { + return root.asMap().entrySet().stream() + .map(DmaapPropertyReader::getTransformedMandatoryInfoProperties).flatMap(m -> m.entrySet().stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + private static Map getTransformedMandatoryInfoProperties(Map.Entry el) { + String prefix = el.getKey() + "."; + AnyNode val = el.getValue(); + Map map = Maps.newHashMap(); + map.put(prefix + "basicAuthUsername", val.getAsOptional("aaf_username").orElse(AnyNode.nullValue()).asString().replace("\"", "")); + map.put(prefix + "basicAuthPassword", val.getAsOptional("aaf_password").orElse(AnyNode.nullValue()).asString().replace("\"", "")); + map.putAll(getParamsFromDmaapInfoTopicUrl(prefix, val.get("dmaap_info").get("topic_url").asString().replace("\"", ""))); + return map; + } + + /*** + * Dmaap url structure pub - https://:/events/ + * .., sub - https://: + * /events/../G1/u1"; + * + * Onap url structure pub - http://:/. + * , + */ + private static Map getParamsFromDmaapInfoTopicUrl(String keyPrefix, String topicUrl) { + Map topicUrlParts = Maps.newHashMap(); + try { + URL url = new URL(topicUrl); + topicUrlParts.put(keyPrefix + CAMBRIA_URL_KEY, url.getAuthority()); + String[] pathParts = url.getPath().split("/"); + if (pathParts.length > 2 && "events".equals(pathParts[1])) { + // DCAE internal dmaap topic convention + topicUrlParts.put(keyPrefix + CAMBRIA_TOPIC_KEY, pathParts[2]); + } else { + // ONAP dmaap topic convention + topicUrlParts.put(keyPrefix + CAMBRIA_TOPIC_KEY, pathParts[2]); + topicUrlParts.put(keyPrefix + CAMBRIA_HOSTS_KEY, url.getHost()); + } + } catch (MalformedURLException e) { + log.error("Invalid URL found under topic_url key!", e); + e.printStackTrace(); + } + return topicUrlParts; + } +} \ No newline at end of file -- cgit 1.2.3-korg