2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (c) 2017 AT&T Intellectual Property
6 * ===================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ===================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ============LICENSE_END=============================================
22 * ====================================================================
25 package org.onap.music.rest;
27 import java.nio.ByteBuffer;
28 import java.util.List;
30 import java.util.UUID;
32 import javax.ws.rs.Consumes;
33 import javax.ws.rs.DELETE;
34 import javax.ws.rs.GET;
35 import javax.ws.rs.HeaderParam;
36 import javax.ws.rs.POST;
37 import javax.ws.rs.PUT;
38 import javax.ws.rs.Path;
39 import javax.ws.rs.PathParam;
40 import javax.ws.rs.Produces;
41 import javax.ws.rs.core.Context;
42 import javax.ws.rs.core.MediaType;
43 import javax.ws.rs.core.MultivaluedMap;
44 import javax.ws.rs.core.Response;
45 import javax.ws.rs.core.Response.ResponseBuilder;
46 import javax.ws.rs.core.Response.Status;
47 import javax.ws.rs.core.UriInfo;
49 import org.apache.commons.lang3.StringUtils;
50 import org.mindrot.jbcrypt.BCrypt;
51 import org.onap.music.authentication.CachingUtil;
52 import org.onap.music.authentication.MusicAAFAuthentication;
53 import org.onap.music.authentication.MusicAuthenticator;
54 import org.onap.music.authentication.MusicAuthenticator.Operation;
55 import org.onap.music.datastore.PreparedQueryObject;
56 import org.onap.music.datastore.jsonobjects.JsonDelete;
57 import org.onap.music.datastore.jsonobjects.JsonInsert;
58 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
59 import org.onap.music.datastore.jsonobjects.JsonTable;
60 import org.onap.music.datastore.jsonobjects.JsonUpdate;
61 import org.onap.music.eelf.logging.EELFLoggerDelegate;
62 import org.onap.music.exceptions.MusicLockingException;
63 import org.onap.music.exceptions.MusicQueryException;
64 import org.onap.music.eelf.logging.format.AppMessages;
65 import org.onap.music.eelf.logging.format.ErrorSeverity;
66 import org.onap.music.eelf.logging.format.ErrorTypes;
67 import org.onap.music.exceptions.MusicServiceException;
68 import org.onap.music.main.MusicCore;
69 import org.onap.music.datastore.Condition;
70 import org.onap.music.datastore.MusicDataStoreHandle;
71 import org.onap.music.main.MusicUtil;
72 import org.onap.music.main.ResultType;
73 import org.onap.music.main.ReturnType;
74 import org.onap.music.response.jsonobjects.JsonResponse;
76 import com.datastax.driver.core.DataType;
77 import com.datastax.driver.core.ResultSet;
78 import com.datastax.driver.core.Row;
79 import com.datastax.driver.core.TableMetadata;
81 import io.swagger.annotations.Api;
82 import io.swagger.annotations.ApiOperation;
83 import io.swagger.annotations.ApiParam;
84 import io.swagger.annotations.ApiResponses;
85 import io.swagger.annotations.ApiResponse;
88 //@Path("/v{version: [0-9]+}/keyspaces")
89 @Path("/v2/keyspaces")
90 @Api(value = "Data Api")
91 public class RestMusicDataAPI {
93 * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR
94 * version back from the client to the server, and from the server back to the client - This
95 * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR
96 * version (if not specified by the client on the request) - Contains a single position value
97 * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on
98 * request; however, this header should be provided if the client needs to take advantage of
99 * MINOR incremented version functionality - Is mandatory for the server on response
101 *** X-patchVersion *** - Used only to communicate a PATCH version in a response for
102 * troubleshooting purposes only, and will not be provided by the client on request - This will
103 * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version
104 * of the MAJOR (if not specified by the client on the request) - Contains a single position
105 * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the
106 * server on response (CURRENTLY NOT USED)
108 *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the
109 * server on response, and shall include the entire version of the API (e.g. if the full version
110 * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are
111 * not using the latest version of the API (CURRENTLY NOT USED)
115 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class);
116 private static final String XMINORVERSION = "X-minorVersion";
117 private static final String XPATCHVERSION = "X-patchVersion";
118 private static final String NS = "ns";
119 private static final String VERSION = "v2";
120 private MusicAuthenticator authenticator = new MusicAAFAuthentication();
121 // Set to true in env like ONAP. Where access to creating and dropping keyspaces exist.
122 private static final boolean KEYSPACE_ACTIVE = false;
124 private class RowIdentifier {
125 public String primarKeyValue;
126 public StringBuilder rowIdString;
127 @SuppressWarnings("unused")
128 public PreparedQueryObject queryObject;// the string with all the row
129 // identifiers separated by AND
131 public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
132 PreparedQueryObject queryObject) {
133 this.primarKeyValue = primaryKeyValue;
134 this.rowIdString = rowIdString;
135 this.queryObject = queryObject;
141 * Create Keyspace REST
144 * @param keyspaceName
150 @ApiOperation(value = "Create Keyspace", response = String.class,hidden = true)
151 @Consumes(MediaType.APPLICATION_JSON)
152 @Produces(MediaType.APPLICATION_JSON)
153 public Response createKeySpace(
154 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
155 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
156 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
157 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
158 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
159 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
160 JsonKeySpace kspObject,
161 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) {
163 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
164 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
165 logger.info(EELFLoggerDelegate.applicationLogger,"In Create Keyspace " + keyspaceName);
166 if ( KEYSPACE_ACTIVE ) {
167 logger.info(EELFLoggerDelegate.applicationLogger,"Creating Keyspace " + keyspaceName);
168 Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization);
169 String userId = userCredentials.get(MusicUtil.USERID);
170 String password = userCredentials.get(MusicUtil.PASSWORD);
171 Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password);
172 if (!authMap.isEmpty()) {
173 logger.error(EELFLoggerDelegate.errorLogger,authMap.get("Exception").toString(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
174 response.status(Status.UNAUTHORIZED);
175 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
178 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CREATE_KEYSPACE)) {
179 return response.status(Status.UNAUTHORIZED)
180 .entity(new JsonResponse(ResultType.FAILURE)
181 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
185 String consistency = MusicUtil.EVENTUAL;// for now this needs only
186 // eventual consistency
188 if(kspObject == null || kspObject.getReplicationInfo() == null) {
189 response.status(Status.BAD_REQUEST);
190 return response.entity(new JsonResponse(ResultType.FAILURE).setError(ResultType.BODYMISSING.getResult()).toMap()).build();
192 PreparedQueryObject queryObject = new PreparedQueryObject();
193 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && kspObject.getConsistencyInfo().get("consistency") != null) {
194 if(MusicUtil.isValidConsistency(kspObject.getConsistencyInfo().get("consistency")))
195 queryObject.setConsistency(kspObject.getConsistencyInfo().get("consistency"));
197 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
199 long start = System.currentTimeMillis();
200 Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
201 String repString = null;
203 repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
204 } catch (Exception e) {
205 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
208 queryObject.appendQueryString(
209 "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
210 if (kspObject.getDurabilityOfWrites() != null) {
211 queryObject.appendQueryString(
212 " AND durable_writes = " + kspObject.getDurabilityOfWrites());
215 queryObject.appendQueryString(";");
216 long end = System.currentTimeMillis();
217 logger.info(EELFLoggerDelegate.applicationLogger,
218 "Time taken for setting up query in create keyspace:" + (end - start));
220 ResultType result = ResultType.FAILURE;
222 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
223 logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
224 } catch ( MusicServiceException ex) {
225 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
226 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
230 queryObject = new PreparedQueryObject();
231 queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
232 + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
233 MusicCore.nonKeyRelatedPut(queryObject, consistency);
234 queryObject = new PreparedQueryObject();
235 queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
236 + " to '" + userId + "'");
237 queryObject.appendQueryString(";");
238 MusicCore.nonKeyRelatedPut(queryObject, consistency);
239 } catch (Exception e) {
240 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
244 boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
245 String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt());
246 queryObject = new PreparedQueryObject();
247 queryObject.appendQueryString(
248 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
249 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
250 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), aid));
251 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
252 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
253 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
254 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd));
255 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
256 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
257 CachingUtil.updateMusicCache(keyspaceName, ns);
258 CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd);
259 MusicCore.eventualPut(queryObject);
260 } catch (Exception e) {
261 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
262 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
265 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
267 String vError = "Keyspace Creation no longer supported after versions 3.2.x. Contact DBA to create the keyspace.";
268 logger.info(EELFLoggerDelegate.applicationLogger,vError);
269 logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
270 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build();
273 EELFLoggerDelegate.mdcRemove("keyspace");
281 * @param keyspaceName
287 @ApiOperation(value = "Delete Keyspace", response = String.class,hidden=true)
288 @Produces(MediaType.APPLICATION_JSON)
289 public Response dropKeySpace(
290 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
291 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
292 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
293 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
294 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
295 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
296 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception {
298 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
299 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
300 logger.info(EELFLoggerDelegate.applicationLogger,"In Drop Keyspace " + keyspaceName);
301 if ( KEYSPACE_ACTIVE ) {
302 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DROP_KEYSPACE)) {
303 return response.status(Status.UNAUTHORIZED)
304 .entity(new JsonResponse(ResultType.FAILURE)
305 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
309 String consistency = MusicUtil.EVENTUAL;// for now this needs only
312 String appName = CachingUtil.getAppName(keyspaceName);
313 String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
314 PreparedQueryObject pQuery = new PreparedQueryObject();
315 pQuery.appendQueryString(
316 "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
317 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
318 Row row = MusicCore.get(pQuery).one();
319 long count = row.getLong(0);
322 logger.error(EELFLoggerDelegate.errorLogger,"Keyspace not found. Please make sure keyspace exists.", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
323 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
325 } else if (count == 1) {
326 pQuery = new PreparedQueryObject();
327 pQuery.appendQueryString(
328 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
329 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
330 MusicUtil.DEFAULTKEYSPACENAME));
331 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
332 MusicCore.nonKeyRelatedPut(pQuery, consistency);
334 pQuery = new PreparedQueryObject();
335 pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
336 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
337 MusicCore.nonKeyRelatedPut(pQuery, consistency);
340 PreparedQueryObject queryObject = new PreparedQueryObject();
341 queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
342 ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
343 if ( result.equals(ResultType.FAILURE) ) {
344 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
346 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
348 String vError = "Keyspace Droping no longer supported after versions 3.2.x. Contact DBA to drop the keyspace.";
349 logger.info(EELFLoggerDelegate.applicationLogger,vError);
350 logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
351 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build();
354 EELFLoggerDelegate.mdcRemove("keyspace");
369 @Path("/{keyspace: .*}/tables/{tablename: .*}")
370 @ApiOperation(value = "Create Table", response = String.class)
371 @Consumes(MediaType.APPLICATION_JSON)
372 @Produces(MediaType.APPLICATION_JSON)
373 @ApiResponses(value={
374 @ApiResponse(code= 400, message = "Will return JSON response with message"),
375 @ApiResponse(code= 401, message = "Unautorized User")
377 public Response createTable(
378 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
379 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
380 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
381 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
382 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
383 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
385 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
386 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception {
388 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
389 if(keyspace == null || keyspace.isEmpty() || tablename == null || tablename.isEmpty()){
390 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
391 .setError("One or more path parameters are not set, please check and try again."
392 + "Parameter values: keyspace='" + keyspace + "' tablename='" + tablename + "'")
395 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
396 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_TABLE)) {
397 return response.status(Status.UNAUTHORIZED)
398 .entity(new JsonResponse(ResultType.FAILURE)
399 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
403 String consistency = MusicUtil.EVENTUAL;
404 // for now this needs only eventual consistency
406 String primaryKey = null;
407 String partitionKey = tableObj.getPartitionKey();
408 String clusterKey = tableObj.getClusteringKey();
409 String filteringKey = tableObj.getFilteringKey();
410 if(filteringKey != null) {
411 clusterKey = clusterKey + "," + filteringKey;
413 primaryKey = tableObj.getPrimaryKey(); // get primaryKey if available
415 PreparedQueryObject queryObject = new PreparedQueryObject();
416 // first read the information about the table fields
417 Map<String, String> fields = tableObj.getFields();
418 StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
420 for (Map.Entry<String, String> entry : fields.entrySet()) {
421 if (entry.getKey().equals("PRIMARY KEY")) {
422 primaryKey = entry.getValue(); // replaces primaryKey
423 primaryKey = primaryKey.trim();
425 if (counter == 0 ) fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
426 else fieldsString.append("," + entry.getKey() + " " + entry.getValue() + "");
429 if (counter != (fields.size() - 1) ) {
431 counter = counter + 1;
434 if((primaryKey != null) && (partitionKey == null)) {
435 primaryKey = primaryKey.trim();
436 int count1 = StringUtils.countMatches(primaryKey, ')');
437 int count2 = StringUtils.countMatches(primaryKey, '(');
438 if (count1 != count2) {
439 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
440 .setError("Create Table Error: primary key '(' and ')' do not match, primary key=" + primaryKey)
444 if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) )
446 if (primaryKey.contains(",") ) {
447 partitionKey= primaryKey.substring(0,primaryKey.indexOf(','));
448 partitionKey=partitionKey.replaceAll("[\\(]+","");
449 clusterKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index
450 clusterKey=clusterKey.replaceAll("[)]+", "");
452 partitionKey=primaryKey;
453 partitionKey=partitionKey.replaceAll("[\\)]+","");
454 partitionKey=partitionKey.replaceAll("[\\(]+","");
457 } else { // not null and has ) before the last char
458 partitionKey= primaryKey.substring(0,primaryKey.indexOf(')'));
459 partitionKey=partitionKey.replaceAll("[\\(]+","");
460 partitionKey = partitionKey.trim();
461 clusterKey= primaryKey.substring(primaryKey.indexOf(')'));
462 clusterKey=clusterKey.replaceAll("[\\(]+","");
463 clusterKey=clusterKey.replaceAll("[\\)]+","");
464 clusterKey = clusterKey.trim();
465 if (clusterKey.indexOf(',') == 0) clusterKey=clusterKey.substring(1);
466 clusterKey = clusterKey.trim();
467 if (clusterKey.equals(",") ) clusterKey=""; // print error if needed ( ... ),)
470 if (!(partitionKey.isEmpty() || clusterKey.isEmpty())
471 && (partitionKey.equalsIgnoreCase(clusterKey) ||
472 clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) )
474 logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey + " and primary key=" + primaryKey );
475 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(
476 "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ") of"
477 + " primary key=" + primaryKey)
482 if (partitionKey.isEmpty() ) primaryKey="";
483 else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")";
484 else primaryKey=" (" + partitionKey + ")," + clusterKey;
487 if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )");
489 } // end of length > 0
491 if (!(partitionKey.isEmpty() || clusterKey.isEmpty())
492 && (partitionKey.equalsIgnoreCase(clusterKey) ||
493 clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) )
495 logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey);
496 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(
497 "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ")")
501 if (partitionKey.isEmpty() ) primaryKey="";
502 else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")";
503 else primaryKey=" (" + partitionKey + ")," + clusterKey;
506 if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )");
508 fieldsString.append(")");
510 } // end of last field check
513 // information about the name-value style properties
514 Map<String, Object> propertiesMap = tableObj.getProperties();
515 StringBuilder propertiesString = new StringBuilder();
516 if (propertiesMap != null) {
518 for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
519 Object ot = entry.getValue();
520 String value = ot + "";
521 if (ot instanceof String) {
522 value = "'" + value + "'";
523 } else if (ot instanceof Map) {
524 @SuppressWarnings("unchecked")
525 Map<String, Object> otMap = (Map<String, Object>) ot;
526 value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
529 propertiesString.append(entry.getKey() + "=" + value + "");
530 if (counter != propertiesMap.size() - 1)
531 propertiesString.append(" AND ");
533 counter = counter + 1;
537 String clusteringOrder = tableObj.getClusteringOrder();
539 if (clusteringOrder != null && !(clusteringOrder.isEmpty())) {
540 String[] arrayClusterOrder = clusteringOrder.split("[,]+");
542 for (int i = 0; i < arrayClusterOrder.length; i++) {
543 String[] clusterS = arrayClusterOrder[i].trim().split("[ ]+");
544 if ( (clusterS.length ==2) && (clusterS[1].equalsIgnoreCase("ASC") || clusterS[1].equalsIgnoreCase("DESC"))) {
547 return response.status(Status.BAD_REQUEST)
548 .entity(new JsonResponse(ResultType.FAILURE)
549 .setError("createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:"+ clusteringOrder+".")
552 // add validation for column names in cluster key
555 if (!(clusterKey.isEmpty())) {
556 clusteringOrder = "CLUSTERING ORDER BY (" +clusteringOrder +")";
557 //cjc check if propertiesString.length() >0 instead propertiesMap
558 if (propertiesMap != null) {
559 propertiesString.append(" AND "+ clusteringOrder);
561 propertiesString.append(clusteringOrder);
564 logger.warn("Skipping clustering order=("+clusteringOrder+ ") since clustering key is empty ");
568 queryObject.appendQueryString(
569 "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
572 if (propertiesString != null && propertiesString.length()>0 )
573 queryObject.appendQueryString(" WITH " + propertiesString);
574 queryObject.appendQueryString(";");
575 ResultType result = ResultType.FAILURE;
577 result = MusicCore.createTable(keyspace, tablename, queryObject, consistency);
578 } catch (MusicServiceException ex) {
579 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR);
580 response.status(Status.BAD_REQUEST);
581 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
583 if ( result.equals(ResultType.FAILURE) ) {
584 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build();
586 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename.trim() + " Created under keyspace " + keyspace.trim()).toMap()).build();
588 EELFLoggerDelegate.mdcRemove("keyspace");
601 @Path("/{keyspace: .*}/tables/{tablename: .*}/index/{field: .*}")
602 @ApiOperation(value = "Create Index", response = String.class)
603 @Produces(MediaType.APPLICATION_JSON)
604 public Response createIndex(
605 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
606 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
607 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
608 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
609 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
610 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
611 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
612 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename,
613 @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName,
614 @Context UriInfo info) throws Exception {
616 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
617 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty()) || (fieldName == null || fieldName.isEmpty())){
618 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
619 .setError("one or more path parameters are not set, please check and try again")
622 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
623 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_INDEX)) {
624 return response.status(Status.UNAUTHORIZED)
625 .entity(new JsonResponse(ResultType.FAILURE)
626 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
630 MultivaluedMap<String, String> rowParams = info.getQueryParameters();
631 String indexName = "";
632 if (rowParams.getFirst("index_name") != null)
633 indexName = rowParams.getFirst("index_name");
634 PreparedQueryObject query = new PreparedQueryObject();
635 query.appendQueryString("Create index if not exists " + indexName + " on " + keyspace + "."
636 + tablename + " (" + fieldName + ");");
638 ResultType result = ResultType.FAILURE;
640 result = MusicCore.nonKeyRelatedPut(query, "eventual");
641 } catch (MusicServiceException ex) {
642 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
643 response.status(Status.BAD_REQUEST);
644 return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
646 if ( result.equals(ResultType.SUCCESS) ) {
647 return response.status(Status.OK).entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build();
649 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build();
652 EELFLoggerDelegate.mdcRemove("keyspace");
665 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
666 @ApiOperation(value = "Insert Into Table", response = String.class)
667 @Consumes(MediaType.APPLICATION_JSON)
668 @Produces(MediaType.APPLICATION_JSON)
669 public Response insertIntoTable(
670 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
671 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
672 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
673 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
674 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
675 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
677 @ApiParam(value = "Keyspace Name",
678 required = true) @PathParam("keyspace") String keyspace,
679 @ApiParam(value = "Table Name",
680 required = true) @PathParam("tablename") String tablename) {
682 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
683 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
684 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
685 .setError("one or more path parameters are not set, please check and try again")
688 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
689 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.INSERT_INTO_TABLE)) {
690 return response.status(Status.UNAUTHORIZED)
691 .entity(new JsonResponse(ResultType.FAILURE)
692 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
696 Map<String, Object> valuesMap = insObj.getValues();
697 PreparedQueryObject queryObject = new PreparedQueryObject();
698 TableMetadata tableInfo = null;
700 tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
701 if(tableInfo == null) {
702 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
704 } catch (MusicServiceException e) {
705 logger.error(EELFLoggerDelegate.errorLogger, e, AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
706 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
708 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
709 StringBuilder fieldsString = new StringBuilder("(vector_ts,");
711 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
712 StringBuilder valueString = new StringBuilder("(" + "?" + ",");
713 queryObject.addValue(vectorTs);
715 String primaryKey = "";
716 Map<String, byte[]> objectMap = insObj.getObjectMap();
717 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
718 fieldsString.append("" + entry.getKey());
719 Object valueObj = entry.getValue();
720 if (primaryKeyName.equals(entry.getKey())) {
721 primaryKey = entry.getValue() + "";
722 primaryKey = primaryKey.replace("'", "''");
724 DataType colType = null;
726 colType = tableInfo.getColumn(entry.getKey()).getType();
727 } catch(NullPointerException ex) {
728 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
729 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
732 Object formattedValue = null;
734 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
735 } catch (Exception e) {
736 logger.error(EELFLoggerDelegate.errorLogger,e);
738 valueString.append("?");
740 queryObject.addValue(formattedValue);
742 if (counter == valuesMap.size() - 1) {
743 fieldsString.append(")");
744 valueString.append(")");
746 fieldsString.append(",");
747 valueString.append(",");
749 counter = counter + 1;
753 if(objectMap != null) {
754 for (Map.Entry<String, byte[]> entry : objectMap.entrySet()) {
756 fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ",");
757 valueString.replace(valueString.length()-1, valueString.length(), ",");
759 fieldsString.append("" + entry.getKey());
760 byte[] valueObj = entry.getValue();
761 if (primaryKeyName.equals(entry.getKey())) {
762 primaryKey = entry.getValue() + "";
763 primaryKey = primaryKey.replace("'", "''");
766 DataType colType = tableInfo.getColumn(entry.getKey()).getType();
768 ByteBuffer formattedValue = null;
770 if(colType.toString().toLowerCase().contains("blob"))
771 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
773 valueString.append("?");
775 queryObject.addValue(formattedValue);
776 counter = counter + 1;
777 /*if (counter == valuesMap.size() - 1) {
778 fieldsString.append(")");
779 valueString.append(")");
781 fieldsString.append(",");
782 valueString.append(",");
786 if(primaryKey == null || primaryKey.length() <= 0) {
787 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
788 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build();
791 fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ")");
792 valueString.replace(valueString.length()-1, valueString.length(), ")");
794 queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
795 + fieldsString + " VALUES " + valueString);
797 String ttl = insObj.getTtl();
798 String timestamp = insObj.getTimestamp();
800 if ((ttl != null) && (timestamp != null)) {
801 logger.info(EELFLoggerDelegate.applicationLogger, "both there");
802 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
803 queryObject.addValue(Integer.parseInt(ttl));
804 queryObject.addValue(Long.parseLong(timestamp));
807 if ((ttl != null) && (timestamp == null)) {
808 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
809 queryObject.appendQueryString(" USING TTL ?");
810 queryObject.addValue(Integer.parseInt(ttl));
813 if ((ttl == null) && (timestamp != null)) {
814 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
815 queryObject.appendQueryString(" USING TIMESTAMP ?");
816 queryObject.addValue(Long.parseLong(timestamp));
819 queryObject.appendQueryString(";");
821 ReturnType result = null;
822 String consistency = insObj.getConsistencyInfo().get("type");
823 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && insObj.getConsistencyInfo().get("consistency") != null) {
824 if(MusicUtil.isValidConsistency(insObj.getConsistencyInfo().get("consistency")))
825 queryObject.setConsistency(insObj.getConsistencyInfo().get("consistency"));
827 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
829 queryObject.setOperation("insert");
831 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
832 result = MusicCore.eventualPut(queryObject);
833 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
834 String lockId = insObj.getConsistencyInfo().get("lockId");
836 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
837 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
838 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
839 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
841 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
842 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
844 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
847 } catch (Exception ex) {
848 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
849 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
853 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
854 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
855 }else if(result.getResult() == ResultType.FAILURE) {
856 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result.getResult()).setError(result.getMessage()).toMap()).build();
858 return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
860 EELFLoggerDelegate.mdcRemove("keyspace");
871 * @throws MusicServiceException
872 * @throws MusicQueryException
876 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
877 @ApiOperation(value = "Update Table", response = String.class)
878 @Consumes(MediaType.APPLICATION_JSON)
879 @Produces(MediaType.APPLICATION_JSON)
880 public Response updateTable(
881 @ApiParam(value = "Major Version",
882 required = true) @PathParam("version") String version,
883 @ApiParam(value = "Minor Version",
884 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
885 @ApiParam(value = "Patch Version",
886 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
887 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
888 @ApiParam(value = "Application namespace",
889 required = true) @HeaderParam(NS) String ns,
890 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
891 JsonUpdate updateObj,
892 @ApiParam(value = "Keyspace Name",
893 required = true) @PathParam("keyspace") String keyspace,
894 @ApiParam(value = "Table Name",
895 required = true) @PathParam("tablename") String tablename,
896 @Context UriInfo info) throws MusicQueryException, MusicServiceException {
898 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
899 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
900 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
901 .setError("one or more path parameters are not set, please check and try again")
904 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
905 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.UPDATE_TABLE)) {
906 return response.status(Status.UNAUTHORIZED)
907 .entity(new JsonResponse(ResultType.FAILURE)
908 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
912 long startTime = System.currentTimeMillis();
913 String operationId = UUID.randomUUID().toString();// just for infoging
915 String consistency = updateObj.getConsistencyInfo().get("type");
917 logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
918 + " update-" + operationId + "-------------------------");
919 // obtain the field value pairs of the update
921 PreparedQueryObject queryObject = new PreparedQueryObject();
922 Map<String, Object> valuesMap = updateObj.getValues();
924 TableMetadata tableInfo;
926 tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
927 } catch (MusicServiceException e) {
928 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
929 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
931 if (tableInfo == null) {
932 logger.error(EELFLoggerDelegate.errorLogger,"Table information not found. Please check input for table name= "+tablename, AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
933 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
934 .setError("Table information not found. Please check input for table name= "
935 + keyspace + "." + tablename).toMap()).build();
938 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
939 StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
940 queryObject.addValue(vectorTs);
942 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
943 Object valueObj = entry.getValue();
944 DataType colType = null;
946 colType = tableInfo.getColumn(entry.getKey()).getType();
947 } catch(NullPointerException ex) {
948 logger.error(EELFLoggerDelegate.errorLogger, ex, "Invalid column name : "+entry.getKey());
949 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
951 Object valueString = null;
953 valueString = MusicUtil.convertToActualDataType(colType, valueObj);
954 } catch (Exception e) {
955 logger.error(EELFLoggerDelegate.errorLogger,e);
957 fieldValueString.append(entry.getKey() + "= ?");
958 queryObject.addValue(valueString);
959 if (counter != valuesMap.size() - 1)
960 fieldValueString.append(",");
961 counter = counter + 1;
963 String ttl = updateObj.getTtl();
964 String timestamp = updateObj.getTimestamp();
966 queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
967 if ((ttl != null) && (timestamp != null)) {
969 logger.info("both there");
970 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
971 queryObject.addValue(Integer.parseInt(ttl));
972 queryObject.addValue(Long.parseLong(timestamp));
975 if ((ttl != null) && (timestamp == null)) {
976 logger.info("ONLY TTL there");
977 queryObject.appendQueryString(" USING TTL ?");
978 queryObject.addValue(Integer.parseInt(ttl));
981 if ((ttl == null) && (timestamp != null)) {
982 logger.info("ONLY timestamp there");
983 queryObject.appendQueryString(" USING TIMESTAMP ?");
984 queryObject.addValue(Long.parseLong(timestamp));
986 // get the row specifier
987 RowIdentifier rowId = null;
989 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
990 if(rowId == null || rowId.primarKeyValue.isEmpty()) {
991 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
992 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
994 } catch (MusicServiceException ex) {
995 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
996 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
999 queryObject.appendQueryString(
1000 " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
1002 // get the conditional, if any
1003 Condition conditionInfo;
1004 if (updateObj.getConditions() == null)
1005 conditionInfo = null;
1006 else {// to avoid parsing repeatedly, just send the select query to
1008 PreparedQueryObject selectQuery = new PreparedQueryObject();
1009 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
1010 + rowId.rowIdString + ";");
1011 selectQuery.addValue(rowId.primarKeyValue);
1012 conditionInfo = new Condition(updateObj.getConditions(), selectQuery);
1015 ReturnType operationResult = null;
1016 long jsonParseCompletionTime = System.currentTimeMillis();
1018 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && updateObj.getConsistencyInfo().get("consistency") != null) {
1019 if(MusicUtil.isValidConsistency(updateObj.getConsistencyInfo().get("consistency")))
1020 queryObject.setConsistency(updateObj.getConsistencyInfo().get("consistency"));
1022 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
1024 queryObject.setOperation("update");
1025 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1026 operationResult = MusicCore.eventualPut(queryObject);
1027 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1028 String lockId = updateObj.getConsistencyInfo().get("lockId");
1029 if(lockId == null) {
1030 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1031 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1032 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1033 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1035 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
1036 queryObject, lockId, conditionInfo);
1037 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
1038 // this function is mainly for the benchmarks
1040 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
1041 rowId.primarKeyValue, queryObject, conditionInfo);
1042 } catch (MusicLockingException e) {
1043 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1044 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
1046 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1048 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
1049 queryObject, conditionInfo);
1050 } catch (MusicLockingException e) {
1051 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1052 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
1054 }else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1055 operationResult = MusicCore.eventualPut_nb(queryObject, keyspace, tablename, rowId.primarKeyValue);
1057 long actualUpdateCompletionTime = System.currentTimeMillis();
1059 long endTime = System.currentTimeMillis();
1060 String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
1061 + ":" + "|total operation time:" + (endTime - startTime)
1062 + "|json parsing time:" + (jsonParseCompletionTime - startTime)
1063 + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
1066 if (operationResult != null && operationResult.getTimingInfo() != null) {
1067 String lockManagementTime = operationResult.getTimingInfo();
1068 timingString = timingString + lockManagementTime;
1070 logger.info(EELFLoggerDelegate.applicationLogger, timingString);
1072 if (operationResult==null) {
1073 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1074 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1076 if ( operationResult.getResult() == ResultType.SUCCESS ) {
1077 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1079 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1080 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
1083 EELFLoggerDelegate.mdcRemove("keyspace");
1094 * @throws MusicServiceException
1095 * @throws MusicQueryException
1099 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
1100 @ApiOperation(value = "Delete From table", response = String.class)
1101 @Consumes(MediaType.APPLICATION_JSON)
1102 @Produces(MediaType.APPLICATION_JSON)
1103 public Response deleteFromTable(
1104 @ApiParam(value = "Major Version",
1105 required = true) @PathParam("version") String version,
1106 @ApiParam(value = "Minor Version",
1107 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1108 @ApiParam(value = "Patch Version",
1109 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1110 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1111 @ApiParam(value = "Application namespace",
1112 required = true) @HeaderParam(NS) String ns,
1113 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1115 @ApiParam(value = "Keyspace Name",
1116 required = true) @PathParam("keyspace") String keyspace,
1117 @ApiParam(value = "Table Name",
1118 required = true) @PathParam("tablename") String tablename,
1119 @Context UriInfo info) throws MusicQueryException, MusicServiceException {
1121 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1122 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1123 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1124 .setError("one or more path parameters are not set, please check and try again")
1127 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1128 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DELETE_FROM_TABLE)) {
1129 return response.status(Status.UNAUTHORIZED)
1130 .entity(new JsonResponse(ResultType.FAILURE)
1131 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1135 if(delObj == null) {
1136 logger.error(EELFLoggerDelegate.errorLogger,"Required HTTP Request body is missing.", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
1137 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
1139 PreparedQueryObject queryObject = new PreparedQueryObject();
1140 StringBuilder columnString = new StringBuilder();
1143 List<String> columnList = delObj.getColumns();
1144 if (columnList != null) {
1145 for (String column : columnList) {
1146 columnString.append(column);
1147 if (counter != columnList.size() - 1)
1148 columnString.append(",");
1149 counter = counter + 1;
1153 // get the row specifier
1154 RowIdentifier rowId = null;
1156 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1157 } catch (MusicServiceException ex) {
1158 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1159 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1161 String rowSpec = rowId.rowIdString.toString();
1163 if ((columnList != null) && (!rowSpec.isEmpty())) {
1164 queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
1165 + tablename + " WHERE " + rowSpec + ";");
1168 if ((columnList == null) && (!rowSpec.isEmpty())) {
1169 queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
1173 if ((columnList != null) && (rowSpec.isEmpty())) {
1174 queryObject.appendQueryString(
1175 "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
1177 // get the conditional, if any
1178 Condition conditionInfo;
1179 if (delObj.getConditions() == null)
1180 conditionInfo = null;
1181 else {// to avoid parsing repeatedly, just send the select query to
1183 PreparedQueryObject selectQuery = new PreparedQueryObject();
1184 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
1185 + rowId.rowIdString + ";");
1186 selectQuery.addValue(rowId.primarKeyValue);
1187 conditionInfo = new Condition(delObj.getConditions(), selectQuery);
1190 String consistency = delObj.getConsistencyInfo().get("type");
1193 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && delObj.getConsistencyInfo().get("consistency")!=null) {
1195 if(MusicUtil.isValidConsistency(delObj.getConsistencyInfo().get("consistency")))
1196 queryObject.setConsistency(delObj.getConsistencyInfo().get("consistency"));
1198 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
1201 ReturnType operationResult = null;
1202 queryObject.setOperation("delete");
1204 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1205 operationResult = MusicCore.eventualPut(queryObject);
1206 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1207 String lockId = delObj.getConsistencyInfo().get("lockId");
1208 if(lockId == null) {
1209 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1210 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1211 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1212 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1214 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
1215 queryObject, lockId, conditionInfo);
1216 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1217 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
1218 queryObject, conditionInfo);
1219 } else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1221 operationResult = MusicCore.eventualPut_nb(queryObject, keyspace, tablename, rowId.primarKeyValue);
1223 } catch (MusicLockingException e) {
1224 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1225 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1226 .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
1228 if (operationResult==null) {
1229 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1230 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1232 if (operationResult.getResult().equals(ResultType.SUCCESS)) {
1233 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1235 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1236 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
1239 EELFLoggerDelegate.mdcRemove("keyspace");
1251 @Path("/{keyspace: .*}/tables/{tablename: .*}")
1252 @ApiOperation(value = "Drop Table", response = String.class)
1253 @Produces(MediaType.APPLICATION_JSON)
1254 public Response dropTable(
1255 @ApiParam(value = "Major Version",
1256 required = true) @PathParam("version") String version,
1257 @ApiParam(value = "Minor Version",
1258 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1259 @ApiParam(value = "Patch Version",
1260 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1261 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1262 @ApiParam(value = "Application namespace",
1263 required = true) @HeaderParam(NS) String ns,
1264 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1265 @ApiParam(value = "Keyspace Name",
1266 required = true) @PathParam("keyspace") String keyspace,
1267 @ApiParam(value = "Table Name",
1268 required = true) @PathParam("tablename") String tablename) throws Exception {
1270 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1271 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1272 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1273 .setError("one or more path parameters are not set, please check and try again")
1276 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1277 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DROP_TABLE)) {
1278 return response.status(Status.UNAUTHORIZED)
1279 .entity(new JsonResponse(ResultType.FAILURE)
1280 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1284 String consistency = "eventual";// for now this needs only eventual
1286 PreparedQueryObject query = new PreparedQueryObject();
1287 query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
1289 return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
1290 } catch (MusicServiceException ex) {
1291 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1292 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1295 EELFLoggerDelegate.mdcRemove("keyspace");
1308 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows/criticalget")
1309 @ApiOperation(value = "Select Critical", response = Map.class)
1310 @Consumes(MediaType.APPLICATION_JSON)
1311 @Produces(MediaType.APPLICATION_JSON)
1312 public Response selectCritical(
1313 @ApiParam(value = "Major Version",
1314 required = true) @PathParam("version") String version,
1315 @ApiParam(value = "Minor Version",
1316 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1317 @ApiParam(value = "Patch Version",
1318 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1319 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1320 @ApiParam(value = "Application namespace",
1321 required = true) @HeaderParam(NS) String ns,
1322 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1324 @ApiParam(value = "Keyspace Name",
1325 required = true) @PathParam("keyspace") String keyspace,
1326 @ApiParam(value = "Table Name",
1327 required = true) @PathParam("tablename") String tablename,
1328 @Context UriInfo info) throws Exception {
1330 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1331 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1332 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1333 .setError("one or more path parameters are not set, please check and try again")
1336 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1337 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT_CRITICAL)) {
1338 return response.status(Status.UNAUTHORIZED)
1339 .entity(new JsonResponse(ResultType.FAILURE)
1340 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1344 String lockId = selObj.getConsistencyInfo().get("lockId");
1346 PreparedQueryObject queryObject = new PreparedQueryObject();
1348 RowIdentifier rowId = null;
1350 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1351 } catch (MusicServiceException ex) {
1352 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1353 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1355 queryObject.appendQueryString(
1356 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1358 ResultSet results = null;
1360 String consistency = selObj.getConsistencyInfo().get("type");
1362 if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1363 if(lockId == null) {
1364 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1365 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1366 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1367 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1369 results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1371 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1372 results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1374 if(results!=null && results.getAvailableWithoutFetching() >0) {
1375 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
1377 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setError("No data found").toMap()).build();
1380 EELFLoggerDelegate.mdcRemove("keyspace");
1393 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
1394 @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1395 @Produces(MediaType.APPLICATION_JSON)
1396 public Response select(
1397 @ApiParam(value = "Major Version",
1398 required = true) @PathParam("version") String version,
1399 @ApiParam(value = "Minor Version",
1400 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1401 @ApiParam(value = "Patch Version",
1402 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1403 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1404 @ApiParam(value = "Application namespace",
1405 required = true) @HeaderParam(NS) String ns,
1406 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1407 @ApiParam(value = "Keyspace Name",
1408 required = true) @PathParam("keyspace") String keyspace,
1409 @ApiParam(value = "Table Name",
1410 required = true) @PathParam("tablename") String tablename,
1411 @Context UriInfo info) throws Exception {
1413 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1414 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1415 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1416 .setError("one or more path parameters are not set, please check and try again")
1419 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1420 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT)) {
1421 return response.status(Status.UNAUTHORIZED)
1422 .entity(new JsonResponse(ResultType.FAILURE)
1423 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1427 PreparedQueryObject queryObject = new PreparedQueryObject();
1429 if (info.getQueryParameters().isEmpty())// select all
1430 queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
1432 int limit = -1; // do not limit the number of results
1434 queryObject = selectSpecificQuery(keyspace, tablename, info, limit);
1435 } catch (MusicServiceException ex) {
1436 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1437 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1442 ResultSet results = MusicCore.get(queryObject);
1443 if(results.getAvailableWithoutFetching() >0) {
1444 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
1446 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).setError("No data found").toMap()).build();
1447 } catch (MusicServiceException ex) {
1448 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1449 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1452 EELFLoggerDelegate.mdcRemove("keyspace");
1463 * @throws MusicServiceException
1465 public PreparedQueryObject selectSpecificQuery(String keyspace,
1466 String tablename, UriInfo info, int limit)
1467 throws MusicServiceException {
1469 PreparedQueryObject queryObject = new PreparedQueryObject();
1470 StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1471 queryObject).rowIdString;
1473 queryObject.appendQueryString(
1474 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1477 queryObject.appendQueryString(" LIMIT " + limit);
1480 queryObject.appendQueryString(";");
1490 * @param queryObject
1492 * @throws MusicServiceException
1494 private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1495 MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1496 throws MusicServiceException {
1497 StringBuilder rowSpec = new StringBuilder();
1499 TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
1500 if (tableInfo == null) {
1501 logger.error(EELFLoggerDelegate.errorLogger,
1502 "Table information not found. Please check input for table name= "
1503 + keyspace + "." + tablename);
1504 throw new MusicServiceException(
1505 "Table information not found. Please check input for table name= "
1506 + keyspace + "." + tablename);
1508 StringBuilder primaryKey = new StringBuilder();
1509 for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1510 String keyName = entry.getKey();
1511 List<String> valueList = entry.getValue();
1512 String indValue = valueList.get(0);
1513 DataType colType = null;
1514 Object formattedValue = null;
1516 colType = tableInfo.getColumn(entry.getKey()).getType();
1517 formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1518 } catch (Exception e) {
1519 logger.error(EELFLoggerDelegate.errorLogger,e);
1521 if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey()))
1522 primaryKey.append(indValue);
1523 rowSpec.append(keyName + "= ?");
1524 queryObject.addValue(formattedValue);
1525 if (counter != rowParams.size() - 1)
1526 rowSpec.append(" AND ");
1527 counter = counter + 1;
1529 return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);