Reduce the number of problems in aai-common by removing unused imports
[aai/aai-common.git] / aai-schema-abstraction / src / main / java / org / onap / aai / schemaif / json / JsonSchemaProvider.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2019 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.aai.schemaif.json;
23
24 import java.io.BufferedOutputStream;
25 import java.io.ByteArrayInputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.PrintWriter;
28 import java.io.StringWriter;
29 import java.util.Arrays;
30 import java.util.HashSet;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.concurrent.ConcurrentHashMap;
34 import java.util.zip.ZipEntry;
35 import java.util.zip.ZipInputStream;
36
37 import org.onap.aai.cl.api.Logger;
38 import org.onap.aai.cl.eelf.LoggerFactory;
39 import org.onap.aai.schemaif.SchemaProvider;
40 import org.onap.aai.schemaif.SchemaProviderException;
41 import org.onap.aai.schemaif.SchemaProviderMsgs;
42 import org.onap.aai.schemaif.definitions.EdgeSchema;
43 import org.onap.aai.schemaif.definitions.VertexSchema;
44 import org.onap.aai.schemaif.json.definitions.JsonEdgeSchema;
45 import org.onap.aai.schemaif.json.definitions.JsonSchema;
46 import org.onap.aai.schemaif.json.definitions.JsonVertexSchema;
47 import org.springframework.http.HttpEntity;
48 import org.springframework.http.HttpHeaders;
49 import org.springframework.http.HttpMethod;
50 import org.springframework.http.HttpStatus;
51 import org.springframework.http.ResponseEntity;
52 import org.springframework.web.client.RestTemplate;
53
54 public class JsonSchemaProvider implements SchemaProvider {
55     // Logger logger = LoggerFactory.getInstance().getLogger(JsonSchemaProvider.class.getName());
56     Logger logger = LoggerFactory.getInstance().getLogger(SchemaProvider.class);
57
58     private JsonSchemaProviderConfig config;
59     private Map<String, SchemaInstance> schemaCache = new ConcurrentHashMap<>();
60     private RestTemplate restTemplate = null;
61
62     public JsonSchemaProvider(JsonSchemaProviderConfig config) {
63         this.config = config;
64
65         SecureClientHttpRequestFactory fac = new SecureClientHttpRequestFactory(config);
66         fac.setBufferRequestBody(false);
67         this.restTemplate = new RestTemplate(fac);
68     }
69
70     @Override
71     public void loadSchema() throws SchemaProviderException {
72         // Load the latest schema version
73         fetchSchemaVersion(getLatestSchemaVersion());
74     }
75
76     @Override
77     public String getLatestSchemaVersion() throws SchemaProviderException {
78         return "v0";
79     }
80
81     @Override
82     public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException {
83         SchemaInstance inst = getSchemaVersion(schemaVersion);
84         return inst.getVertexSchema(vertexName);
85     }
86
87     @Override
88     public EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version)
89             throws SchemaProviderException {
90         SchemaInstance inst = getSchemaVersion(version);
91         return inst.getEdgeSchema(sourceVertex, targetVertex, edgeType);
92     }
93
94     @Override
95     public Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException {
96         SchemaInstance inst = getSchemaVersion(version);
97
98         Set<EdgeSchema> edgeList = inst.getEdgeSchema(vertexType);
99         if (edgeList == null) {
100             edgeList = new HashSet<>();
101         }
102
103         return edgeList;
104     }
105
106     @Override
107     public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version)
108             throws SchemaProviderException {
109         SchemaInstance inst = getSchemaVersion(version);
110
111         Set<EdgeSchema> edgeList = inst.getEdgeSchemas(sourceType, targetType);
112         if (edgeList == null) {
113             edgeList = new HashSet<>();
114         }
115
116         return edgeList;
117     }
118
119     public void loadSchema(String payload, String version) throws SchemaProviderException {
120         JsonSchema jsonSchema = JsonSchema.fromJson(payload);
121         SchemaInstance schemaInst = new SchemaInstance();
122
123         for (JsonVertexSchema jsonVertex : jsonSchema.getNodeTypes()) {
124             FromJsonVertexSchema vSchema = new FromJsonVertexSchema();
125             vSchema.fromJson(jsonVertex, jsonSchema.getDataTypes(), jsonSchema.getCommonProperties());
126             schemaInst.addVertex(vSchema);
127         }
128
129         for (JsonEdgeSchema jsonEdge : jsonSchema.getRelationshipTypes()) {
130             FromJsonEdgeSchema eSchema = new FromJsonEdgeSchema();
131             eSchema.fromJson(jsonEdge);
132             schemaInst.addEdge(eSchema);
133         }
134
135         schemaCache.put(version, schemaInst);
136     }
137
138     private synchronized void fetchSchemaVersion(String version) throws SchemaProviderException {
139         if (schemaCache.get(version) != null) {
140             return;
141         }
142
143         String url = config.getSchemaServiceBaseUrl() + "/" + version;
144
145         HttpHeaders headers = new HttpHeaders();
146         headers.put("X-FromAppId", Arrays.asList(config.getServiceName()));
147         headers.put("X-TransactionId", Arrays.asList(java.util.UUID.randomUUID().toString()));
148         headers.setAccept(Arrays.asList(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM));
149
150         HttpEntity<String> entity = new HttpEntity<>(headers);
151
152         ResponseEntity<byte[]> response = restTemplate.exchange(url, HttpMethod.GET, entity, byte[].class);
153
154         if (response.getStatusCodeValue() == HttpStatus.NOT_FOUND.value()) {
155             logger.warn(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "version " + version + " not found");
156             throw new SchemaProviderException("Schema version " + version + " not found");
157         } else if (response.getStatusCodeValue() != HttpStatus.OK.value()) {
158             logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR,
159                     "failed to load version " + version + ": " + response.getBody());
160             throw new SchemaProviderException("Error getting schema version " + version + ":" + response.getBody());
161         }
162
163         try {
164             SchemaServiceResponse resp = SchemaServiceResponse.fromJson(unzipAndGetJSONString(response.getBody()));
165             loadSchema(resp.getData().toJson(), version);
166         } catch (Exception ex) {
167             StringWriter writer = new StringWriter();
168             PrintWriter printWriter = new PrintWriter(writer);
169             ex.printStackTrace(printWriter);
170             logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR,
171                     "failed to load version " + version + ": " + response.getBody() + "\n" + writer.toString());
172             throw new SchemaProviderException("Error loading schema version " + version + ":" + ex.getMessage());
173
174         }
175
176         logger.info(SchemaProviderMsgs.LOADED_SCHEMA_FILE, version);
177     }
178
179     static final int BUFFER = 512;
180     static final long TOOBIG = 0x6400000; // Max size of unzipped data, 100MB
181     static final int TOOMANY = 1024; // Max number of files
182
183     protected String unzipAndGetJSONString(byte[] inputData) throws java.io.IOException {
184         ZipEntry entry;
185         String result = "";
186         int entries = 0;
187         long total = 0;
188         try (ByteArrayInputStream bis = new ByteArrayInputStream(inputData);
189                 ZipInputStream zis = new ZipInputStream(bis)) {
190             while ((entry = zis.getNextEntry()) != null) {
191                 int count;
192                 byte[] data = new byte[BUFFER];
193                 if (entry.isDirectory()) {
194                     continue;
195                 }
196                 ByteArrayOutputStream fos = new ByteArrayOutputStream();
197                 BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
198                 while (total + BUFFER <= TOOBIG && (count = zis.read(data, 0, BUFFER)) != -1) {
199                     dest.write(data, 0, count);
200                     total += count;
201                 }
202                 dest.flush();
203                 result = fos.toString();
204                 dest.close();
205                 zis.closeEntry();
206                 entries++;
207                 if (entries > TOOMANY) {
208                     throw new IllegalStateException("Too many files to unzip.");
209                 }
210                 if (total + BUFFER > TOOBIG) {
211                     throw new IllegalStateException("File being unzipped is too big.");
212                 }
213             }
214         }
215         return result;
216     }
217
218     private SchemaInstance getSchemaVersion(String version) throws SchemaProviderException {
219         // TODO: For now, we are only supporting a single version of the schema. Load that
220         // version regardless of what the client asks for.
221         String versionToLoad = getLatestSchemaVersion();
222         SchemaInstance inst = schemaCache.get(versionToLoad);
223
224         if (inst == null) {
225             fetchSchemaVersion(versionToLoad);
226             inst = schemaCache.get(versionToLoad);
227             if (inst == null) {
228                 throw new SchemaProviderException("Unable to find schema version " + versionToLoad);
229             }
230         }
231
232         return inst;
233     }
234
235     @Override
236     public Map<String, VertexSchema> getVertexMap(String schemaVersion) throws SchemaProviderException {
237         return getSchemaVersion(schemaVersion).getVertexMap();
238     }
239
240 }