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;
28 import java.util.HashMap;
30 import javax.ws.rs.Consumes;
31 import javax.ws.rs.DELETE;
32 import javax.ws.rs.GET;
33 import javax.ws.rs.HeaderParam;
34 import javax.ws.rs.POST;
35 import javax.ws.rs.PUT;
36 import javax.ws.rs.Path;
37 import javax.ws.rs.PathParam;
38 import javax.ws.rs.Produces;
39 import javax.ws.rs.core.Context;
40 import javax.ws.rs.core.MediaType;
41 import javax.ws.rs.core.UriInfo;
42 import javax.ws.rs.core.Response;
43 import javax.ws.rs.core.Response.ResponseBuilder;
44 import javax.ws.rs.core.Response.Status;
45 import org.onap.music.datastore.jsonobjects.JsonDelete;
46 import org.onap.music.datastore.jsonobjects.JsonInsert;
47 import org.onap.music.datastore.jsonobjects.JsonTable;
48 import org.onap.music.datastore.jsonobjects.JsonUpdate;
49 import org.onap.music.eelf.logging.EELFLoggerDelegate;
51 import org.onap.music.eelf.logging.format.AppMessages;
52 import org.onap.music.eelf.logging.format.ErrorSeverity;
53 import org.onap.music.eelf.logging.format.ErrorTypes;
54 import org.apache.commons.lang3.StringUtils;
55 import org.onap.music.datastore.MusicDataStoreHandle;
56 import org.onap.music.datastore.PreparedQueryObject;
57 import com.datastax.driver.core.ResultSet;
58 import org.onap.music.exceptions.MusicQueryException;
59 import org.onap.music.exceptions.MusicServiceException;
60 import org.onap.music.main.MusicCore;
61 import org.onap.music.main.MusicUtil;
62 import org.onap.music.main.ResultType;
63 import org.onap.music.response.jsonobjects.JsonResponse;
65 import io.swagger.annotations.Api;
66 import io.swagger.annotations.ApiOperation;
67 import io.swagger.annotations.ApiParam;
69 @Path("/v2/priorityq/")
71 public class RestMusicQAPI {
73 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicQAPI.class);
85 @Path("/keyspaces/{keyspace}/{qname}") // qname same as tablename
86 @ApiOperation(value = "Create Q", response = String.class)
87 @Consumes(MediaType.APPLICATION_JSON)
88 @Produces(MediaType.APPLICATION_JSON)
89 public Response createQ(
90 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
91 @ApiParam(value = "Minor Version",
92 required = false) @HeaderParam("X-minorVersion") String minorVersion,
93 @ApiParam(value = "Patch Version",
94 required = false) @HeaderParam("X-patchVersion") String patchVersion,
95 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
96 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
97 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
99 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
100 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception {
101 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
103 Map<String, String> fields = tableObj.getFields();
104 if (fields == null) {
105 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
106 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
107 return response.status(Status.BAD_REQUEST)
108 .entity(new JsonResponse(ResultType.FAILURE)
109 .setError("CreateQ/Required table fields are empty or not set").toMap())
113 String primaryKey = tableObj.getPrimaryKey();
114 String partitionKey = tableObj.getPartitionKey();
115 String clusteringKey = tableObj.getClusteringKey();
116 String filteringKey = tableObj.getFilteringKey();
117 String clusteringOrder = tableObj.getClusteringOrder();
119 if(primaryKey == null) {
120 primaryKey = tableObj.getFields().get("PRIMARY KEY");
123 if ((primaryKey == null) && (partitionKey == null)) {
124 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
125 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
126 return response.status(Status.BAD_REQUEST)
127 .entity(new JsonResponse(ResultType.FAILURE)
128 .setError("CreateQ: Partition key cannot be empty").toMap())
132 if ((primaryKey == null) && (clusteringKey == null)) {
133 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
134 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
135 return response.status(Status.BAD_REQUEST)
136 .entity(new JsonResponse(ResultType.FAILURE)
137 .setError("CreateQ: Clustering key cannot be empty").toMap())
141 if (clusteringOrder == null) {
142 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
143 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
144 return response.status(Status.BAD_REQUEST)
145 .entity(new JsonResponse(ResultType.FAILURE)
146 .setError("CreateQ: Clustering Order cannot be empty").toMap())
150 if ((primaryKey!=null) && (partitionKey == null)) {
151 primaryKey = primaryKey.trim();
152 int count1 = StringUtils.countMatches(primaryKey,')');
153 int count2 = StringUtils.countMatches(primaryKey,'(');
154 if (count1 != count2) {
155 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
156 .setError("CreateQ Error: primary key '(' and ')' do not match, primary key=" + primaryKey)
160 if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) )
162 if (primaryKey.contains(",") ) {
163 partitionKey= primaryKey.substring(0,primaryKey.indexOf(','));
164 partitionKey=partitionKey.replaceAll("[\\(]+","");
165 clusteringKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index
166 clusteringKey=clusteringKey.replaceAll("[)]+", "");
168 partitionKey=primaryKey;
169 partitionKey=partitionKey.replaceAll("[\\)]+","");
170 partitionKey=partitionKey.replaceAll("[\\(]+","");
174 partitionKey= primaryKey.substring(0,primaryKey.indexOf(')'));
175 partitionKey=partitionKey.replaceAll("[\\(]+","");
176 partitionKey = partitionKey.trim();
177 clusteringKey= primaryKey.substring(primaryKey.indexOf(')'));
178 clusteringKey=clusteringKey.replaceAll("[\\(]+","");
179 clusteringKey=clusteringKey.replaceAll("[\\)]+","");
180 clusteringKey = clusteringKey.trim();
181 if (clusteringKey.indexOf(',') == 0) clusteringKey=clusteringKey.substring(1);
182 clusteringKey = clusteringKey.trim();
183 if (clusteringKey.equals(",") ) clusteringKey=""; // print error if needed ( ... ),)
187 if (partitionKey.trim().isEmpty()) {
188 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
189 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
190 return response.status(Status.BAD_REQUEST)
191 .entity(new JsonResponse(ResultType.FAILURE)
192 .setError("CreateQ: Partition key cannot be empty").toMap())
196 if (clusteringKey.trim().isEmpty()) {
197 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
198 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
199 return response.status(Status.BAD_REQUEST)
200 .entity(new JsonResponse(ResultType.FAILURE)
201 .setError("CreateQ: Clustering key cannot be empty").toMap())
205 if((filteringKey != null) && (filteringKey.equalsIgnoreCase(partitionKey))) {
206 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
207 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
208 return response.status(Status.BAD_REQUEST)
209 .entity(new JsonResponse(ResultType.FAILURE)
210 .setError("CreateQ: Filtering key cannot be same as Partition Key").toMap())
214 return new RestMusicDataAPI().createTable(version, minorVersion, patchVersion, aid, ns, authorization, tableObj, keyspace, tablename);
225 @Path("/keyspaces/{keyspace}/{qname}/rows")
226 @ApiOperation(value = "", response = Void.class)
227 @Consumes(MediaType.APPLICATION_JSON)
228 @Produces(MediaType.APPLICATION_JSON)
229 // public Map<String, Object> insertIntoQ(
230 public Response insertIntoQ(
231 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
232 @ApiParam(value = "Minor Version",
233 required = false) @HeaderParam("X-minorVersion") String minorVersion,
234 @ApiParam(value = "Patch Version",
235 required = false) @HeaderParam("X-patchVersion") String patchVersion,
236 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
237 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
238 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
240 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
241 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename)
243 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
244 if (insObj.getValues().isEmpty()) {
245 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
246 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
247 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
248 .setError("Required HTTP Request body is missing.").toMap()).build();
250 return new RestMusicDataAPI().insertIntoTable(version, minorVersion, patchVersion, aid, ns,
251 authorization, insObj, keyspace, tablename);
264 @Path("/keyspaces/{keyspace}/{qname}/rows")
265 @ApiOperation(value = "updateQ", response = String.class)
266 @Consumes(MediaType.APPLICATION_JSON)
267 @Produces(MediaType.APPLICATION_JSON)
268 public Response updateQ(
269 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
270 @ApiParam(value = "Minor Version",
271 required = false) @HeaderParam("X-minorVersion") String minorVersion,
272 @ApiParam(value = "Patch Version",
273 required = false) @HeaderParam("X-patchVersion") String patchVersion,
274 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
275 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
276 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
277 JsonUpdate updateObj,
278 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
279 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
280 @Context UriInfo info) throws MusicServiceException, MusicQueryException {
282 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
283 if (updateObj.getValues().isEmpty()) {
284 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
285 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
286 return response.status(Status.BAD_REQUEST)
287 .entity(new JsonResponse(ResultType.FAILURE).setError(
288 "Required HTTP Request body is missing. JsonUpdate updateObj.getValues() is empty. ")
294 return new RestMusicDataAPI().updateTable(version, minorVersion, patchVersion, aid, ns,
295 authorization,updateObj, keyspace, tablename, info);
310 @Path("/keyspaces/{keyspace}/{qname}/rows")
311 @ApiOperation(value = "deleteQ", response = String.class)
312 @Consumes(MediaType.APPLICATION_JSON)
313 @Produces(MediaType.APPLICATION_JSON)
314 public Response deleteFromQ(
315 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
316 @ApiParam(value = "Minor Version",
317 required = false) @HeaderParam("X-minorVersion") String minorVersion,
318 @ApiParam(value = "Patch Version",
319 required = false) @HeaderParam("X-patchVersion") String patchVersion,
320 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
321 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
322 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
324 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
325 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
326 @Context UriInfo info) throws MusicServiceException, MusicQueryException {
327 // added checking as per RestMusicDataAPI
328 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
329 if (delObj == null) {
330 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
331 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
332 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
333 .setError("deleteFromQ JsonDelete delObjis empty").toMap()).build();
336 return new RestMusicDataAPI().deleteFromTable(version, minorVersion, patchVersion, aid, ns,
337 authorization, delObj, keyspace, tablename, info);
349 @Path("/keyspaces/{keyspace}/{qname}/peek")
350 @ApiOperation(value = "", response = Map.class)
351 @Produces(MediaType.APPLICATION_JSON)
352 //public Map<String, HashMap<String, Object>> peek(
353 public Response peek(
354 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
355 @ApiParam(value = "Minor Version",
356 required = false) @HeaderParam("X-minorVersion") String minorVersion,
357 @ApiParam(value = "Patch Version",
358 required = false) @HeaderParam("X-patchVersion") String patchVersion,
359 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
360 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
361 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
362 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
363 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
364 @Context UriInfo info) {
365 int limit =1; //peek must return just the top row
366 Map<String ,String> auth = new HashMap<>();
367 String userId =auth.get(MusicUtil.USERID);
368 String password =auth.get(MusicUtil.PASSWORD);
369 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
371 PreparedQueryObject queryObject = new PreparedQueryObject();
372 if (info.getQueryParameters() == null ) //|| info.getQueryParameters().isEmpty())
373 queryObject.appendQueryString(
374 "SELECT * FROM " + keyspace + "." + tablename + " LIMIT " + limit + ";");
378 queryObject = new RestMusicDataAPI().selectSpecificQuery(keyspace, tablename, info, limit);
379 } catch (MusicServiceException ex) {
380 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR,
381 ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, ex);
382 return response.status(Status.BAD_REQUEST)
383 .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap())
389 ResultSet results = MusicCore.get(queryObject);
390 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS)
391 .setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
392 } catch (MusicServiceException ex) {
393 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR,
394 ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR, ex);
395 return response.status(Status.BAD_REQUEST)
396 .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap())
411 @Path("/keyspaces/{keyspace}/{qname}/filter")
412 @ApiOperation(value = "filter", response = Map.class)
413 @Produces(MediaType.APPLICATION_JSON)
414 // public Map<String, HashMap<String, Object>> filter(
415 public Response filter(
416 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
417 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
418 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
419 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
420 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
421 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
422 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
423 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
424 @Context UriInfo info) throws Exception {
425 return new RestMusicDataAPI().select(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename, info);// , limit)
437 @ApiOperation(value = "DropQ", response = String.class)
438 @Path("/keyspaces/{keyspace}/{qname}")
439 @Produces(MediaType.APPLICATION_JSON)
440 public Response dropQ(
441 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
442 @ApiParam(value = "Minor Version",
443 required = false) @HeaderParam("X-minorVersion") String minorVersion,
444 @ApiParam(value = "Patch Version",
445 required = false) @HeaderParam("X-patchVersion") String patchVersion,
446 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
447 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
448 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
449 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
450 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception {
452 return new RestMusicDataAPI().dropTable(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename);