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.search;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.concurrent.TimeUnit;
25 import java.util.concurrent.Callable;
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;
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;
61 import com.att.eelf.configuration.EELFLogger;
62 import com.att.eelf.configuration.EELFManager;
64 * Implements the search subdomain in the REST API. All API calls must include
65 * X-FromAppId and X-TransactionId in the header.
71 @Path("/{version: v[789]|v1[0123]|latest}/search")
72 public class SearchProvider extends RESTAPI {
74 protected static String authPolicyFunctionName = "search";
76 public static final String GENERIC_QUERY = "/generic-query";
78 public static final String NODES_QUERY = "/nodes-query";
80 public static final String TARGET_ENTITY = "DB";
81 private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchProvider.class);
83 * Gets the generic query response.
85 * @param headers the headers
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
93 /* ---------------- Start Generic Query --------------------- */
95 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
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
106 return runner(AAIConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED,
107 AAIConstants.AAI_TRAVERSAL_TIMEOUT_APP,
108 AAIConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT,
112 new Callable<Response>() {
114 public Response call() {
115 return processGenericQueryResponse(headers, req, startNodeType, startNodeKeyParams, includeNodeTypes, depth, versionParam);
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
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;
139 LoggingContext.save();
140 LoggingContext.targetEntity(TARGET_ENTITY);
141 LoggingContext.targetServiceName(methodName);
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;
152 version = Version.valueOf(versionParam);
154 final ModelType factoryType = ModelType.MOXY;
155 Loader loader = LoaderFactory.createLoaderForVersion(factoryType, version);
156 TransactionalGraphEngine dbEngine = new TitanDBEngine(
157 QueryStyle.TRAVERSAL,
160 DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
161 UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer);
162 SearchGraph searchGraph = new SearchGraph();
164 LoggingContext.startTime();
165 StopWatch.conditionalStart();
166 searchResult = searchGraph.runGenericQuery(
177 dbTimeMsecs += StopWatch.stopIfStarted();
179 LoggingContext.successStatusFields();
180 LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
182 LOGGER.info ("Completed");
183 LoggingContext.restoreIfPossible();
184 LoggingContext.successStatusFields();
186 String respTm = genDate();
188 } catch (AAIException e) {
189 LoggingContext.restoreIfPossible();
190 // send error response
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))
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))
209 // log success or failure
211 ErrorLogHelper.logException(ex);
218 /* ---------------- End Generic Query --------------------- */
221 * Gets the nodes query response.
223 * @param headers the headers
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
230 /* ---------------- Start Nodes Query --------------------- */
232 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
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)
243 return runner(AAIConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED,
244 AAIConstants.AAI_TRAVERSAL_TIMEOUT_APP,
245 AAIConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT,
249 new Callable<Response>() {
251 public Response call() {
252 return processNodesQueryResponse(headers, req, searchNodeType, edgeFilterList, filterList, versionParam);
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;
272 LoggingContext.save();
273 LoggingContext.targetEntity(TARGET_ENTITY);
274 LoggingContext.targetServiceName(methodName);
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);
282 final Version version;
283 if ("latest".equals(versionParam)) {
284 version = AAIProperties.LATEST;
286 version = Version.valueOf(versionParam);
288 final ModelType factoryType = ModelType.MOXY;
289 Loader loader = LoaderFactory.createLoaderForVersion(factoryType, version);
290 TransactionalGraphEngine dbEngine = new TitanDBEngine(
291 QueryStyle.TRAVERSAL,
294 DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
295 UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer);
296 SearchGraph searchGraph = new SearchGraph();
298 LoggingContext.startTime();
299 StopWatch.conditionalStart();
301 searchResult = searchGraph.runNodesQuery(headers,
308 dbTimeMsecs += StopWatch.stopIfStarted();
309 LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
310 LoggingContext.successStatusFields();
311 LOGGER.info ("Completed");
313 LoggingContext.restoreIfPossible();
314 LoggingContext.successStatusFields();
316 String respTm = genDate();
317 } catch (AAIException e) {
318 LoggingContext.restoreIfPossible();
319 // send error response
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))
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))
338 // log success or failure
340 ErrorLogHelper.logException(ex);