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
206 .CRITICAL, ErrorTypes.DATAERROR, e);
209 queryObject.appendQueryString(
210 "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
211 if (kspObject.getDurabilityOfWrites() != null) {
212 queryObject.appendQueryString(
213 " AND durable_writes = " + kspObject.getDurabilityOfWrites());
216 queryObject.appendQueryString(";");
217 long end = System.currentTimeMillis();
218 logger.info(EELFLoggerDelegate.applicationLogger,
219 "Time taken for setting up query in create keyspace:" + (end - start));
221 ResultType result = ResultType.FAILURE;
223 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
224 logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
225 } catch ( MusicServiceException ex) {
226 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
227 .WARN, ErrorTypes.MUSICSERVICEERROR, ex);
228 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
232 queryObject = new PreparedQueryObject();
233 queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
234 + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
235 MusicCore.nonKeyRelatedPut(queryObject, consistency);
236 queryObject = new PreparedQueryObject();
237 queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
238 + " to '" + userId + "'");
239 queryObject.appendQueryString(";");
240 MusicCore.nonKeyRelatedPut(queryObject, consistency);
241 } catch (Exception e) {
242 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity
243 .WARN, ErrorTypes.MUSICSERVICEERROR, e);
247 boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
248 String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt());
249 queryObject = new PreparedQueryObject();
250 queryObject.appendQueryString(
251 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
252 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
253 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), aid));
254 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
255 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
256 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
257 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd));
258 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
259 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
260 CachingUtil.updateMusicCache(keyspaceName, ns);
261 CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd);
262 MusicCore.eventualPut(queryObject);
263 } catch (Exception e) {
264 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity
265 .WARN, ErrorTypes.MUSICSERVICEERROR, e);
266 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
269 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
271 String vError = "Keyspace Creation no longer supported after versions 3.2.x. Contact DBA to create the keyspace.";
272 logger.info(EELFLoggerDelegate.applicationLogger,vError);
273 logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
274 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build();
277 EELFLoggerDelegate.mdcRemove("keyspace");
285 * @param keyspaceName
291 @ApiOperation(value = "Delete Keyspace", response = String.class,hidden=true)
292 @Produces(MediaType.APPLICATION_JSON)
293 public Response dropKeySpace(
294 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
295 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
296 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
297 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
298 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
299 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
300 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception {
302 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
303 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
304 logger.info(EELFLoggerDelegate.applicationLogger,"In Drop Keyspace " + keyspaceName);
305 if ( KEYSPACE_ACTIVE ) {
306 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DROP_KEYSPACE)) {
307 return response.status(Status.UNAUTHORIZED)
308 .entity(new JsonResponse(ResultType.FAILURE)
309 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
313 String consistency = MusicUtil.EVENTUAL;// for now this needs only
316 String appName = CachingUtil.getAppName(keyspaceName);
317 String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
318 PreparedQueryObject pQuery = new PreparedQueryObject();
319 pQuery.appendQueryString(
320 "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
321 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
322 Row row = MusicCore.get(pQuery).one();
323 long count = row.getLong(0);
326 logger.error(EELFLoggerDelegate.errorLogger,"Keyspace not found. Please make sure keyspace exists.", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
327 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
329 } else if (count == 1) {
330 pQuery = new PreparedQueryObject();
331 pQuery.appendQueryString(
332 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
333 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
334 MusicUtil.DEFAULTKEYSPACENAME));
335 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
336 MusicCore.nonKeyRelatedPut(pQuery, consistency);
338 pQuery = new PreparedQueryObject();
339 pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
340 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
341 MusicCore.nonKeyRelatedPut(pQuery, consistency);
344 PreparedQueryObject queryObject = new PreparedQueryObject();
345 queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
346 ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
347 if ( result.equals(ResultType.FAILURE) ) {
348 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
350 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
352 String vError = "Keyspace Droping no longer supported after versions 3.2.x. Contact DBA to drop the keyspace.";
353 logger.info(EELFLoggerDelegate.applicationLogger,vError);
354 logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
355 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build();
358 EELFLoggerDelegate.mdcRemove("keyspace");
373 @Path("/{keyspace: .*}/tables/{tablename: .*}")
374 @ApiOperation(value = "Create Table", response = String.class)
375 @Consumes(MediaType.APPLICATION_JSON)
376 @Produces(MediaType.APPLICATION_JSON)
377 @ApiResponses(value={
378 @ApiResponse(code= 400, message = "Will return JSON response with message"),
379 @ApiResponse(code= 401, message = "Unautorized User")
381 public Response createTable(
382 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
383 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
384 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
385 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
386 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
387 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
389 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
390 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception {
392 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
393 if(keyspace == null || keyspace.isEmpty() || tablename == null || tablename.isEmpty()){
394 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
395 .setError("One or more path parameters are not set, please check and try again."
396 + "Parameter values: keyspace='" + keyspace + "' tablename='" + tablename + "'")
399 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
400 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_TABLE)) {
401 return response.status(Status.UNAUTHORIZED)
402 .entity(new JsonResponse(ResultType.FAILURE)
403 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
407 String consistency = MusicUtil.EVENTUAL;
408 // for now this needs only eventual consistency
410 String primaryKey = null;
411 String partitionKey = tableObj.getPartitionKey();
412 String clusterKey = tableObj.getClusteringKey();
413 String filteringKey = tableObj.getFilteringKey();
414 if(filteringKey != null) {
415 clusterKey = clusterKey + "," + filteringKey;
417 primaryKey = tableObj.getPrimaryKey(); // get primaryKey if available
419 PreparedQueryObject queryObject = new PreparedQueryObject();
420 // first read the information about the table fields
421 Map<String, String> fields = tableObj.getFields();
422 StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
424 for (Map.Entry<String, String> entry : fields.entrySet()) {
425 if (entry.getKey().equals("PRIMARY KEY")) {
426 primaryKey = entry.getValue(); // replaces primaryKey
427 primaryKey = primaryKey.trim();
429 if (counter == 0 ) fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
430 else fieldsString.append("," + entry.getKey() + " " + entry.getValue() + "");
433 if (counter != (fields.size() - 1) ) {
435 counter = counter + 1;
438 if((primaryKey != null) && (partitionKey == null)) {
439 primaryKey = primaryKey.trim();
440 int count1 = StringUtils.countMatches(primaryKey, ')');
441 int count2 = StringUtils.countMatches(primaryKey, '(');
442 if (count1 != count2) {
443 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
444 .setError("Create Table Error: primary key '(' and ')' do not match, primary key=" + primaryKey)
448 if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) )
450 if (primaryKey.contains(",") ) {
451 partitionKey= primaryKey.substring(0,primaryKey.indexOf(','));
452 partitionKey=partitionKey.replaceAll("[\\(]+","");
453 clusterKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index
454 clusterKey=clusterKey.replaceAll("[)]+", "");
456 partitionKey=primaryKey;
457 partitionKey=partitionKey.replaceAll("[\\)]+","");
458 partitionKey=partitionKey.replaceAll("[\\(]+","");
461 } else { // not null and has ) before the last char
462 partitionKey= primaryKey.substring(0,primaryKey.indexOf(')'));
463 partitionKey=partitionKey.replaceAll("[\\(]+","");
464 partitionKey = partitionKey.trim();
465 clusterKey= primaryKey.substring(primaryKey.indexOf(')'));
466 clusterKey=clusterKey.replaceAll("[\\(]+","");
467 clusterKey=clusterKey.replaceAll("[\\)]+","");
468 clusterKey = clusterKey.trim();
469 if (clusterKey.indexOf(',') == 0) clusterKey=clusterKey.substring(1);
470 clusterKey = clusterKey.trim();
471 if (clusterKey.equals(",") ) clusterKey=""; // print error if needed ( ... ),)
474 if (!(partitionKey.isEmpty() || clusterKey.isEmpty())
475 && (partitionKey.equalsIgnoreCase(clusterKey) ||
476 clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) )
478 logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey + " and primary key=" + primaryKey );
479 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(
480 "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ") of"
481 + " primary key=" + primaryKey)
486 if (partitionKey.isEmpty() ) primaryKey="";
487 else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")";
488 else primaryKey=" (" + partitionKey + ")," + clusterKey;
491 if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )");
493 } // end of length > 0
495 if (!(partitionKey.isEmpty() || clusterKey.isEmpty())
496 && (partitionKey.equalsIgnoreCase(clusterKey) ||
497 clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) )
499 logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey);
500 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(
501 "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ")")
505 if (partitionKey.isEmpty() ) primaryKey="";
506 else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")";
507 else primaryKey=" (" + partitionKey + ")," + clusterKey;
510 if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )");
512 fieldsString.append(")");
514 } // end of last field check
517 // information about the name-value style properties
518 Map<String, Object> propertiesMap = tableObj.getProperties();
519 StringBuilder propertiesString = new StringBuilder();
520 if (propertiesMap != null) {
522 for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
523 Object ot = entry.getValue();
524 String value = ot + "";
525 if (ot instanceof String) {
526 value = "'" + value + "'";
527 } else if (ot instanceof Map) {
528 @SuppressWarnings("unchecked")
529 Map<String, Object> otMap = (Map<String, Object>) ot;
530 value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
533 propertiesString.append(entry.getKey() + "=" + value + "");
534 if (counter != propertiesMap.size() - 1)
535 propertiesString.append(" AND ");
537 counter = counter + 1;
541 String clusteringOrder = tableObj.getClusteringOrder();
543 if (clusteringOrder != null && !(clusteringOrder.isEmpty())) {
544 String[] arrayClusterOrder = clusteringOrder.split("[,]+");
546 for (int i = 0; i < arrayClusterOrder.length; i++) {
547 String[] clusterS = arrayClusterOrder[i].trim().split("[ ]+");
548 if ( (clusterS.length ==2) && (clusterS[1].equalsIgnoreCase("ASC") || clusterS[1].equalsIgnoreCase("DESC"))) {
551 return response.status(Status.BAD_REQUEST)
552 .entity(new JsonResponse(ResultType.FAILURE)
553 .setError("createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:"+ clusteringOrder+".")
556 // add validation for column names in cluster key
559 if (!(clusterKey.isEmpty())) {
560 clusteringOrder = "CLUSTERING ORDER BY (" +clusteringOrder +")";
561 //cjc check if propertiesString.length() >0 instead propertiesMap
562 if (propertiesMap != null) {
563 propertiesString.append(" AND "+ clusteringOrder);
565 propertiesString.append(clusteringOrder);
568 logger.warn("Skipping clustering order=("+clusteringOrder+ ") since clustering key is empty ");
572 queryObject.appendQueryString(
573 "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
576 if (propertiesString != null && propertiesString.length()>0 )
577 queryObject.appendQueryString(" WITH " + propertiesString);
578 queryObject.appendQueryString(";");
579 ResultType result = ResultType.FAILURE;
581 result = MusicCore.createTable(keyspace, tablename, queryObject, consistency);
582 } catch (MusicServiceException ex) {
583 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
584 .CRITICAL, ErrorTypes.MUSICSERVICEERROR, ex);
585 response.status(Status.BAD_REQUEST);
586 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
588 if ( result.equals(ResultType.FAILURE) ) {
589 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build();
591 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename.trim() + " Created under keyspace " + keyspace.trim()).toMap()).build();
593 EELFLoggerDelegate.mdcRemove("keyspace");
606 @Path("/{keyspace: .*}/tables/{tablename: .*}/index/{field: .*}")
607 @ApiOperation(value = "Create Index", response = String.class)
608 @Produces(MediaType.APPLICATION_JSON)
609 public Response createIndex(
610 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
611 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
612 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
613 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
614 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
615 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
616 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
617 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename,
618 @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName,
619 @Context UriInfo info) throws Exception {
621 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
622 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty()) || (fieldName == null || fieldName.isEmpty())){
623 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
624 .setError("one or more path parameters are not set, please check and try again")
627 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
628 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_INDEX)) {
629 return response.status(Status.UNAUTHORIZED)
630 .entity(new JsonResponse(ResultType.FAILURE)
631 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
635 MultivaluedMap<String, String> rowParams = info.getQueryParameters();
636 String indexName = "";
637 if (rowParams.getFirst("index_name") != null)
638 indexName = rowParams.getFirst("index_name");
639 PreparedQueryObject query = new PreparedQueryObject();
640 query.appendQueryString("Create index if not exists " + indexName + " on " + keyspace + "."
641 + tablename + " (" + fieldName + ");");
643 ResultType result = ResultType.FAILURE;
645 result = MusicCore.nonKeyRelatedPut(query, "eventual");
646 } catch (MusicServiceException ex) {
647 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
648 .CRITICAL, ErrorTypes.GENERALSERVICEERROR, ex);
649 response.status(Status.BAD_REQUEST);
650 return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
652 if ( result.equals(ResultType.SUCCESS) ) {
653 return response.status(Status.OK).entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build();
655 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build();
658 EELFLoggerDelegate.mdcRemove("keyspace");
671 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
672 @ApiOperation(value = "Insert Into Table", response = String.class)
673 @Consumes(MediaType.APPLICATION_JSON)
674 @Produces(MediaType.APPLICATION_JSON)
675 public Response insertIntoTable(
676 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
677 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
678 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
679 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
680 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
681 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
683 @ApiParam(value = "Keyspace Name",
684 required = true) @PathParam("keyspace") String keyspace,
685 @ApiParam(value = "Table Name",
686 required = true) @PathParam("tablename") String tablename) {
688 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
689 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
690 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
691 .setError("one or more path parameters are not set, please check and try again")
694 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
695 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.INSERT_INTO_TABLE)) {
696 return response.status(Status.UNAUTHORIZED)
697 .entity(new JsonResponse(ResultType.FAILURE)
698 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
702 Map<String, Object> valuesMap = insObj.getValues();
703 PreparedQueryObject queryObject = new PreparedQueryObject();
704 TableMetadata tableInfo = null;
706 tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
707 if(tableInfo == null) {
708 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
710 } catch (MusicServiceException e) {
711 logger.error(EELFLoggerDelegate.errorLogger, e, AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
712 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
714 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
715 StringBuilder fieldsString = new StringBuilder("(vector_ts,");
717 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
718 StringBuilder valueString = new StringBuilder("(" + "?" + ",");
719 queryObject.addValue(vectorTs);
721 String primaryKey = "";
722 Map<String, byte[]> objectMap = insObj.getObjectMap();
723 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
724 fieldsString.append("" + entry.getKey());
725 Object valueObj = entry.getValue();
726 if (primaryKeyName.equals(entry.getKey())) {
727 primaryKey = entry.getValue() + "";
728 primaryKey = primaryKey.replace("'", "''");
730 DataType colType = null;
732 colType = tableInfo.getColumn(entry.getKey()).getType();
733 } catch(NullPointerException ex) {
734 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey
735 (), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR, ex);
736 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
739 Object formattedValue = null;
741 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
742 } catch (Exception e) {
743 logger.error(EELFLoggerDelegate.errorLogger,e);
745 valueString.append("?");
747 queryObject.addValue(formattedValue);
749 if (counter == valuesMap.size() - 1) {
750 fieldsString.append(")");
751 valueString.append(")");
753 fieldsString.append(",");
754 valueString.append(",");
756 counter = counter + 1;
760 if(objectMap != null) {
761 for (Map.Entry<String, byte[]> entry : objectMap.entrySet()) {
763 fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ",");
764 valueString.replace(valueString.length()-1, valueString.length(), ",");
766 fieldsString.append("" + entry.getKey());
767 byte[] valueObj = entry.getValue();
768 if (primaryKeyName.equals(entry.getKey())) {
769 primaryKey = entry.getValue() + "";
770 primaryKey = primaryKey.replace("'", "''");
773 DataType colType = tableInfo.getColumn(entry.getKey()).getType();
775 ByteBuffer formattedValue = null;
777 if(colType.toString().toLowerCase().contains("blob"))
778 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
780 valueString.append("?");
782 queryObject.addValue(formattedValue);
783 counter = counter + 1;
784 /*if (counter == valuesMap.size() - 1) {
785 fieldsString.append(")");
786 valueString.append(")");
788 fieldsString.append(",");
789 valueString.append(",");
793 if(primaryKey == null || primaryKey.length() <= 0) {
794 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
795 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build();
798 fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ")");
799 valueString.replace(valueString.length()-1, valueString.length(), ")");
801 queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
802 + fieldsString + " VALUES " + valueString);
804 String ttl = insObj.getTtl();
805 String timestamp = insObj.getTimestamp();
807 if ((ttl != null) && (timestamp != null)) {
808 logger.info(EELFLoggerDelegate.applicationLogger, "both there");
809 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
810 queryObject.addValue(Integer.parseInt(ttl));
811 queryObject.addValue(Long.parseLong(timestamp));
814 if ((ttl != null) && (timestamp == null)) {
815 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
816 queryObject.appendQueryString(" USING TTL ?");
817 queryObject.addValue(Integer.parseInt(ttl));
820 if ((ttl == null) && (timestamp != null)) {
821 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
822 queryObject.appendQueryString(" USING TIMESTAMP ?");
823 queryObject.addValue(Long.parseLong(timestamp));
826 queryObject.appendQueryString(";");
828 ReturnType result = null;
829 String consistency = insObj.getConsistencyInfo().get("type");
830 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && insObj.getConsistencyInfo().get("consistency") != null) {
831 if(MusicUtil.isValidConsistency(insObj.getConsistencyInfo().get("consistency")))
832 queryObject.setConsistency(insObj.getConsistencyInfo().get("consistency"));
834 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
836 queryObject.setOperation("insert");
838 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
839 result = MusicCore.eventualPut(queryObject);
840 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
841 String lockId = insObj.getConsistencyInfo().get("lockId");
843 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
844 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
845 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
846 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
848 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
849 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
851 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
854 } catch (Exception ex) {
855 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
856 .WARN, ErrorTypes.MUSICSERVICEERROR, ex);
857 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
861 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
862 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
863 }else if(result.getResult() == ResultType.FAILURE) {
864 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result.getResult()).setError(result.getMessage()).toMap()).build();
866 return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
868 EELFLoggerDelegate.mdcRemove("keyspace");
879 * @throws MusicServiceException
880 * @throws MusicQueryException
884 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
885 @ApiOperation(value = "Update Table", response = String.class)
886 @Consumes(MediaType.APPLICATION_JSON)
887 @Produces(MediaType.APPLICATION_JSON)
888 public Response updateTable(
889 @ApiParam(value = "Major Version",
890 required = true) @PathParam("version") String version,
891 @ApiParam(value = "Minor Version",
892 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
893 @ApiParam(value = "Patch Version",
894 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
895 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
896 @ApiParam(value = "Application namespace",
897 required = true) @HeaderParam(NS) String ns,
898 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
899 JsonUpdate updateObj,
900 @ApiParam(value = "Keyspace Name",
901 required = true) @PathParam("keyspace") String keyspace,
902 @ApiParam(value = "Table Name",
903 required = true) @PathParam("tablename") String tablename,
904 @Context UriInfo info) throws MusicQueryException, MusicServiceException {
906 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
907 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
908 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
909 .setError("one or more path parameters are not set, please check and try again")
912 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
913 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.UPDATE_TABLE)) {
914 return response.status(Status.UNAUTHORIZED)
915 .entity(new JsonResponse(ResultType.FAILURE)
916 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
920 long startTime = System.currentTimeMillis();
921 String operationId = UUID.randomUUID().toString();// just for infoging
923 String consistency = updateObj.getConsistencyInfo().get("type");
925 logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
926 + " update-" + operationId + "-------------------------");
927 // obtain the field value pairs of the update
929 PreparedQueryObject queryObject = new PreparedQueryObject();
930 Map<String, Object> valuesMap = updateObj.getValues();
932 TableMetadata tableInfo;
934 tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
935 } catch (MusicServiceException e) {
936 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
937 .GENERALSERVICEERROR, e);
938 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
940 if (tableInfo == null) {
941 logger.error(EELFLoggerDelegate.errorLogger,"Table information not found. Please check input for table name= "+tablename, AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
942 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
943 .setError("Table information not found. Please check input for table name= "
944 + keyspace + "." + tablename).toMap()).build();
947 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
948 StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
949 queryObject.addValue(vectorTs);
951 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
952 Object valueObj = entry.getValue();
953 DataType colType = null;
955 colType = tableInfo.getColumn(entry.getKey()).getType();
956 } catch(NullPointerException ex) {
957 logger.error(EELFLoggerDelegate.errorLogger, ex, "Invalid column name : "+entry.getKey(), ex);
958 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
960 Object valueString = null;
962 valueString = MusicUtil.convertToActualDataType(colType, valueObj);
963 } catch (Exception e) {
964 logger.error(EELFLoggerDelegate.errorLogger,e);
966 fieldValueString.append(entry.getKey() + "= ?");
967 queryObject.addValue(valueString);
968 if (counter != valuesMap.size() - 1)
969 fieldValueString.append(",");
970 counter = counter + 1;
972 String ttl = updateObj.getTtl();
973 String timestamp = updateObj.getTimestamp();
975 queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
976 if ((ttl != null) && (timestamp != null)) {
978 logger.info("both there");
979 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
980 queryObject.addValue(Integer.parseInt(ttl));
981 queryObject.addValue(Long.parseLong(timestamp));
984 if ((ttl != null) && (timestamp == null)) {
985 logger.info("ONLY TTL there");
986 queryObject.appendQueryString(" USING TTL ?");
987 queryObject.addValue(Integer.parseInt(ttl));
990 if ((ttl == null) && (timestamp != null)) {
991 logger.info("ONLY timestamp there");
992 queryObject.appendQueryString(" USING TIMESTAMP ?");
993 queryObject.addValue(Long.parseLong(timestamp));
995 // get the row specifier
996 RowIdentifier rowId = null;
998 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
999 if(rowId == null || rowId.primarKeyValue.isEmpty()) {
1000 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1001 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
1003 } catch (MusicServiceException ex) {
1004 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
1005 .GENERALSERVICEERROR, ex);
1006 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1009 queryObject.appendQueryString(
1010 " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
1012 // get the conditional, if any
1013 Condition conditionInfo;
1014 if (updateObj.getConditions() == null)
1015 conditionInfo = null;
1016 else {// to avoid parsing repeatedly, just send the select query to
1018 PreparedQueryObject selectQuery = new PreparedQueryObject();
1019 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
1020 + rowId.rowIdString + ";");
1021 selectQuery.addValue(rowId.primarKeyValue);
1022 conditionInfo = new Condition(updateObj.getConditions(), selectQuery);
1025 ReturnType operationResult = null;
1026 long jsonParseCompletionTime = System.currentTimeMillis();
1028 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && updateObj.getConsistencyInfo().get("consistency") != null) {
1029 if(MusicUtil.isValidConsistency(updateObj.getConsistencyInfo().get("consistency")))
1030 queryObject.setConsistency(updateObj.getConsistencyInfo().get("consistency"));
1032 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
1034 queryObject.setOperation("update");
1035 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1036 operationResult = MusicCore.eventualPut(queryObject);
1037 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1038 String lockId = updateObj.getConsistencyInfo().get("lockId");
1039 if(lockId == null) {
1040 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1041 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1042 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1043 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1045 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
1046 queryObject, lockId, conditionInfo);
1047 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
1048 // this function is mainly for the benchmarks
1050 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
1051 rowId.primarKeyValue, queryObject, conditionInfo);
1052 } catch (MusicLockingException e) {
1053 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
1054 ErrorTypes.GENERALSERVICEERROR, e);
1055 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
1057 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1059 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
1060 queryObject, conditionInfo);
1061 } catch (MusicLockingException e) {
1062 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
1063 ErrorTypes.GENERALSERVICEERROR, e);
1064 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
1066 }else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1067 operationResult = MusicCore.eventualPut_nb(queryObject, keyspace, tablename, rowId.primarKeyValue);
1069 long actualUpdateCompletionTime = System.currentTimeMillis();
1071 long endTime = System.currentTimeMillis();
1072 String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
1073 + ":" + "|total operation time:" + (endTime - startTime)
1074 + "|json parsing time:" + (jsonParseCompletionTime - startTime)
1075 + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
1078 if (operationResult != null && operationResult.getTimingInfo() != null) {
1079 String lockManagementTime = operationResult.getTimingInfo();
1080 timingString = timingString + lockManagementTime;
1082 logger.info(EELFLoggerDelegate.applicationLogger, timingString);
1084 if (operationResult==null) {
1085 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1086 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1088 if ( operationResult.getResult() == ResultType.SUCCESS ) {
1089 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1091 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1092 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
1095 EELFLoggerDelegate.mdcRemove("keyspace");
1106 * @throws MusicServiceException
1107 * @throws MusicQueryException
1111 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
1112 @ApiOperation(value = "Delete From table", response = String.class)
1113 @Consumes(MediaType.APPLICATION_JSON)
1114 @Produces(MediaType.APPLICATION_JSON)
1115 public Response deleteFromTable(
1116 @ApiParam(value = "Major Version",
1117 required = true) @PathParam("version") String version,
1118 @ApiParam(value = "Minor Version",
1119 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1120 @ApiParam(value = "Patch Version",
1121 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1122 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1123 @ApiParam(value = "Application namespace",
1124 required = true) @HeaderParam(NS) String ns,
1125 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1127 @ApiParam(value = "Keyspace Name",
1128 required = true) @PathParam("keyspace") String keyspace,
1129 @ApiParam(value = "Table Name",
1130 required = true) @PathParam("tablename") String tablename,
1131 @Context UriInfo info) throws MusicQueryException, MusicServiceException {
1133 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1134 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1135 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1136 .setError("one or more path parameters are not set, please check and try again")
1139 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1140 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DELETE_FROM_TABLE)) {
1141 return response.status(Status.UNAUTHORIZED)
1142 .entity(new JsonResponse(ResultType.FAILURE)
1143 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1147 if(delObj == null) {
1148 logger.error(EELFLoggerDelegate.errorLogger,"Required HTTP Request body is missing.", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
1149 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
1151 PreparedQueryObject queryObject = new PreparedQueryObject();
1152 StringBuilder columnString = new StringBuilder();
1155 List<String> columnList = delObj.getColumns();
1156 if (columnList != null) {
1157 for (String column : columnList) {
1158 columnString.append(column);
1159 if (counter != columnList.size() - 1)
1160 columnString.append(",");
1161 counter = counter + 1;
1165 // get the row specifier
1166 RowIdentifier rowId = null;
1168 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1169 } catch (MusicServiceException ex) {
1170 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
1171 .GENERALSERVICEERROR, ex);
1172 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1174 String rowSpec = rowId.rowIdString.toString();
1176 if ((columnList != null) && (!rowSpec.isEmpty())) {
1177 queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
1178 + tablename + " WHERE " + rowSpec + ";");
1181 if ((columnList == null) && (!rowSpec.isEmpty())) {
1182 queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
1186 if ((columnList != null) && (rowSpec.isEmpty())) {
1187 queryObject.appendQueryString(
1188 "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
1190 // get the conditional, if any
1191 Condition conditionInfo;
1192 if (delObj.getConditions() == null)
1193 conditionInfo = null;
1194 else {// to avoid parsing repeatedly, just send the select query to
1196 PreparedQueryObject selectQuery = new PreparedQueryObject();
1197 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
1198 + rowId.rowIdString + ";");
1199 selectQuery.addValue(rowId.primarKeyValue);
1200 conditionInfo = new Condition(delObj.getConditions(), selectQuery);
1203 String consistency = delObj.getConsistencyInfo().get("type");
1206 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && delObj.getConsistencyInfo().get("consistency")!=null) {
1208 if(MusicUtil.isValidConsistency(delObj.getConsistencyInfo().get("consistency")))
1209 queryObject.setConsistency(delObj.getConsistencyInfo().get("consistency"));
1211 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
1214 ReturnType operationResult = null;
1215 queryObject.setOperation("delete");
1217 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1218 operationResult = MusicCore.eventualPut(queryObject);
1219 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1220 String lockId = delObj.getConsistencyInfo().get("lockId");
1221 if(lockId == null) {
1222 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1223 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1224 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1225 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1227 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
1228 queryObject, lockId, conditionInfo);
1229 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1230 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
1231 queryObject, conditionInfo);
1232 } else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1234 operationResult = MusicCore.eventualPut_nb(queryObject, keyspace, tablename, rowId.primarKeyValue);
1236 } catch (MusicLockingException e) {
1237 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
1238 .GENERALSERVICEERROR, e);
1239 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1240 .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
1242 if (operationResult==null) {
1243 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1244 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1246 if (operationResult.getResult().equals(ResultType.SUCCESS)) {
1247 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1249 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1250 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
1253 EELFLoggerDelegate.mdcRemove("keyspace");
1265 @Path("/{keyspace: .*}/tables/{tablename: .*}")
1266 @ApiOperation(value = "Drop Table", response = String.class)
1267 @Produces(MediaType.APPLICATION_JSON)
1268 public Response dropTable(
1269 @ApiParam(value = "Major Version",
1270 required = true) @PathParam("version") String version,
1271 @ApiParam(value = "Minor Version",
1272 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1273 @ApiParam(value = "Patch Version",
1274 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1275 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1276 @ApiParam(value = "Application namespace",
1277 required = true) @HeaderParam(NS) String ns,
1278 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1279 @ApiParam(value = "Keyspace Name",
1280 required = true) @PathParam("keyspace") String keyspace,
1281 @ApiParam(value = "Table Name",
1282 required = true) @PathParam("tablename") String tablename) throws Exception {
1284 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1285 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1286 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1287 .setError("one or more path parameters are not set, please check and try again")
1290 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1291 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DROP_TABLE)) {
1292 return response.status(Status.UNAUTHORIZED)
1293 .entity(new JsonResponse(ResultType.FAILURE)
1294 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1298 String consistency = "eventual";// for now this needs only eventual
1300 PreparedQueryObject query = new PreparedQueryObject();
1301 query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
1303 return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
1304 } catch (MusicServiceException ex) {
1305 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes
1306 .GENERALSERVICEERROR);
1307 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1310 EELFLoggerDelegate.mdcRemove("keyspace");
1323 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows/criticalget")
1324 @ApiOperation(value = "Select Critical", response = Map.class)
1325 @Consumes(MediaType.APPLICATION_JSON)
1326 @Produces(MediaType.APPLICATION_JSON)
1327 public Response selectCritical(
1328 @ApiParam(value = "Major Version",
1329 required = true) @PathParam("version") String version,
1330 @ApiParam(value = "Minor Version",
1331 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1332 @ApiParam(value = "Patch Version",
1333 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1334 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1335 @ApiParam(value = "Application namespace",
1336 required = true) @HeaderParam(NS) String ns,
1337 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1339 @ApiParam(value = "Keyspace Name",
1340 required = true) @PathParam("keyspace") String keyspace,
1341 @ApiParam(value = "Table Name",
1342 required = true) @PathParam("tablename") String tablename,
1343 @Context UriInfo info) throws Exception {
1345 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1346 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1347 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1348 .setError("one or more path parameters are not set, please check and try again")
1351 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1352 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT_CRITICAL)) {
1353 return response.status(Status.UNAUTHORIZED)
1354 .entity(new JsonResponse(ResultType.FAILURE)
1355 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1359 String lockId = selObj.getConsistencyInfo().get("lockId");
1361 PreparedQueryObject queryObject = new PreparedQueryObject();
1363 RowIdentifier rowId = null;
1365 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1366 } catch (MusicServiceException ex) {
1367 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
1368 .GENERALSERVICEERROR, ex);
1369 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1371 queryObject.appendQueryString(
1372 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1374 ResultSet results = null;
1376 String consistency = selObj.getConsistencyInfo().get("type");
1378 if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1379 if(lockId == null) {
1380 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1381 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1382 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1383 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1385 results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1387 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1388 results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1390 if(results!=null && results.getAvailableWithoutFetching() >0) {
1391 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
1393 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setError("No data found").toMap()).build();
1396 EELFLoggerDelegate.mdcRemove("keyspace");
1409 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
1410 @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1411 @Produces(MediaType.APPLICATION_JSON)
1412 public Response select(
1413 @ApiParam(value = "Major Version",
1414 required = true) @PathParam("version") String version,
1415 @ApiParam(value = "Minor Version",
1416 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1417 @ApiParam(value = "Patch Version",
1418 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1419 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1420 @ApiParam(value = "Application namespace",
1421 required = true) @HeaderParam(NS) String ns,
1422 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1423 @ApiParam(value = "Keyspace Name",
1424 required = true) @PathParam("keyspace") String keyspace,
1425 @ApiParam(value = "Table Name",
1426 required = true) @PathParam("tablename") String tablename,
1427 @Context UriInfo info) throws Exception {
1429 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1430 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1431 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1432 .setError("one or more path parameters are not set, please check and try again")
1435 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1436 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT)) {
1437 return response.status(Status.UNAUTHORIZED)
1438 .entity(new JsonResponse(ResultType.FAILURE)
1439 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1443 PreparedQueryObject queryObject = new PreparedQueryObject();
1445 if (info.getQueryParameters().isEmpty())// select all
1446 queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
1448 int limit = -1; // do not limit the number of results
1450 queryObject = selectSpecificQuery(keyspace, tablename, info, limit);
1451 } catch (MusicServiceException ex) {
1452 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
1453 ErrorTypes.GENERALSERVICEERROR, ex);
1454 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1459 ResultSet results = MusicCore.get(queryObject);
1460 if(results.getAvailableWithoutFetching() >0) {
1461 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
1463 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).setError("No data found").toMap()).build();
1464 } catch (MusicServiceException ex) {
1465 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR,
1466 ErrorTypes.MUSICSERVICEERROR, ex);
1467 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1470 EELFLoggerDelegate.mdcRemove("keyspace");
1481 * @throws MusicServiceException
1483 public PreparedQueryObject selectSpecificQuery(String keyspace,
1484 String tablename, UriInfo info, int limit)
1485 throws MusicServiceException {
1487 PreparedQueryObject queryObject = new PreparedQueryObject();
1488 StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1489 queryObject).rowIdString;
1491 queryObject.appendQueryString(
1492 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1495 queryObject.appendQueryString(" LIMIT " + limit);
1498 queryObject.appendQueryString(";");
1508 * @param queryObject
1510 * @throws MusicServiceException
1512 private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1513 MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1514 throws MusicServiceException {
1515 StringBuilder rowSpec = new StringBuilder();
1517 TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
1518 if (tableInfo == null) {
1519 logger.error(EELFLoggerDelegate.errorLogger,
1520 "Table information not found. Please check input for table name= "
1521 + keyspace + "." + tablename);
1522 throw new MusicServiceException(
1523 "Table information not found. Please check input for table name= "
1524 + keyspace + "." + tablename);
1526 StringBuilder primaryKey = new StringBuilder();
1527 for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1528 String keyName = entry.getKey();
1529 List<String> valueList = entry.getValue();
1530 String indValue = valueList.get(0);
1531 DataType colType = null;
1532 Object formattedValue = null;
1534 colType = tableInfo.getColumn(entry.getKey()).getType();
1535 formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1536 } catch (Exception e) {
1537 logger.error(EELFLoggerDelegate.errorLogger,e);
1539 if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey()))
1540 primaryKey.append(indValue);
1541 rowSpec.append(keyName + "= ?");
1542 queryObject.addValue(formattedValue);
1543 if (counter != rowParams.size() - 1)
1544 rowSpec.append(" AND ");
1545 counter = counter + 1;
1547 return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);