Update the license for 2017-2018 license
[aai/traversal.git] / aai-traversal / src / main / java / org / onap / aai / rest / search / SearchProvider.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.search;
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.concurrent.TimeUnit;
25 import java.util.concurrent.Callable;
26
27 import javax.servlet.http.HttpServletRequest;
28 import javax.ws.rs.GET;
29 import javax.ws.rs.Path;
30 import javax.ws.rs.PathParam;
31 import javax.ws.rs.Produces;
32 import javax.ws.rs.QueryParam;
33 import javax.ws.rs.core.Context;
34 import javax.ws.rs.core.HttpHeaders;
35 import javax.ws.rs.core.MediaType;
36 import javax.ws.rs.core.Response;
37 import javax.ws.rs.core.Response.Status;
38 import javax.ws.rs.core.UriInfo;
39
40 import org.onap.aai.db.props.AAIProperties;
41 import org.onap.aai.dbgraphmap.SearchGraph;
42 import org.onap.aai.dbmap.DBConnectionType;
43 import org.onap.aai.exceptions.AAIException;
44 import org.onap.aai.introspection.Loader;
45 import org.onap.aai.introspection.LoaderFactory;
46 import org.onap.aai.introspection.ModelType;
47 import org.onap.aai.introspection.Version;
48 import org.onap.aai.logging.ErrorLogHelper;
49 import org.onap.aai.logging.LoggingContext;
50 import org.onap.aai.logging.StopWatch;
51 import org.onap.aai.logging.LoggingContext.StatusCode;
52 import org.onap.aai.restcore.HttpMethod;
53 import org.onap.aai.restcore.RESTAPI;
54 import org.onap.aai.serialization.db.DBSerializer;
55 import org.onap.aai.serialization.engines.QueryStyle;
56 import org.onap.aai.serialization.engines.TitanDBEngine;
57 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
58 import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
59 import org.onap.aai.util.AAIConstants;
60
61 import com.att.eelf.configuration.EELFLogger;
62 import com.att.eelf.configuration.EELFManager;
63 /**
64  * Implements the search subdomain in the REST API. All API calls must include
65  * X-FromAppId and X-TransactionId in the header.
66  * 
67  
68  *
69  */
70
71 @Path("/{version: v[789]|v1[0123]|latest}/search")
72 public class SearchProvider extends RESTAPI {
73         
74         protected static String authPolicyFunctionName = "search";
75
76         public static final String GENERIC_QUERY = "/generic-query";
77
78         public static final String NODES_QUERY = "/nodes-query";
79
80         public static final String TARGET_ENTITY = "DB";
81         private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchProvider.class);
82         /**
83          * Gets the generic query response.
84          *
85          * @param headers the headers
86          * @param req the req
87          * @param startNodeType the start node type
88          * @param startNodeKeyParams the start node key params
89          * @param includeNodeTypes the include node types
90          * @param depth the depth
91          * @return the generic query response
92          */
93         /* ---------------- Start Generic Query --------------------- */
94         @GET
95         @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
96         @Path(GENERIC_QUERY)
97         public Response getGenericQueryResponse(@Context HttpHeaders headers,
98                                                                                         @Context HttpServletRequest req,
99                                                                                         @QueryParam("start-node-type") final String startNodeType,
100                                                                                         @QueryParam("key") final List<String> startNodeKeyParams,
101                                                                                         @QueryParam("include") final List<String> includeNodeTypes,
102                                                                                         @QueryParam("depth") final int depth,
103                                                                                         @PathParam("version")String versionParam,
104                                                                                         @Context UriInfo info
105         ) {
106                 return runner(AAIConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED,
107                                 AAIConstants.AAI_TRAVERSAL_TIMEOUT_APP,
108                                 AAIConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT,
109                                 headers,
110                                 info,
111                                 HttpMethod.GET,
112                                 new Callable<Response>() {
113                                         @Override
114                                         public Response call() {
115                                                 return processGenericQueryResponse(headers, req, startNodeType, startNodeKeyParams, includeNodeTypes, depth, versionParam);
116                                         }
117                                 }
118                 );
119         }
120
121         public Response processGenericQueryResponse(@Context HttpHeaders headers,
122                                                                                                 @Context HttpServletRequest req,
123                                                                                                 @QueryParam("start-node-type") final String startNodeType,
124                                                                                                 @QueryParam("key") final List<String> startNodeKeyParams,
125                                                                                                 @QueryParam("include") final List<String> includeNodeTypes,
126                                                                                                 @QueryParam("depth") final int depth,
127                                                                                                 @PathParam("version")String versionParam
128                                                                                         ) {
129                 
130                 String methodName = "getGenericQueryResponse";
131                 AAIException ex = null;
132                 Response searchResult = null;
133                 String fromAppId = null;
134                 String transId = null;
135                 String rqstTm = genDate();
136                 ArrayList<String> templateVars = new ArrayList<String>();
137                 double dbTimeMsecs = 0;
138                 try { 
139                         LoggingContext.save();
140                         LoggingContext.targetEntity(TARGET_ENTITY);
141                         LoggingContext.targetServiceName(methodName);
142                         
143                         fromAppId = getFromAppId(headers);
144                         transId = getTransId(headers);
145                         String realTime = headers.getRequestHeaders().getFirst("Real-Time");
146                         //only consider header value for search         
147                         DBConnectionType type = this.determineConnectionType("force-cache", realTime);
148                         final Version version;
149                         if ("latest".equals(versionParam)) {
150                                 version = AAIProperties.LATEST;
151                         } else {
152                                 version = Version.valueOf(versionParam);
153                         }
154                         final ModelType factoryType = ModelType.MOXY;
155                         Loader loader = LoaderFactory.createLoaderForVersion(factoryType, version);
156                         TransactionalGraphEngine dbEngine = new TitanDBEngine(
157                                         QueryStyle.TRAVERSAL,
158                                         type,
159                                         loader);
160                         DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
161                         UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer);
162                         SearchGraph searchGraph = new SearchGraph();
163                         
164                         LoggingContext.startTime();
165                         StopWatch.conditionalStart();
166                         searchResult = searchGraph.runGenericQuery(
167                                                                                                            headers,
168                                                                                                            startNodeType,
169                                                                                                            startNodeKeyParams,
170                                                                                                            includeNodeTypes, 
171                                                                                                            depth,
172                                                                                                            dbEngine,
173                                                                                                            loader,
174                                                                                                            urlBuilder
175                                                                                                            
176                                                                                                            );
177                         dbTimeMsecs += StopWatch.stopIfStarted();
178                 
179                         LoggingContext.successStatusFields();
180                         LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
181                         
182                         LOGGER.info ("Completed");
183                         LoggingContext.restoreIfPossible();
184                         LoggingContext.successStatusFields();
185         
186                         String respTm = genDate();
187
188                 } catch (AAIException e) { 
189                         LoggingContext.restoreIfPossible();
190                         // send error response
191                         ex = e;
192                         templateVars.add("GET Search");
193                         templateVars.add("getGenericQueryResponse");
194                         searchResult =  Response
195                                                         .status(e.getErrorObject().getHTTPResponseCode())
196                                                         .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
197                                                         .build();
198                 } catch (Exception e) {
199                         LoggingContext.restoreIfPossible();
200                         // send error response
201                         ex = new AAIException("AAI_4000", e);
202                         templateVars.add("GET Search");
203                         templateVars.add("getGenericQueryResponse");
204                         searchResult = Response
205                                                         .status(Status.INTERNAL_SERVER_ERROR)
206                                                         .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
207                                                         .build();
208                 } finally {
209                         // log success or failure
210                         if (ex != null){
211                                 ErrorLogHelper.logException(ex);
212                         }
213                 }
214
215                 return searchResult;
216         }
217
218         /* ---------------- End Generic Query --------------------- */
219
220         /**
221          * Gets the nodes query response.
222          *
223          * @param headers the headers
224          * @param req the req
225          * @param searchNodeType the search node type
226          * @param edgeFilterList the edge filter list
227          * @param filterList the filter list
228          * @return the nodes query response
229          */
230         /* ---------------- Start Nodes Query --------------------- */
231         @GET
232         @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
233         @Path(NODES_QUERY)
234         public Response getNodesQueryResponse(@Context HttpHeaders headers,
235                                                                                   @Context HttpServletRequest req,
236                                                                                   @QueryParam("search-node-type") final String searchNodeType,
237                                                                                   @QueryParam("edge-filter") final List<String> edgeFilterList,
238                                                                                   @QueryParam("filter") final List<String> filterList,
239                                                                                   @PathParam("version")String versionParam,
240                                                                                   @Context UriInfo info)
241
242         {
243                 return runner(AAIConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED,
244                                 AAIConstants.AAI_TRAVERSAL_TIMEOUT_APP,
245                                 AAIConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT,
246                                 headers,
247                                 info,
248                                 HttpMethod.GET,
249                                 new Callable<Response>() {
250                                         @Override
251                                         public Response call() {
252                                                 return processNodesQueryResponse(headers, req, searchNodeType, edgeFilterList, filterList, versionParam);
253                                         }
254                                 }
255                 );
256         }
257         public Response processNodesQueryResponse(@Context HttpHeaders headers,
258                                                                                           @Context HttpServletRequest req,
259                                                                                           @QueryParam("search-node-type") final String searchNodeType,
260                                                                                           @QueryParam("edge-filter") final List<String> edgeFilterList,
261                                                                                           @QueryParam("filter") final List<String> filterList,
262                                                                                           @PathParam("version")String versionParam) {
263                 String methodName = "getNodesQueryResponse";
264                 AAIException ex = null;
265                 Response searchResult = null;
266                 String fromAppId = null;
267                 String transId = null;
268                 String rqstTm = genDate();
269                 ArrayList<String> templateVars = new ArrayList<String>();       
270                 double dbTimeMsecs = 0;
271                 try { 
272                         LoggingContext.save();
273                         LoggingContext.targetEntity(TARGET_ENTITY);
274                         LoggingContext.targetServiceName(methodName);
275                         
276                         fromAppId = getFromAppId(headers);
277                         transId = getTransId(headers);
278                         String realTime = headers.getRequestHeaders().getFirst("Real-Time");
279                         //only consider header value for search         
280                         DBConnectionType type = this.determineConnectionType("force-cache", realTime);
281                         
282                         final Version version;
283                         if ("latest".equals(versionParam)) {
284                                 version = AAIProperties.LATEST;
285                         } else {
286                                 version = Version.valueOf(versionParam);
287                         }
288                         final ModelType factoryType = ModelType.MOXY;
289                         Loader loader = LoaderFactory.createLoaderForVersion(factoryType, version);
290                         TransactionalGraphEngine dbEngine = new TitanDBEngine(
291                                         QueryStyle.TRAVERSAL,
292                                         type,
293                                         loader);
294                         DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
295                         UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer);
296                         SearchGraph searchGraph = new SearchGraph();
297                         
298                         LoggingContext.startTime();
299                         StopWatch.conditionalStart();
300                         
301                         searchResult = searchGraph.runNodesQuery(headers,
302                                                                                                         searchNodeType,
303                                                                                                         edgeFilterList, 
304                                                                                                         filterList,
305                                                                                                         dbEngine,
306                                                                                                         loader,
307                                                                                                         urlBuilder);
308                         dbTimeMsecs += StopWatch.stopIfStarted();
309                         LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
310                         LoggingContext.successStatusFields();
311                         LOGGER.info ("Completed");
312                         
313                         LoggingContext.restoreIfPossible();
314                         LoggingContext.successStatusFields();
315         
316                         String respTm = genDate();
317                 } catch (AAIException e) {
318                         LoggingContext.restoreIfPossible();
319                         // send error response
320                         ex = e;
321                         templateVars.add("GET Search");
322                         templateVars.add("getNodesQueryResponse");
323                         searchResult =  Response
324                                                         .status(e.getErrorObject().getHTTPResponseCode())
325                                                         .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
326                                                         .build();
327                 } catch (Exception e) {
328                         LoggingContext.restoreIfPossible();
329                         // send error response
330                         ex = new AAIException("AAI_4000", e);
331                         templateVars.add("GET Search");
332                         templateVars.add("getNodesQueryResponse");
333                         searchResult = Response
334                                                         .status(Status.INTERNAL_SERVER_ERROR)
335                                                         .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
336                                                         .build();
337                 } finally {
338                         // log success or failure
339                         if (ex != null){
340                                 ErrorLogHelper.logException(ex);
341                         }
342                 }
343                 return searchResult;
344         }
345
346
347         
348 }