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 ( MusicUtil.isKeyspaceActive() ) {
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)
198 .setError("Invalid Consistency type").toMap()).build();
201 long start = System.currentTimeMillis();
202 Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
203 String repString = null;
205 repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
206 } catch (Exception e) {
207 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity
208 .CRITICAL, ErrorTypes.DATAERROR, e);
211 queryObject.appendQueryString(
212 "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
213 if (kspObject.getDurabilityOfWrites() != null) {
214 queryObject.appendQueryString(
215 " AND durable_writes = " + kspObject.getDurabilityOfWrites());
218 queryObject.appendQueryString(";");
219 long end = System.currentTimeMillis();
220 logger.info(EELFLoggerDelegate.applicationLogger,
221 "Time taken for setting up query in create keyspace:" + (end - start));
223 ResultType result = ResultType.FAILURE;
225 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
226 logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
227 } catch ( MusicServiceException ex) {
228 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
229 .WARN, ErrorTypes.MUSICSERVICEERROR, ex);
230 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
234 queryObject = new PreparedQueryObject();
235 queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
236 + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
237 MusicCore.nonKeyRelatedPut(queryObject, consistency);
238 queryObject = new PreparedQueryObject();
239 queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
240 + " to '" + userId + "'");
241 queryObject.appendQueryString(";");
242 MusicCore.nonKeyRelatedPut(queryObject, consistency);
243 } catch (Exception e) {
244 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity
245 .WARN, ErrorTypes.MUSICSERVICEERROR, e);
249 boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
250 String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt());
251 queryObject = new PreparedQueryObject();
252 queryObject.appendQueryString(
253 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
254 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
255 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), aid));
256 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
257 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
258 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
259 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd));
260 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
261 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
262 CachingUtil.updateMusicCache(keyspaceName, ns);
263 CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd);
264 MusicCore.eventualPut(queryObject);
265 } catch (Exception e) {
266 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity
267 .WARN, ErrorTypes.MUSICSERVICEERROR, e);
268 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
271 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
273 String vError = "Keyspace Creation has been turned off. Contact DBA to create the keyspace or set keyspace.active to true.";
274 logger.info(EELFLoggerDelegate.applicationLogger,vError);
275 logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
276 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build();
279 EELFLoggerDelegate.mdcRemove("keyspace");
287 * @param keyspaceName
293 @ApiOperation(value = "Delete Keyspace", response = String.class,hidden=true)
294 @Produces(MediaType.APPLICATION_JSON)
295 public Response dropKeySpace(
296 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
297 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
298 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
299 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
300 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
301 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
302 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception {
304 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
305 EELFLoggerDelegate.mdcPut("keyspace", "( " + keyspaceName + " ) ");
306 logger.info(EELFLoggerDelegate.applicationLogger,"In Drop Keyspace " + keyspaceName);
307 if (MusicUtil.isKeyspaceActive()) {
308 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DROP_KEYSPACE)) {
309 return response.status(Status.UNAUTHORIZED)
310 .entity(new JsonResponse(ResultType.FAILURE)
311 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
314 String consistency = MusicUtil.EVENTUAL;// for now this needs only
317 String appName = CachingUtil.getAppName(keyspaceName);
318 String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
319 PreparedQueryObject pQuery = new PreparedQueryObject();
320 pQuery.appendQueryString(
321 "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
322 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
323 Row row = MusicCore.get(pQuery).one();
324 long count = row.getLong(0);
327 logger.error(EELFLoggerDelegate.errorLogger,"Keyspace not found. Please make sure keyspace exists.", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
328 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
330 } else if (count == 1) {
331 pQuery = new PreparedQueryObject();
332 pQuery.appendQueryString(
333 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
334 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
335 MusicUtil.DEFAULTKEYSPACENAME));
336 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
337 MusicCore.nonKeyRelatedPut(pQuery, consistency);
339 pQuery = new PreparedQueryObject();
340 pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
341 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
342 MusicCore.nonKeyRelatedPut(pQuery, consistency);
345 PreparedQueryObject queryObject = new PreparedQueryObject();
346 queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
347 ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
348 if ( result.equals(ResultType.FAILURE) ) {
349 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
351 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
353 String vError = "Keyspace deletion has been turned off. Contact DBA to delete the keyspace or set keyspace.active to true.";
354 logger.info(EELFLoggerDelegate.applicationLogger,vError);
355 logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
356 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build();
359 EELFLoggerDelegate.mdcRemove("keyspace");
371 * @throws Exception -
374 @Path("/{keyspace: .*}/tables/{tablename: .*}")
375 @ApiOperation(value = "Create Table", response = String.class)
376 @Consumes(MediaType.APPLICATION_JSON)
377 @Produces(MediaType.APPLICATION_JSON)
378 @ApiResponses(value={
379 @ApiResponse(code= 400, message = "Will return JSON response with message"),
380 @ApiResponse(code= 401, message = "Unautorized User")
382 public Response createTable(
383 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
384 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
385 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
386 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
387 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
388 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
390 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
391 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception {
393 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
394 if(keyspace == null || keyspace.isEmpty() || tablename == null || tablename.isEmpty()){
395 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
396 .setError("One or more path parameters are not set, please check and try again."
397 + "Parameter values: keyspace='" + keyspace + "' tablename='" + tablename + "'")
400 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
401 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_TABLE)) {
402 return response.status(Status.UNAUTHORIZED)
403 .entity(new JsonResponse(ResultType.FAILURE)
404 .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
409 String primaryKey = null;
410 String partitionKey = tableObj.getPartitionKey();
411 String clusterKey = tableObj.getClusteringKey();
412 String filteringKey = tableObj.getFilteringKey();
413 if(filteringKey != null) {
414 clusterKey = clusterKey + "," + filteringKey;
416 primaryKey = tableObj.getPrimaryKey(); // get primaryKey if available
418 PreparedQueryObject queryObject = new PreparedQueryObject();
419 // first read the information about the table fields
420 Map<String, String> fields = tableObj.getFields();
421 if (fields == null) {
422 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
423 .setError("Create Table Error: No fields in request").toMap()).build();
426 StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
428 for (Map.Entry<String, String> entry : fields.entrySet()) {
429 if (entry.getKey().equals("PRIMARY KEY")) {
430 primaryKey = entry.getValue(); // replaces primaryKey
431 primaryKey = primaryKey.trim();
433 if (counter == 0 ) fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
434 else fieldsString.append("," + entry.getKey() + " " + entry.getValue() + "");
437 if (counter != (fields.size() - 1) ) {
438 counter = counter + 1;
441 if((primaryKey != null) && (partitionKey == null)) {
442 primaryKey = primaryKey.trim();
443 int count1 = StringUtils.countMatches(primaryKey, ')');
444 int count2 = StringUtils.countMatches(primaryKey, '(');
445 if (count1 != count2) {
446 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
447 .setError("Create Table Error: primary key '(' and ')' do not match, primary key=" + primaryKey)
451 if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) ) {
452 if (primaryKey.contains(",") ) {
453 partitionKey= primaryKey.substring(0,primaryKey.indexOf(','));
454 partitionKey=partitionKey.replaceAll("[\\(]+","");
455 clusterKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index
456 clusterKey=clusterKey.replaceAll("[)]+", "");
458 partitionKey=primaryKey;
459 partitionKey=partitionKey.replaceAll("[\\)]+","");
460 partitionKey=partitionKey.replaceAll("[\\(]+","");
463 } else { // not null and has ) before the last char
464 partitionKey= primaryKey.substring(0,primaryKey.indexOf(')'));
465 partitionKey=partitionKey.replaceAll("[\\(]+","");
466 partitionKey = partitionKey.trim();
467 clusterKey= primaryKey.substring(primaryKey.indexOf(')'));
468 clusterKey=clusterKey.replaceAll("[\\(]+","");
469 clusterKey=clusterKey.replaceAll("[\\)]+","");
470 clusterKey = clusterKey.trim();
471 if (clusterKey.indexOf(',') == 0) {
472 clusterKey=clusterKey.substring(1);
474 clusterKey = clusterKey.trim();
475 if (clusterKey.equals(",") ) clusterKey=""; // print error if needed ( ... ),)
478 if (!(partitionKey.isEmpty() || clusterKey.isEmpty())
479 && (partitionKey.equalsIgnoreCase(clusterKey) ||
480 clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) {
481 logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey + " and primary key=" + primaryKey );
482 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(
483 "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ") of"
484 + " primary key=" + primaryKey)
489 if (partitionKey.isEmpty() ) primaryKey="";
490 else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")";
491 else primaryKey=" (" + partitionKey + ")," + clusterKey;
494 if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )");
496 } else { // end of length > 0
498 if (!(partitionKey.isEmpty() || clusterKey.isEmpty())
499 && (partitionKey.equalsIgnoreCase(clusterKey) ||
500 clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) {
501 logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey);
502 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(
503 "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ")")
507 if (partitionKey.isEmpty() ) primaryKey="";
508 else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")";
509 else primaryKey=" (" + partitionKey + ")," + clusterKey;
511 if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )");
513 fieldsString.append(")");
515 } // end of last field check
518 // information about the name-value style properties
519 Map<String, Object> propertiesMap = tableObj.getProperties();
520 StringBuilder propertiesString = new StringBuilder();
521 if (propertiesMap != null) {
523 for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
524 Object ot = entry.getValue();
525 String value = ot + "";
526 if (ot instanceof String) {
527 value = "'" + value + "'";
528 } else if (ot instanceof Map) {
529 @SuppressWarnings("unchecked")
530 Map<String, Object> otMap = (Map<String, Object>) ot;
531 value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
534 propertiesString.append(entry.getKey() + "=" + value + "");
535 if (counter != propertiesMap.size() - 1)
536 propertiesString.append(" AND ");
538 counter = counter + 1;
542 String clusteringOrder = tableObj.getClusteringOrder();
544 if (clusteringOrder != null && !(clusteringOrder.isEmpty())) {
545 String[] arrayClusterOrder = clusteringOrder.split("[,]+");
547 for (int i = 0; i < arrayClusterOrder.length; i++) {
548 String[] clusterS = arrayClusterOrder[i].trim().split("[ ]+");
549 if ( (clusterS.length ==2) && (clusterS[1].equalsIgnoreCase("ASC") || clusterS[1].equalsIgnoreCase("DESC"))) {
552 return response.status(Status.BAD_REQUEST)
553 .entity(new JsonResponse(ResultType.FAILURE)
554 .setError("createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:"+ clusteringOrder+".")
557 // add validation for column names in cluster key
560 if (!(clusterKey.isEmpty())) {
561 clusteringOrder = "CLUSTERING ORDER BY (" +clusteringOrder +")";
562 //cjc check if propertiesString.length() >0 instead propertiesMap
563 if (propertiesMap != null) {
564 propertiesString.append(" AND "+ clusteringOrder);
566 propertiesString.append(clusteringOrder);
569 logger.warn("Skipping clustering order=("+clusteringOrder+ ") since clustering key is empty ");
573 queryObject.appendQueryString(
574 "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
577 if (propertiesString != null && propertiesString.length()>0 )
578 queryObject.appendQueryString(" WITH " + propertiesString);
579 queryObject.appendQueryString(";");
580 ResultType result = ResultType.FAILURE;
582 result = MusicCore.createTable(keyspace, tablename, queryObject, consistency);
583 } catch (MusicServiceException ex) {
584 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR);
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 PreparedQueryObject queryObject = new PreparedQueryObject();
703 TableMetadata tableInfo = null;
705 tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
706 if(tableInfo == null) {
707 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
709 } catch (MusicServiceException e) {
710 logger.error(EELFLoggerDelegate.errorLogger, e, AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
711 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
713 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
714 StringBuilder fieldsString = new StringBuilder("(vector_ts,");
716 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
717 StringBuilder valueString = new StringBuilder("(" + "?" + ",");
718 queryObject.addValue(vectorTs);
720 Map<String, Object> valuesMap = insObj.getValues();
721 if (valuesMap==null) {
722 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
723 .setError("Nothing to insert. No values provided in request.").toMap()).build();
726 String primaryKey = "";
727 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
728 fieldsString.append("" + entry.getKey());
729 Object valueObj = entry.getValue();
730 if (primaryKeyName.equals(entry.getKey())) {
731 primaryKey = entry.getValue() + "";
732 primaryKey = primaryKey.replace("'", "''");
734 DataType colType = null;
736 colType = tableInfo.getColumn(entry.getKey()).getType();
737 } catch(NullPointerException ex) {
738 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey
739 (), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR, ex);
740 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
743 Object formattedValue = null;
745 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
746 } catch (Exception e) {
747 logger.error(EELFLoggerDelegate.errorLogger,e);
749 valueString.append("?");
751 queryObject.addValue(formattedValue);
753 if (counter == valuesMap.size() - 1) {
754 fieldsString.append(")");
755 valueString.append(")");
757 fieldsString.append(",");
758 valueString.append(",");
760 counter = counter + 1;
764 Map<String, byte[]> objectMap = insObj.getObjectMap();
765 if(objectMap != null) {
766 for (Map.Entry<String, byte[]> entry : objectMap.entrySet()) {
768 fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ",");
769 valueString.replace(valueString.length()-1, valueString.length(), ",");
771 fieldsString.append("" + entry.getKey());
772 byte[] valueObj = entry.getValue();
773 if (primaryKeyName.equals(entry.getKey())) {
774 primaryKey = entry.getValue() + "";
775 primaryKey = primaryKey.replace("'", "''");
778 DataType colType = tableInfo.getColumn(entry.getKey()).getType();
780 ByteBuffer formattedValue = null;
782 if(colType.toString().toLowerCase().contains("blob"))
783 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
785 valueString.append("?");
787 queryObject.addValue(formattedValue);
788 counter = counter + 1;
789 fieldsString.append(",");
790 valueString.append(",");
794 if(primaryKey == null || primaryKey.length() <= 0) {
795 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
796 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build();
799 fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ")");
800 valueString.replace(valueString.length()-1, valueString.length(), ")");
802 queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
803 + fieldsString + " VALUES " + valueString);
805 String ttl = insObj.getTtl();
806 String timestamp = insObj.getTimestamp();
808 if ((ttl != null) && (timestamp != null)) {
809 logger.info(EELFLoggerDelegate.applicationLogger, "both there");
810 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
811 queryObject.addValue(Integer.parseInt(ttl));
812 queryObject.addValue(Long.parseLong(timestamp));
815 if ((ttl != null) && (timestamp == null)) {
816 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
817 queryObject.appendQueryString(" USING TTL ?");
818 queryObject.addValue(Integer.parseInt(ttl));
821 if ((ttl == null) && (timestamp != null)) {
822 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
823 queryObject.appendQueryString(" USING TIMESTAMP ?");
824 queryObject.addValue(Long.parseLong(timestamp));
827 queryObject.appendQueryString(";");
829 ReturnType result = null;
830 String consistency = insObj.getConsistencyInfo().get("type");
831 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && insObj.getConsistencyInfo().get("consistency") != null) {
832 if(MusicUtil.isValidConsistency(insObj.getConsistencyInfo().get("consistency")))
833 queryObject.setConsistency(insObj.getConsistencyInfo().get("consistency"));
835 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
837 queryObject.setOperation("insert");
839 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
840 result = MusicCore.eventualPut(queryObject);
841 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
842 String lockId = insObj.getConsistencyInfo().get("lockId");
844 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
845 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
846 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
847 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
849 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
850 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
852 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
855 } catch (Exception ex) {
856 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
857 .WARN, ErrorTypes.MUSICSERVICEERROR, ex);
858 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
862 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
863 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
864 }else if(result.getResult() == ResultType.FAILURE) {
865 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result.getResult()).setError(result.getMessage()).toMap()).build();
867 return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
869 EELFLoggerDelegate.mdcRemove("keyspace");
880 * @throws MusicServiceException
881 * @throws MusicQueryException
885 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
886 @ApiOperation(value = "Update Table", response = String.class)
887 @Consumes(MediaType.APPLICATION_JSON)
888 @Produces(MediaType.APPLICATION_JSON)
889 public Response updateTable(
890 @ApiParam(value = "Major Version",
891 required = true) @PathParam("version") String version,
892 @ApiParam(value = "Minor Version",
893 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
894 @ApiParam(value = "Patch Version",
895 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
896 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
897 @ApiParam(value = "Application namespace",
898 required = true) @HeaderParam(NS) String ns,
899 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
900 JsonUpdate updateObj,
901 @ApiParam(value = "Keyspace Name",
902 required = true) @PathParam("keyspace") String keyspace,
903 @ApiParam(value = "Table Name",
904 required = true) @PathParam("tablename") String tablename,
905 @Context UriInfo info) throws MusicQueryException, MusicServiceException {
907 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
908 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
909 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
910 .setError("one or more path parameters are not set, please check and try again")
913 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
914 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.UPDATE_TABLE)) {
915 return response.status(Status.UNAUTHORIZED)
916 .entity(new JsonResponse(ResultType.FAILURE)
917 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
921 long startTime = System.currentTimeMillis();
922 String operationId = UUID.randomUUID().toString(); // just for infoging
924 String consistency = updateObj.getConsistencyInfo().get("type");
926 logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
927 + " update-" + operationId + "-------------------------");
928 // obtain the field value pairs of the update
930 PreparedQueryObject queryObject = new PreparedQueryObject();
931 Map<String, Object> valuesMap = updateObj.getValues();
933 TableMetadata tableInfo;
935 tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
936 } catch (MusicServiceException e) {
937 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
938 .GENERALSERVICEERROR, e);
939 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
941 if (tableInfo == null) {
942 logger.error(EELFLoggerDelegate.errorLogger,"Table information not found. Please check input for table name= "+tablename, AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
943 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
944 .setError("Table information not found. Please check input for table name= "
945 + keyspace + "." + tablename).toMap()).build();
947 String vectorTs = 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)) {
977 logger.info("both there");
978 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
979 queryObject.addValue(Integer.parseInt(ttl));
980 queryObject.addValue(Long.parseLong(timestamp));
983 if ((ttl != null) && (timestamp == null)) {
984 logger.info("ONLY TTL there");
985 queryObject.appendQueryString(" USING TTL ?");
986 queryObject.addValue(Integer.parseInt(ttl));
989 if ((ttl == null) && (timestamp != null)) {
990 logger.info("ONLY timestamp there");
991 queryObject.appendQueryString(" USING TIMESTAMP ?");
992 queryObject.addValue(Long.parseLong(timestamp));
994 // get the row specifier
995 RowIdentifier rowId = null;
997 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
998 if(rowId == null || rowId.primarKeyValue.isEmpty()) {
999 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1000 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
1002 } catch (MusicServiceException ex) {
1003 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
1004 .GENERALSERVICEERROR, ex);
1005 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1008 queryObject.appendQueryString(
1009 " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
1011 // get the conditional, if any
1012 Condition conditionInfo;
1013 if (updateObj.getConditions() == null)
1014 conditionInfo = null;
1016 // to avoid parsing repeatedly, just send the select query to obtain row
1017 PreparedQueryObject selectQuery = new PreparedQueryObject();
1018 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
1019 + rowId.rowIdString + ";");
1020 selectQuery.addValue(rowId.primarKeyValue);
1021 conditionInfo = new Condition(updateObj.getConditions(), selectQuery);
1024 ReturnType operationResult = null;
1025 long jsonParseCompletionTime = System.currentTimeMillis();
1027 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && updateObj.getConsistencyInfo().get("consistency") != null) {
1028 if(MusicUtil.isValidConsistency(updateObj.getConsistencyInfo().get("consistency")))
1029 queryObject.setConsistency(updateObj.getConsistencyInfo().get("consistency"));
1031 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
1033 queryObject.setOperation("update");
1034 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1035 operationResult = MusicCore.eventualPut(queryObject);
1036 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1037 String lockId = updateObj.getConsistencyInfo().get("lockId");
1038 if(lockId == null) {
1039 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1040 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1041 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1042 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1044 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
1045 queryObject, lockId, conditionInfo);
1046 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
1047 // this function is mainly for the benchmarks
1049 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
1050 rowId.primarKeyValue, queryObject, conditionInfo);
1051 } catch (MusicLockingException e) {
1052 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
1053 ErrorTypes.GENERALSERVICEERROR, e);
1054 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
1056 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1058 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
1059 queryObject, conditionInfo);
1060 } catch (MusicLockingException e) {
1061 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e);
1062 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
1064 }else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1065 operationResult = MusicCore.eventualPut_nb(queryObject, keyspace, tablename, rowId.primarKeyValue);
1067 long actualUpdateCompletionTime = System.currentTimeMillis();
1069 long endTime = System.currentTimeMillis();
1070 String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
1071 + ":" + "|total operation time:" + (endTime - startTime)
1072 + "|json parsing time:" + (jsonParseCompletionTime - startTime)
1073 + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
1076 if (operationResult != null && operationResult.getTimingInfo() != null) {
1077 String lockManagementTime = operationResult.getTimingInfo();
1078 timingString = timingString + lockManagementTime;
1080 logger.info(EELFLoggerDelegate.applicationLogger, timingString);
1082 if (operationResult==null) {
1083 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1084 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1086 if ( operationResult.getResult() == ResultType.SUCCESS ) {
1087 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1089 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1090 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
1093 EELFLoggerDelegate.mdcRemove("keyspace");
1104 * @throws MusicServiceException
1105 * @throws MusicQueryException
1109 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
1110 @ApiOperation(value = "Delete From table", response = String.class)
1111 @Consumes(MediaType.APPLICATION_JSON)
1112 @Produces(MediaType.APPLICATION_JSON)
1113 public Response deleteFromTable(
1114 @ApiParam(value = "Major Version",
1115 required = true) @PathParam("version") String version,
1116 @ApiParam(value = "Minor Version",
1117 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1118 @ApiParam(value = "Patch Version",
1119 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1120 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1121 @ApiParam(value = "Application namespace",
1122 required = true) @HeaderParam(NS) String ns,
1123 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1125 @ApiParam(value = "Keyspace Name",
1126 required = true) @PathParam("keyspace") String keyspace,
1127 @ApiParam(value = "Table Name",
1128 required = true) @PathParam("tablename") String tablename,
1129 @Context UriInfo info) throws MusicQueryException, MusicServiceException {
1131 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1132 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1133 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1134 .setError("one or more path parameters are not set, please check and try again")
1137 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1138 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DELETE_FROM_TABLE)) {
1139 return response.status(Status.UNAUTHORIZED)
1140 .entity(new JsonResponse(ResultType.FAILURE)
1141 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1145 if(delObj == null) {
1146 logger.error(EELFLoggerDelegate.errorLogger,"Required HTTP Request body is missing.", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
1147 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
1149 PreparedQueryObject queryObject = new PreparedQueryObject();
1150 StringBuilder columnString = new StringBuilder();
1153 List<String> columnList = delObj.getColumns();
1154 if (columnList != null) {
1155 for (String column : columnList) {
1156 columnString.append(column);
1157 if (counter != columnList.size() - 1)
1158 columnString.append(",");
1159 counter = counter + 1;
1163 // get the row specifier
1164 RowIdentifier rowId = null;
1166 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1167 } catch (MusicServiceException ex) {
1168 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
1169 .GENERALSERVICEERROR, ex);
1170 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1172 String rowSpec = rowId.rowIdString.toString();
1174 if ((columnList != null) && (!rowSpec.isEmpty())) {
1175 queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
1176 + tablename + " WHERE " + rowSpec + ";");
1179 if ((columnList == null) && (!rowSpec.isEmpty())) {
1180 queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
1184 if ((columnList != null) && (rowSpec.isEmpty())) {
1185 queryObject.appendQueryString(
1186 "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
1188 // get the conditional, if any
1189 Condition conditionInfo;
1190 if (delObj.getConditions() == null) {
1191 conditionInfo = null;
1193 // to avoid parsing repeatedly, just send the select query to
1195 PreparedQueryObject selectQuery = new PreparedQueryObject();
1196 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
1197 + rowId.rowIdString + ";");
1198 selectQuery.addValue(rowId.primarKeyValue);
1199 conditionInfo = new Condition(delObj.getConditions(), selectQuery);
1202 String consistency = delObj.getConsistencyInfo().get("type");
1205 if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && delObj.getConsistencyInfo().get("consistency")!=null) {
1207 if(MusicUtil.isValidConsistency(delObj.getConsistencyInfo().get("consistency")))
1208 queryObject.setConsistency(delObj.getConsistencyInfo().get("consistency"));
1210 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build();
1213 ReturnType operationResult = null;
1214 queryObject.setOperation("delete");
1216 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1217 operationResult = MusicCore.eventualPut(queryObject);
1218 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1219 String lockId = delObj.getConsistencyInfo().get("lockId");
1220 if(lockId == null) {
1221 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1222 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1223 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1224 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1226 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
1227 queryObject, lockId, conditionInfo);
1228 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1229 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
1230 queryObject, conditionInfo);
1231 } else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1233 operationResult = MusicCore.eventualPut_nb(queryObject, keyspace, tablename, rowId.primarKeyValue);
1235 } catch (MusicLockingException e) {
1236 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e);
1237 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1238 .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
1240 if (operationResult==null) {
1241 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1242 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1244 if (operationResult.getResult().equals(ResultType.SUCCESS)) {
1245 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1247 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1248 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
1251 EELFLoggerDelegate.mdcRemove("keyspace");
1263 @Path("/{keyspace: .*}/tables/{tablename: .*}")
1264 @ApiOperation(value = "Drop Table", response = String.class)
1265 @Produces(MediaType.APPLICATION_JSON)
1266 public Response dropTable(
1267 @ApiParam(value = "Major Version",
1268 required = true) @PathParam("version") String version,
1269 @ApiParam(value = "Minor Version",
1270 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1271 @ApiParam(value = "Patch Version",
1272 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1273 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1274 @ApiParam(value = "Application namespace",
1275 required = true) @HeaderParam(NS) String ns,
1276 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1277 @ApiParam(value = "Keyspace Name",
1278 required = true) @PathParam("keyspace") String keyspace,
1279 @ApiParam(value = "Table Name",
1280 required = true) @PathParam("tablename") String tablename) throws Exception {
1282 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1283 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1284 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1285 .setError("one or more path parameters are not set, please check and try again")
1288 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1289 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DROP_TABLE)) {
1290 return response.status(Status.UNAUTHORIZED)
1291 .entity(new JsonResponse(ResultType.FAILURE)
1292 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1296 String consistency = "eventual";// for now this needs only eventual
1298 PreparedQueryObject query = new PreparedQueryObject();
1299 query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
1301 return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
1302 } catch (MusicServiceException ex) {
1303 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes
1304 .GENERALSERVICEERROR);
1305 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1308 EELFLoggerDelegate.mdcRemove("keyspace");
1321 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows/criticalget")
1322 @ApiOperation(value = "Select Critical", response = Map.class)
1323 @Consumes(MediaType.APPLICATION_JSON)
1324 @Produces(MediaType.APPLICATION_JSON)
1325 public Response selectCritical(
1326 @ApiParam(value = "Major Version",
1327 required = true) @PathParam("version") String version,
1328 @ApiParam(value = "Minor Version",
1329 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1330 @ApiParam(value = "Patch Version",
1331 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1332 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1333 @ApiParam(value = "Application namespace",
1334 required = true) @HeaderParam(NS) String ns,
1335 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1337 @ApiParam(value = "Keyspace Name",
1338 required = true) @PathParam("keyspace") String keyspace,
1339 @ApiParam(value = "Table Name",
1340 required = true) @PathParam("tablename") String tablename,
1341 @Context UriInfo info) throws Exception {
1343 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1344 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1345 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1346 .setError("one or more path parameters are not set, please check and try again")
1349 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1350 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT_CRITICAL)) {
1351 return response.status(Status.UNAUTHORIZED)
1352 .entity(new JsonResponse(ResultType.FAILURE)
1353 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1357 String lockId = selObj.getConsistencyInfo().get("lockId");
1359 PreparedQueryObject queryObject = new PreparedQueryObject();
1361 RowIdentifier rowId = null;
1363 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1364 } catch (MusicServiceException ex) {
1365 logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
1366 .GENERALSERVICEERROR, ex);
1367 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1369 queryObject.appendQueryString(
1370 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1372 ResultSet results = null;
1374 String consistency = selObj.getConsistencyInfo().get("type");
1376 if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1377 if(lockId == null) {
1378 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1379 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1380 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1381 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1383 results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,lockId);
1384 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1385 results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1387 }catch(Exception ex) {
1388 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1391 if(results!=null && results.getAvailableWithoutFetching() >0) {
1392 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
1394 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setError("No data found").toMap()).build();
1397 EELFLoggerDelegate.mdcRemove("keyspace");
1410 @Path("/{keyspace: .*}/tables/{tablename: .*}/rows")
1411 @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1412 @Produces(MediaType.APPLICATION_JSON)
1413 public Response select(
1414 @ApiParam(value = "Major Version",
1415 required = true) @PathParam("version") String version,
1416 @ApiParam(value = "Minor Version",
1417 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1418 @ApiParam(value = "Patch Version",
1419 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1420 @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid,
1421 @ApiParam(value = "Application namespace",
1422 required = true) @HeaderParam(NS) String ns,
1423 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
1424 @ApiParam(value = "Keyspace Name",
1425 required = true) @PathParam("keyspace") String keyspace,
1426 @ApiParam(value = "Table Name",
1427 required = true) @PathParam("tablename") String tablename,
1428 @Context UriInfo info) throws Exception {
1430 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1431 if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){
1432 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1433 .setError("one or more path parameters are not set, please check and try again")
1436 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) ");
1437 if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT)) {
1438 return response.status(Status.UNAUTHORIZED)
1439 .entity(new JsonResponse(ResultType.FAILURE)
1440 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
1444 PreparedQueryObject queryObject = new PreparedQueryObject();
1446 if (info.getQueryParameters().isEmpty())// select all
1447 queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
1449 int limit = -1; // do not limit the number of results
1451 queryObject = selectSpecificQuery(keyspace, tablename, info, limit);
1452 } catch (MusicServiceException ex) {
1453 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
1454 ErrorTypes.GENERALSERVICEERROR, ex);
1455 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1460 ResultSet results = MusicCore.get(queryObject);
1461 if(results.getAvailableWithoutFetching() >0) {
1462 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build();
1464 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).setError("No data found").toMap()).build();
1465 } catch (MusicServiceException ex) {
1466 logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR,
1467 ErrorTypes.MUSICSERVICEERROR, ex);
1468 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1471 EELFLoggerDelegate.mdcRemove("keyspace");
1482 * @throws MusicServiceException
1484 public PreparedQueryObject selectSpecificQuery(String keyspace,
1485 String tablename, UriInfo info, int limit)
1486 throws MusicServiceException {
1488 PreparedQueryObject queryObject = new PreparedQueryObject();
1489 StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1490 queryObject).rowIdString;
1492 queryObject.appendQueryString(
1493 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1496 queryObject.appendQueryString(" LIMIT " + limit);
1499 queryObject.appendQueryString(";");
1509 * @param queryObject
1511 * @throws MusicServiceException
1513 private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1514 MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1515 throws MusicServiceException {
1516 StringBuilder rowSpec = new StringBuilder();
1518 TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
1519 if (tableInfo == null) {
1520 logger.error(EELFLoggerDelegate.errorLogger,
1521 "Table information not found. Please check input for table name= "
1522 + keyspace + "." + tablename);
1523 throw new MusicServiceException(
1524 "Table information not found. Please check input for table name= "
1525 + keyspace + "." + tablename);
1527 StringBuilder primaryKey = new StringBuilder();
1528 for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1529 String keyName = entry.getKey();
1530 List<String> valueList = entry.getValue();
1531 String indValue = valueList.get(0);
1532 DataType colType = null;
1533 Object formattedValue = null;
1535 colType = tableInfo.getColumn(entry.getKey()).getType();
1536 formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1537 } catch (Exception e) {
1538 logger.error(EELFLoggerDelegate.errorLogger,e);
1540 if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey()))
1541 primaryKey.append(indValue);
1542 rowSpec.append(keyName + "= ?");
1543 queryObject.addValue(formattedValue);
1544 if (counter != rowParams.size() - 1)
1545 rowSpec.append(" AND ");
1546 counter = counter + 1;
1548 return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);