diff options
author | ChrisC <cc697w@intl.att.com> | 2017-01-31 11:40:03 +0100 |
---|---|---|
committer | ChrisC <cc697w@intl.att.com> | 2017-01-31 12:59:33 +0100 |
commit | 025301d08b061482c1f046d562bf017c8cbcfe8d (patch) | |
tree | 68a2a549736c9bf0f7cd4e71c76e40ef7e2606f2 /common/src/main/java/org/openecomp/mso/properties | |
parent | 2754ad52f833278a5c925bd788a16d1dce16a598 (diff) |
Initial OpenECOMP MSO commit
Change-Id: Ia6a7574859480717402cc2f22534d9973a78fa6d
Signed-off-by: ChrisC <cc697w@intl.att.com>
Diffstat (limited to 'common/src/main/java/org/openecomp/mso/properties')
7 files changed, 994 insertions, 0 deletions
diff --git a/common/src/main/java/org/openecomp/mso/properties/AbstractMsoProperties.java b/common/src/main/java/org/openecomp/mso/properties/AbstractMsoProperties.java new file mode 100644 index 0000000000..69d2f98324 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/properties/AbstractMsoProperties.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 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========================================================= + */ + +package org.openecomp.mso.properties; + + +import java.io.IOException; +import java.util.Properties; + +import org.openecomp.mso.logger.MsoLogger; + +public abstract class AbstractMsoProperties { + + public static final int DEFAULT_RELOAD_TIME_MIN=1; + + public static final String RELOAD_TIME_PROPERTY="mso.properties.reload.time.minutes"; + + protected static MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.GENERAL); + + protected String propertiesFileName; + + protected int automaticRefreshInMinutes=0; + + public String getPropertiesFileName() { + return propertiesFileName; + } + + public int getAutomaticRefreshInMinutes() { + return automaticRefreshInMinutes; + } + + protected synchronized void reloadPropertiesFile() throws IOException { + this.loadPropertiesFile(this.propertiesFileName); + } + + /** + * This method load a properties file from a source path. + * + * @param propertiesPath The path to the file + * @throws IOException In case of issues during the opening + */ + + protected abstract void loadPropertiesFile(String propertiesPath) throws IOException; + + @Override + protected abstract AbstractMsoProperties clone(); + + @Override + public abstract int hashCode(); + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract String toString(); + + +} diff --git a/common/src/main/java/org/openecomp/mso/properties/MsoJavaProperties.java b/common/src/main/java/org/openecomp/mso/properties/MsoJavaProperties.java new file mode 100644 index 0000000000..aa791f896e --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/properties/MsoJavaProperties.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 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========================================================= + */ + +package org.openecomp.mso.properties; + + +import java.io.FileReader; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Properties; +import org.openecomp.mso.utils.CryptoUtils; + +public class MsoJavaProperties extends AbstractMsoProperties { + + + private Properties msoProperties = new Properties(); + + + public MsoJavaProperties() { + + } + + public synchronized void setProperty(String key,String value) { + msoProperties.setProperty(key, value); + } + + public synchronized String getProperty(String key, String defaultValue) { + if (msoProperties.containsKey(key)) { + return msoProperties.getProperty(key); + } else { + return defaultValue; + } + } + + public synchronized int getIntProperty(String key, int defaultValue) { + + int value = defaultValue; + if (msoProperties.containsKey(key)) { + try { + value = Integer.parseInt(msoProperties.getProperty(key)); + } catch (NumberFormatException e) { + LOGGER.debug("Exception while parsing integer: " + msoProperties.getProperty(key), e); + } + } + return value; + + } + + public synchronized boolean getBooleanProperty(String key, boolean defaultValue) { + + if (msoProperties.containsKey(key)) { + return Boolean.parseBoolean(msoProperties.getProperty(key)); + } else { + return defaultValue; + } + + } + + public synchronized String getEncryptedProperty(String key, String defaultValue, String encryptionKey) { + + if (msoProperties.containsKey(key)) { + try { + return CryptoUtils.decrypt(msoProperties.getProperty(key), encryptionKey); + } catch (GeneralSecurityException e) { + LOGGER.debug("Exception while decrypting property: " + msoProperties.getProperty(key), e); + } + } + return defaultValue; + + } + + public synchronized int size() { + return this.msoProperties.size(); + } + + + @Override + protected synchronized void reloadPropertiesFile() throws IOException { + this.loadPropertiesFile(this.propertiesFileName); + } + + /** + * This method load a properties file from a source path. + * + * @param propertiesPath The path to the file + * @throws IOException In case of issues during the opening + */ + @Override + protected synchronized void loadPropertiesFile(String propertiesPath) throws IOException { + + FileReader reader = null; + + propertiesFileName = propertiesPath; + try { + msoProperties.clear(); + reader = new FileReader(propertiesPath); + msoProperties.load(reader); + + } finally { + this.automaticRefreshInMinutes = this.getIntProperty(RELOAD_TIME_PROPERTY, DEFAULT_RELOAD_TIME_MIN); + // Always close the file + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + LOGGER.debug("Exception while closing reader for file:" + propertiesPath, e); + } + } + } + + @Override + public synchronized MsoJavaProperties clone() { + MsoJavaProperties msoCopy = new MsoJavaProperties(); + msoCopy.msoProperties.putAll(msoProperties); + msoCopy.propertiesFileName = this.propertiesFileName; + msoCopy.automaticRefreshInMinutes = this.automaticRefreshInMinutes; + return msoCopy; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((msoProperties == null) ? 0 : msoProperties.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + MsoJavaProperties other = (MsoJavaProperties) obj; + if (!msoProperties.equals(other.msoProperties)) { + return false; + } + return true; + } + + @Override + public String toString() { + + StringBuffer response = new StringBuffer(); + response.append("Config file " + propertiesFileName + "(Timer:" + automaticRefreshInMinutes + "mins):" + + System.getProperty("line.separator")); + for (Object key : this.msoProperties.keySet()) { + String propertyName = (String) key; + response.append(propertyName); + response.append("="); + response.append(this.msoProperties.getProperty(propertyName)); + response.append(System.getProperty("line.separator")); + } + response.append(System.getProperty("line.separator")); + response.append(System.getProperty("line.separator")); + return response.toString(); + } +} diff --git a/common/src/main/java/org/openecomp/mso/properties/MsoJsonProperties.java b/common/src/main/java/org/openecomp/mso/properties/MsoJsonProperties.java new file mode 100644 index 0000000000..323c4dbe99 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/properties/MsoJsonProperties.java @@ -0,0 +1,172 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 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========================================================= + */ + +package org.openecomp.mso.properties; + + +import java.io.FileReader; +import java.io.IOException; +import java.security.GeneralSecurityException; + +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParseException; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.openecomp.mso.utils.CryptoUtils; + + +public class MsoJsonProperties extends AbstractMsoProperties { + + protected ObjectMapper mapper = new ObjectMapper(); + + protected JsonNode jsonRootNode = mapper.createObjectNode(); + + protected MsoJsonProperties() { + + } + + public synchronized JsonNode getJsonRootNode () { + return this.jsonRootNode; + } + + /** + * This method is used to get the text encrypted in the string value of the node. + * @param jsonNode The JsonNode containing the strig to decode + * @param defaultValue The default value in case of issue + * @param encryptionKey The encryption Key in AES 128 bits + * @return the String decrypted + */ + public synchronized String getEncryptedProperty(JsonNode jsonNode, String defaultValue, String encryptionKey) { + + if (jsonNode.isTextual()) { + try { + return CryptoUtils.decrypt(jsonNode.asText(), encryptionKey); + } catch (GeneralSecurityException e) { + LOGGER.debug("Exception while decrypting property: " + jsonNode.asText(), e); + } + } + + return defaultValue; + } + + /** + * This method load a properties file from a source path. + * + * @param propertiesPath The path to the file + * @throws IOException In case of issues during the opening + */ + @Override + protected synchronized void loadPropertiesFile(String propertiesPath) throws IOException { + + FileReader reader = null; + + this.propertiesFileName = propertiesPath; + + try { + // Clean + this.jsonRootNode = mapper.createObjectNode(); + + reader = new FileReader(propertiesPath); + + // Try a tree load + this.jsonRootNode = mapper.readValue(reader, JsonNode.class); + + + } finally { + JsonNode reloadJsonProp = this.jsonRootNode.get(RELOAD_TIME_PROPERTY); + if (reloadJsonProp != null) { + this.automaticRefreshInMinutes = reloadJsonProp.asInt(DEFAULT_RELOAD_TIME_MIN); + } else { + this.automaticRefreshInMinutes = DEFAULT_RELOAD_TIME_MIN; + } + + // Always close the file + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + LOGGER.debug("Exception while closing reader for file:" + propertiesFileName, e); + } + } + } + + @Override + public synchronized MsoJsonProperties clone() { + MsoJsonProperties msoCopy = new MsoJsonProperties(); + + ObjectMapper mapper = new ObjectMapper(); + try { + msoCopy.jsonRootNode = mapper.createObjectNode(); + msoCopy.jsonRootNode = mapper.readValue(this.jsonRootNode.toString(), JsonNode.class); + } catch (JsonParseException e) { + LOGGER.debug("JsonParseException when cloning the object:" + this.propertiesFileName, e); + } catch (JsonMappingException e) { + LOGGER.debug("JsonMappingException when cloning the object:" + this.propertiesFileName, e); + } catch (IOException e) { + LOGGER.debug("IOException when cloning the object:" + this.propertiesFileName, e); + } + + msoCopy.propertiesFileName = this.propertiesFileName; + msoCopy.automaticRefreshInMinutes = this.automaticRefreshInMinutes; + return msoCopy; + } + + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((jsonRootNode == null) ? 0 : jsonRootNode.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MsoJsonProperties other = (MsoJsonProperties) obj; + if (jsonRootNode == null) { + if (other.jsonRootNode != null) + return false; + } else if (!jsonRootNode.equals(other.jsonRootNode)) + return false; + return true; + } + + @Override + public String toString() { + StringBuffer response = new StringBuffer(); + response.append("Config file " + propertiesFileName + "(Timer:" + automaticRefreshInMinutes + "mins):" + + System.getProperty("line.separator")); + response.append(this.jsonRootNode.toString()); + response.append(System.getProperty("line.separator")); + response.append(System.getProperty("line.separator")); + return response.toString(); + + } + + +} diff --git a/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesException.java b/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesException.java new file mode 100644 index 0000000000..caf0ffad46 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesException.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 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========================================================= + */ + +package org.openecomp.mso.properties; + + +/** + * Exception during artifact installation. + */ +public class MsoPropertiesException extends Exception { + + /** + * serialization id. + */ + private static final long serialVersionUID = 4095937499475915021L; + + /** + * @param message The message to dump + * @param cause The Throwable cause object + */ + public MsoPropertiesException (final String message) { + super (message); + + } + + /** + * @param message The message to dump + * @param cause The Throwable cause object + */ + public MsoPropertiesException (final String message, final Throwable cause) { + super (message, cause); + + } +} diff --git a/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesFactory.java b/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesFactory.java new file mode 100644 index 0000000000..77676314bc --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesFactory.java @@ -0,0 +1,395 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 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========================================================= + */ + +package org.openecomp.mso.properties; + + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import javax.ejb.ConcurrencyManagement; +import javax.ejb.ConcurrencyManagementType; +import javax.ejb.LocalBean; +import javax.ejb.Schedule; +import javax.ejb.Singleton; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +import org.openecomp.mso.logger.MessageEnum; +import org.openecomp.mso.logger.MsoLogger; +import org.openecomp.mso.utils.CryptoUtils; + +/** + * This EJB Singleton class returns an instance of the mso properties for a specified file. + * This class can handle many config at the same time and is thread safe. + * This instance is a copy of the one cached so it can be modified or reloaded without impacting the others class using + * it. + * The mso properties files loaded and cached here will be reloaded every X second (it's configurable with the init + * method) + * This class can be used as an EJB or can be instantiated directly as long as the EJB has been initialized for the current + * module. Locks are made manually and not using EJB locks to allow this. + * + * + */ +@Singleton(name = "MsoPropertiesFactory") +@ConcurrencyManagement(ConcurrencyManagementType.BEAN) +@LocalBean +@Path("/properties") +public class MsoPropertiesFactory implements Serializable { + + private static final long serialVersionUID = 4365495305496742113L; + + protected static String prefixMsoPropertiesPath = System.getProperty ("mso.config.path"); + + private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.GENERAL); + + // Keep a static copy of properties for global usage + private static final ConcurrentHashMap <String, MsoPropertiesParameters> msoPropertiesCache; + + static { + if (prefixMsoPropertiesPath == null) { + // Hardcode if nothing is received + prefixMsoPropertiesPath = ""; + } + msoPropertiesCache = new ConcurrentHashMap <String, MsoPropertiesParameters> (); + } + + private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock (); + + public MsoPropertiesFactory () { + + } + + private boolean isJsonFile(String propertiesFilePath) { + return propertiesFilePath.endsWith(".json"); + } + + + private boolean isJavaPropertiesFile (String propertiesFilePath) { + return propertiesFilePath.endsWith(".properties"); + } + + private MsoPropertiesParameters createObjectType (MsoPropertiesParameters msoPropParams, String propertiesFilePath) throws MsoPropertiesException, IOException { + + try { + if (this.isJavaPropertiesFile(propertiesFilePath)) { + + msoPropParams.msoProperties = new MsoJavaProperties(); + msoPropParams.msoPropertiesType = MsoPropertiesParameters.MsoPropertiesType.JAVA_PROP; + } else if (this.isJsonFile(propertiesFilePath)) { + + msoPropParams.msoProperties = new MsoJsonProperties(); + msoPropParams.msoPropertiesType = MsoPropertiesParameters.MsoPropertiesType.JSON_PROP; + } else { + throw new MsoPropertiesException("Unable to load the MSO properties file because format is not recognized (only .json or .properties): " + propertiesFilePath); + } + + msoPropParams.msoProperties.loadPropertiesFile (propertiesFilePath); + + return msoPropParams; + } finally { + if (msoPropParams.msoProperties!=null) { + msoPropParams.refreshCounter = msoPropParams.msoProperties.getAutomaticRefreshInMinutes(); + } + } + + } + + /** + * This method is used to create a MsoProperties file cache and factory. + * The ID is kept in cache even if the config fails to be loaded. + * This is used to maintain the config ID until someone fixes the config file. + * + * @param msoPropertiesID A string representing the key of the config + * @param propertiesFilePath The mso properties file to load + * + * @throws MsoPropertiesException In case of issues with the mso properties loading + * + * @see MsoPropertiesFactory#getMsoJavaProperties() + * @see MsoPropertiesFactory#getMsoJsonProperties() + */ + public void initializeMsoProperties (String msoPropertiesID, + String propertiesFilePath) throws MsoPropertiesException { + + rwl.writeLock ().lock (); + + String msoPropPath="none"; + MsoPropertiesParameters msoPropertiesParams=new MsoPropertiesParameters(); + try { + msoPropPath = prefixMsoPropertiesPath + propertiesFilePath; + if (msoPropertiesCache.get (msoPropertiesID) != null) { + throw new MsoPropertiesException ("The factory contains already an instance of this mso properties: " + + msoPropPath); + } + // Create the global MsoProperties object + msoPropertiesParams = createObjectType(msoPropertiesParams, msoPropPath); + + } catch (FileNotFoundException e) { + throw new MsoPropertiesException ("Unable to load the MSO properties file because it has not been found:" + + msoPropPath, e); + + } catch (IOException e) { + throw new MsoPropertiesException ("Unable to load the MSO properties file because IOException occurs: " + + msoPropPath, e); + } finally { + // put it in all cases, just to not forget about him and attempt a default reload + msoPropertiesCache.put (msoPropertiesID, msoPropertiesParams); + rwl.writeLock ().unlock (); + } + } + + public void removeMsoProperties (String msoPropertiesID) throws MsoPropertiesException { + + rwl.writeLock ().lock (); + try { + if (MsoPropertiesFactory.msoPropertiesCache.remove (msoPropertiesID) == null) { + throw new MsoPropertiesException ("Mso properties not found in cache:" + msoPropertiesID); + } + } finally { + rwl.writeLock ().unlock (); + } + } + + /** + * This method clears all the configs in cache, the factory will then be free of any config. + * + * @see MsoPropertiesFactory#initializeMsoProperties(String, String) + */ + public void removeAllMsoProperties () { + + rwl.writeLock ().lock (); + try { + MsoPropertiesFactory.msoPropertiesCache.clear (); + } finally { + rwl.writeLock ().unlock (); + } + } + + /** + * THis method can be used to change the file and timer fields of an existing MSO properties file. + * + * @param msoPropertiesID The MSO properties ID + * @param newMsoPropPath The new file Path + * @throws MsoPropertiesException In case of the MSO Properties is not found in cache + */ + public void changeMsoPropertiesFilePath (String msoPropertiesID, + String newMsoPropPath) throws MsoPropertiesException { + + rwl.writeLock ().lock (); + try { + MsoPropertiesParameters msoPropInCache = MsoPropertiesFactory.msoPropertiesCache.get (msoPropertiesID); + + if (msoPropInCache != null) { + msoPropInCache.msoProperties.propertiesFileName = prefixMsoPropertiesPath + newMsoPropPath; + + } else { + throw new MsoPropertiesException ("Mso properties not found in cache:" + msoPropertiesID); + } + } finally { + rwl.writeLock ().unlock (); + } + } + + private AbstractMsoProperties getAndCloneProperties(String msoPropertiesID, MsoPropertiesParameters.MsoPropertiesType type) throws MsoPropertiesException { + rwl.readLock ().lock (); + try { + MsoPropertiesParameters msoPropInCache = MsoPropertiesFactory.msoPropertiesCache.get (msoPropertiesID); + if (msoPropInCache == null) { + throw new MsoPropertiesException ("Mso properties not found in cache:" + msoPropertiesID); + } else { + if (type.equals(msoPropInCache.msoPropertiesType)) { + return msoPropInCache.msoProperties.clone (); + } else { + throw new MsoPropertiesException ("Mso properties is not "+type.name()+" properties type:" + msoPropertiesID); + } + + } + } finally { + rwl.readLock ().unlock (); + } + } + + /** + * Get the MSO Properties (As Java Properties) as a copy of the mso properties cache. + * The object returned can therefore be modified. + * + * @return A copy of the mso properties, properties class can be empty if the file has not been read properly + * @throws MsoPropertiesException If the mso properties does not exist in the cache + */ + public MsoJavaProperties getMsoJavaProperties (String msoPropertiesID) throws MsoPropertiesException { + + return (MsoJavaProperties)getAndCloneProperties(msoPropertiesID,MsoPropertiesParameters.MsoPropertiesType.JAVA_PROP); + } + + /** + * Get the MSO Properties (As JSON Properties) as a copy of the mso properties cache. + * The object returned can therefore be modified. + * + * @return A copy of the mso properties, properties class can be empty if the file has not been read properly + * @throws MsoPropertiesException If the mso properties does not exist in the cache + */ + public MsoJsonProperties getMsoJsonProperties (String msoPropertiesID) throws MsoPropertiesException { + + return (MsoJsonProperties)getAndCloneProperties(msoPropertiesID,MsoPropertiesParameters.MsoPropertiesType.JSON_PROP); + } + + /** + * Get all MSO Properties as a copy of the mso properties cache. + * The objects returned can therefore be modified. + * + * @return A List of copies of the mso properties, can be empty + */ + public List <AbstractMsoProperties> getAllMsoProperties () { + + List <AbstractMsoProperties> resultList = new LinkedList <AbstractMsoProperties> (); + rwl.readLock ().lock (); + try { + + for (MsoPropertiesParameters msoProp:MsoPropertiesFactory.msoPropertiesCache.values ()) { + resultList.add(msoProp.msoProperties.clone()); + } + return resultList; + + } finally { + rwl.readLock ().unlock (); + } + + } + + /** + * This method is not intended to be called, it's used to refresh the config automatically + * + * @return true if Properties have been reloaded, false otherwise + */ + @Schedule(minute = "*/1", hour = "*", persistent = false) + public boolean reloadMsoProperties () { + AbstractMsoProperties msoPropInCache = null; + try { + if (!rwl.writeLock ().tryLock () && !rwl.writeLock ().tryLock (30L, TimeUnit.SECONDS)) { + LOGGER.debug ("Busy write lock on mso properties factory, skipping the reloading"); + return false; + } + } catch (InterruptedException e1) { + LOGGER.debug ("Interrupted while trying to acquire write lock on mso properties factory, skipping the reloading"); + Thread.currentThread ().interrupt (); + return false; + } + try { + for (Entry <String, MsoPropertiesParameters> entryMsoPropTimer : MsoPropertiesFactory.msoPropertiesCache.entrySet ()) { + + if (entryMsoPropTimer.getValue ().refreshCounter <= 1) { + // It's time to reload the config + msoPropInCache = MsoPropertiesFactory.msoPropertiesCache.get (entryMsoPropTimer.getKey ()).msoProperties; + try { + AbstractMsoProperties oldProps = msoPropInCache.clone (); + msoPropInCache.reloadPropertiesFile (); + entryMsoPropTimer.getValue().refreshCounter=entryMsoPropTimer.getValue().msoProperties.getAutomaticRefreshInMinutes(); + + if (!msoPropInCache.equals (oldProps)) { + LOGGER.info (MessageEnum.LOAD_PROPERTIES_SUC, msoPropInCache.getPropertiesFileName (), "", ""); + } + } catch (FileNotFoundException ef) { + LOGGER.error (MessageEnum.NO_PROPERTIES, msoPropInCache.propertiesFileName, "", "", MsoLogger.ErrorCode.PermissionError, "", ef); + } catch (Exception e) { + LOGGER.error (MessageEnum.LOAD_PROPERTIES_FAIL, msoPropInCache.propertiesFileName, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "", e); + } + + } else { + --entryMsoPropTimer.getValue().refreshCounter; + } + } + return true; + } catch (Exception e) { + LOGGER.error (MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. Global issue while reloading", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "", e); + return false; + } finally { + rwl.writeLock ().unlock (); + } + } + + /** + * This method can be used to known if the MSO properties instance hold is different from the one in cache + * + * @param msoPropertiesID The MSO properties ID + * @param oldMsoProperties The MSO Properties instance that must be compared to + * @return True if they are the same, false otherwise + * @throws MsoPropertiesException + */ + public boolean propertiesHaveChanged (String msoPropertiesID, AbstractMsoProperties oldMsoProperties) throws MsoPropertiesException { + rwl.readLock ().lock (); + try { + if (MsoPropertiesFactory.msoPropertiesCache.get (msoPropertiesID) == null) { + throw new MsoPropertiesException ("Mso properties not found in cache:" + msoPropertiesID); + } + + AbstractMsoProperties msoPropInCache = MsoPropertiesFactory.msoPropertiesCache.get (msoPropertiesID).msoProperties; + if (oldMsoProperties != null) { + return !oldMsoProperties.equals (msoPropInCache); + } else { + return msoPropInCache != null; + } + } finally { + rwl.readLock ().unlock (); + } + } + + @GET + @Path("/show") + @Produces("text/plain") + public Response showProperties () { + + List <AbstractMsoProperties> listMsoProp = this.getAllMsoProperties (); + StringBuffer response = new StringBuffer (); + + if (listMsoProp.isEmpty ()) { + response.append ("No file defined"); + } + + for (AbstractMsoProperties properties : listMsoProp) { + + response.append(properties.toString()); + } + + return Response.status (200).entity (response).build (); + } + + @GET + @Path("/encrypt/{value}/{cryptKey}") + @Produces("text/plain") + public Response encryptProperty (@PathParam("value") String value, @PathParam("cryptKey") String cryptKey) { + try { + String encryptedValue = CryptoUtils.encrypt (value, cryptKey); + return Response.status (200).entity (encryptedValue).build (); + } catch (Exception e) { + LOGGER.error (MessageEnum.GENERAL_EXCEPTION_ARG, "Encryption error", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Error in encrypting property", e); + return Response.status (500).entity (e.getMessage ()).build (); + } + } +} diff --git a/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesParameters.java b/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesParameters.java new file mode 100644 index 0000000000..358550a2bb --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/properties/MsoPropertiesParameters.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 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========================================================= + */ + +package org.openecomp.mso.properties; + + +public class MsoPropertiesParameters { + + protected enum MsoPropertiesType {JSON_PROP,JAVA_PROP}; + + protected MsoPropertiesType msoPropertiesType; + + protected int refreshCounter; + + protected AbstractMsoProperties msoProperties; +} diff --git a/common/src/main/java/org/openecomp/mso/properties/MsoPropertyInitializer.java b/common/src/main/java/org/openecomp/mso/properties/MsoPropertyInitializer.java new file mode 100644 index 0000000000..38e3ae3650 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/properties/MsoPropertyInitializer.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * OPENECOMP - MSO + * ================================================================================ + * Copyright (C) 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========================================================= + */ + +package org.openecomp.mso.properties; + + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +import org.openecomp.mso.logger.MessageEnum; +import org.openecomp.mso.logger.MsoLogger; + +/** + * This class will attempt to initialize MSO Properties when part of a web application. + * It will look for the configuration file mso.properties in the + * following order: + * 1. In an init-param "mso.configuration" in web.xml + * 2. In a system property "mso.configuration" + * 3. In the default location "/etc/ecomp/mso/config/mso.properties" + * + * If all else fails, the MSO Properties will go uninitialized, and will + * attempt to use the default constructors within the MsoProperties class. + * + * + */ +@WebListener +public class MsoPropertyInitializer implements ServletContextListener +{ + + private MsoPropertiesFactory msoPropertiesFactory=new MsoPropertiesFactory(); + + public MsoPropertyInitializer () { + } + + @Override + public void contextDestroyed(ServletContextEvent event) { + // Nothing to do... + } + + + @Override + public void contextInitialized(ServletContextEvent event) + { + + // Note - this logger may be before or after MSO Logging configuration applied + MsoLogger initLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.GENERAL); + try { + // Look first in the init-parameters + String msoPropConfigParam = event.getServletContext().getInitParameter("mso.configuration"); + if (msoPropConfigParam != null && !msoPropConfigParam.isEmpty() ) { + String[] configFileSplit = msoPropConfigParam.split(","); + for (String msoPropConfig:configFileSplit) { + String[] msoPropDecoded = msoPropConfig.split("="); + + try { + msoPropertiesFactory.initializeMsoProperties(msoPropDecoded[0], msoPropDecoded[1]); + initLogger.info(MessageEnum.LOAD_PROPERTIES_SUC, msoPropDecoded[1], "", ""); + initLogger.debug("Mso properties successfully loaded:"+msoPropDecoded[1]+",ID:"+msoPropDecoded[0]+")"); + } catch (MsoPropertiesException e) { + initLogger.error(MessageEnum.LOAD_PROPERTIES_FAIL, msoPropDecoded[1] + ". MSO Properties failed due to an mso properties exception", "", "", MsoLogger.ErrorCode.DataError, "Error in contextInitialized", e); + } + } + } + } + catch (Exception e) { + initLogger.error(MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. MSO Properties failed to initialize completely", "", "", MsoLogger.ErrorCode.DataError, "", e); + } + } +} |