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 * ====================================================================
22 package org.onap.music.rest;
24 import java.util.ArrayList;
25 import java.util.List;
27 import java.util.UUID;
28 import javax.ws.rs.Consumes;
29 import javax.ws.rs.DELETE;
30 import javax.ws.rs.GET;
31 import javax.ws.rs.HeaderParam;
32 import javax.ws.rs.POST;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.core.Context;
38 import javax.ws.rs.core.HttpHeaders;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.MultivaluedMap;
41 import javax.ws.rs.core.Response;
42 import javax.ws.rs.core.Response.ResponseBuilder;
43 import javax.ws.rs.core.Response.Status;
44 import javax.ws.rs.core.UriInfo;
45 import org.onap.music.datastore.PreparedQueryObject;
46 import org.onap.music.datastore.jsonobjects.JsonDelete;
47 import org.onap.music.datastore.jsonobjects.JsonInsert;
48 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
49 import org.onap.music.datastore.jsonobjects.JsonTable;
50 import org.onap.music.datastore.jsonobjects.JsonUpdate;
51 import org.onap.music.eelf.logging.EELFLoggerDelegate;
52 import org.onap.music.exceptions.MusicLockingException;
53 import org.onap.music.eelf.logging.format.AppMessages;
54 import org.onap.music.eelf.logging.format.ErrorSeverity;
55 import org.onap.music.eelf.logging.format.ErrorTypes;
56 import org.onap.music.exceptions.MusicServiceException;
57 import org.onap.music.main.CachingUtil;
58 import org.onap.music.main.MusicCore;
59 import org.onap.music.main.MusicCore.Condition;
60 import org.onap.music.main.MusicUtil;
61 import org.onap.music.main.ResultType;
62 import org.onap.music.main.ReturnType;
63 import org.onap.music.response.jsonobjects.JsonResponse;
65 import com.datastax.driver.core.DataType;
66 import com.datastax.driver.core.ResultSet;
67 import com.datastax.driver.core.Row;
68 import com.datastax.driver.core.TableMetadata;
69 import io.swagger.annotations.Api;
70 import io.swagger.annotations.ApiOperation;
71 import io.swagger.annotations.ApiParam;
74 //@Path("/v{version: [0-9]+}/keyspaces")
75 @Path("/v2/keyspaces")
76 @Api(value = "Data Api")
77 public class RestMusicDataAPI {
79 * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR
80 * version back from the client to the server, and from the server back to the client - This
81 * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR
82 * version (if not specified by the client on the request) - Contains a single position value
83 * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on
84 * request; however, this header should be provided if the client needs to take advantage of
85 * MINOR incremented version functionality - Is mandatory for the server on response
87 *** X-patchVersion *** - Used only to communicate a PATCH version in a response for
88 * troubleshooting purposes only, and will not be provided by the client on request - This will
89 * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version
90 * of the MAJOR (if not specified by the client on the request) - Contains a single position
91 * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the
92 * server on response (CURRENTLY NOT USED)
94 *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the
95 * server on response, and shall include the entire version of the API (e.g. if the full version
96 * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are
97 * not using the latest version of the API (CURRENTLY NOT USED)
101 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class);
102 private static final String XLATESTVERSION = "X-latestVersion";
103 private static final String XMINORVERSION = "X-minorVersion";
104 private static final String XPATCHVERSION = "X-patchVersion";
105 private static final String NS = "ns";
106 private static final String USERID = "userId";
107 private static final String PASSWORD = "password";
109 private class RowIdentifier {
110 public String primarKeyValue;
111 public StringBuilder rowIdString;
112 @SuppressWarnings("unused")
113 public PreparedQueryObject queryObject;// the string with all the row
114 // identifiers separated by AND
116 public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
117 PreparedQueryObject queryObject) {
118 this.primarKeyValue = primaryKeyValue;
119 this.rowIdString = rowIdString;
120 this.queryObject = queryObject;
124 @SuppressWarnings("unused")
125 private String buildVersion(String major, String minor, String patch) {
127 major += "." + minor;
129 major += "." + patch;
136 * Currently this will build a header with X-latestVersion, X-minorVersion and X-pathcVersion
137 * X-latestVerstion will be equal to the latest full version.
138 * X-minorVersion - will be equal to the latest minor version.
139 * X-pathVersion - will be equal to the latest patch version.
140 * Future plans will change this.
147 private ResponseBuilder buildVersionResponse(String major, String minor, String patch) {
148 ResponseBuilder response = Response.noContent();
149 String versionIn = buildVersion(major,minor,patch);
150 String version = MusicUtil.getVersion();
151 String[] verArray = version.split("\\.",3);
152 if ( minor != null ) {
153 response.header(XMINORVERSION,minor);
155 response.header(XMINORVERSION,verArray[1]);
157 if ( patch != null ) {
158 response.header(XPATCHVERSION,patch);
160 response.header(XPATCHVERSION,verArray[2]);
162 response.header(XLATESTVERSION,version);
167 * Create Keyspace REST
170 * @param keyspaceName
176 @ApiOperation(value = "Create Keyspace", response = String.class)
177 @Consumes(MediaType.APPLICATION_JSON)
178 @Produces(MediaType.APPLICATION_JSON)
179 //public Map<String, Object> createKeySpace(
180 public Response createKeySpace(
181 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
182 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
183 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
184 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
185 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
186 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
187 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
188 JsonKeySpace kspObject,
189 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) {
190 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
192 Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password);
193 if (!authMap.isEmpty()) {
194 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
195 response.status(Status.UNAUTHORIZED);
196 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
198 if(kspObject == null || kspObject.getReplicationInfo() == null) {
199 authMap.put(ResultType.EXCEPTION.getResult(), ResultType.BODYMISSING.getResult());
200 response.status(Status.BAD_REQUEST);
201 return response.entity(authMap).build();
205 authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
207 } catch (Exception e) {
208 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
209 response.status(Status.BAD_REQUEST);
210 return response.entity(new JsonResponse(ResultType.FAILURE).setError("Unable to authenticate.").toMap()).build();
212 String newAid = null;
213 if (!authMap.isEmpty()) {
214 if (authMap.containsKey("aid")) {
215 newAid = (String) authMap.get("aid");
217 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
218 response.status(Status.UNAUTHORIZED);
219 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
223 String consistency = MusicUtil.EVENTUAL;// for now this needs only
224 // eventual consistency
226 PreparedQueryObject queryObject = new PreparedQueryObject();
227 long start = System.currentTimeMillis();
228 Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
229 String repString = null;
231 repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
232 } catch (Exception e) {
233 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
236 queryObject.appendQueryString(
237 "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
238 if (kspObject.getDurabilityOfWrites() != null) {
239 queryObject.appendQueryString(
240 " AND durable_writes = " + kspObject.getDurabilityOfWrites());
243 queryObject.appendQueryString(";");
244 long end = System.currentTimeMillis();
245 logger.info(EELFLoggerDelegate.applicationLogger,
246 "Time taken for setting up query in create keyspace:" + (end - start));
248 ResultType result = ResultType.FAILURE;
250 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
251 logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
252 } catch ( MusicServiceException ex) {
253 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
254 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
258 queryObject = new PreparedQueryObject();
259 queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
260 + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
261 MusicCore.nonKeyRelatedPut(queryObject, consistency);
262 queryObject = new PreparedQueryObject();
263 queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
264 + " to '" + userId + "'");
265 queryObject.appendQueryString(";");
266 MusicCore.nonKeyRelatedPut(queryObject, consistency);
267 } catch (Exception e) {
268 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
272 boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
273 queryObject = new PreparedQueryObject();
274 queryObject.appendQueryString(
275 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
276 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
277 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
278 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
279 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
280 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
281 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), password));
282 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
283 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
284 CachingUtil.updateMusicCache(keyspaceName, ns);
285 CachingUtil.updateMusicValidateCache(ns, userId, password);
286 MusicCore.eventualPut(queryObject);
287 } catch (Exception e) {
288 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
289 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
292 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
298 * @param keyspaceName
304 @ApiOperation(value = "Delete Keyspace", response = String.class)
305 @Produces(MediaType.APPLICATION_JSON)
306 //public Map<String, Object> dropKeySpace(
307 public Response dropKeySpace(
308 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
309 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
310 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
311 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
312 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
313 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
314 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
315 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception {
316 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
318 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password,keyspaceName, aid, "dropKeySpace");
319 if (authMap.containsKey("aid"))
320 authMap.remove("aid");
321 if (!authMap.isEmpty()) {
322 return response.status(Status.UNAUTHORIZED).entity(authMap).build();
325 String consistency = MusicUtil.EVENTUAL;// for now this needs only
328 String appName = CachingUtil.getAppName(keyspaceName);
329 String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
330 PreparedQueryObject pQuery = new PreparedQueryObject();
331 pQuery.appendQueryString(
332 "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
333 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
334 Row row = MusicCore.get(pQuery).one();
335 long count = row.getLong(0);
338 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
339 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
341 } else if (count == 1) {
342 pQuery = new PreparedQueryObject();
343 pQuery.appendQueryString(
344 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
345 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
346 MusicUtil.DEFAULTKEYSPACENAME));
347 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
348 MusicCore.nonKeyRelatedPut(pQuery, consistency);
350 pQuery = new PreparedQueryObject();
351 pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
352 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
353 MusicCore.nonKeyRelatedPut(pQuery, consistency);
356 PreparedQueryObject queryObject = new PreparedQueryObject();
357 queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
358 ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
359 if ( result.equals(ResultType.FAILURE) ) {
360 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
362 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
376 @Path("/{keyspace}/tables/{tablename}")
377 @ApiOperation(value = "Create Table", response = String.class)
378 @Consumes(MediaType.APPLICATION_JSON)
379 @Produces(MediaType.APPLICATION_JSON)
380 //public Map<String, Object> createTable(
381 public Response createTable(
382 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
383 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
384 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
385 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
386 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
387 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
388 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
390 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
391 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception {
392 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
393 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
395 if (authMap.containsKey("aid"))
396 authMap.remove("aid");
397 if (!authMap.isEmpty()) {
398 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
399 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
401 String consistency = MusicUtil.EVENTUAL;
402 // for now this needs only eventual consistency
403 PreparedQueryObject queryObject = new PreparedQueryObject();
404 // first read the information about the table fields
405 Map<String, String> fields = tableObj.getFields();
406 StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
409 for (Map.Entry<String, String> entry : fields.entrySet()) {
411 if (entry.getKey().equals("PRIMARY KEY")) {
412 if(! entry.getValue().contains("("))
413 primaryKey = entry.getValue();
415 primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1);
416 primaryKey = primaryKey.substring(0, primaryKey.indexOf(')'));
418 fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")");
420 fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
421 if (counter == fields.size() - 1)
422 fieldsString.append(")");
424 fieldsString.append(",");
425 counter = counter + 1;
427 // information about the name-value style properties
428 Map<String, Object> propertiesMap = tableObj.getProperties();
429 StringBuilder propertiesString = new StringBuilder();
430 if (propertiesMap != null) {
432 for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
433 Object ot = entry.getValue();
434 String value = ot + "";
435 if (ot instanceof String) {
436 value = "'" + value + "'";
437 } else if (ot instanceof Map) {
438 @SuppressWarnings("unchecked")
439 Map<String, Object> otMap = (Map<String, Object>) ot;
440 value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
443 propertiesString.append(entry.getKey() + "=" + value + "");
444 if (counter != propertiesMap.size() - 1)
445 propertiesString.append(" AND ");
447 counter = counter + 1;
451 queryObject.appendQueryString(
452 "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
454 if (propertiesMap != null)
455 queryObject.appendQueryString(" WITH " + propertiesString);
457 queryObject.appendQueryString(";");
458 ResultType result = ResultType.FAILURE;
461 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
462 } catch (MusicServiceException ex) {
463 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR);
464 response.status(Status.BAD_REQUEST);
465 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
467 if ( result.equals(ResultType.FAILURE) ) {
468 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build();
470 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename + " Created under keyspace " + keyspace).toMap()).build();
482 @Path("/{keyspace}/tables/{tablename}/index/{field}")
483 @ApiOperation(value = "Create Index", response = String.class)
484 @Produces(MediaType.APPLICATION_JSON)
485 public Response createIndex(
486 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
487 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
488 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
489 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
490 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
491 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
492 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
493 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
494 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename,
495 @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName,
496 @Context UriInfo info) throws Exception {
497 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
499 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "createIndex");
500 response.header(XLATESTVERSION, MusicUtil.getVersion());
501 if (authMap.containsKey("aid"))
502 authMap.remove("aid");
503 if (!authMap.isEmpty()) {
504 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
505 response.status(Status.UNAUTHORIZED);
506 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
508 MultivaluedMap<String, String> rowParams = info.getQueryParameters();
509 String indexName = "";
510 if (rowParams.getFirst("index_name") != null)
511 indexName = rowParams.getFirst("index_name");
512 PreparedQueryObject query = new PreparedQueryObject();
513 query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "."
514 + tablename + " (" + fieldName + ");");
516 ResultType result = ResultType.FAILURE;
518 result = MusicCore.nonKeyRelatedPut(query, "eventual");
519 } catch (MusicServiceException ex) {
520 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
521 response.status(Status.BAD_REQUEST);
522 return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
524 if ( result.equals(ResultType.SUCCESS) ) {
525 return response.entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build();
527 return response.entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build();
540 @Path("/{keyspace}/tables/{tablename}/rows")
541 @ApiOperation(value = "Insert Into Table", response = String.class)
542 @Consumes(MediaType.APPLICATION_JSON)
543 @Produces(MediaType.APPLICATION_JSON)
544 public Response insertIntoTable(
545 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
546 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
547 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
548 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
549 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
550 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
551 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
553 @ApiParam(value = "Keyspace Name",
554 required = true) @PathParam("keyspace") String keyspace,
555 @ApiParam(value = "Table Name",
556 required = true) @PathParam("tablename") String tablename) {
557 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
559 Map<String, Object> authMap = null;
562 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
563 aid, "insertIntoTable");
564 } catch (Exception e) {
565 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
566 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
568 if (authMap.containsKey("aid"))
569 authMap.remove("aid");
570 if (!authMap.isEmpty()) {
571 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
572 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
575 Map<String, Object> valuesMap = insObj.getValues();
576 PreparedQueryObject queryObject = new PreparedQueryObject();
577 TableMetadata tableInfo = null;
579 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
580 if(tableInfo == null) {
581 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
583 } catch (MusicServiceException e) {
584 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
585 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
587 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
588 StringBuilder fieldsString = new StringBuilder("(vector_ts,");
590 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
591 StringBuilder valueString = new StringBuilder("(" + "?" + ",");
592 queryObject.addValue(vectorTs);
594 String primaryKey = "";
596 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
597 fieldsString.append("" + entry.getKey());
598 Object valueObj = entry.getValue();
599 if (primaryKeyName.equals(entry.getKey())) {
600 primaryKey = entry.getValue() + "";
601 primaryKey = primaryKey.replace("'", "''");
603 DataType colType = null;
605 colType = tableInfo.getColumn(entry.getKey()).getType();
606 } catch(NullPointerException ex) {
607 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
608 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
611 Object formattedValue = null;
613 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
614 } catch (Exception e) {
615 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
617 valueString.append("?");
618 queryObject.addValue(formattedValue);
620 if (counter == valuesMap.size() - 1) {
621 fieldsString.append(")");
622 valueString.append(")");
624 fieldsString.append(",");
625 valueString.append(",");
627 counter = counter + 1;
630 if(primaryKey == null || primaryKey.length() <= 0) {
631 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
632 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build();
635 queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
636 + fieldsString + " VALUES " + valueString);
638 String ttl = insObj.getTtl();
639 String timestamp = insObj.getTimestamp();
641 if ((ttl != null) && (timestamp != null)) {
642 logger.info(EELFLoggerDelegate.applicationLogger, "both there");
643 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
644 queryObject.addValue(Integer.parseInt(ttl));
645 queryObject.addValue(Long.parseLong(timestamp));
648 if ((ttl != null) && (timestamp == null)) {
649 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
650 queryObject.appendQueryString(" USING TTL ?");
651 queryObject.addValue(Integer.parseInt(ttl));
654 if ((ttl == null) && (timestamp != null)) {
655 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
656 queryObject.appendQueryString(" USING TIMESTAMP ?");
657 queryObject.addValue(Long.parseLong(timestamp));
660 queryObject.appendQueryString(";");
662 ReturnType result = null;
663 String consistency = insObj.getConsistencyInfo().get("type");
665 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
666 result = MusicCore.eventualPut(queryObject);
667 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
668 String lockId = insObj.getConsistencyInfo().get("lockId");
670 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
671 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
672 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
673 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
675 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
676 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
677 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
680 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
681 result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
684 } catch (Exception ex) {
685 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
686 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
690 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
691 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
693 return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
706 @Path("/{keyspace}/tables/{tablename}/rows")
707 @ApiOperation(value = "Update Table", response = String.class)
708 @Consumes(MediaType.APPLICATION_JSON)
709 @Produces(MediaType.APPLICATION_JSON)
710 public Response updateTable(
711 @ApiParam(value = "Major Version",
712 required = true) @PathParam("version") String version,
713 @ApiParam(value = "Minor Version",
714 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
715 @ApiParam(value = "Patch Version",
716 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
717 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
718 @ApiParam(value = "Application namespace",
719 required = true) @HeaderParam(NS) String ns,
720 @ApiParam(value = "userId",
721 required = true) @HeaderParam(USERID) String userId,
722 @ApiParam(value = "Password",
723 required = true) @HeaderParam(PASSWORD) String password,
724 JsonUpdate updateObj,
725 @ApiParam(value = "Keyspace Name",
726 required = true) @PathParam("keyspace") String keyspace,
727 @ApiParam(value = "Table Name",
728 required = true) @PathParam("tablename") String tablename,
729 @Context UriInfo info) {
730 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
732 Map<String, Object> authMap;
734 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
736 } catch (Exception e) {
737 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
738 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
740 if (authMap.containsKey("aid"))
741 authMap.remove("aid");
742 if (!authMap.isEmpty()) {
743 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
744 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
746 long startTime = System.currentTimeMillis();
747 String operationId = UUID.randomUUID().toString();// just for infoging
749 String consistency = updateObj.getConsistencyInfo().get("type");
750 logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
751 + " update-" + operationId + "-------------------------");
752 // obtain the field value pairs of the update
754 PreparedQueryObject queryObject = new PreparedQueryObject();
755 Map<String, Object> valuesMap = updateObj.getValues();
757 TableMetadata tableInfo;
759 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
760 } catch (MusicServiceException e) {
761 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
762 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
764 if (tableInfo == null) {
765 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
766 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
767 .setError("Table information not found. Please check input for table name= "
768 + keyspace + "." + tablename).toMap()).build();
771 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
772 StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
773 queryObject.addValue(vectorTs);
775 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
776 Object valueObj = entry.getValue();
777 DataType colType = null;
779 colType = tableInfo.getColumn(entry.getKey()).getType();
780 } catch(NullPointerException ex) {
781 logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey());
782 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
784 Object valueString = null;
786 valueString = MusicUtil.convertToActualDataType(colType, valueObj);
787 } catch (Exception e) {
788 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
790 fieldValueString.append(entry.getKey() + "= ?");
791 queryObject.addValue(valueString);
792 if (counter != valuesMap.size() - 1)
793 fieldValueString.append(",");
794 counter = counter + 1;
796 String ttl = updateObj.getTtl();
797 String timestamp = updateObj.getTimestamp();
799 queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
800 if ((ttl != null) && (timestamp != null)) {
802 logger.info("both there");
803 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
804 queryObject.addValue(Integer.parseInt(ttl));
805 queryObject.addValue(Long.parseLong(timestamp));
808 if ((ttl != null) && (timestamp == null)) {
809 logger.info("ONLY TTL there");
810 queryObject.appendQueryString(" USING TTL ?");
811 queryObject.addValue(Integer.parseInt(ttl));
814 if ((ttl == null) && (timestamp != null)) {
815 logger.info("ONLY timestamp there");
816 queryObject.appendQueryString(" USING TIMESTAMP ?");
817 queryObject.addValue(Long.parseLong(timestamp));
819 // get the row specifier
820 RowIdentifier rowId = null;
822 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
823 if(rowId == null || rowId.primarKeyValue.isEmpty()) {
824 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
825 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
827 } catch (MusicServiceException ex) {
828 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
829 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
832 queryObject.appendQueryString(
833 " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
835 // get the conditional, if any
836 Condition conditionInfo;
837 if (updateObj.getConditions() == null)
838 conditionInfo = null;
839 else {// to avoid parsing repeatedly, just send the select query to
841 PreparedQueryObject selectQuery = new PreparedQueryObject();
842 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
843 + rowId.rowIdString + ";");
844 selectQuery.addValue(rowId.primarKeyValue);
845 conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery);
848 ReturnType operationResult = null;
849 long jsonParseCompletionTime = System.currentTimeMillis();
851 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
852 operationResult = MusicCore.eventualPut(queryObject);
853 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
854 String lockId = updateObj.getConsistencyInfo().get("lockId");
856 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
857 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
858 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
859 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
861 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
862 queryObject, lockId, conditionInfo);
863 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
864 // this function is mainly for the benchmarks
866 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
867 rowId.primarKeyValue, queryObject, conditionInfo);
868 } catch (MusicLockingException e) {
869 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
870 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
872 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
874 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
875 queryObject, conditionInfo);
876 } catch (MusicLockingException e) {
877 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
878 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
881 long actualUpdateCompletionTime = System.currentTimeMillis();
883 long endTime = System.currentTimeMillis();
884 String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
885 + ":" + "|total operation time:" + (endTime - startTime)
886 + "|json parsing time:" + (jsonParseCompletionTime - startTime)
887 + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
890 if (operationResult != null && operationResult.getTimingInfo() != null) {
891 String lockManagementTime = operationResult.getTimingInfo();
892 timingString = timingString + lockManagementTime;
894 logger.info(EELFLoggerDelegate.applicationLogger, timingString);
896 if (operationResult==null) {
897 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
898 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
900 if ( operationResult.getResult() == ResultType.SUCCESS ) {
901 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
903 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
904 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
919 @Path("/{keyspace}/tables/{tablename}/rows")
920 @ApiOperation(value = "Delete From table", response = String.class)
921 @Consumes(MediaType.APPLICATION_JSON)
922 @Produces(MediaType.APPLICATION_JSON)
923 public Response deleteFromTable(
924 @ApiParam(value = "Major Version",
925 required = true) @PathParam("version") String version,
926 @ApiParam(value = "Minor Version",
927 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
928 @ApiParam(value = "Patch Version",
929 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
930 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
931 @ApiParam(value = "Application namespace",
932 required = true) @HeaderParam(NS) String ns,
933 @ApiParam(value = "userId",
934 required = true) @HeaderParam(USERID) String userId,
935 @ApiParam(value = "Password",
936 required = true) @HeaderParam(PASSWORD) String password,
938 @ApiParam(value = "Keyspace Name",
939 required = true) @PathParam("keyspace") String keyspace,
940 @ApiParam(value = "Table Name",
941 required = true) @PathParam("tablename") String tablename,
942 @Context UriInfo info) {
943 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
945 Map<String, Object> authMap = null;
947 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
948 aid, "deleteFromTable");
949 } catch (Exception e) {
950 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
951 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
953 if (authMap.containsKey("aid"))
954 authMap.remove("aid");
955 if (!authMap.isEmpty()) {
956 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
957 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
960 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
961 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
963 PreparedQueryObject queryObject = new PreparedQueryObject();
964 StringBuilder columnString = new StringBuilder();
967 ArrayList<String> columnList = delObj.getColumns();
968 if (columnList != null) {
969 for (String column : columnList) {
970 columnString.append(column);
971 if (counter != columnList.size() - 1)
972 columnString.append(",");
973 counter = counter + 1;
977 // get the row specifier
978 RowIdentifier rowId = null;
980 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
981 } catch (MusicServiceException ex) {
982 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
983 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
985 String rowSpec = rowId.rowIdString.toString();
987 if ((columnList != null) && (!rowSpec.isEmpty())) {
988 queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
989 + tablename + " WHERE " + rowSpec + ";");
992 if ((columnList == null) && (!rowSpec.isEmpty())) {
993 queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
997 if ((columnList != null) && (rowSpec.isEmpty())) {
998 queryObject.appendQueryString(
999 "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
1001 // get the conditional, if any
1002 Condition conditionInfo;
1003 if (delObj.getConditions() == null)
1004 conditionInfo = null;
1005 else {// to avoid parsing repeatedly, just send the select query to
1007 PreparedQueryObject selectQuery = new PreparedQueryObject();
1008 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
1009 + rowId.rowIdString + ";");
1010 selectQuery.addValue(rowId.primarKeyValue);
1011 conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery);
1014 String consistency = delObj.getConsistencyInfo().get("type");
1016 ReturnType operationResult = null;
1018 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1019 operationResult = MusicCore.eventualPut(queryObject);
1020 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1021 String lockId = delObj.getConsistencyInfo().get("lockId");
1022 if(lockId == null) {
1023 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1024 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1025 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1026 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1028 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
1029 queryObject, lockId, conditionInfo);
1030 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1031 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
1032 queryObject, conditionInfo);
1034 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1035 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
1036 queryObject, conditionInfo);
1038 } catch (MusicLockingException e) {
1039 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1040 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1041 .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
1043 if (operationResult==null) {
1044 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1045 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1047 if (operationResult.getResult().equals(ResultType.SUCCESS)) {
1048 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1050 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1051 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
1063 @Path("/{keyspace}/tables/{tablename}")
1064 @ApiOperation(value = "Drop Table", response = String.class)
1065 @Produces(MediaType.APPLICATION_JSON)
1066 public Response dropTable(
1067 @ApiParam(value = "Major Version",
1068 required = true) @PathParam("version") String version,
1069 @ApiParam(value = "Minor Version",
1070 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1071 @ApiParam(value = "Patch Version",
1072 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1073 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1074 @ApiParam(value = "Application namespace",
1075 required = true) @HeaderParam(NS) String ns,
1076 @ApiParam(value = "userId",
1077 required = true) @HeaderParam(USERID) String userId,
1078 @ApiParam(value = "Password",
1079 required = true) @HeaderParam(PASSWORD) String password,
1080 @ApiParam(value = "Keyspace Name",
1081 required = true) @PathParam("keyspace") String keyspace,
1082 @ApiParam(value = "Table Name",
1083 required = true) @PathParam("tablename") String tablename) throws Exception {
1084 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
1086 Map<String, Object> authMap =
1087 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
1088 if (authMap.containsKey("aid"))
1089 authMap.remove("aid");
1090 if (!authMap.isEmpty()) {
1091 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1092 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1094 String consistency = "eventual";// for now this needs only eventual
1096 PreparedQueryObject query = new PreparedQueryObject();
1097 query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
1099 return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
1100 } catch (MusicServiceException ex) {
1101 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1102 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1116 @Path("/{keyspace}/tables/{tablename}/rows/criticalget")
1117 @ApiOperation(value = "Select Critical", response = Map.class)
1118 @Consumes(MediaType.APPLICATION_JSON)
1119 @Produces(MediaType.APPLICATION_JSON)
1120 public Response selectCritical(
1121 @ApiParam(value = "Major Version",
1122 required = true) @PathParam("version") String version,
1123 @ApiParam(value = "Minor Version",
1124 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1125 @ApiParam(value = "Patch Version",
1126 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1127 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1128 @ApiParam(value = "Application namespace",
1129 required = true) @HeaderParam(NS) String ns,
1130 @ApiParam(value = "userId",
1131 required = true) @HeaderParam(USERID) String userId,
1132 @ApiParam(value = "Password",
1133 required = true) @HeaderParam(PASSWORD) String password,
1135 @ApiParam(value = "Keyspace Name",
1136 required = true) @PathParam("keyspace") String keyspace,
1137 @ApiParam(value = "Table Name",
1138 required = true) @PathParam("tablename") String tablename,
1139 @Context UriInfo info) throws Exception {
1140 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
1142 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "selectCritical");
1143 if (authMap.containsKey("aid"))
1144 authMap.remove("aid");
1145 if (!authMap.isEmpty()) {
1146 logger.error(EELFLoggerDelegate.errorLogger,"Error while authentication... ", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1147 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1149 String lockId = selObj.getConsistencyInfo().get("lockId");
1151 PreparedQueryObject queryObject = new PreparedQueryObject();
1153 RowIdentifier rowId = null;
1155 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1156 } catch (MusicServiceException ex) {
1157 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1158 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1160 queryObject.appendQueryString(
1161 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1163 ResultSet results = null;
1165 String consistency = selObj.getConsistencyInfo().get("type");
1167 if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1168 if(lockId == null) {
1169 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1170 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1171 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1172 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1174 results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1176 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1177 results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1180 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1181 results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
1184 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1196 @Path("/{keyspace}/tables/{tablename}/rows")
1197 @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1198 @Produces(MediaType.APPLICATION_JSON)
1199 public Response select(
1200 @ApiParam(value = "Major Version",
1201 required = true) @PathParam("version") String version,
1202 @ApiParam(value = "Minor Version",
1203 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1204 @ApiParam(value = "Patch Version",
1205 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1206 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1207 @ApiParam(value = "Application namespace",
1208 required = true) @HeaderParam(NS) String ns,
1209 @ApiParam(value = "userId",
1210 required = true) @HeaderParam(USERID) String userId,
1211 @ApiParam(value = "Password",
1212 required = true) @HeaderParam(PASSWORD) String password,
1213 @ApiParam(value = "Keyspace Name",
1214 required = true) @PathParam("keyspace") String keyspace,
1215 @ApiParam(value = "Table Name",
1216 required = true) @PathParam("tablename") String tablename,
1217 @Context UriInfo info) throws Exception {
1218 ResponseBuilder response = buildVersionResponse(version, minorVersion, patchVersion);
1220 Map<String, Object> authMap =
1221 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
1222 if (authMap.containsKey("aid"))
1223 authMap.remove("aid");
1224 if (!authMap.isEmpty()) {
1225 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1226 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1228 PreparedQueryObject queryObject = new PreparedQueryObject();
1230 if (info.getQueryParameters().isEmpty())// select all
1231 queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
1233 int limit = -1; // do not limit the number of results
1235 queryObject = selectSpecificQuery(version, minorVersion, patchVersion, aid, ns,
1236 userId, password, keyspace, tablename, info, limit);
1237 } catch (MusicServiceException ex) {
1238 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1239 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1244 ResultSet results = MusicCore.get(queryObject);
1245 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1246 } catch (MusicServiceException ex) {
1247 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1248 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1260 * @throws MusicServiceException
1262 public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
1263 String patchVersion, String aid, String ns, String userId, String password,
1264 String keyspace, String tablename, UriInfo info, int limit)
1265 throws MusicServiceException {
1267 PreparedQueryObject queryObject = new PreparedQueryObject();
1268 StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1269 queryObject).rowIdString;
1271 queryObject.appendQueryString(
1272 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1275 queryObject.appendQueryString(" LIMIT " + limit);
1278 queryObject.appendQueryString(";");
1288 * @param queryObject
1290 * @throws MusicServiceException
1292 private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1293 MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1294 throws MusicServiceException {
1295 StringBuilder rowSpec = new StringBuilder();
1297 TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
1298 if (tableInfo == null) {
1299 logger.error(EELFLoggerDelegate.errorLogger,
1300 "Table information not found. Please check input for table name= "
1301 + keyspace + "." + tablename);
1302 throw new MusicServiceException(
1303 "Table information not found. Please check input for table name= "
1304 + keyspace + "." + tablename);
1306 StringBuilder primaryKey = new StringBuilder();
1307 for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1308 String keyName = entry.getKey();
1309 List<String> valueList = entry.getValue();
1310 String indValue = valueList.get(0);
1311 DataType colType = null;
1312 Object formattedValue = null;
1314 colType = tableInfo.getColumn(entry.getKey()).getType();
1315 formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1316 } catch (Exception e) {
1317 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1319 primaryKey.append(indValue);
1320 rowSpec.append(keyName + "= ?");
1321 queryObject.addValue(formattedValue);
1322 if (counter != rowParams.size() - 1)
1323 rowSpec.append(" AND ");
1324 counter = counter + 1;
1326 return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);