/*- * ============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.cloud; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonRootName; import org.openecomp.mso.logger.MsoLogger; /** * JavaBean JSON class for a CloudConfig. This bean maps a JSON-format cloud * configuration file to Java. The CloudConfig contains information about * Openstack cloud configurations (in particular for the NVP/AIC cloud). * It includes: * - CloudIdentity objects, representing DCP nodes (Openstack Identity Service) * - CloudSite objects, representing LCP nodes (Openstack Compute & other services) * * Note that this is only used to access Cloud Configurations loaded from a * JSON config file, so there are no explicit property setters. * * This class also contains methods to query cloud sites and/or identity * services by ID. * */ @JsonRootName("cloud_config") public class CloudConfig { @JsonProperty("identity_services") private Map identityServices = new HashMap (); @JsonProperty("cloud_sites") private Map cloudSites = new HashMap (); private static ObjectMapper mapper = new ObjectMapper (); private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); protected String configFilePath; protected int refreshTimerInMinutes; public CloudConfig () { mapper.enable (DeserializationConfig.Feature.UNWRAP_ROOT_VALUE); mapper.enable (DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY); } /** * Get a Map of all IdentityServices that have been loaded. * @return the Map */ public synchronized Map getIdentityServices () { return identityServices; } /** * Get a Map of all CloudSites that have been loaded. * @return the Map */ public synchronized Map getCloudSites () { return cloudSites; } /** * Get a specific CloudSites, based on an ID. The ID is first checked against * the regions, and if no match is found there, then against individual entries * to try and find one with a CLLI that matches the ID and an AIC version of 2.5. * @param id the ID to match * @return a CloudSite, or null of no match found */ public synchronized CloudSite getCloudSite (String id) { if (id != null) { if (cloudSites.containsKey (id)) { return cloudSites.get (id); } // check for id == CLLI now as well return getCloudSiteWithClli(id, "2.5"); } return null; } /** * Get a specific CloudSites, based on a CLLI and (optional) version, which will be matched * against the aic_version field of the CloudSite. * @param clli the CLLI to match * @param version the version to match; may be null in which case any version matches * @return a CloudSite, or null of no match found */ public synchronized CloudSite getCloudSiteWithClli(String clli, String version) { if (clli != null) { // New with 1610 - find cloud site called "DEFAULT" - return that object, // with the name modified to match what they asked for. We're looping thru // the cloud sites anyway - so save off the default one in case we need it. CloudSite defaultCloudSite = null; for (CloudSite cs : cloudSites.values()) { if (cs.getClli() != null && clli.equals(cs.getClli())) { if (version == null || version.equals(cs.getAic_version())) { return cs; } } else if (cs.getId().equalsIgnoreCase("default")) { // save it off in case we need it defaultCloudSite = cs.clone(); } } // If we get here - we didn't find a match - so return the default cloud site if (defaultCloudSite != null) { defaultCloudSite.setRegionId(clli); defaultCloudSite.setId(clli); } return defaultCloudSite; } return null; } /** * Get a specific CloudIdentity, based on an ID. * @param id the ID to match * @return a CloudIdentity, or null of no match found */ public synchronized CloudIdentity getIdentityService (String id) { if (identityServices.containsKey (id)) { return identityServices.get (id); } return null; } protected synchronized void reloadPropertiesFile() throws JsonParseException, JsonMappingException, IOException { this.loadCloudConfig(this.configFilePath, this.refreshTimerInMinutes); } protected synchronized void loadCloudConfig (String configFile, int refreshTimer) throws JsonParseException, JsonMappingException, IOException { FileReader reader=null; configFilePath=configFile; this.refreshTimerInMinutes = refreshTimer; CloudConfig cloudConfig = null; try { reader = new FileReader (configFile); // Parse the JSON input into a CloudConfig cloudConfig = mapper.readValue (reader, CloudConfig.class); this.cloudSites = cloudConfig.cloudSites; this.identityServices = cloudConfig.identityServices; // Copy Cloud Identity IDs to CloudIdentity objects for (Entry entry : cloudConfig.getIdentityServices ().entrySet ()) { entry.getValue ().setId (entry.getKey ()); } // Copy Cloud Site IDs to CloudSite objects, and set up internal // pointers to their corresponding identity service. for (Entry entry : cloudConfig.getCloudSites ().entrySet ()) { CloudSite s = entry.getValue (); s.setId (entry.getKey ()); s.setIdentityService (cloudConfig.getIdentityService (s.getIdentityServiceId ())); } } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { LOGGER.debug("Exception while closing reader for file:" + configFilePath, e); } } } public String getConfigFilePath() { return configFilePath; } @Override public synchronized CloudConfig clone() { CloudConfig ccCopy = new CloudConfig(); for (Entry e:identityServices.entrySet()) { ccCopy.identityServices.put(e.getKey(), e.getValue().clone()); } for (Entry e:cloudSites.entrySet()) { ccCopy.cloudSites.put(e.getKey(), e.getValue().clone()); } ccCopy.configFilePath = this.configFilePath; ccCopy.refreshTimerInMinutes = this.refreshTimerInMinutes; return ccCopy; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cloudSites == null) ? 0 : cloudSites.hashCode()); result = prime * result + ((configFilePath == null) ? 0 : configFilePath.hashCode()); result = prime * result + ((identityServices == null) ? 0 : identityServices.hashCode()); result = prime * result + refreshTimerInMinutes; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; CloudConfig other = (CloudConfig) obj; if (cloudSites == null) { if (other.cloudSites != null) return false; } else if (!cloudSites.equals(other.cloudSites)) return false; if (configFilePath == null) { if (other.configFilePath != null) return false; } else if (!configFilePath.equals(other.configFilePath)) return false; if (identityServices == null) { if (other.identityServices != null) return false; } else if (!identityServices.equals(other.identityServices)) return false; if (refreshTimerInMinutes != other.refreshTimerInMinutes) return false; return true; } }