2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.aai.schemaif.json;
23 import java.io.BufferedOutputStream;
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.PrintWriter;
27 import java.io.StringWriter;
28 import java.util.Arrays;
29 import java.util.HashSet;
32 import java.util.concurrent.ConcurrentHashMap;
33 import java.util.zip.ZipEntry;
34 import java.util.zip.ZipInputStream;
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;
54 public class JsonSchemaProvider implements SchemaProvider {
55 // Logger logger = LoggerFactory.getInstance().getLogger(JsonSchemaProvider.class.getName());
56 Logger logger = LoggerFactory.getInstance().getLogger(SchemaProvider.class);
58 private JsonSchemaProviderConfig config;
59 private Map<String,SchemaInstance> schemaCache = new ConcurrentHashMap<>();
60 private RestTemplate restTemplate = null;
62 public JsonSchemaProvider(JsonSchemaProviderConfig config) {
65 SecureClientHttpRequestFactory fac = new SecureClientHttpRequestFactory(config);
66 fac.setBufferRequestBody(false);
67 this.restTemplate = new RestTemplate(fac);
71 public void loadSchema() throws SchemaProviderException {
72 // Load the latest schema version
73 fetchSchemaVersion(getLatestSchemaVersion());
77 public String getLatestSchemaVersion() throws SchemaProviderException {
82 public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException {
83 SchemaInstance inst = getSchemaVersion(schemaVersion);
84 return inst.getVertexSchema(vertexName);
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);
95 public Set<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException {
96 SchemaInstance inst = getSchemaVersion(version);
98 Set<EdgeSchema> edgeList = inst.getEdgeSchema(vertexType);
99 if (edgeList == null) {
100 edgeList = new HashSet<>();
107 public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version)
108 throws SchemaProviderException {
109 SchemaInstance inst = getSchemaVersion(version);
111 Set<EdgeSchema> edgeList = inst.getEdgeSchemas(sourceType, targetType);
112 if (edgeList == null) {
113 edgeList = new HashSet<>();
119 public void loadSchema(String payload, String version) throws SchemaProviderException {
120 JsonSchema jsonSchema = JsonSchema.fromJson(payload);
121 SchemaInstance schemaInst = new SchemaInstance();
123 for (JsonVertexSchema jsonVertex : jsonSchema.getNodeTypes()) {
124 FromJsonVertexSchema vSchema = new FromJsonVertexSchema();
125 vSchema.fromJson(jsonVertex, jsonSchema.getDataTypes(), jsonSchema.getCommonProperties());
126 schemaInst.addVertex(vSchema);
129 for (JsonEdgeSchema jsonEdge : jsonSchema.getRelationshipTypes()) {
130 FromJsonEdgeSchema eSchema = new FromJsonEdgeSchema();
131 eSchema.fromJson(jsonEdge);
132 schemaInst.addEdge(eSchema);
135 schemaCache.put(version, schemaInst);
138 private synchronized void fetchSchemaVersion(String version) throws SchemaProviderException {
139 if (schemaCache.get(version) != null) {
144 String url = config.getSchemaServiceBaseUrl() + "/" + version;
146 HttpHeaders headers = new HttpHeaders();
147 headers.put("X-FromAppId", Arrays.asList(config.getServiceName()));
148 headers.put("X-TransactionId", Arrays.asList(java.util.UUID.randomUUID().toString()));
149 headers.setAccept(Arrays.asList(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM));
151 HttpEntity <String> entity = new HttpEntity<>(headers);
153 ResponseEntity<byte[]> response = restTemplate.exchange(url, HttpMethod.GET, entity, byte[].class);
156 if (response.getStatusCodeValue() == HttpStatus.NOT_FOUND.value()) {
157 logger.warn(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "version " + version + " not found");
158 throw new SchemaProviderException("Schema version " + version + " not found");
160 else if (response.getStatusCodeValue() != HttpStatus.OK.value()) {
161 logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "failed to load version " + version + ": " + response.getBody());
162 throw new SchemaProviderException("Error getting schema version " + version + ":" + response.getBody());
166 SchemaServiceResponse resp = SchemaServiceResponse.fromJson(unzipAndGetJSONString(response.getBody()));
167 loadSchema(resp.getData().toJson(), version);
169 catch (Exception ex) {
170 StringWriter writer = new StringWriter();
171 PrintWriter printWriter = new PrintWriter(writer);
172 ex.printStackTrace(printWriter);
173 logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "failed to load version " + version + ": "
174 + response.getBody() + "\n" + writer.toString());
175 throw new SchemaProviderException("Error loading schema version " + version + ":" + ex.getMessage());
179 logger.info(SchemaProviderMsgs.LOADED_SCHEMA_FILE, version);
182 static final int BUFFER = 512;
183 static final long TOOBIG = 0x6400000; // Max size of unzipped data, 100MB
184 static final int TOOMANY = 1024; // Max number of files
186 protected String unzipAndGetJSONString(byte[] inputData) throws java.io.IOException {
191 try (ByteArrayInputStream bis = new ByteArrayInputStream(inputData); ZipInputStream zis = new ZipInputStream(bis)) {
192 while ((entry = zis.getNextEntry()) != null) {
194 byte[] data = new byte[BUFFER];
195 if (entry.isDirectory()) {
198 ByteArrayOutputStream fos = new ByteArrayOutputStream();
199 BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
200 while (total + BUFFER <= TOOBIG && (count = zis.read(data, 0, BUFFER)) != -1) {
201 dest.write(data, 0, count);
205 result = fos.toString();
209 if (entries > TOOMANY) {
210 throw new IllegalStateException("Too many files to unzip.");
212 if (total + BUFFER > TOOBIG) {
213 throw new IllegalStateException("File being unzipped is too big.");
220 private SchemaInstance getSchemaVersion(String version) throws SchemaProviderException {
221 // TODO: For now, we are only supporting a single version of the schema. Load that
222 // version regardless of what the client asks for.
223 String versionToLoad = getLatestSchemaVersion();
224 SchemaInstance inst = schemaCache.get(versionToLoad);
227 fetchSchemaVersion(versionToLoad);
228 inst = schemaCache.get(versionToLoad);
230 throw new SchemaProviderException("Unable to find schema version " + versionToLoad);
238 public Map<String, VertexSchema> getVertexMap(String schemaVersion) throws SchemaProviderException {
239 return getSchemaVersion(schemaVersion).getVertexMap();