maven improvements and clean up
[sdc.git] / common-app-api / src / main / java / org / openecomp / sdc / common / util / YamlToObjectConverter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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.sdc.common.util;
22
23 import org.apache.commons.codec.binary.Base64;
24 import org.openecomp.sdc.be.config.Configuration.*;
25 import org.openecomp.sdc.be.config.Configuration.ElasticSearchConfig.IndicesTimeFrequencyEntry;
26 import org.openecomp.sdc.be.config.DistributionEngineConfiguration;
27 import org.openecomp.sdc.be.config.DistributionEngineConfiguration.ComponentArtifactTypesConfig;
28 import org.openecomp.sdc.be.config.DistributionEngineConfiguration.CreateTopicConfig;
29 import org.openecomp.sdc.be.config.DistributionEngineConfiguration.DistributionNotificationTopicConfig;
30 import org.openecomp.sdc.be.config.DistributionEngineConfiguration.DistributionStatusTopicConfig;
31 import org.openecomp.sdc.be.config.validation.DeploymentArtifactHeatConfiguration;
32 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
33 import org.openecomp.sdc.common.log.wrappers.Logger;
34 import org.openecomp.sdc.fe.config.Configuration.FeMonitoringConfig;
35 import org.yaml.snakeyaml.TypeDescription;
36 import org.yaml.snakeyaml.Yaml;
37 import org.yaml.snakeyaml.error.YAMLException;
38 import org.yaml.snakeyaml.introspector.PropertyUtils;
39 import org.yaml.snakeyaml.nodes.Node;
40
41 import java.io.ByteArrayInputStream;
42 import java.io.File;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.nio.file.Files;
46 import java.nio.file.Paths;
47 import java.util.HashMap;
48 import java.util.Map;
49
50 public class YamlToObjectConverter {
51
52         private static Logger log = Logger.getLogger(YamlToObjectConverter.class.getName());
53
54         private static HashMap<String, Yaml> yamls = new HashMap<>();
55
56         private static Yaml defaultYaml = new Yaml();
57
58         static {
59
60                 org.yaml.snakeyaml.constructor.Constructor deConstructor = new org.yaml.snakeyaml.constructor.Constructor(
61                                 DistributionEngineConfiguration.class);
62                 TypeDescription deDescription = new TypeDescription(DistributionEngineConfiguration.class);
63                 deDescription.putListPropertyType("distributionStatusTopic", DistributionStatusTopicConfig.class);
64                 deDescription.putListPropertyType("distribNotifServiceArtifactTypes", ComponentArtifactTypesConfig.class);
65                 deDescription.putListPropertyType("distribNotifResourceArtifactTypes", ComponentArtifactTypesConfig.class);
66                 deDescription.putListPropertyType("createTopic", CreateTopicConfig.class);
67                 deDescription.putListPropertyType("distributionNotificationTopic", DistributionNotificationTopicConfig.class);
68                 deConstructor.addTypeDescription(deDescription);
69                 Yaml yaml = new Yaml(deConstructor);
70                 yamls.put(DistributionEngineConfiguration.class.getName(), yaml);
71
72                 // FE conf
73                 org.yaml.snakeyaml.constructor.Constructor feConfConstructor = new org.yaml.snakeyaml.constructor.Constructor(
74                                 org.openecomp.sdc.fe.config.Configuration.class);
75                 TypeDescription feConfDescription = new TypeDescription(org.openecomp.sdc.fe.config.Configuration.class);
76                 feConfDescription.putListPropertyType("systemMonitoring", FeMonitoringConfig.class);
77                 feConfConstructor.addTypeDescription(feConfDescription);
78                 yamls.put(org.openecomp.sdc.fe.config.Configuration.class.getName(), new Yaml(feConfConstructor));
79
80                 // BE conf
81                 org.yaml.snakeyaml.constructor.Constructor beConfConstructor = new org.yaml.snakeyaml.constructor.Constructor(
82                                 org.openecomp.sdc.be.config.Configuration.class);
83                 TypeDescription beConfDescription = new TypeDescription(org.openecomp.sdc.be.config.Configuration.class);
84                 beConfConstructor.addTypeDescription(beConfDescription);
85
86                 // systemMonitoring
87                 beConfDescription.putListPropertyType("systemMonitoring", BeMonitoringConfig.class);
88
89                 // elasticSearch
90                 beConfDescription.putListPropertyType("elasticSearch", ElasticSearchConfig.class);
91                 TypeDescription esDescription = new TypeDescription(ElasticSearchConfig.class);
92                 esDescription.putListPropertyType("indicesTimeFrequency", IndicesTimeFrequencyEntry.class);
93                 beConfConstructor.addTypeDescription(esDescription);
94
95                 // resourceDeploymentArtifacts and serviceDeploymentArtifacts
96                 beConfDescription.putMapPropertyType("resourceDeploymentArtifacts", String.class,
97                                 ArtifactTypeConfig.class);
98                 beConfDescription.putMapPropertyType("serviceDeploymentArtifacts", String.class,
99                                 ArtifactTypeConfig.class);
100
101                 // onboarding
102                 beConfDescription.putListPropertyType("onboarding", OnboardingConfig.class);
103
104                 // ecompPortal
105                 beConfDescription.putListPropertyType("ecompPortal", EcompPortalConfig.class);
106                 // switchoverDetector
107                 beConfDescription.putListPropertyType("switchoverDetector", SwitchoverDetectorConfig.class);
108
109                 // ApplicationL1Cache
110                 beConfDescription.putListPropertyType("applicationL1Cache", ApplicationL1CacheConfig.class);
111
112                 // ApplicationL2Cache
113                 beConfDescription.putListPropertyType("applicationL2Cache", ApplicationL2CacheConfig.class);
114
115                 // tosca validators config
116                 beConfDescription.putListPropertyType("toscaValidators", ToscaValidatorsConfig.class);
117
118                 yamls.put(org.openecomp.sdc.be.config.Configuration.class.getName(), new Yaml(beConfConstructor));
119
120                 // HEAT deployment artifact
121                 org.yaml.snakeyaml.constructor.Constructor depArtHeatConstructor = new org.yaml.snakeyaml.constructor.Constructor(
122                                 DeploymentArtifactHeatConfiguration.class);
123                 PropertyUtils propertyUtils = new PropertyUtils();
124                 // Skip properties which are found in YAML but not found in POJO
125                 propertyUtils.setSkipMissingProperties(true);
126                 depArtHeatConstructor.setPropertyUtils(propertyUtils);
127                 yamls.put(org.openecomp.sdc.be.config.validation.DeploymentArtifactHeatConfiguration.class.getName(),
128                                 new Yaml(depArtHeatConstructor));
129
130         }
131
132         private static <T> Yaml getYamlByClassName(Class<T> className) {
133
134                 Yaml yaml = yamls.get(className.getName());
135                 if (yaml == null) {
136                         yaml = defaultYaml;
137                 }
138
139                 return yaml;
140         }
141
142         public <T> T convert(String dirPath, Class<T> className, String configFileName) {
143
144                 T config = null;
145
146                 try {
147
148                         String fullFileName = dirPath + File.separator + configFileName;
149
150                         config = convert(fullFileName, className);
151
152                 } catch (Exception e) {
153                         log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"","","Failed to convert yaml file {} to object.", configFileName,e);
154                 }
155
156                 return config;
157         }
158
159         public class MyYamlConstructor extends org.yaml.snakeyaml.constructor.Constructor {
160                 private HashMap<String, Class<?>> classMap = new HashMap<>();
161
162                 public MyYamlConstructor(Class<? extends Object> theRoot) {
163                         super(theRoot);
164                         classMap.put(DistributionEngineConfiguration.class.getName(), DistributionEngineConfiguration.class);
165                         classMap.put(DistributionStatusTopicConfig.class.getName(), DistributionStatusTopicConfig.class);
166                 }
167
168                 /*
169                  * This is a modified version of the Constructor. Rather than using a
170                  * class loader to get external classes, they are already predefined
171                  * above. This approach works similar to the typeTags structure in the
172                  * original constructor, except that class information is pre-populated
173                  * during initialization rather than runtime.
174                  *
175                  * @see
176                  * org.yaml.snakeyaml.constructor.Constructor#getClassForNode(org.yaml.
177                  * snakeyaml.nodes.Node)
178                  */
179                 protected Class<?> getClassForNode(Node node) {
180                         String name = node.getTag().getClassName();
181                         Class<?> cl = classMap.get(name);
182                         if (cl == null)
183                                 throw new YAMLException("Class not found: " + name);
184                         else
185                                 return cl;
186                 }
187         }
188
189         public <T> T convert(String fullFileName, Class<T> className) {
190
191                 T config = null;
192
193                 Yaml yaml = getYamlByClassName(className);
194
195                 InputStream in = null;
196                 try {
197
198                         File f = new File(fullFileName);
199                         if (!f.exists()) {
200                                 log.warn(EcompLoggerErrorCode.UNKNOWN_ERROR,"","","The file {} cannot be found. Ignore reading configuration.",fullFileName);
201                                 return null;
202                         }
203                         in = Files.newInputStream(Paths.get(fullFileName));
204
205                         config = yaml.loadAs(in, className);
206
207                         // System.out.println(config.toString());
208                 } catch (Exception e) {
209                         log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"","","Failed to convert yaml file {} to object.", fullFileName, e);
210                 } finally {
211                         if (in != null) {
212                                 try {
213                                         in.close();
214                                 } catch (IOException e) {
215                                         log.debug("Failed to close input stream", e);
216                                 }
217                         }
218                 }
219
220                 return config;
221         }
222
223         public <T> T convert(byte[] fileContents, Class<T> className) {
224
225                 T config = null;
226
227                 Yaml yaml = getYamlByClassName(className);
228
229                 InputStream in = null;
230                 try {
231
232                         in = new ByteArrayInputStream(fileContents);
233
234                         config = yaml.loadAs(in, className);
235
236                 } catch (Exception e) {
237                         log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"","","Failed to convert yaml file to object", e);
238                 } finally {
239                         if (in != null) {
240                                 try {
241                                         in.close();
242                                 } catch (IOException e) {
243                                         log.debug("Failed to close input stream", e);
244                                 }
245                         }
246                 }
247
248                 return config;
249         }
250
251         public boolean isValidYamlEncoded64(byte[] fileContents) {
252                 log.trace("Received Base64 data - decoding before validating...");
253                 byte[] decodedFileContents = Base64.decodeBase64(fileContents);
254                 
255                 return isValidYaml(decodedFileContents);
256         }
257         @SuppressWarnings("unchecked")
258         public boolean isValidYaml(byte[] fileContents) {
259                 try {
260                         
261                         Iterable<Object> mappedToscaTemplateIt =  defaultYaml.loadAll(new ByteArrayInputStream(fileContents));
262                         
263                          for (Object o : mappedToscaTemplateIt) {
264                         System.out.println("Loaded object type:" + o.getClass());
265                         Map<String, Object> map = (Map<String, Object>) o;
266                          }
267                         
268                 } catch (Exception e) {
269                         log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"","","Failed to convert yaml file to object - yaml is invalid", e);
270                         return false;
271                 }
272                 return true;
273         }
274 }