2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (c) 2017 AT&T Intellectual Property
6 * ===================================================================
7 * Modifications Copyright (C) 2019 IBM.
8 * Modifications Copyright (c) 2019 Samsung
9 * ===================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
22 * ============LICENSE_END=============================================
23 * ====================================================================
26 package org.onap.music.rest;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.HeaderParam;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.PUT;
35 import javax.ws.rs.Path;
36 import javax.ws.rs.PathParam;
37 import javax.ws.rs.Produces;
38 import javax.ws.rs.core.Context;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.UriInfo;
41 import javax.ws.rs.core.Response;
42 import javax.ws.rs.core.Response.ResponseBuilder;
43 import javax.ws.rs.core.Response.Status;
44 import org.onap.music.datastore.jsonobjects.JsonDelete;
45 import org.onap.music.datastore.jsonobjects.JsonInsert;
46 import org.onap.music.datastore.jsonobjects.JsonTable;
47 import org.onap.music.datastore.jsonobjects.JsonUpdate;
48 import org.onap.music.eelf.logging.EELFLoggerDelegate;
50 import org.onap.music.eelf.logging.format.AppMessages;
51 import org.onap.music.eelf.logging.format.ErrorSeverity;
52 import org.onap.music.eelf.logging.format.ErrorTypes;
53 import org.apache.commons.lang3.StringUtils;
54 import org.onap.music.datastore.MusicDataStoreHandle;
55 import org.onap.music.datastore.PreparedQueryObject;
56 import com.datastax.driver.core.ResultSet;
57 import org.onap.music.exceptions.MusicQueryException;
58 import org.onap.music.exceptions.MusicServiceException;
59 import org.onap.music.main.MusicCore;
60 import org.onap.music.main.MusicUtil;
61 import org.onap.music.main.ResultType;
62 import org.onap.music.response.jsonobjects.JsonResponse;
64 import io.swagger.annotations.Api;
65 import io.swagger.annotations.ApiOperation;
66 import io.swagger.annotations.ApiParam;
68 @Path("/v2/priorityq/")
69 @Api(value = "Q Api",hidden = true)
70 public class RestMusicQAPI {
72 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicQAPI.class);
84 @Path("/keyspaces/{keyspace}/{qname}") // qname same as tablename
85 @ApiOperation(value = "Create Q", response = String.class)
86 @Consumes(MediaType.APPLICATION_JSON)
87 @Produces(MediaType.APPLICATION_JSON)
88 public Response createQ(
89 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
90 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
91 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
92 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
93 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
94 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
96 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
97 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception {
98 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
100 Map<String, String> fields = tableObj.getFields();
101 if (fields == null) {
102 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
103 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
104 return response.status(Status.BAD_REQUEST)
105 .entity(new JsonResponse(ResultType.FAILURE)
106 .setError("CreateQ/Required table fields are empty or not set").toMap())
110 String primaryKey = tableObj.getPrimaryKey();
111 String partitionKey = tableObj.getPartitionKey();
112 String clusteringKey = tableObj.getClusteringKey();
113 String filteringKey = tableObj.getFilteringKey();
114 String clusteringOrder = tableObj.getClusteringOrder();
116 if(primaryKey == null) {
117 primaryKey = tableObj.getFields().get("PRIMARY KEY");
120 if ((primaryKey == null) && (partitionKey == null)) {
121 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
122 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
123 return response.status(Status.BAD_REQUEST)
124 .entity(new JsonResponse(ResultType.FAILURE)
125 .setError("CreateQ: Partition key cannot be empty").toMap())
129 if ((primaryKey == null) && (clusteringKey == null)) {
130 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
131 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
132 return response.status(Status.BAD_REQUEST)
133 .entity(new JsonResponse(ResultType.FAILURE)
134 .setError("CreateQ: Clustering key cannot be empty").toMap())
138 if (clusteringOrder == null) {
139 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
140 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
141 return response.status(Status.BAD_REQUEST)
142 .entity(new JsonResponse(ResultType.FAILURE)
143 .setError("CreateQ: Clustering Order cannot be empty").toMap())
147 if ((primaryKey!=null) && (partitionKey == null)) {
148 primaryKey = primaryKey.trim();
149 int count1 = StringUtils.countMatches(primaryKey,')');
150 int count2 = StringUtils.countMatches(primaryKey,'(');
151 if (count1 != count2) {
152 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
153 .setError("CreateQ Error: primary key '(' and ')' do not match, primary key=" + primaryKey)
157 if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) ) {
158 if (primaryKey.contains(",") ) {
159 partitionKey= primaryKey.substring(0,primaryKey.indexOf(','));
160 partitionKey=partitionKey.replaceAll("[\\(]+","");
161 clusteringKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index
162 clusteringKey=clusteringKey.replaceAll("[)]+", "");
164 partitionKey=primaryKey;
165 partitionKey=partitionKey.replaceAll("[\\)]+","");
166 partitionKey=partitionKey.replaceAll("[\\(]+","");
170 partitionKey= primaryKey.substring(0,primaryKey.indexOf(')'));
171 partitionKey=partitionKey.replaceAll("[\\(]+","");
172 partitionKey = partitionKey.trim();
173 clusteringKey= primaryKey.substring(primaryKey.indexOf(')'));
174 clusteringKey=clusteringKey.replaceAll("[\\(]+","");
175 clusteringKey=clusteringKey.replaceAll("[\\)]+","");
176 clusteringKey = clusteringKey.trim();
177 if (clusteringKey.indexOf(',') == 0)
178 clusteringKey=clusteringKey.substring(1);
179 clusteringKey = clusteringKey.trim();
180 if (clusteringKey.equals(",") )
181 clusteringKey=""; // print error if needed ( ... ),)
185 if (partitionKey.trim().isEmpty()) {
186 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
187 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
188 return response.status(Status.BAD_REQUEST)
189 .entity(new JsonResponse(ResultType.FAILURE)
190 .setError("CreateQ: Partition key cannot be empty").toMap())
194 if (clusteringKey.trim().isEmpty()) {
195 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
196 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
197 return response.status(Status.BAD_REQUEST)
198 .entity(new JsonResponse(ResultType.FAILURE)
199 .setError("CreateQ: Clustering key cannot be empty").toMap())
203 if((filteringKey != null) && (filteringKey.equalsIgnoreCase(partitionKey))) {
204 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
205 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
206 return response.status(Status.BAD_REQUEST)
207 .entity(new JsonResponse(ResultType.FAILURE)
208 .setError("CreateQ: Filtering key cannot be same as Partition Key").toMap())
212 return new RestMusicDataAPI().createTable(version, minorVersion, patchVersion, aid, ns, authorization, tableObj, keyspace, tablename);
223 @Path("/keyspaces/{keyspace}/{qname}/rows")
224 @ApiOperation(value = "", response = Void.class)
225 @Consumes(MediaType.APPLICATION_JSON)
226 @Produces(MediaType.APPLICATION_JSON)
227 // public Map<String, Object> insertIntoQ(
228 public Response insertIntoQ(
229 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
230 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
231 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
232 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
233 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
234 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
236 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
237 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) {
239 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
240 if (insObj.getValues().isEmpty()) {
241 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
242 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
243 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
244 .setError("Required HTTP Request body is missing.").toMap()).build();
246 return new RestMusicDataAPI().insertIntoTable(version, minorVersion, patchVersion, aid, ns,
247 authorization, insObj, keyspace, tablename);
260 @Path("/keyspaces/{keyspace}/{qname}/rows")
261 @ApiOperation(value = "updateQ", response = String.class)
262 @Consumes(MediaType.APPLICATION_JSON)
263 @Produces(MediaType.APPLICATION_JSON)
264 public Response updateQ(
265 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
266 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
267 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
268 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
269 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
270 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
271 JsonUpdate updateObj,
272 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
273 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
274 @Context UriInfo info) throws MusicServiceException, MusicQueryException {
276 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
277 if (updateObj.getValues().isEmpty()) {
278 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
279 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
280 return response.status(Status.BAD_REQUEST)
281 .entity(new JsonResponse(ResultType.FAILURE)
282 .setError("Required HTTP Request body is missing. JsonUpdate updateObj.getValues() is empty. ")
286 return new RestMusicDataAPI().updateTable(version, minorVersion, patchVersion, aid, ns,
287 authorization,updateObj, keyspace, tablename, info);
302 @Path("/keyspaces/{keyspace}/{qname}/rows")
303 @ApiOperation(value = "deleteQ", response = String.class)
304 @Consumes(MediaType.APPLICATION_JSON)
305 @Produces(MediaType.APPLICATION_JSON)
306 public Response deleteFromQ(
307 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
308 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
309 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
310 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
311 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
312 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
314 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
315 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
316 @Context UriInfo info) throws MusicServiceException, MusicQueryException {
317 // added checking as per RestMusicDataAPI
318 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
319 if (delObj == null) {
320 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
321 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
322 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
323 .setError("deleteFromQ JsonDelete delObjis empty").toMap()).build();
326 return new RestMusicDataAPI().deleteFromTable(version, minorVersion, patchVersion, aid, ns,
327 authorization, delObj, keyspace, tablename, info);
339 @Path("/keyspaces/{keyspace}/{qname}/peek")
340 @ApiOperation(value = "", response = Map.class)
341 @Produces(MediaType.APPLICATION_JSON)
342 //public Map<String, HashMap<String, Object>> peek(
343 public Response peek(
344 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
345 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
346 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
347 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
348 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
349 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
350 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
351 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
352 @Context UriInfo info) {
353 int limit =1; //peek must return just the top row
354 // Map<String ,String> auth = new HashMap<>();
355 // String userId =auth.get(MusicUtil.USERID);
356 // String password =auth.get(MusicUtil.PASSWORD);
357 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
359 PreparedQueryObject queryObject = new PreparedQueryObject();
360 if (info.getQueryParameters() == null ) { //|| info.getQueryParameters().isEmpty())
361 queryObject.appendQueryString(
362 "SELECT * FROM " + keyspace + "." + tablename + " LIMIT " + limit + ";");
365 queryObject = new RestMusicDataAPI().selectSpecificQuery(keyspace, tablename, info, limit);
366 } catch (MusicServiceException ex) {
367 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR,
368 ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, ex);
369 return response.status(Status.BAD_REQUEST)
370 .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap())
376 ResultSet results = MusicCore.get(queryObject);
377 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS)
378 .setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
379 } catch (MusicServiceException ex) {
380 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR,
381 ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR, ex);
382 return response.status(Status.BAD_REQUEST)
383 .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap())
398 @Path("/keyspaces/{keyspace}/{qname}/filter")
399 @ApiOperation(value = "filter", response = Map.class)
400 @Produces(MediaType.APPLICATION_JSON)
401 // public Map<String, HashMap<String, Object>> filter(
402 public Response filter(
403 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
404 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
405 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
406 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
407 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
408 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
409 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
410 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
411 @Context UriInfo info) throws Exception {
413 return new RestMusicDataAPI().selectWithCritical(version, minorVersion, patchVersion, aid, ns, authorization,null, keyspace, tablename, info);// , limit)
425 @ApiOperation(value = "DropQ", response = String.class)
426 @Path("/keyspaces/{keyspace}/{qname}")
427 @Produces(MediaType.APPLICATION_JSON)
428 public Response dropQ(
429 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
430 @ApiParam(value = "Minor Version",
431 required = false) @HeaderParam("X-minorVersion") String minorVersion,
432 @ApiParam(value = "Patch Version",
433 required = false) @HeaderParam("X-patchVersion") String patchVersion,
434 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
435 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
436 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
437 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
438 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception {
440 return new RestMusicDataAPI().dropTable(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename);