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