Change the header to SO
[so.git] / adapters / mso-adapter-utils / src / main / java / org / openecomp / mso / cloud / CloudConfig.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.mso.cloud;
22
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.Map.Entry;
28
29 import org.codehaus.jackson.JsonParseException;
30 import org.codehaus.jackson.annotate.JsonProperty;
31 import org.codehaus.jackson.map.DeserializationConfig;
32 import org.codehaus.jackson.map.JsonMappingException;
33 import org.codehaus.jackson.map.ObjectMapper;
34 import org.codehaus.jackson.map.annotate.JsonRootName;
35 import org.openecomp.mso.logger.MessageEnum;
36 import org.openecomp.mso.logger.MsoLogger;
37 import org.openecomp.mso.openstack.exceptions.MsoCloudIdentityNotFound;
38
39 /**
40  * JavaBean JSON class for a CloudConfig. This bean maps a JSON-format cloud
41  * configuration file to Java. The CloudConfig contains information about
42  * Openstack cloud configurations. It includes: 
43  * - CloudIdentity objects,representing DCP nodes (Openstack Identity Service) 
44  * - CloudSite objects, representing LCP nodes (Openstack Compute & other services)
45  *
46  * Note that this is only used to access Cloud Configurations loaded from a JSON
47  * config file, so there are no explicit property setters.
48  *
49  * This class also contains methods to query cloud sites and/or identity
50  * services by ID.
51  *
52  */
53
54 @JsonRootName("cloud_config")
55 public class CloudConfig {
56
57     private boolean                    validCloudConfig = false;
58     @JsonProperty("identity_services")
59     private Map<String, CloudIdentity> identityServices = new HashMap<String, CloudIdentity>();
60     @JsonProperty("cloud_sites")
61     private Map<String, CloudSite>     cloudSites       = new HashMap<String, CloudSite>();
62
63     private static ObjectMapper        mapper           = new ObjectMapper();
64
65     private static final MsoLogger     LOGGER           = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
66
67     protected String                   configFilePath;
68
69     protected int                      refreshTimerInMinutes;
70
71     public CloudConfig() {
72         mapper.enable(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE);
73         mapper.enable(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
74     }
75
76     /**
77      * Get a Map of all IdentityServices that have been loaded.
78      * 
79      * @return the Map
80      */
81     public synchronized Map<String, CloudIdentity> getIdentityServices() {
82         return identityServices;
83     }
84
85     /**
86      * Get a Map of all CloudSites that have been loaded.
87      * 
88      * @return the Map
89      */
90     public synchronized Map<String, CloudSite> getCloudSites() {
91         return cloudSites;
92     }
93
94     /**
95      * Get a specific CloudSites, based on an ID. The ID is first checked
96      * against the regions, and if no match is found there, then against
97      * individual entries to try and find one with a CLLI that matches the ID
98      * and an AIC version of 2.5.
99      * 
100      * @param id
101      *            the ID to match
102      * @return a CloudSite, or null of no match found
103      */
104     public synchronized CloudSite getCloudSite(String id) {
105         if (id != null) {
106             if (cloudSites.containsKey(id)) {
107                 return cloudSites.get(id);
108             }
109             // check for id == CLLI now as well
110             return getCloudSiteWithClli(id, "2.5");
111         }
112         return null;
113     }
114
115     /**
116      * Get a specific CloudSites, based on a CLLI and (optional) version, which
117      * will be matched against the aic_version field of the CloudSite.
118      * 
119      * @param clli
120      *            the CLLI to match
121      * @param version
122      *            the version to match; may be null in which case any version
123      *            matches
124      * @return a CloudSite, or null of no match found
125      */
126     public synchronized CloudSite getCloudSiteWithClli(String clli, String version) {
127         if (clli != null) {
128             // New with 1610 - find cloud site called "DEFAULT" - return that
129             // object,with the name modified to match what they asked for. We're
130             // looping thru the cloud sites anyway - so save off the default one in case we
131             // need it.
132             CloudSite defaultCloudSite = null;
133             for (CloudSite cs : cloudSites.values()) {
134                 if (cs.getClli() != null && clli.equals(cs.getClli())) {
135                     if (version == null || version.equals(cs.getAic_version())) {
136                         return cs;
137                     }
138                 } else if (cs.getId().equalsIgnoreCase("default")) {
139                     // save it off in case we need it
140                     defaultCloudSite = cs.clone();
141                 }
142             }
143             // If we get here - we didn't find a match - so return the default
144             // cloud site
145             if (defaultCloudSite != null) {
146                 defaultCloudSite.setRegionId(clli);
147                 defaultCloudSite.setId(clli);
148             }
149             return defaultCloudSite;
150         }
151         return null;
152     }
153
154     /**
155      * Get a specific CloudIdentity, based on an ID.
156      * 
157      * @param id
158      *            the ID to match
159      * @return a CloudIdentity, or null of no match found
160      */
161     public synchronized CloudIdentity getIdentityService(String id) {
162         if (identityServices.containsKey(id)) {
163             return identityServices.get(id);
164         }
165         return null;
166     }
167
168     protected synchronized void reloadPropertiesFile() throws JsonParseException, JsonMappingException, IOException, MsoCloudIdentityNotFound {
169         this.loadCloudConfig(this.configFilePath, this.refreshTimerInMinutes);
170     }
171
172     protected synchronized void loadCloudConfig(String configFile, int refreshTimer)
173             throws JsonParseException, JsonMappingException, IOException, MsoCloudIdentityNotFound {
174
175         FileReader reader = null;
176         configFilePath = configFile;
177         this.refreshTimerInMinutes = refreshTimer;
178
179         CloudConfig cloudConfig = null;
180         this.validCloudConfig=false;
181         
182         try {
183             reader = new FileReader(configFile);
184             // Parse the JSON input into a CloudConfig
185
186             cloudConfig = mapper.readValue(reader, CloudConfig.class);
187
188             this.cloudSites = cloudConfig.cloudSites;
189             this.identityServices = cloudConfig.identityServices;
190
191             // Copy Cloud Identity IDs to CloudIdentity objects
192             for (Entry<String, CloudIdentity> entry : cloudConfig.getIdentityServices().entrySet()) {
193                 entry.getValue().setId(entry.getKey());
194             }
195
196             // Copy Cloud Site IDs to CloudSite objects, and set up internal
197             // pointers to their corresponding identity service.
198             for (Entry<String, CloudSite> entry : cloudConfig.getCloudSites().entrySet()) {
199                 CloudSite s = entry.getValue();
200                 s.setId(entry.getKey());
201                 CloudIdentity cloudIdentity = cloudConfig.getIdentityService(s.getIdentityServiceId());
202                 s.setIdentityService(cloudIdentity);
203                 if (cloudIdentity == null) {
204                     throw new MsoCloudIdentityNotFound(s.getId()+" Cloud site refers to a non-existing identity service: "+s.getIdentityServiceId());
205                 }
206             }
207             this.validCloudConfig=true;
208             
209         } finally {
210             try {
211                 if (reader != null) {
212                     reader.close();
213                 }
214             } catch (IOException e) {
215                 LOGGER.debug("Exception while closing reader for file:" + configFilePath, e);
216             }
217         }
218     }
219
220     public String getConfigFilePath() {
221         return configFilePath;
222     }
223
224     /**
225      * @return the validCouldConfig
226      */
227     public synchronized boolean isValidCloudConfig() {
228         return validCloudConfig;
229     }
230
231     @Override
232     public synchronized CloudConfig clone() {
233         CloudConfig ccCopy = new CloudConfig();
234         for (Entry<String, CloudIdentity> e : identityServices.entrySet()) {
235
236             ccCopy.identityServices.put(e.getKey(), e.getValue().clone());
237         }
238
239         for (Entry<String, CloudSite> e : cloudSites.entrySet()) {
240
241             ccCopy.cloudSites.put(e.getKey(), e.getValue().clone());
242         }
243         ccCopy.configFilePath = this.configFilePath;
244         ccCopy.refreshTimerInMinutes = this.refreshTimerInMinutes;
245         ccCopy.validCloudConfig = this.validCloudConfig;
246         return ccCopy;
247     }
248
249     /* (non-Javadoc)
250      * @see java.lang.Object#hashCode()
251      */
252     @Override
253     public int hashCode() {
254         final int prime = 31;
255         int result = 1;
256         result = prime * result + ((cloudSites == null) ? 0 : cloudSites.hashCode());
257         result = prime * result + ((configFilePath == null) ? 0 : configFilePath.hashCode());
258         result = prime * result + ((identityServices == null) ? 0 : identityServices.hashCode());
259         result = prime * result + refreshTimerInMinutes;
260         result = prime * result + (validCloudConfig ? 1231 : 1237);
261         return result;
262     }
263
264     /* (non-Javadoc)
265      * @see java.lang.Object#equals(java.lang.Object)
266      */
267     @Override
268     public boolean equals(Object obj) {
269         if (this == obj)
270             return true;
271         if (obj == null)
272             return false;
273         if (getClass() != obj.getClass())
274             return false;
275         CloudConfig other = (CloudConfig) obj;
276         if (cloudSites == null) {
277             if (other.cloudSites != null)
278                 return false;
279         } else if (!cloudSites.equals(other.cloudSites))
280             return false;
281         if (configFilePath == null) {
282             if (other.configFilePath != null)
283                 return false;
284         } else if (!configFilePath.equals(other.configFilePath))
285             return false;
286         if (identityServices == null) {
287             if (other.identityServices != null)
288                 return false;
289         } else if (!identityServices.equals(other.identityServices))
290             return false;
291         if (refreshTimerInMinutes != other.refreshTimerInMinutes)
292             return false;
293         if (validCloudConfig != other.validCloudConfig)
294             return false;
295         return true;
296     }
297
298   
299 }