2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (c) 2017 AT&T Intellectual Property
6 * ===================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * ============LICENSE_END=============================================
20 * ====================================================================
23 package org.onap.music.rest;
25 import java.util.ArrayList;
26 import java.util.List;
28 import java.util.UUID;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.HeaderParam;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.PUT;
35 import javax.ws.rs.Path;
36 import javax.ws.rs.PathParam;
37 import javax.ws.rs.Produces;
38 import javax.ws.rs.core.Context;
39 import javax.ws.rs.core.HttpHeaders;
40 import javax.ws.rs.core.MediaType;
41 import javax.ws.rs.core.MultivaluedMap;
42 import javax.ws.rs.core.Response;
43 import javax.ws.rs.core.Response.ResponseBuilder;
44 import javax.ws.rs.core.Response.Status;
45 import javax.ws.rs.core.UriInfo;
47 import org.mindrot.jbcrypt.BCrypt;
48 import org.onap.music.datastore.PreparedQueryObject;
49 import org.onap.music.datastore.jsonobjects.JsonDelete;
50 import org.onap.music.datastore.jsonobjects.JsonInsert;
51 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
52 import org.onap.music.datastore.jsonobjects.JsonTable;
53 import org.onap.music.datastore.jsonobjects.JsonUpdate;
54 import org.onap.music.eelf.logging.EELFLoggerDelegate;
55 import org.onap.music.exceptions.MusicLockingException;
56 import org.onap.music.eelf.logging.format.AppMessages;
57 import org.onap.music.eelf.logging.format.ErrorSeverity;
58 import org.onap.music.eelf.logging.format.ErrorTypes;
59 import org.onap.music.exceptions.MusicServiceException;
60 import org.onap.music.main.CachingUtil;
61 import org.onap.music.main.MusicCore;
62 import org.onap.music.main.MusicCore.Condition;
63 import org.onap.music.main.MusicUtil;
64 import org.onap.music.main.ResultType;
65 import org.onap.music.main.ReturnType;
66 import org.onap.music.response.jsonobjects.JsonResponse;
68 import com.datastax.driver.core.DataType;
69 import com.datastax.driver.core.ResultSet;
70 import com.datastax.driver.core.Row;
71 import com.datastax.driver.core.TableMetadata;
72 import io.swagger.annotations.Api;
73 import io.swagger.annotations.ApiOperation;
74 import io.swagger.annotations.ApiParam;
77 //@Path("/v{version: [0-9]+}/keyspaces")
78 @Path("/v2/keyspaces")
79 @Api(value = "Data Api")
80 public class RestMusicDataAPI {
82 * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR
83 * version back from the client to the server, and from the server back to the client - This
84 * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR
85 * version (if not specified by the client on the request) - Contains a single position value
86 * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on
87 * request; however, this header should be provided if the client needs to take advantage of
88 * MINOR incremented version functionality - Is mandatory for the server on response
90 *** X-patchVersion *** - Used only to communicate a PATCH version in a response for
91 * troubleshooting purposes only, and will not be provided by the client on request - This will
92 * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version
93 * of the MAJOR (if not specified by the client on the request) - Contains a single position
94 * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the
95 * server on response (CURRENTLY NOT USED)
97 *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the
98 * server on response, and shall include the entire version of the API (e.g. if the full version
99 * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are
100 * not using the latest version of the API (CURRENTLY NOT USED)
104 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class);
105 private static final String XMINORVERSION = "X-minorVersion";
106 private static final String XPATCHVERSION = "X-patchVersion";
107 private static final String NS = "ns";
108 private static final String USERID = "userId";
109 private static final String PASSWORD = "password";
110 private static final String VERSION = "v2";
112 private class RowIdentifier {
113 public String primarKeyValue;
114 public StringBuilder rowIdString;
115 @SuppressWarnings("unused")
116 public PreparedQueryObject queryObject;// the string with all the row
117 // identifiers separated by AND
119 public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
120 PreparedQueryObject queryObject) {
121 this.primarKeyValue = primaryKeyValue;
122 this.rowIdString = rowIdString;
123 this.queryObject = queryObject;
129 * Create Keyspace REST
132 * @param keyspaceName
138 @ApiOperation(value = "Create Keyspace", response = String.class)
139 @Consumes(MediaType.APPLICATION_JSON)
140 @Produces(MediaType.APPLICATION_JSON)
141 //public Map<String, Object> createKeySpace(
142 public Response createKeySpace(
143 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
144 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
145 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
146 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
147 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
148 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
149 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
150 JsonKeySpace kspObject,
151 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) {
152 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
154 Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password);
155 if (!authMap.isEmpty()) {
156 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
157 response.status(Status.UNAUTHORIZED);
158 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
160 if(kspObject == null || kspObject.getReplicationInfo() == null) {
161 authMap.put(ResultType.EXCEPTION.getResult(), ResultType.BODYMISSING.getResult());
162 response.status(Status.BAD_REQUEST);
163 return response.entity(authMap).build();
167 authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
169 } catch (Exception e) {
170 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
171 response.status(Status.BAD_REQUEST);
172 return response.entity(new JsonResponse(ResultType.FAILURE).setError("Unable to authenticate.").toMap()).build();
174 String newAid = null;
175 if (!authMap.isEmpty()) {
176 if (authMap.containsKey("aid")) {
177 newAid = (String) authMap.get("aid");
179 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
180 response.status(Status.UNAUTHORIZED);
181 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
185 String consistency = MusicUtil.EVENTUAL;// for now this needs only
186 // eventual consistency
188 PreparedQueryObject queryObject = new PreparedQueryObject();
189 long start = System.currentTimeMillis();
190 Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
191 String repString = null;
193 repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
194 } catch (Exception e) {
195 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
198 queryObject.appendQueryString(
199 "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
200 if (kspObject.getDurabilityOfWrites() != null) {
201 queryObject.appendQueryString(
202 " AND durable_writes = " + kspObject.getDurabilityOfWrites());
205 queryObject.appendQueryString(";");
206 long end = System.currentTimeMillis();
207 logger.info(EELFLoggerDelegate.applicationLogger,
208 "Time taken for setting up query in create keyspace:" + (end - start));
210 ResultType result = ResultType.FAILURE;
212 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
213 logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
214 } catch ( MusicServiceException ex) {
215 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
216 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
220 queryObject = new PreparedQueryObject();
221 // queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
222 // + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
223 queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS ? "
224 + " WITH PASSWORD = ? AND LOGIN = true;");
225 queryObject.addValue(userId);
226 queryObject.addValue(password);
227 MusicCore.nonKeyRelatedPut(queryObject, consistency);
228 queryObject = new PreparedQueryObject();
229 queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
230 + " to '" + userId + "'");
231 queryObject.appendQueryString(";");
232 MusicCore.nonKeyRelatedPut(queryObject, consistency);
233 } catch (Exception e) {
234 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
238 boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
239 String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt());
240 queryObject = new PreparedQueryObject();
241 queryObject.appendQueryString(
242 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
243 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
244 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
245 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
246 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
247 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
248 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd));
249 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
250 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
251 CachingUtil.updateMusicCache(keyspaceName, ns);
252 CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd);
253 MusicCore.eventualPut(queryObject);
254 } catch (Exception e) {
255 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
256 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
259 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
265 * @param keyspaceName
271 @ApiOperation(value = "Delete Keyspace", response = String.class)
272 @Produces(MediaType.APPLICATION_JSON)
273 //public Map<String, Object> dropKeySpace(
274 public Response dropKeySpace(
275 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
276 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
277 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
278 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
279 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
280 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
281 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
282 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception {
283 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
285 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password,keyspaceName, aid, "dropKeySpace");
286 if (authMap.containsKey("aid"))
287 authMap.remove("aid");
288 if (!authMap.isEmpty()) {
289 return response.status(Status.UNAUTHORIZED).entity(authMap).build();
292 String consistency = MusicUtil.EVENTUAL;// for now this needs only
295 String appName = CachingUtil.getAppName(keyspaceName);
296 String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
297 PreparedQueryObject pQuery = new PreparedQueryObject();
298 pQuery.appendQueryString(
299 "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
300 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
301 Row row = MusicCore.get(pQuery).one();
302 long count = row.getLong(0);
305 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
306 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
308 } else if (count == 1) {
309 pQuery = new PreparedQueryObject();
310 pQuery.appendQueryString(
311 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
312 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
313 MusicUtil.DEFAULTKEYSPACENAME));
314 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
315 MusicCore.nonKeyRelatedPut(pQuery, consistency);
317 pQuery = new PreparedQueryObject();
318 pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
319 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
320 MusicCore.nonKeyRelatedPut(pQuery, consistency);
323 PreparedQueryObject queryObject = new PreparedQueryObject();
324 queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
325 ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
326 if ( result.equals(ResultType.FAILURE) ) {
327 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
329 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
343 @Path("/{keyspace}/tables/{tablename}")
344 @ApiOperation(value = "Create Table", response = String.class)
345 @Consumes(MediaType.APPLICATION_JSON)
346 @Produces(MediaType.APPLICATION_JSON)
347 //public Map<String, Object> createTable(
348 public Response createTable(
349 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
350 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
351 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
352 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
353 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
354 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
355 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
357 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
358 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception {
359 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
360 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
362 if (authMap.containsKey("aid"))
363 authMap.remove("aid");
364 if (!authMap.isEmpty()) {
365 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
366 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
368 String consistency = MusicUtil.EVENTUAL;
369 // for now this needs only eventual consistency
370 PreparedQueryObject queryObject = new PreparedQueryObject();
371 // first read the information about the table fields
372 Map<String, String> fields = tableObj.getFields();
373 StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
376 for (Map.Entry<String, String> entry : fields.entrySet()) {
378 if (entry.getKey().equals("PRIMARY KEY")) {
379 if(! entry.getValue().contains("("))
380 primaryKey = entry.getValue();
382 primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1);
383 primaryKey = primaryKey.substring(0, primaryKey.indexOf(')'));
385 fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")");
387 fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
388 if (counter == fields.size() - 1)
389 fieldsString.append(")");
391 fieldsString.append(",");
392 counter = counter + 1;
394 // information about the name-value style properties
395 Map<String, Object> propertiesMap = tableObj.getProperties();
396 StringBuilder propertiesString = new StringBuilder();
397 if (propertiesMap != null) {
399 for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
400 Object ot = entry.getValue();
401 String value = ot + "";
402 if (ot instanceof String) {
403 value = "'" + value + "'";
404 } else if (ot instanceof Map) {
405 @SuppressWarnings("unchecked")
406 Map<String, Object> otMap = (Map<String, Object>) ot;
407 value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
410 propertiesString.append(entry.getKey() + "=" + value + "");
411 if (counter != propertiesMap.size() - 1)
412 propertiesString.append(" AND ");
414 counter = counter + 1;
418 queryObject.appendQueryString(
419 "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
421 if (propertiesMap != null)
422 queryObject.appendQueryString(" WITH " + propertiesString);
424 queryObject.appendQueryString(";");
425 ResultType result = ResultType.FAILURE;
428 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
429 } catch (MusicServiceException ex) {
430 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR);
431 response.status(Status.BAD_REQUEST);
432 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
434 if ( result.equals(ResultType.FAILURE) ) {
435 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build();
437 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename + " Created under keyspace " + keyspace).toMap()).build();
449 @Path("/{keyspace}/tables/{tablename}/index/{field}")
450 @ApiOperation(value = "Create Index", response = String.class)
451 @Produces(MediaType.APPLICATION_JSON)
452 public Response createIndex(
453 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
454 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
455 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
456 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
457 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
458 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
459 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
460 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
461 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename,
462 @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName,
463 @Context UriInfo info) throws Exception {
464 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
466 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "createIndex");
467 if (authMap.containsKey("aid"))
468 authMap.remove("aid");
469 if (!authMap.isEmpty()) {
470 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
471 response.status(Status.UNAUTHORIZED);
472 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
474 MultivaluedMap<String, String> rowParams = info.getQueryParameters();
475 String indexName = "";
476 if (rowParams.getFirst("index_name") != null)
477 indexName = rowParams.getFirst("index_name");
478 PreparedQueryObject query = new PreparedQueryObject();
479 query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "."
480 + tablename + " (" + fieldName + ");");
482 ResultType result = ResultType.FAILURE;
484 result = MusicCore.nonKeyRelatedPut(query, "eventual");
485 } catch (MusicServiceException ex) {
486 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
487 response.status(Status.BAD_REQUEST);
488 return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
490 if ( result.equals(ResultType.SUCCESS) ) {
491 return response.entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build();
493 return response.entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build();
506 @Path("/{keyspace}/tables/{tablename}/rows")
507 @ApiOperation(value = "Insert Into Table", response = String.class)
508 @Consumes(MediaType.APPLICATION_JSON)
509 @Produces(MediaType.APPLICATION_JSON)
510 public Response insertIntoTable(
511 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
512 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
513 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
514 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
515 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
516 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
517 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
519 @ApiParam(value = "Keyspace Name",
520 required = true) @PathParam("keyspace") String keyspace,
521 @ApiParam(value = "Table Name",
522 required = true) @PathParam("tablename") String tablename) {
523 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
525 Map<String, Object> authMap = null;
528 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
529 aid, "insertIntoTable");
530 } catch (Exception e) {
531 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
532 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
534 if (authMap.containsKey("aid"))
535 authMap.remove("aid");
536 if (!authMap.isEmpty()) {
537 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
538 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
541 Map<String, Object> valuesMap = insObj.getValues();
542 PreparedQueryObject queryObject = new PreparedQueryObject();
543 TableMetadata tableInfo = null;
545 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
546 if(tableInfo == null) {
547 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
549 } catch (MusicServiceException e) {
550 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
551 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
553 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
554 StringBuilder fieldsString = new StringBuilder("(vector_ts,");
556 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
557 StringBuilder valueString = new StringBuilder("(" + "?" + ",");
558 queryObject.addValue(vectorTs);
560 String primaryKey = "";
562 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
563 fieldsString.append("" + entry.getKey());
564 Object valueObj = entry.getValue();
565 if (primaryKeyName.equals(entry.getKey())) {
566 primaryKey = entry.getValue() + "";
567 primaryKey = primaryKey.replace("'", "''");
569 DataType colType = null;
571 colType = tableInfo.getColumn(entry.getKey()).getType();
572 } catch(NullPointerException ex) {
573 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
574 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
577 Object formattedValue = null;
579 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
580 } catch (Exception e) {
581 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
583 valueString.append("?");
584 queryObject.addValue(formattedValue);
586 if (counter == valuesMap.size() - 1) {
587 fieldsString.append(")");
588 valueString.append(")");
590 fieldsString.append(",");
591 valueString.append(",");
593 counter = counter + 1;
596 if(primaryKey == null || primaryKey.length() <= 0) {
597 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
598 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build();
601 queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
602 + fieldsString + " VALUES " + valueString);
604 String ttl = insObj.getTtl();
605 String timestamp = insObj.getTimestamp();
607 if ((ttl != null) && (timestamp != null)) {
608 logger.info(EELFLoggerDelegate.applicationLogger, "both there");
609 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
610 queryObject.addValue(Integer.parseInt(ttl));
611 queryObject.addValue(Long.parseLong(timestamp));
614 if ((ttl != null) && (timestamp == null)) {
615 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
616 queryObject.appendQueryString(" USING TTL ?");
617 queryObject.addValue(Integer.parseInt(ttl));
620 if ((ttl == null) && (timestamp != null)) {
621 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
622 queryObject.appendQueryString(" USING TIMESTAMP ?");
623 queryObject.addValue(Long.parseLong(timestamp));
626 queryObject.appendQueryString(";");
628 ReturnType result = null;
629 String consistency = insObj.getConsistencyInfo().get("type");
631 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
632 result = MusicCore.eventualPut(queryObject);
633 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
634 String lockId = insObj.getConsistencyInfo().get("lockId");
636 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
637 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
638 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
639 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
641 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
642 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
643 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
646 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
647 result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
650 } catch (Exception ex) {
651 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
652 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
656 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
657 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
659 return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
672 @Path("/{keyspace}/tables/{tablename}/rows")
673 @ApiOperation(value = "Update Table", response = String.class)
674 @Consumes(MediaType.APPLICATION_JSON)
675 @Produces(MediaType.APPLICATION_JSON)
676 public Response updateTable(
677 @ApiParam(value = "Major Version",
678 required = true) @PathParam("version") String version,
679 @ApiParam(value = "Minor Version",
680 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
681 @ApiParam(value = "Patch Version",
682 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
683 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
684 @ApiParam(value = "Application namespace",
685 required = true) @HeaderParam(NS) String ns,
686 @ApiParam(value = "userId",
687 required = true) @HeaderParam(USERID) String userId,
688 @ApiParam(value = "Password",
689 required = true) @HeaderParam(PASSWORD) String password,
690 JsonUpdate updateObj,
691 @ApiParam(value = "Keyspace Name",
692 required = true) @PathParam("keyspace") String keyspace,
693 @ApiParam(value = "Table Name",
694 required = true) @PathParam("tablename") String tablename,
695 @Context UriInfo info) {
696 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
698 Map<String, Object> authMap;
700 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
702 } catch (Exception e) {
703 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
704 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
706 if (authMap.containsKey("aid"))
707 authMap.remove("aid");
708 if (!authMap.isEmpty()) {
709 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
710 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
712 long startTime = System.currentTimeMillis();
713 String operationId = UUID.randomUUID().toString();// just for infoging
715 String consistency = updateObj.getConsistencyInfo().get("type");
716 logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
717 + " update-" + operationId + "-------------------------");
718 // obtain the field value pairs of the update
720 PreparedQueryObject queryObject = new PreparedQueryObject();
721 Map<String, Object> valuesMap = updateObj.getValues();
723 TableMetadata tableInfo;
725 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
726 } catch (MusicServiceException e) {
727 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
728 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
730 if (tableInfo == null) {
731 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
732 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
733 .setError("Table information not found. Please check input for table name= "
734 + keyspace + "." + tablename).toMap()).build();
737 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
738 StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
739 queryObject.addValue(vectorTs);
741 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
742 Object valueObj = entry.getValue();
743 DataType colType = null;
745 colType = tableInfo.getColumn(entry.getKey()).getType();
746 } catch(NullPointerException ex) {
747 logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey());
748 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
750 Object valueString = null;
752 valueString = MusicUtil.convertToActualDataType(colType, valueObj);
753 } catch (Exception e) {
754 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
756 fieldValueString.append(entry.getKey() + "= ?");
757 queryObject.addValue(valueString);
758 if (counter != valuesMap.size() - 1)
759 fieldValueString.append(",");
760 counter = counter + 1;
762 String ttl = updateObj.getTtl();
763 String timestamp = updateObj.getTimestamp();
765 queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
766 if ((ttl != null) && (timestamp != null)) {
768 logger.info("both there");
769 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
770 queryObject.addValue(Integer.parseInt(ttl));
771 queryObject.addValue(Long.parseLong(timestamp));
774 if ((ttl != null) && (timestamp == null)) {
775 logger.info("ONLY TTL there");
776 queryObject.appendQueryString(" USING TTL ?");
777 queryObject.addValue(Integer.parseInt(ttl));
780 if ((ttl == null) && (timestamp != null)) {
781 logger.info("ONLY timestamp there");
782 queryObject.appendQueryString(" USING TIMESTAMP ?");
783 queryObject.addValue(Long.parseLong(timestamp));
785 // get the row specifier
786 RowIdentifier rowId = null;
788 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
789 if(rowId == null || rowId.primarKeyValue.isEmpty()) {
790 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
791 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
793 } catch (MusicServiceException ex) {
794 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
795 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
798 queryObject.appendQueryString(
799 " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
801 // get the conditional, if any
802 Condition conditionInfo;
803 if (updateObj.getConditions() == null)
804 conditionInfo = null;
805 else {// to avoid parsing repeatedly, just send the select query to
807 PreparedQueryObject selectQuery = new PreparedQueryObject();
808 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
809 + rowId.rowIdString + ";");
810 selectQuery.addValue(rowId.primarKeyValue);
811 conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery);
814 ReturnType operationResult = null;
815 long jsonParseCompletionTime = System.currentTimeMillis();
817 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
818 operationResult = MusicCore.eventualPut(queryObject);
819 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
820 String lockId = updateObj.getConsistencyInfo().get("lockId");
822 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
823 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
824 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
825 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
827 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
828 queryObject, lockId, conditionInfo);
829 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
830 // this function is mainly for the benchmarks
832 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
833 rowId.primarKeyValue, queryObject, conditionInfo);
834 } catch (MusicLockingException e) {
835 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
836 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
838 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
840 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
841 queryObject, conditionInfo);
842 } catch (MusicLockingException e) {
843 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
844 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
847 long actualUpdateCompletionTime = System.currentTimeMillis();
849 long endTime = System.currentTimeMillis();
850 String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
851 + ":" + "|total operation time:" + (endTime - startTime)
852 + "|json parsing time:" + (jsonParseCompletionTime - startTime)
853 + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
856 if (operationResult != null && operationResult.getTimingInfo() != null) {
857 String lockManagementTime = operationResult.getTimingInfo();
858 timingString = timingString + lockManagementTime;
860 logger.info(EELFLoggerDelegate.applicationLogger, timingString);
862 if (operationResult==null) {
863 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
864 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
866 if ( operationResult.getResult() == ResultType.SUCCESS ) {
867 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
869 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
870 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
885 @Path("/{keyspace}/tables/{tablename}/rows")
886 @ApiOperation(value = "Delete From table", response = String.class)
887 @Consumes(MediaType.APPLICATION_JSON)
888 @Produces(MediaType.APPLICATION_JSON)
889 public Response deleteFromTable(
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 = true) @HeaderParam("aid") String aid,
897 @ApiParam(value = "Application namespace",
898 required = true) @HeaderParam(NS) String ns,
899 @ApiParam(value = "userId",
900 required = true) @HeaderParam(USERID) String userId,
901 @ApiParam(value = "Password",
902 required = true) @HeaderParam(PASSWORD) String password,
904 @ApiParam(value = "Keyspace Name",
905 required = true) @PathParam("keyspace") String keyspace,
906 @ApiParam(value = "Table Name",
907 required = true) @PathParam("tablename") String tablename,
908 @Context UriInfo info) {
909 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
911 Map<String, Object> authMap = null;
913 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
914 aid, "deleteFromTable");
915 } catch (Exception e) {
916 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
917 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
919 if (authMap.containsKey("aid"))
920 authMap.remove("aid");
921 if (!authMap.isEmpty()) {
922 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
923 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
926 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
927 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
929 PreparedQueryObject queryObject = new PreparedQueryObject();
930 StringBuilder columnString = new StringBuilder();
933 ArrayList<String> columnList = delObj.getColumns();
934 if (columnList != null) {
935 for (String column : columnList) {
936 columnString.append(column);
937 if (counter != columnList.size() - 1)
938 columnString.append(",");
939 counter = counter + 1;
943 // get the row specifier
944 RowIdentifier rowId = null;
946 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
947 } catch (MusicServiceException ex) {
948 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
949 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
951 String rowSpec = rowId.rowIdString.toString();
953 if ((columnList != null) && (!rowSpec.isEmpty())) {
954 queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
955 + tablename + " WHERE " + rowSpec + ";");
958 if ((columnList == null) && (!rowSpec.isEmpty())) {
959 queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
963 if ((columnList != null) && (rowSpec.isEmpty())) {
964 queryObject.appendQueryString(
965 "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
967 // get the conditional, if any
968 Condition conditionInfo;
969 if (delObj.getConditions() == null)
970 conditionInfo = null;
971 else {// to avoid parsing repeatedly, just send the select query to
973 PreparedQueryObject selectQuery = new PreparedQueryObject();
974 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
975 + rowId.rowIdString + ";");
976 selectQuery.addValue(rowId.primarKeyValue);
977 conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery);
980 String consistency = delObj.getConsistencyInfo().get("type");
982 ReturnType operationResult = null;
984 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
985 operationResult = MusicCore.eventualPut(queryObject);
986 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
987 String lockId = delObj.getConsistencyInfo().get("lockId");
989 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
990 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
991 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
992 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
994 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
995 queryObject, lockId, conditionInfo);
996 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
997 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
998 queryObject, conditionInfo);
1000 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1001 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
1002 queryObject, conditionInfo);
1004 } catch (MusicLockingException e) {
1005 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1006 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1007 .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
1009 if (operationResult==null) {
1010 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1011 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1013 if (operationResult.getResult().equals(ResultType.SUCCESS)) {
1014 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1016 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1017 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
1029 @Path("/{keyspace}/tables/{tablename}")
1030 @ApiOperation(value = "Drop Table", response = String.class)
1031 @Produces(MediaType.APPLICATION_JSON)
1032 public Response dropTable(
1033 @ApiParam(value = "Major Version",
1034 required = true) @PathParam("version") String version,
1035 @ApiParam(value = "Minor Version",
1036 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1037 @ApiParam(value = "Patch Version",
1038 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1039 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1040 @ApiParam(value = "Application namespace",
1041 required = true) @HeaderParam(NS) String ns,
1042 @ApiParam(value = "userId",
1043 required = true) @HeaderParam(USERID) String userId,
1044 @ApiParam(value = "Password",
1045 required = true) @HeaderParam(PASSWORD) String password,
1046 @ApiParam(value = "Keyspace Name",
1047 required = true) @PathParam("keyspace") String keyspace,
1048 @ApiParam(value = "Table Name",
1049 required = true) @PathParam("tablename") String tablename) throws Exception {
1050 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1052 Map<String, Object> authMap =
1053 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
1054 if (authMap.containsKey("aid"))
1055 authMap.remove("aid");
1056 if (!authMap.isEmpty()) {
1057 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1058 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1060 String consistency = "eventual";// for now this needs only eventual
1062 PreparedQueryObject query = new PreparedQueryObject();
1063 query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
1065 return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
1066 } catch (MusicServiceException ex) {
1067 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1068 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1082 @Path("/{keyspace}/tables/{tablename}/rows/criticalget")
1083 @ApiOperation(value = "Select Critical", response = Map.class)
1084 @Consumes(MediaType.APPLICATION_JSON)
1085 @Produces(MediaType.APPLICATION_JSON)
1086 public Response selectCritical(
1087 @ApiParam(value = "Major Version",
1088 required = true) @PathParam("version") String version,
1089 @ApiParam(value = "Minor Version",
1090 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1091 @ApiParam(value = "Patch Version",
1092 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1093 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1094 @ApiParam(value = "Application namespace",
1095 required = true) @HeaderParam(NS) String ns,
1096 @ApiParam(value = "userId",
1097 required = true) @HeaderParam(USERID) String userId,
1098 @ApiParam(value = "Password",
1099 required = true) @HeaderParam(PASSWORD) String password,
1101 @ApiParam(value = "Keyspace Name",
1102 required = true) @PathParam("keyspace") String keyspace,
1103 @ApiParam(value = "Table Name",
1104 required = true) @PathParam("tablename") String tablename,
1105 @Context UriInfo info) throws Exception {
1106 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1108 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "selectCritical");
1109 if (authMap.containsKey("aid"))
1110 authMap.remove("aid");
1111 if (!authMap.isEmpty()) {
1112 logger.error(EELFLoggerDelegate.errorLogger,"Error while authentication... ", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1113 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1115 String lockId = selObj.getConsistencyInfo().get("lockId");
1117 PreparedQueryObject queryObject = new PreparedQueryObject();
1119 RowIdentifier rowId = null;
1121 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1122 } catch (MusicServiceException ex) {
1123 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1124 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1126 queryObject.appendQueryString(
1127 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1129 ResultSet results = null;
1131 String consistency = selObj.getConsistencyInfo().get("type");
1133 if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1134 if(lockId == null) {
1135 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1136 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1137 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1138 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1140 results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1142 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1143 results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1146 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1147 results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
1150 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1162 @Path("/{keyspace}/tables/{tablename}/rows")
1163 @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1164 @Produces(MediaType.APPLICATION_JSON)
1165 public Response select(
1166 @ApiParam(value = "Major Version",
1167 required = true) @PathParam("version") String version,
1168 @ApiParam(value = "Minor Version",
1169 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1170 @ApiParam(value = "Patch Version",
1171 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1172 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1173 @ApiParam(value = "Application namespace",
1174 required = true) @HeaderParam(NS) String ns,
1175 @ApiParam(value = "userId",
1176 required = true) @HeaderParam(USERID) String userId,
1177 @ApiParam(value = "Password",
1178 required = true) @HeaderParam(PASSWORD) String password,
1179 @ApiParam(value = "Keyspace Name",
1180 required = true) @PathParam("keyspace") String keyspace,
1181 @ApiParam(value = "Table Name",
1182 required = true) @PathParam("tablename") String tablename,
1183 @Context UriInfo info) throws Exception {
1184 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1186 Map<String, Object> authMap =
1187 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
1188 if (authMap.containsKey("aid"))
1189 authMap.remove("aid");
1190 if (!authMap.isEmpty()) {
1191 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1192 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1194 PreparedQueryObject queryObject = new PreparedQueryObject();
1196 if (info.getQueryParameters().isEmpty())// select all
1197 queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
1199 int limit = -1; // do not limit the number of results
1201 queryObject = selectSpecificQuery(VERSION, minorVersion, patchVersion, aid, ns,
1202 userId, password, keyspace, tablename, info, limit);
1203 } catch (MusicServiceException ex) {
1204 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1205 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1210 ResultSet results = MusicCore.get(queryObject);
1211 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1212 } catch (MusicServiceException ex) {
1213 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1214 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1226 * @throws MusicServiceException
1228 public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
1229 String patchVersion, String aid, String ns, String userId, String password,
1230 String keyspace, String tablename, UriInfo info, int limit)
1231 throws MusicServiceException {
1233 PreparedQueryObject queryObject = new PreparedQueryObject();
1234 StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1235 queryObject).rowIdString;
1237 queryObject.appendQueryString(
1238 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1241 queryObject.appendQueryString(" LIMIT " + limit);
1244 queryObject.appendQueryString(";");
1254 * @param queryObject
1256 * @throws MusicServiceException
1258 private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1259 MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1260 throws MusicServiceException {
1261 StringBuilder rowSpec = new StringBuilder();
1263 TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
1264 if (tableInfo == null) {
1265 logger.error(EELFLoggerDelegate.errorLogger,
1266 "Table information not found. Please check input for table name= "
1267 + keyspace + "." + tablename);
1268 throw new MusicServiceException(
1269 "Table information not found. Please check input for table name= "
1270 + keyspace + "." + tablename);
1272 StringBuilder primaryKey = new StringBuilder();
1273 for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1274 String keyName = entry.getKey();
1275 List<String> valueList = entry.getValue();
1276 String indValue = valueList.get(0);
1277 DataType colType = null;
1278 Object formattedValue = null;
1280 colType = tableInfo.getColumn(entry.getKey()).getType();
1281 formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1282 } catch (Exception e) {
1283 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1285 primaryKey.append(indValue);
1286 rowSpec.append(keyName + "= ?");
1287 queryObject.addValue(formattedValue);
1288 if (counter != rowParams.size() - 1)
1289 rowSpec.append(" AND ");
1290 counter = counter + 1;
1292 return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);