Reduce the number of problems in schema-service
[aai/schema-service.git] / aai-schema-gen / src / main / java / org / onap / aai / schemagen / GenerateXsd.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 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.aai.schemagen;
22
23 import java.io.BufferedWriter;
24 import java.io.File;
25 import java.io.IOException;
26 import java.nio.charset.Charset;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30 import java.nio.file.Paths;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36
37 import org.onap.aai.schemagen.genxsd.HTMLfromOXM;
38 import org.onap.aai.schemagen.genxsd.NodesYAMLfromOXM;
39 import org.onap.aai.schemagen.genxsd.YAMLfromOXM;
40 import org.onap.aai.setup.SchemaVersion;
41 import org.onap.aai.setup.SchemaVersions;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.beans.BeansException;
45 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
46 import org.w3c.dom.NodeList;
47
48 public class GenerateXsd {
49
50     private static final Logger logger = LoggerFactory.getLogger(GenerateXsd.class);
51     protected static String apiVersion = null;
52     public static AnnotationConfigApplicationContext ctx = null;
53     static String apiVersionFmt = null;
54     static boolean useAnnotationsInXsd = false;
55     static String responsesUrl = null;
56     static String responsesLabel = null;
57     static String jsonEdges = null;
58     static Map<String, String> generatedJavaType;
59     static Map<String, String> appliedPaths;
60     static String RELEASE = System.getProperty("aai.release", "onap");
61
62     static NodeList javaTypeNodes;
63     static Map<String, String> javaTypeDefinitions = createJavaTypeDefinitions();
64
65     private static Map<String, String> createJavaTypeDefinitions() {
66         StringBuilder aaiInternal = new StringBuilder();
67         Map<String, String> javaTypeDefinitions = new HashMap<String, String>();
68         aaiInternal.append("  aai-internal:\n");
69         aaiInternal.append("    properties:\n");
70         aaiInternal.append("      property-name:\n");
71         aaiInternal.append("        type: string\n");
72         aaiInternal.append("      property-value:\n");
73         aaiInternal.append("        type: string\n");
74         // javaTypeDefinitions.put("aai-internal", aaiInternal.toString());
75         return javaTypeDefinitions;
76     }
77
78     public static final int VALUE_NONE = 0;
79     public static final int VALUE_DESCRIPTION = 1;
80     public static final int VALUE_INDEXED_PROPS = 2;
81     public static final int VALUE_CONTAINER = 3;
82
83     private static final String GENERATE_TYPE_XSD = "xsd";
84     private static final String GENERATE_TYPE_YAML = "yaml";
85
86     private final static String NODE_DIR = System.getProperty("nodes.configuration.location");
87     private final static String EDGE_DIR = System.getProperty("edges.configuration.location");
88     private static final String BASE_ROOT = "aai-schema/";
89     private static final String BASE_AUTO_GEN_ROOT = "aai-schema/";
90
91     private static final String ROOT = BASE_ROOT + "src/main/resources";
92     private static final String AUTO_GEN_ROOT = BASE_AUTO_GEN_ROOT + "src/main/resources";
93
94     private static final String NORMAL_START_DIR = "aai-schema-gen";
95     private static final String XSD_DIR = ROOT + "/" + RELEASE + "/aai_schema";
96
97     private static final String YAML_DIR = (((System.getProperty("user.dir") != null)
98         && (!System.getProperty("user.dir").contains(NORMAL_START_DIR))) ? AUTO_GEN_ROOT : ROOT)
99         + "/" + RELEASE + "/aai_swagger_yaml";
100
101     /* These three strings are for yaml auto-generation from aai-common class */
102
103     private static final int SWAGGER_SUPPORT_STARTS_VERSION = 1; // minimum version to support
104                                                                  // swagger documentation
105
106     private static boolean validVersion(String versionToGen) {
107
108         if ("ALL".equalsIgnoreCase(versionToGen)) {
109             return true;
110         }
111
112         SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
113         if (schemaVersions == null) {
114             return false;
115         }
116         for (SchemaVersion v : schemaVersions.getVersions()) {
117             if (v.toString().equals(versionToGen)) {
118                 return true;
119             }
120         }
121
122         return false;
123     }
124
125     private static boolean versionSupportsSwagger(String version) {
126         return Integer.parseInt(version.substring(1)) >= SWAGGER_SUPPORT_STARTS_VERSION;
127     }
128
129     public static String getAPIVersion() {
130         return apiVersion;
131     }
132
133     public static String getYamlDir() {
134         return YAML_DIR;
135     }
136
137     public static String getResponsesUrl() {
138         return responsesUrl;
139     }
140
141     public static void main(String[] args) throws IOException {
142         String versionToGen = System.getProperty("gen_version");
143         if (versionToGen == null) {
144             System.err.println("Version is required, ie v<n> or ALL.");
145             System.exit(1);
146         } else {
147             versionToGen = versionToGen.toLowerCase();
148         }
149
150         String fileTypeToGen = System.getProperty("gen_type");
151         if (fileTypeToGen == null) {
152             fileTypeToGen = GENERATE_TYPE_XSD;
153         } else {
154             fileTypeToGen = fileTypeToGen.toLowerCase();
155         }
156
157         try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
158             "org.onap.aai.setup", "org.onap.aai.schemagen")) {
159             SchemaVersions schemaVersions = ctx.getBean(SchemaVersions.class);
160
161             if (!fileTypeToGen.equals(GENERATE_TYPE_XSD)
162                 && !fileTypeToGen.equals(GENERATE_TYPE_YAML)) {
163                 System.err.println("Invalid gen_type passed. " + fileTypeToGen);
164                 System.exit(1);
165             }
166
167             String responsesLabel = System.getProperty("yamlresponses_url");
168             responsesUrl = responsesLabel;
169
170             List<SchemaVersion> versionsToGen = new ArrayList<>();
171             if (!"ALL".equalsIgnoreCase(versionToGen) && versionToGen != null
172                 && !versionToGen.matches("v\\d+") && !validVersion(versionToGen)) {
173                 System.err.println("Invalid version passed. " + versionToGen);
174                 System.exit(1);
175             } else if ("ALL".equalsIgnoreCase(versionToGen)) {
176                 versionsToGen = schemaVersions.getVersions();
177                 Collections.sort(versionsToGen);
178                 Collections.reverse(versionsToGen);
179             } else {
180                 versionsToGen.add(new SchemaVersion(versionToGen));
181             }
182
183             // process file type System property
184             if (fileTypeToGen.equals(GENERATE_TYPE_YAML)) {
185                 if (responsesUrl == null || responsesUrl.length() < 1 || responsesLabel == null
186                     || responsesLabel.length() < 1) {
187                     System.err.println(
188                         "generating swagger yaml file requires yamlresponses_url and yamlresponses_label properties");
189                     System.exit(1);
190                 } else {
191                     responsesUrl = "description: " + "Response codes found in [response codes]("
192                         + responsesLabel + ").\n";
193                 }
194             }
195             /*
196              * TODO: Oxm Path is config driven
197              */
198             String oxmPath;
199             if (System.getProperty("user.dir") != null
200                 && !System.getProperty("user.dir").contains(NORMAL_START_DIR)) {
201                 oxmPath = BASE_AUTO_GEN_ROOT + NODE_DIR;
202             } else {
203                 oxmPath = BASE_ROOT + NODE_DIR;
204             }
205
206             String outfileName = null;
207             File outfile;
208             String nodesfileName = null;
209             File nodesfile;
210             String fileContent = null;
211             String nodesContent = null;
212
213             for (SchemaVersion v : versionsToGen) {
214                 apiVersion = v.toString();
215                 logger.debug("YAMLdir = " + YAML_DIR);
216                 logger.debug("Generating " + apiVersion + " " + fileTypeToGen);
217                 apiVersionFmt = "." + apiVersion + ".";
218                 generatedJavaType = new HashMap<String, String>();
219                 appliedPaths = new HashMap<String, String>();
220                 File edgeRuleFile = null;
221                 String fileName = EDGE_DIR + "DbEdgeRules_" + apiVersion + ".json";
222                 logger.debug("user.dir = " + System.getProperty("user.dir"));
223                 if (System.getProperty("user.dir") != null
224                     && !System.getProperty("user.dir").contains(NORMAL_START_DIR)) {
225                     fileName = BASE_AUTO_GEN_ROOT + fileName;
226
227                 } else {
228                     fileName = BASE_ROOT + fileName;
229
230                 }
231                 edgeRuleFile = new File(fileName);
232                 // Document doc = ni.getSchema(translateVersion(v));
233
234                 if (fileTypeToGen.equals(GENERATE_TYPE_XSD)) {
235                     outfileName = XSD_DIR + "/aai_schema_" + apiVersion + "." + GENERATE_TYPE_XSD;
236                     try {
237                         HTMLfromOXM swagger = ctx.getBean(HTMLfromOXM.class);
238                         swagger.setVersion(v);
239                         fileContent = swagger.process();
240                         if (fileContent.startsWith("Schema format issue")) {
241                             throw new Exception(fileContent);
242                         }
243                     } catch (Exception e) {
244                         logger.error("Exception creating output file " + outfileName);
245                         logger.error(e.getMessage());
246                         System.exit(-1);
247                     }
248                 } else if (versionSupportsSwagger(apiVersion)) {
249                     outfileName =
250                         YAML_DIR + "/aai_swagger_" + apiVersion + "." + GENERATE_TYPE_YAML;
251                     nodesfileName = YAML_DIR + "/aai_swagger_" + apiVersion + "." + "nodes" + "."
252                         + GENERATE_TYPE_YAML;
253                     try {
254                         YAMLfromOXM swagger = (YAMLfromOXM) ctx.getBean(YAMLfromOXM.class);
255                         swagger.setVersion(v);
256                         fileContent = swagger.process();
257                         Map<String, Integer> combinedJavaTypes = swagger.getCombinedJavaTypes();
258                         NodesYAMLfromOXM nodesSwagger = ctx.getBean(NodesYAMLfromOXM.class);
259                         nodesSwagger.setVersion(v);
260                         nodesSwagger.setCombinedJavaTypes(combinedJavaTypes);
261                         nodesContent = nodesSwagger.process();
262                     } catch (Exception e) {
263                         logger.error("Exception creating output file " + outfileName, e);
264                     }
265                 } else {
266                     continue;
267                 }
268                 outfile = new File(outfileName);
269                 File parentDir = outfile.getParentFile();
270                 if (!parentDir.exists()) {
271                     parentDir.mkdirs();
272                 }
273                 if (nodesfileName != null) {
274                     BufferedWriter nodesBW = null;
275                     nodesfile = new File(nodesfileName);
276                     parentDir = nodesfile.getParentFile();
277                     if (!parentDir.exists()) {
278                         parentDir.mkdirs();
279                     }
280                     try {
281                         if (!nodesfile.createNewFile()) {
282                             logger.error("File {} already exist", nodesfileName);
283                         }
284                     } catch (IOException e) {
285                         logger.error("Exception creating output file " + nodesfileName, e);
286                     }
287                     try {
288                         Charset charset = StandardCharsets.UTF_8;
289                         Path path = Paths.get(nodesfileName);
290                         nodesBW = Files.newBufferedWriter(path, charset);
291                         nodesBW.write(nodesContent);
292                     } catch (IOException e) {
293                         logger.error("Exception writing output file " + outfileName, e);
294                     } finally {
295                         if (nodesBW != null) {
296                             nodesBW.close();
297                         }
298                     }
299                 }
300
301                 try {
302                     if (!outfile.createNewFile()) {
303                         logger.error("File {} already exist", outfileName);
304                     }
305                 } catch (IOException e) {
306                     logger.error("Exception creating output file " + outfileName, e);
307                 }
308                 BufferedWriter bw = null;
309                 try {
310                     Charset charset = StandardCharsets.UTF_8;
311                     Path path = Paths.get(outfileName);
312                     bw = Files.newBufferedWriter(path, charset);
313                     bw.write(fileContent);
314                 } catch (IOException e) {
315                     logger.error("Exception writing output file " + outfileName, e);
316                 } finally {
317                     if (bw != null) {
318                         bw.close();
319                     }
320                 }
321                 logger.debug("GeneratedXSD successful, saved in " + outfileName);
322             }
323         } catch (BeansException e) {
324             logger.warn("Unable to initialize AnnotationConfigApplicationContext ", e);
325         }
326
327     }
328
329 }