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", required = false) @HeaderParam("X-minorVersion") String minorVersion,
92 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
93 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
94 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
95 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
97 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
98 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception {
99 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
101 Map<String, String> fields = tableObj.getFields();
102 if (fields == null) {
103 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
104 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
105 return response.status(Status.BAD_REQUEST)
106 .entity(new JsonResponse(ResultType.FAILURE)
107 .setError("CreateQ/Required table fields are empty or not set").toMap())
111 String primaryKey = tableObj.getPrimaryKey();
112 String partitionKey = tableObj.getPartitionKey();
113 String clusteringKey = tableObj.getClusteringKey();
114 String filteringKey = tableObj.getFilteringKey();
115 String clusteringOrder = tableObj.getClusteringOrder();
117 if(primaryKey == null) {
118 primaryKey = tableObj.getFields().get("PRIMARY KEY");
121 if ((primaryKey == null) && (partitionKey == null)) {
122 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
123 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
124 return response.status(Status.BAD_REQUEST)
125 .entity(new JsonResponse(ResultType.FAILURE)
126 .setError("CreateQ: Partition key cannot be empty").toMap())
130 if ((primaryKey == null) && (clusteringKey == null)) {
131 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
132 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
133 return response.status(Status.BAD_REQUEST)
134 .entity(new JsonResponse(ResultType.FAILURE)
135 .setError("CreateQ: Clustering key cannot be empty").toMap())
139 if (clusteringOrder == null) {
140 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
141 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
142 return response.status(Status.BAD_REQUEST)
143 .entity(new JsonResponse(ResultType.FAILURE)
144 .setError("CreateQ: Clustering Order cannot be empty").toMap())
148 if ((primaryKey!=null) && (partitionKey == null)) {
149 primaryKey = primaryKey.trim();
150 int count1 = StringUtils.countMatches(primaryKey,')');
151 int count2 = StringUtils.countMatches(primaryKey,'(');
152 if (count1 != count2) {
153 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
154 .setError("CreateQ Error: primary key '(' and ')' do not match, primary key=" + primaryKey)
158 if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) ) {
159 if (primaryKey.contains(",") ) {
160 partitionKey= primaryKey.substring(0,primaryKey.indexOf(','));
161 partitionKey=partitionKey.replaceAll("[\\(]+","");
162 clusteringKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index
163 clusteringKey=clusteringKey.replaceAll("[)]+", "");
165 partitionKey=primaryKey;
166 partitionKey=partitionKey.replaceAll("[\\)]+","");
167 partitionKey=partitionKey.replaceAll("[\\(]+","");
171 partitionKey= primaryKey.substring(0,primaryKey.indexOf(')'));
172 partitionKey=partitionKey.replaceAll("[\\(]+","");
173 partitionKey = partitionKey.trim();
174 clusteringKey= primaryKey.substring(primaryKey.indexOf(')'));
175 clusteringKey=clusteringKey.replaceAll("[\\(]+","");
176 clusteringKey=clusteringKey.replaceAll("[\\)]+","");
177 clusteringKey = clusteringKey.trim();
178 if (clusteringKey.indexOf(',') == 0) clusteringKey=clusteringKey.substring(1);
179 clusteringKey = clusteringKey.trim();
180 if (clusteringKey.equals(",") ) clusteringKey=""; // print error if needed ( ... ),)
184 if (partitionKey.trim().isEmpty()) {
185 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
186 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
187 return response.status(Status.BAD_REQUEST)
188 .entity(new JsonResponse(ResultType.FAILURE)
189 .setError("CreateQ: Partition key cannot be empty").toMap())
193 if (clusteringKey.trim().isEmpty()) {
194 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
195 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
196 return response.status(Status.BAD_REQUEST)
197 .entity(new JsonResponse(ResultType.FAILURE)
198 .setError("CreateQ: Clustering key cannot be empty").toMap())
202 if((filteringKey != null) && (filteringKey.equalsIgnoreCase(partitionKey))) {
203 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
204 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
205 return response.status(Status.BAD_REQUEST)
206 .entity(new JsonResponse(ResultType.FAILURE)
207 .setError("CreateQ: Filtering key cannot be same as Partition Key").toMap())
211 return new RestMusicDataAPI().createTable(version, minorVersion, patchVersion, aid, ns, authorization, tableObj, keyspace, tablename);
222 @Path("/keyspaces/{keyspace}/{qname}/rows")
223 @ApiOperation(value = "", response = Void.class)
224 @Consumes(MediaType.APPLICATION_JSON)
225 @Produces(MediaType.APPLICATION_JSON)
226 // public Map<String, Object> insertIntoQ(
227 public Response insertIntoQ(
228 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
229 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
230 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
231 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
232 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
233 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
235 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
236 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) {
238 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
239 if (insObj.getValues().isEmpty()) {
240 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
241 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
242 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
243 .setError("Required HTTP Request body is missing.").toMap()).build();
245 return new RestMusicDataAPI().insertIntoTable(version, minorVersion, patchVersion, aid, ns,
246 authorization, insObj, keyspace, tablename);
259 @Path("/keyspaces/{keyspace}/{qname}/rows")
260 @ApiOperation(value = "updateQ", response = String.class)
261 @Consumes(MediaType.APPLICATION_JSON)
262 @Produces(MediaType.APPLICATION_JSON)
263 public Response updateQ(
264 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
265 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
266 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
267 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
268 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
269 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
270 JsonUpdate updateObj,
271 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
272 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
273 @Context UriInfo info) throws MusicServiceException, MusicQueryException {
275 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
276 if (updateObj.getValues().isEmpty()) {
277 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
278 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
279 return response.status(Status.BAD_REQUEST)
280 .entity(new JsonResponse(ResultType.FAILURE)
281 .setError("Required HTTP Request body is missing. JsonUpdate updateObj.getValues() is empty. ")
285 return new RestMusicDataAPI().updateTable(version, minorVersion, patchVersion, aid, ns,
286 authorization,updateObj, keyspace, tablename, info);
301 @Path("/keyspaces/{keyspace}/{qname}/rows")
302 @ApiOperation(value = "deleteQ", response = String.class)
303 @Consumes(MediaType.APPLICATION_JSON)
304 @Produces(MediaType.APPLICATION_JSON)
305 public Response deleteFromQ(
306 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
307 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
308 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
309 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
310 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
311 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
313 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
314 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
315 @Context UriInfo info) throws MusicServiceException, MusicQueryException {
316 // added checking as per RestMusicDataAPI
317 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
318 if (delObj == null) {
319 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
320 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
321 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
322 .setError("deleteFromQ JsonDelete delObjis empty").toMap()).build();
325 return new RestMusicDataAPI().deleteFromTable(version, minorVersion, patchVersion, aid, ns,
326 authorization, delObj, keyspace, tablename, info);
338 @Path("/keyspaces/{keyspace}/{qname}/peek")
339 @ApiOperation(value = "", response = Map.class)
340 @Produces(MediaType.APPLICATION_JSON)
341 //public Map<String, HashMap<String, Object>> peek(
342 public Response peek(
343 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
344 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
345 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
346 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
347 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
348 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
349 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
350 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
351 @Context UriInfo info) {
352 int limit =1; //peek must return just the top row
353 Map<String ,String> auth = new HashMap<>();
354 String userId =auth.get(MusicUtil.USERID);
355 String password =auth.get(MusicUtil.PASSWORD);
356 ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion);
358 PreparedQueryObject queryObject = new PreparedQueryObject();
359 if (info.getQueryParameters() == null ) { //|| info.getQueryParameters().isEmpty())
360 queryObject.appendQueryString(
361 "SELECT * FROM " + keyspace + "." + tablename + " LIMIT " + limit + ";");
364 queryObject = new RestMusicDataAPI().selectSpecificQuery(keyspace, tablename, info, limit);
365 } catch (MusicServiceException ex) {
366 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR,
367 ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, ex);
368 return response.status(Status.BAD_REQUEST)
369 .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap())
375 ResultSet results = MusicCore.get(queryObject);
376 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS)
377 .setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
378 } catch (MusicServiceException ex) {
379 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR,
380 ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR, ex);
381 return response.status(Status.BAD_REQUEST)
382 .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap())
397 @Path("/keyspaces/{keyspace}/{qname}/filter")
398 @ApiOperation(value = "filter", response = Map.class)
399 @Produces(MediaType.APPLICATION_JSON)
400 // public Map<String, HashMap<String, Object>> filter(
401 public Response filter(
402 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
403 @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion,
404 @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion,
405 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
406 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
407 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
408 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
409 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename,
410 @Context UriInfo info) throws Exception {
412 return new RestMusicDataAPI().select(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename, info);// , limit)
424 @ApiOperation(value = "DropQ", response = String.class)
425 @Path("/keyspaces/{keyspace}/{qname}")
426 @Produces(MediaType.APPLICATION_JSON)
427 public Response dropQ(
428 @ApiParam(value = "Major Version", required = true) @PathParam("version") String version,
429 @ApiParam(value = "Minor Version",
430 required = false) @HeaderParam("X-minorVersion") String minorVersion,
431 @ApiParam(value = "Patch Version",
432 required = false) @HeaderParam("X-patchVersion") String patchVersion,
433 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
434 @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns,
435 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
436 @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace,
437 @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception {
439 return new RestMusicDataAPI().dropTable(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename);