Sonar fixes
[aai/traversal.git] / aai-traversal / src / main / java / org / onap / aai / rest / RecentAPIConsumer.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 package org.onap.aai.rest;
21
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;
26
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;
48
49 import javax.ws.rs.*;
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;
54
55 @Path("/recents/{version: v[1-9][0-9]*|latest}")
56 public class RecentAPIConsumer extends RESTAPI {
57
58         private static final String AAI_3021 = "AAI_3021";
59
60         /** The introspector factory type. */
61         private ModelType introspectorFactoryType = ModelType.MOXY;
62
63         private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY;
64         /** The query style. */
65
66         private static final Logger LOGGER = LoggerFactory.getLogger(RecentAPIConsumer.class);
67
68         private HttpEntry traversalUriHttpEntry;
69
70         private SchemaVersions schemaVersions;
71
72         private String basePath;
73
74         private GremlinServerSingleton gremlinServerSingleton;
75
76         private XmlFormatTransformer xmlFormatTransformer;
77
78
79         @Autowired
80         public RecentAPIConsumer(
81                 HttpEntry traversalUriHttpEntry,
82                 SchemaVersions schemaVersions,
83                 GremlinServerSingleton gremlinServerSingleton,
84                 XmlFormatTransformer xmlFormatTransformer,
85                 @Value("${schema.uri.base.path}") String basePath
86         ){
87                 this.traversalUriHttpEntry  = traversalUriHttpEntry;
88                 this.schemaVersions         = schemaVersions;
89                 this.gremlinServerSingleton = gremlinServerSingleton;
90                 this.xmlFormatTransformer   = xmlFormatTransformer;
91                 this.basePath               = basePath;
92         }
93
94         @GET
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) {
100
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>() {
103                                         @Override
104                                         public Response process() {
105                                                 return processRecentData(content, versionParam, nodeType, info, headers);
106                                         }
107                                 });
108
109         }
110
111         public Response processRecentData(String content, @PathParam("version") String versionParam,
112                         @PathParam("nodeType") String nodeType, @Context UriInfo info, @Context HttpHeaders headers) {
113
114                 String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
115                 String queryProcessor = headers.getRequestHeaders().getFirst("QueryProcessor");
116                 QueryProcessorType processorType = this.processorType;
117                 Response response;
118                 TransactionalGraphEngine dbEngine = null;
119                 try {
120                         
121                         if (queryProcessor != null) {
122                                 processorType = QueryProcessorType.valueOf(queryProcessor);
123                         }
124
125                         SchemaVersion version = new SchemaVersion(versionParam);
126                         this.checkVersion(version);
127                         
128                         traversalUriHttpEntry.setHttpEntryProperties(version);
129                         dbEngine = traversalUriHttpEntry.getDbEngine();
130
131                         /*
132                          * Check for mandatory parameters here
133                          */
134                         
135                         this.checkNodeType(nodeType);
136                         this.checkQueryParams(info.getQueryParameters());
137                         
138                         GenericQueryProcessor processor = null;
139
140
141
142                         processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton).queryFrom(nodeType, "nodeQuery")
143                                         .uriParams(info.getQueryParameters())
144                                         .processWith(processorType).create();
145
146                         
147                         
148                         String result = "";
149                         SubGraphStyle subGraphStyle = null;
150                         List<Object> vertices = processor.execute(subGraphStyle);
151
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;
155                         
156                         Formatter formater = ff.get(format, info.getQueryParameters());
157
158                         result = formater.output(vertices).toString();
159
160                         //LOGGER.info("Completed");
161
162                         String acceptType = headers.getHeaderString("Accept");
163
164                         if(acceptType == null){
165                                 acceptType = MediaType.APPLICATION_JSON;
166                         }
167
168                         if(MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))){
169                                 result = xmlFormatTransformer.transform(result);
170                         }
171
172                         response = Response.status(Status.OK).type(acceptType).entity(result).build();
173
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);
179                 } finally {
180                         
181                         if (dbEngine != null) {
182                                 dbEngine.rollback();
183                         }
184
185                 }
186
187                 return response;
188         }
189
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");
193                 }
194         }
195
196         public void checkNodeType(String nodeType) throws AAIException {
197                 try {
198                         traversalUriHttpEntry.getLoader().introspectorFromName(nodeType);
199                 } catch (AAIUnknownObjectException e) {
200                         throw new AAIException("AAI_6115", "Unrecognized nodeType [" + nodeType + "] passed to recents query."); 
201                 }
202         }
203         public void checkQueryParams(MultivaluedMap<String, String> params) throws AAIException {
204
205                 boolean isHoursParameter = false;
206                 boolean isDateTimeParameter = false;
207                 
208                 if (params != null && params.containsKey("hours") && params.getFirst("hours").matches("-?\\d+")) {
209                         isHoursParameter = true;
210                         long hours;
211                         try{
212                                 hours = Long.parseLong(params.getFirst("hours"));
213                         }
214                         catch(NumberFormatException ex){
215                                 throw new AAIException(AAI_3021, " Invalid Hours. Valid values for hours are 1 to " + AAIConstants.HISTORY_MAX_HOURS);
216                         }
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);
219                         }
220                 }
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);
224                         Long startTime;
225                         try{
226                                 startTime = Long.parseLong(params.getFirst("date-time"));
227                         }
228                         catch(NumberFormatException ex){
229                                 throw new AAIException(AAI_3021, " Invalid Data-time. Valid values for date-time are "+minStartTime+" to " +  System.currentTimeMillis() );
230                         }
231                         if (startTime < minStartTime) {
232                                 throw new AAIException(AAI_3021, " Valid values for date-time are "+minStartTime+" to " +  System.currentTimeMillis() );
233                         }
234                 }
235                 
236                 if(!isHoursParameter && !isDateTimeParameter){
237                         throw new AAIException(AAI_3021, "Send valid hours or date-time to specify the timebounds");
238                 }
239                 
240         if(isHoursParameter && isDateTimeParameter){
241                 throw new AAIException(AAI_3021, "Send either hours or date-time and not both to specify the timebounds");
242                 }
243
244         
245         }
246
247 }