2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.aai.rest;
22 import org.onap.aai.concurrent.AaiCallable;
23 import org.onap.aai.exceptions.AAIException;
24 import org.onap.aai.introspection.ModelType;
25 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
27 import org.onap.aai.rest.db.HttpEntry;
28 import org.onap.aai.rest.search.GenericQueryProcessor;
29 import org.onap.aai.rest.search.GremlinServerSingleton;
30 import org.onap.aai.rest.search.QueryProcessorType;
31 import org.onap.aai.restcore.HttpMethod;
32 import org.onap.aai.restcore.RESTAPI;
33 import org.onap.aai.serialization.db.DBSerializer;
34 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
35 import org.onap.aai.serialization.queryformats.Format;
36 import org.onap.aai.serialization.queryformats.FormatFactory;
37 import org.onap.aai.serialization.queryformats.Formatter;
38 import org.onap.aai.serialization.queryformats.SubGraphStyle;
39 import org.onap.aai.setup.SchemaVersion;
40 import org.onap.aai.setup.SchemaVersions;
41 import org.onap.aai.transforms.XmlFormatTransformer;
42 import org.onap.aai.util.AAIConstants;
43 import org.onap.aai.util.TraversalConstants;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.beans.factory.annotation.Value;
50 import javax.ws.rs.core.*;
51 import javax.ws.rs.core.Response.Status;
52 import java.util.List;
53 import java.util.concurrent.TimeUnit;
55 @Path("/recents/{version: v[1-9][0-9]*|latest}")
56 public class RecentAPIConsumer extends RESTAPI {
58 private static final String AAI_3021 = "AAI_3021";
60 /** The introspector factory type. */
61 private ModelType introspectorFactoryType = ModelType.MOXY;
63 private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY;
64 /** The query style. */
66 private static final Logger LOGGER = LoggerFactory.getLogger(RecentAPIConsumer.class);
68 private HttpEntry traversalUriHttpEntry;
70 private SchemaVersions schemaVersions;
72 private String basePath;
74 private GremlinServerSingleton gremlinServerSingleton;
76 private XmlFormatTransformer xmlFormatTransformer;
80 public RecentAPIConsumer(
81 HttpEntry traversalUriHttpEntry,
82 SchemaVersions schemaVersions,
83 GremlinServerSingleton gremlinServerSingleton,
84 XmlFormatTransformer xmlFormatTransformer,
85 @Value("${schema.uri.base.path}") String basePath
87 this.traversalUriHttpEntry = traversalUriHttpEntry;
88 this.schemaVersions = schemaVersions;
89 this.gremlinServerSingleton = gremlinServerSingleton;
90 this.xmlFormatTransformer = xmlFormatTransformer;
91 this.basePath = basePath;
95 @Path("/{nodeType: .+}")
96 @Consumes({ MediaType.APPLICATION_JSON })
97 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
98 public Response getRecentData(String content, @PathParam("version") String versionParam,
99 @PathParam("nodeType") String nodeType, @Context HttpHeaders headers, @Context UriInfo info) {
101 return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED, TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP,
102 TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT, headers, info, HttpMethod.GET, new AaiCallable<Response>() {
104 public Response process() {
105 return processRecentData(content, versionParam, nodeType, info, headers);
111 public Response processRecentData(String content, @PathParam("version") String versionParam,
112 @PathParam("nodeType") String nodeType, @Context UriInfo info, @Context HttpHeaders headers) {
114 String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
115 String queryProcessor = headers.getRequestHeaders().getFirst("QueryProcessor");
116 QueryProcessorType processorType = this.processorType;
118 TransactionalGraphEngine dbEngine = null;
121 if (queryProcessor != null) {
122 processorType = QueryProcessorType.valueOf(queryProcessor);
125 SchemaVersion version = new SchemaVersion(versionParam);
126 this.checkVersion(version);
128 traversalUriHttpEntry.setHttpEntryProperties(version);
129 dbEngine = traversalUriHttpEntry.getDbEngine();
132 * Check for mandatory parameters here
135 this.checkNodeType(nodeType);
136 this.checkQueryParams(info.getQueryParameters());
138 GenericQueryProcessor processor = null;
142 processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton).queryFrom(nodeType, "nodeQuery")
143 .uriParams(info.getQueryParameters())
144 .processWith(processorType).create();
149 SubGraphStyle subGraphStyle = null;
150 List<Object> vertices = processor.execute(subGraphStyle);
152 DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
153 FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath);
154 Format format = Format.pathed_resourceversion;
156 Formatter formater = ff.get(format, info.getQueryParameters());
158 result = formater.output(vertices).toString();
160 //LOGGER.info("Completed");
162 String acceptType = headers.getHeaderString("Accept");
164 if(acceptType == null){
165 acceptType = MediaType.APPLICATION_JSON;
168 if(MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))){
169 result = xmlFormatTransformer.transform(result);
172 response = Response.status(Status.OK).type(acceptType).entity(result).build();
174 } catch (AAIException e) {
175 response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, e);
176 } catch (Exception e) {
177 AAIException ex = new AAIException("AAI_4000", e);
178 response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, ex);
181 if (dbEngine != null) {
190 private void checkVersion(SchemaVersion version) throws AAIException {
191 if(!schemaVersions.getVersions().contains(version)){
192 throw new AAIException(AAI_3021, "Schema Version is not valid");
196 public void checkNodeType(String nodeType) throws AAIException {
198 traversalUriHttpEntry.getLoader().introspectorFromName(nodeType);
199 } catch (AAIUnknownObjectException e) {
200 throw new AAIException("AAI_6115", "Unrecognized nodeType [" + nodeType + "] passed to recents query.");
203 public void checkQueryParams(MultivaluedMap<String, String> params) throws AAIException {
205 boolean isHoursParameter = false;
206 boolean isDateTimeParameter = false;
208 if (params != null && params.containsKey("hours") && params.getFirst("hours").matches("-?\\d+")) {
209 isHoursParameter = true;
212 hours = Long.parseLong(params.getFirst("hours"));
214 catch(NumberFormatException ex){
215 throw new AAIException(AAI_3021, " Invalid Hours. Valid values for hours are 1 to " + AAIConstants.HISTORY_MAX_HOURS);
217 if (hours < 1 || hours > AAIConstants.HISTORY_MAX_HOURS) {
218 throw new AAIException(AAI_3021, " Valid values for hours are 1 to " + AAIConstants.HISTORY_MAX_HOURS);
221 if (params != null && params.containsKey("date-time") && params.getFirst("date-time").matches("-?\\d+")) {
222 isDateTimeParameter = true;
223 Long minStartTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(AAIConstants.HISTORY_MAX_HOURS);
226 startTime = Long.parseLong(params.getFirst("date-time"));
228 catch(NumberFormatException ex){
229 throw new AAIException(AAI_3021, " Invalid Data-time. Valid values for date-time are "+minStartTime+" to " + System.currentTimeMillis() );
231 if (startTime < minStartTime) {
232 throw new AAIException(AAI_3021, " Valid values for date-time are "+minStartTime+" to " + System.currentTimeMillis() );
236 if(!isHoursParameter && !isDateTimeParameter){
237 throw new AAIException(AAI_3021, "Send valid hours or date-time to specify the timebounds");
240 if(isHoursParameter && isDateTimeParameter){
241 throw new AAIException(AAI_3021, "Send either hours or date-time and not both to specify the timebounds");