Update tosca parser for node template artifacts
[sdc/sdc-tosca.git] / sdc-tosca / src / main / java / org / onap / sdc / tosca / parser / impl / SdcToscaParserFactory.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * sdc-tosca
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 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.onap.sdc.tosca.parser.impl;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import org.onap.sdc.tosca.parser.api.ConformanceLevel;
26 import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
27 import org.onap.sdc.tosca.parser.config.ConfigurationManager;
28 import org.onap.sdc.tosca.parser.config.ErrorInfo;
29 import org.onap.sdc.tosca.parser.config.JToscaValidationIssueInfo;
30 import org.onap.sdc.tosca.parser.config.SdcToscaParserErrors;
31 import org.onap.sdc.tosca.parser.enums.JToscaValidationIssueType;
32 import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException;
33 import org.onap.sdc.tosca.parser.utils.GeneralUtility;
34 import org.onap.sdc.toscaparser.api.ToscaTemplate;
35 import org.onap.sdc.toscaparser.api.common.JToscaException;
36 import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
37 import org.onap.sdc.toscaparser.api.utils.JToscaErrorCodes;
38 import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 public class SdcToscaParserFactory {
43
44     private static Logger log = LoggerFactory.getLogger(SdcToscaParserFactory.class.getName());
45
46     private static ConfigurationManager configurationManager;
47     private static volatile SdcToscaParserFactory instance;
48     private List<JToscaValidationIssue> criticalExceptions = new ArrayList<>();
49     private List<JToscaValidationIssue> warningExceptions = new ArrayList<>();
50     private List<JToscaValidationIssue> notAnalyzadExceptions = new ArrayList<>();
51
52     private SdcToscaParserFactory() {
53     }
54
55     /**
56      * Get an SdcToscaParserFactory instance.
57      *
58      * @return SdcToscaParserFactory instance.
59      */
60     public static SdcToscaParserFactory getInstance() {
61         if (instance == null) {
62             synchronized (SdcToscaParserFactory.class) {
63                 if (instance == null) {
64                     instance = new SdcToscaParserFactory();
65                     configurationManager = ConfigurationManager.getInstance();
66                 }
67             }
68         }
69         return instance;
70     }
71
72     public static void setConfigurationManager(ConfigurationManager configurationManager) {
73         SdcToscaParserFactory.configurationManager = configurationManager;
74     }
75
76     /**
77      * Get an ISdcCsarHelper object for this CSAR file.
78      *
79      * @param csarPath - the absolute path to CSAR file.
80      * @return ISdcCsarHelper object.
81      * @throws SdcToscaParserException - in case the path or CSAR are invalid.
82      */
83     public ISdcCsarHelper getSdcCsarHelper(String csarPath) throws SdcToscaParserException {
84         return init(csarPath, true);
85     }
86
87     /**
88      * Get an ISdcCsarHelper object for this CSAR file.
89      *
90      * @param csarPath        - the absolute path to CSAR file.
91      * @param resolveGetInput - resolve get_input properties
92      * @return ISdcCsarHelper object.
93      * @throws SdcToscaParserException - in case the path or CSAR are invalid.
94      */
95     public ISdcCsarHelper getSdcCsarHelper(String csarPath, boolean resolveGetInput) throws SdcToscaParserException {
96         return init(csarPath, resolveGetInput);
97     }
98
99     private ISdcCsarHelper init(String csarPath, boolean resolveGetInput) throws SdcToscaParserException {
100         synchronized (SdcToscaParserFactory.class) {
101             ToscaTemplate tosca = null;
102             try {
103                 tosca = new ToscaTemplate(csarPath, null, true, null, resolveGetInput);
104             } catch (JToscaException e) {
105                 throwSdcToscaParserException(e);
106             }
107             SdcCsarHelperImpl sdcCsarHelperImpl = new SdcCsarHelperImpl(tosca, configurationManager);
108             String cSarConformanceLevel = sdcCsarHelperImpl.getConformanceLevel();
109             validateCsarVersion(cSarConformanceLevel);
110             try {
111                 handleErrorsByTypes(csarPath, cSarConformanceLevel);
112             } catch (JToscaException e) {
113                 throwSdcToscaParserException(e);
114             }
115             return sdcCsarHelperImpl;
116         }
117     }
118
119     private void handleErrorsByTypes(String csarPath, String cSarConformanceLevel) throws JToscaException {
120         clearValidationIssuesLists();
121         for (JToscaValidationIssue toscaValidationIssue : ThreadLocalsHolder.getCollector().getValidationIssues().values()) {
122             List<JToscaValidationIssueInfo> issueInfos = configurationManager.getJtoscaValidationIssueConfiguration().getValidationIssues()
123                 .get(toscaValidationIssue.getCode());
124             if (issueInfos != null && !issueInfos.isEmpty()) {
125                 final JToscaValidationIssueInfo issueInfo = issueInfos.stream()
126                     .filter(i -> isMatchConformanceLevel(cSarConformanceLevel, i.getSinceCsarConformanceLevel()))
127                     .max((i1, i2) -> GeneralUtility.conformanceLevelCompare(i1.getSinceCsarConformanceLevel(), i2.getSinceCsarConformanceLevel()))
128                     .orElse(null);
129
130                 if (issueInfo != null) {
131                     switch (JToscaValidationIssueType.valueOf(issueInfo.getIssueType())) {
132                         case CRITICAL:
133                             criticalExceptions.add(toscaValidationIssue);
134                             break;
135                         case WARNING:
136                             warningExceptions.add(toscaValidationIssue);
137                             break;
138                         default:
139                             break;
140                     }
141                 } else {
142                     notAnalyzadExceptions.add(toscaValidationIssue);
143                 }
144             } else {//notAnalyzed
145                 notAnalyzadExceptions.add(toscaValidationIssue);
146             }
147         }
148         logErrors(csarPath);
149     }
150
151     private void clearValidationIssuesLists() {
152         notAnalyzadExceptions.clear();
153         criticalExceptions.clear();
154         warningExceptions.clear();
155     }
156
157     private void logErrors(String inputPath) throws JToscaException {
158         //Warnings
159         int warningsCount = warningExceptions.size();
160         if (warningsCount > 0) {
161             log.warn("####################################################################################################");
162             log.warn("CSAR Warnings found! CSAR name - {}", inputPath);
163             log.warn("ToscaTemplate - verifyTemplate - {} Parsing Warning{} occurred...", warningsCount, (warningsCount > 1 ? "s" : ""));
164             for (JToscaValidationIssue info : warningExceptions) {
165                 log.warn("JTosca Exception [{}]: {}. CSAR name - {}", info.getCode(), info.getMessage(), inputPath);
166             }
167             log.warn("####################################################################################################");
168         }
169         //Criticals
170         int criticalsCount = criticalExceptions.size();
171         if (criticalsCount > 0) {
172             log.error("####################################################################################################");
173             log.error("ToscaTemplate - verifyTemplate - {} Parsing Critical{} occurred...", criticalsCount, (criticalsCount > 1 ? "s" : ""));
174             for (JToscaValidationIssue info : criticalExceptions) {
175                 log.error("JTosca Exception [{}]: {}. CSAR name - {}", info.getCode(), info.getMessage(), inputPath);
176             }
177             throw new JToscaException(String.format("CSAR Validation Failed. CSAR name - {}. Please check logs for details.", inputPath),
178                 JToscaErrorCodes.CSAR_TOSCA_VALIDATION_ERROR.getValue());
179         }
180     }
181
182     public List<JToscaValidationIssue> getCriticalExceptions() {
183         return criticalExceptions;
184     }
185
186     public List<JToscaValidationIssue> getWarningExceptions() {
187         return warningExceptions;
188     }
189
190     public List<JToscaValidationIssue> getNotAnalyzadExceptions() {
191         return notAnalyzadExceptions;
192     }
193
194
195     private void validateCsarVersion(String cSarVersion) throws SdcToscaParserException {
196         ConformanceLevel level = configurationManager.getConfiguration().getConformanceLevel();
197         String minVersion = level.getMinVersion();
198         if (cSarVersion != null) {
199             if (GeneralUtility.conformanceLevelCompare(cSarVersion, minVersion) < 0) {
200                 throwConformanceLevelException(minVersion);
201             }
202         } else {
203             throwConformanceLevelException(minVersion);
204         }
205     }
206
207     private boolean isMatchConformanceLevel(String ValidationIssueVersion, String cSarVersion) {
208         if (ValidationIssueVersion != null && cSarVersion != null) {
209             if ((GeneralUtility.conformanceLevelCompare(ValidationIssueVersion, cSarVersion) >= 0)) {
210                 return true;
211             }
212         }
213         return false;
214     }
215
216     private void throwConformanceLevelException(String minVersion) throws SdcToscaParserException {
217         ErrorInfo errorInfo = configurationManager.getErrorConfiguration().getErrorInfo(SdcToscaParserErrors.CONFORMANCE_LEVEL_ERROR.toString());
218         throw new SdcToscaParserException(String.format(errorInfo.getMessage(), minVersion), errorInfo.getCode());
219     }
220
221     private void throwSdcToscaParserException(JToscaException e) throws SdcToscaParserException {
222         ErrorInfo errorInfo = configurationManager.getErrorConfiguration()
223             .getErrorInfo(SdcToscaParserErrors.getSdcErrorByJToscaError(JToscaErrorCodes.getByCode(e.getCode())).toString());
224         throw new SdcToscaParserException(errorInfo.getMessage(), errorInfo.getCode());
225     }
226
227
228 }