47cb27271c8427c8620246bcb743366de5054a0b
[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 package org.onap.aai.schemaif.json;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.io.StringWriter;
27 import java.util.Arrays;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Scanner;
31 import java.util.Set;
32 import java.util.concurrent.ConcurrentHashMap;
33 import java.util.zip.ZipEntry;
34 import java.util.zip.ZipInputStream;
35
36 import org.onap.aai.cl.api.Logger;
37 import org.onap.aai.cl.eelf.LoggerFactory;
38 import org.onap.aai.schemaif.SchemaProvider;
39 import org.onap.aai.schemaif.SchemaProviderException;
40 import org.onap.aai.schemaif.SchemaProviderMsgs;
41 import org.onap.aai.schemaif.definitions.EdgeSchema;
42 import org.onap.aai.schemaif.definitions.VertexSchema;
43 import org.onap.aai.schemaif.json.definitions.JsonEdgeSchema;
44 import org.onap.aai.schemaif.json.definitions.JsonSchema;
45 import org.onap.aai.schemaif.json.definitions.JsonVertexSchema;
46 import org.springframework.http.HttpEntity;
47 import org.springframework.http.HttpHeaders;
48 import org.springframework.http.HttpMethod;
49 import org.springframework.http.HttpStatus;
50 import org.springframework.http.ResponseEntity;
51 import org.springframework.web.client.RestTemplate;
52
53
54 public class JsonSchemaProvider implements SchemaProvider {
55     Logger logger = LoggerFactory.getInstance().getLogger(JsonSchemaProvider.class.getName());
56
57     private JsonSchemaProviderConfig config;
58     private Map<String,SchemaInstance> schemaCache = new ConcurrentHashMap<>();
59     private RestTemplate restTemplate = null;
60
61     public JsonSchemaProvider(JsonSchemaProviderConfig config) {
62         this.config = config;
63
64         SecureClientHttpRequestFactory fac = new SecureClientHttpRequestFactory(config);
65         fac.setBufferRequestBody(false);
66         this.restTemplate = new RestTemplate(fac);
67     }
68
69     @Override
70     public void loadSchema() throws SchemaProviderException {
71         // Load the latest schema version
72         fetchSchemaVersion(getLatestSchemaVersion());
73     }
74
75     @Override
76     public String getLatestSchemaVersion() throws SchemaProviderException {
77         return "v0";
78     }
79
80     @Override
81     public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException {
82         SchemaInstance inst = getSchemaVersion(schemaVersion);
83         return inst.getVertexSchema(vertexName);
84     }
85
86     @Override
87     public EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version)
88             throws SchemaProviderException {
89         SchemaInstance inst = getSchemaVersion(version);
90         return inst.getEdgeSchema(sourceVertex, targetVertex, edgeType);
91     }
92
93     @Override
94     public Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException {
95         SchemaInstance inst = getSchemaVersion(version);
96
97         Set<EdgeSchema> edgeList = inst.getEdgeSchema(vertexType);
98         if (edgeList == null) {
99             edgeList = new HashSet<>();
100         }
101
102         return edgeList;
103     }
104
105     @Override
106     public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version)
107             throws SchemaProviderException {
108         SchemaInstance inst = getSchemaVersion(version);
109
110         Set<EdgeSchema> edgeList = inst.getEdgeSchemas(sourceType, targetType);
111         if (edgeList == null) {
112             edgeList = new HashSet<>();
113         }
114
115         return edgeList;
116     }
117
118     public void loadSchema(String payload, String version) throws SchemaProviderException {
119         JsonSchema jsonSchema = JsonSchema.fromJson(payload);
120         SchemaInstance schemaInst = new SchemaInstance();
121
122         for (JsonVertexSchema jsonVertex : jsonSchema.getNodeTypes()) {
123             FromJsonVertexSchema vSchema = new FromJsonVertexSchema();
124             vSchema.fromJson(jsonVertex, jsonSchema.getDataTypes(), jsonSchema.getCommonProperties());
125             schemaInst.addVertex(vSchema);
126         }
127
128         for (JsonEdgeSchema jsonEdge : jsonSchema.getRelationshipTypes()) {
129             FromJsonEdgeSchema eSchema = new FromJsonEdgeSchema();
130             eSchema.fromJson(jsonEdge);
131             schemaInst.addEdge(eSchema);
132         }
133
134         schemaCache.put(version, schemaInst);
135     }
136
137     private synchronized void fetchSchemaVersion(String version) throws SchemaProviderException {
138         if (schemaCache.get(version) != null) {
139             return;
140         }
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
155         if (response.getStatusCodeValue() == HttpStatus.NOT_FOUND.value()) {
156             logger.warn(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "version " + version + " not found");
157             throw new SchemaProviderException("Schema version " + version + " not found");
158         }
159         else if (response.getStatusCodeValue() != HttpStatus.OK.value()) {
160             logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "failed to load version " + version + ": " + response.getBody());
161             throw new SchemaProviderException("Error getting schema version " + version + ":" + response.getBody());
162         }
163
164         try {
165             SchemaServiceResponse resp = SchemaServiceResponse.fromJson(unzipAndGetJSONString(response));
166             loadSchema(resp.getData().toJson(), version);
167         }
168         catch (Exception ex) {
169             StringWriter writer = new StringWriter();
170             PrintWriter printWriter = new PrintWriter(writer);
171             ex.printStackTrace(printWriter);
172             logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "failed to load version " + version + ": "
173                     + response.getBody() + "\n" + writer.toString());
174             throw new SchemaProviderException("Error loading schema version " + version + ":" + ex.getMessage());
175
176         }
177
178         logger.info(SchemaProviderMsgs.LOADED_SCHEMA_FILE, version);
179     }
180
181     private String unzipAndGetJSONString(ResponseEntity<byte[]> response) throws IOException {
182         StringBuffer sb = new StringBuffer("");
183
184         ZipInputStream zipStream = null;
185         try {
186
187             zipStream = new ZipInputStream(new ByteArrayInputStream(response.getBody()));
188             ZipEntry entry = null;
189             while ((entry = zipStream.getNextEntry()) != null) {
190                 Scanner sc = new Scanner(zipStream);
191                 while (sc.hasNextLine()) {
192                     sb.append(sc.nextLine());
193                 }
194
195             }
196         } finally {
197             try {
198                 if (zipStream != null) {
199                     zipStream.closeEntry();
200                     zipStream.close();
201                 }
202             } catch (Exception e) {
203                 logger.warn(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, e.toString());
204
205             }
206         }
207
208         return sb.toString();
209     }
210
211     private SchemaInstance getSchemaVersion(String version) throws SchemaProviderException {
212         // TODO:  For now, we are only supporting a single version of the schema.  Load that
213         // version regardless of what the client asks for.
214         String versionToLoad = getLatestSchemaVersion();
215         SchemaInstance inst = schemaCache.get(versionToLoad);
216
217         if (inst == null) {
218             fetchSchemaVersion(versionToLoad);
219             inst = schemaCache.get(versionToLoad);
220             if (inst == null) {
221                 throw new SchemaProviderException("Unable to find schema version " + versionToLoad);
222             }
223         }
224
225         return inst;
226     }
227
228     @Override
229     public Map<String, VertexSchema> getVertexMap(String schemaVersion) throws SchemaProviderException {
230       return getSchemaVersion(schemaVersion).getVertexMap();
231     }
232
233 }