diff options
author | 2019-05-09 14:16:37 +0000 | |
---|---|---|
committer | 2019-05-13 14:34:05 -0400 | |
commit | d6e7b63cc580e7b3822be61fe92a493ad5e222a3 (patch) | |
tree | 5a055529781a2989585075e13426979464f5fb33 /src/main | |
parent | 9a8b8ae8d7c8d6931f99def68068f8936a8cc0b3 (diff) |
Changes Listed below:
- Added build version API
- Updated Keyspace active to use Properties setting
- Update Libraries Netty,jbcrypt,Jackson Databind and log4j
- Removed some irrelivant files
- Updated some usint tests to ignore some tests(This will be updated soon)
- Bugfixes
- Missing Values, inform user.
- Respond with proper error
- Fix Locking Contention issue.
- Add locking retry for atomic calls.
Change-Id: Ie218dd92edb0c20e4a0efe33eeaaec84e5293c44
Issue-ID: MUSIC-393
Signed-off-by: Nelson, Thomas (arthurdent3) <nelson24@att.com>
Diffstat (limited to 'src/main')
28 files changed, 1902 insertions, 1445 deletions
diff --git a/src/main/java/org/onap/music/JerseyConfig.java b/src/main/java/org/onap/music/JerseyConfig.java index b3118469..bc394f69 100755 --- a/src/main/java/org/onap/music/JerseyConfig.java +++ b/src/main/java/org/onap/music/JerseyConfig.java @@ -19,39 +19,52 @@ package org.onap.music; import io.swagger.jaxrs.config.BeanConfig; import io.swagger.jaxrs.listing.ApiListingResource; import io.swagger.jaxrs.listing.SwaggerSerializers; + +import javax.annotation.PostConstruct; + import org.glassfish.jersey.server.ResourceConfig; +import org.onap.music.conductor.conditionals.RestMusicConditionalAPI; import org.onap.music.exceptions.MusicExceptionMapper; -import org.onap.music.rest.*; +import org.onap.music.rest.RestMusicAdminAPI; +import org.onap.music.rest.RestMusicDataAPI; +import org.onap.music.rest.RestMusicHealthCheckAPI; +import org.onap.music.rest.RestMusicLocksAPI; +import org.onap.music.rest.RestMusicQAPI; +import org.onap.music.rest.RestMusicTestAPI; +import org.onap.music.rest.RestMusicVersionAPI; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +@Component +public class JerseyConfig extends ResourceConfig { -@Component public class JerseyConfig extends ResourceConfig { + @Value("${spring.jersey.application-path:/}") + private String apiPath; - @Value("${spring.jersey.application-path:/}") private String apiPath; - - public JerseyConfig() { + public JerseyConfig() { this.registerEndpoints(); register(MusicExceptionMapper.class); - } + } - @PostConstruct public void init() { + @PostConstruct + public void init() { this.configureSwagger(); } private void registerEndpoints() { - register(RestMusicAdminAPI.class); + register(RestMusicAdminAPI.class); register(RestMusicDataAPI.class); - register(RestMusicLocksAPI.class); - register(RestMusicQAPI.class); - register(RestMusicTestAPI.class); + register(RestMusicLocksAPI.class); + register(RestMusicConditionalAPI.class); + register(RestMusicQAPI.class); + register(RestMusicTestAPI.class); register(RestMusicVersionAPI.class); register(RestMusicHealthCheckAPI.class); + } private void configureSwagger() { - //Available at localhost:port/swagger.json + // Available at localhost:port/swagger.json this.register(ApiListingResource.class); this.register(SwaggerSerializers.class); diff --git a/src/main/java/org/onap/music/authentication/CachingUtil.java b/src/main/java/org/onap/music/authentication/CachingUtil.java index e02ad496..dba23195 100755 --- a/src/main/java/org/onap/music/authentication/CachingUtil.java +++ b/src/main/java/org/onap/music/authentication/CachingUtil.java @@ -34,6 +34,10 @@ import javax.ws.rs.core.MediaType; import org.apache.commons.codec.binary.Base64; import org.apache.commons.jcs.JCS; import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.engine.CompositeCacheAttributes; +import org.apache.commons.jcs.engine.ElementAttributes; +import org.apache.commons.jcs.engine.behavior.ICompositeCacheAttributes; +import org.apache.commons.jcs.engine.behavior.IElementAttributes; import org.mindrot.jbcrypt.BCrypt; import org.onap.music.authentication.MusicAuthenticator.Operation; import org.onap.music.datastore.PreparedQueryObject; @@ -54,7 +58,7 @@ import com.sun.jersey.api.client.WebResource; /** * All Caching related logic is handled by this class and a schedule cron runs to update cache. - * + * * @author Vikram * */ @@ -71,15 +75,15 @@ public class CachingUtil implements Runnable { private static Map<String, Number> userAttempts = new HashMap<>(); private static Map<String, Calendar> lastFailedTime = new HashMap<>(); private static CacheAccess<String, String> adminUserCache = JCS.getInstance("adminUserCache"); - + public static CacheAccess<String, String> getAdminUserCache() { return adminUserCache; } - + public static void updateAdminUserCache(String authorization,String userId) { adminUserCache.put(authorization,userId); } - + private static final String USERNAME="username"; private static final String PASSWORD="password"; @@ -93,8 +97,8 @@ public class CachingUtil implements Runnable { try { pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), false)); } catch (Exception e1) { - logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(),AppMessages.CACHEERROR, ErrorSeverity - .CRITICAL, ErrorTypes.GENERALSERVICEERROR, e1); + logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(),AppMessages.CACHEERROR, + ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR, e1); } ResultSet rs = MusicCore.get(pQuery); Iterator<Row> it = rs.iterator(); @@ -229,7 +233,7 @@ public class CachingUtil implements Runnable { response.bufferEntity(); String x = response.getEntity(String.class); AAFResponse responseObj = new ObjectMapper().readValue(x, AAFResponse.class);*/ - + return true; } @@ -241,18 +245,18 @@ public class CachingUtil implements Runnable { public static void updateCadiCache(String user, String keyspace) { musicCache.put(user, keyspace); } - + public static String getKSFromCadiCache(String user) { return musicCache.get(user); } - + public static void updateMusicValidateCache(String nameSpace, String userId, String password) { logger.info(EELFLoggerDelegate.applicationLogger,"Updating musicCache for nameSpacce " + nameSpace + " with userId " + userId); Map<String, String> map = new HashMap<>(); map.put(userId, password); musicValidateCache.put(nameSpace, map); } - + public static void updateisAAFCache(String namespace, String isAAF) { appNameCache.put(namespace, isAAF); } @@ -340,7 +344,7 @@ public class CachingUtil implements Runnable { } return resultMap; } - + public static Map<String, Object> verifyOnboarding(String ns, String userId, String password) { Map<String, Object> resultMap = new HashMap<>(); if (ns == null || userId == null || password == null) { @@ -388,10 +392,10 @@ public class CachingUtil implements Runnable { } public static Map<String, Object> authenticateAIDUser(String nameSpace, String userId, String password, - String keyspace) { + String keyspace) { Map<String, Object> resultMap = new HashMap<>(); String pwd = null; - if((musicCache.get(keyspace) != null) && (musicValidateCache.get(nameSpace) != null) + if((musicCache.get(keyspace) != null) && (musicValidateCache.get(nameSpace) != null) && (musicValidateCache.get(nameSpace).containsKey(userId))) { if(!musicCache.get(keyspace).equals(nameSpace)) { resultMap.put("Exception", "Namespace and keyspace doesn't match"); diff --git a/src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java b/src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java index 0fd6c0e2..a84bdd9b 100644 --- a/src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java +++ b/src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java @@ -47,17 +47,13 @@ import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; public class MusicAAFAuthentication implements MusicAuthenticator { - + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicAAFAuthentication.class); - + @Override public boolean authenticateAdmin(String authorization) { logger.info(EELFLoggerDelegate.applicationLogger, "MusicCore.authenticateAdmin: "); String userId = MusicUtil.extractBasicAuthentication(authorization).get(MusicUtil.USERID); - if(MusicUtil.getIsCadi()) { - CachingUtil.updateAdminUserCache(authorization, userId); - return true; - } CacheAccess<String, String> adminCache = CachingUtil.getAdminUserCache(); if (authorization == null) { logger.error(EELFLoggerDelegate.errorLogger, "Authorization cannot be empty..."); @@ -108,8 +104,8 @@ public class MusicAAFAuthentication implements MusicAuthenticator { isAAFApp= CachingUtil.isAAFApplication(namespace); } catch(MusicServiceException e) { logger.error(e.getErrorMessage(), e); - resultMap.put("Exception", e.getMessage()); - return false; + resultMap.put("Exception", e.getMessage()); + return false; } if(isAAFApp == null) { resultMap.put("Exception", "Namespace: "+namespace+" doesn't exist. Please make sure ns(appName)" @@ -133,7 +129,7 @@ public class MusicAAFAuthentication implements MusicAuthenticator { if (isAAF && namespace != null && userId != null && password != null) { boolean isValid = true; try { - isValid = CachingUtil.authenticateAAFUser(namespace, userId, password, keyspace); + isValid = CachingUtil.authenticateAAFUser(namespace, userId, password, keyspace); } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger,"Error while aaf authentication for user:" + userId); logger.error(EELFLoggerDelegate.errorLogger,"Error: "+ e.getMessage(), e); diff --git a/src/main/java/org/onap/music/conductor/conditionals/MusicConditional.java b/src/main/java/org/onap/music/conductor/conditionals/MusicConditional.java index 69ccd104..29740d83 100644 --- a/src/main/java/org/onap/music/conductor/conditionals/MusicConditional.java +++ b/src/main/java/org/onap/music/conductor/conditionals/MusicConditional.java @@ -92,7 +92,12 @@ public class MusicConditional { String key = keyspace + "." + tablename + "." + primaryKey; - String lockId = MusicCore.createLockReference(key); + String lockId; + try { + lockId = MusicCore.createLockReference(key); + } catch (MusicLockingException e) { + return new ReturnType(ResultType.FAILURE, e.getMessage()); + } long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); ReturnType lockAcqResult = MusicCore.acquireLockWithLease(key, lockId, leasePeriod); @@ -160,7 +165,10 @@ public class MusicConditional { } - public static ReturnType update(Map<String,PreparedQueryObject> queryBank, String keyspace, String tableName, String primaryKey,String primaryKeyValue,String planId,String cascadeColumnName,Map<String,String> cascadeColumnValues) throws MusicLockingException, MusicQueryException, MusicServiceException { + public static ReturnType update(Map<String, PreparedQueryObject> queryBank, String keyspace, String tableName, + String primaryKey, String primaryKeyValue, String planId, String cascadeColumnName, + Map<String, String> cascadeColumnValues) + throws MusicLockingException, MusicQueryException, MusicServiceException { String key = keyspace + "." + tableName + "." + primaryKeyValue; String lockId = MusicCore.createLockReference(key); @@ -266,8 +274,8 @@ public class MusicConditional { queryObject.addValue(vector); if(casscadeColumn!=null && casscadeColumnValues!=null) { fieldsString.append(casscadeColumn).append(" ,"); - valueString.append("?,"); - queryObject.addValue(casscadeColumnValues); + valueString.append("?,"); + queryObject.addValue(casscadeColumnValues); } int counter = 0; @@ -276,24 +284,23 @@ public class MusicConditional { fieldsString.append(entry.getKey()); Object valueObj = entry.getValue(); if (primaryKeyName.equals(entry.getKey())) { - localPrimaryKey = entry.getValue() + ""; - localPrimaryKey = localPrimaryKey.replace("'", "''"); + localPrimaryKey = entry.getValue() + ""; + localPrimaryKey = localPrimaryKey.replace("'", "''"); } DataType colType = null; try { colType = tableInfo.getColumn(entry.getKey()).getType(); } catch(NullPointerException ex) { - logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey - (), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR, ex); - + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), + AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR, ex); } Object formattedValue = null; try { - formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); + formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), e); - } + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), e); + } valueString.append("?"); queryObject.addValue(formattedValue); diff --git a/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditionalAPI.java b/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditionalAPI.java index 20fd3150..4a56825a 100644 --- a/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditionalAPI.java +++ b/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditionalAPI.java @@ -65,13 +65,13 @@ import io.swagger.annotations.ApiParam; @Path("/v2/conditional") @Api(value = "Conditional Api", hidden = true) -public class RestMusicConditionalAPI { + public class RestMusicConditionalAPI { private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicAdminAPI.class); private static final String XMINORVERSION = "X-minorVersion"; private static final String XPATCHVERSION = "X-patchVersion"; private static final String NS = "ns"; private static final String VERSION = "v2"; - + private MusicAuthenticator authenticator = new MusicAAFAuthentication(); @POST @@ -146,7 +146,7 @@ public class RestMusicConditionalAPI { @ApiParam(value = "Major Version", required = true) @PathParam("tablename") String tablename, JsonConditional upObj) throws Exception { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); - + if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.INSERT_INTO_TABLE)) { return response.status(Status.UNAUTHORIZED) .entity(new JsonResponse(ResultType.FAILURE) @@ -188,7 +188,6 @@ public class RestMusicConditionalAPI { if (result.getResult() == ResultType.SUCCESS) { return response.status(Status.OK) .entity(new JsonResponse(result.getResult()).setMessage(result.getMessage()).toMap()).build(); - } return response.status(Status.BAD_REQUEST) .entity(new JsonResponse(result.getResult()).setMessage(result.getMessage()).toMap()).build(); diff --git a/src/main/java/org/onap/music/datastore/Condition.java b/src/main/java/org/onap/music/datastore/Condition.java index 2fd4596a..11998ab5 100644 --- a/src/main/java/org/onap/music/datastore/Condition.java +++ b/src/main/java/org/onap/music/datastore/Condition.java @@ -21,6 +21,7 @@ */ package org.onap.music.datastore; + import java.util.Map; import org.onap.music.main.MusicCore; diff --git a/src/main/java/org/onap/music/datastore/MusicDataStore.java b/src/main/java/org/onap/music/datastore/MusicDataStore.java index 1260efa0..2b88b4a8 100755 --- a/src/main/java/org/onap/music/datastore/MusicDataStore.java +++ b/src/main/java/org/onap/music/datastore/MusicDataStore.java @@ -44,7 +44,6 @@ import org.onap.music.eelf.logging.format.ErrorTypes; import org.onap.music.exceptions.MusicQueryException; import org.onap.music.exceptions.MusicServiceException; import org.onap.music.main.MusicUtil; - import com.codahale.metrics.JmxReporter; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ColumnDefinitions; @@ -182,16 +181,16 @@ public class MusicDataStore { logger.info(EELFLoggerDelegate.applicationLogger, "Building with credentials "+MusicUtil.getCassName()+" & "+MusicUtil.getCassPwd()); cluster = Cluster.builder().withPort(MusicUtil.getCassandraPort()) - .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd()) - //.withLoadBalancingPolicy(new RoundRobinPolicy()) - .withoutJMXReporting() - .withPoolingOptions(poolingOptions) - .addContactPoints(addresses).build(); + .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd()) + //.withLoadBalancingPolicy(new RoundRobinPolicy()) + .withoutJMXReporting() + .withPoolingOptions(poolingOptions) + .addContactPoints(addresses).build(); } else cluster = Cluster.builder().withPort(MusicUtil.getCassandraPort()) - //.withLoadBalancingPolicy(new RoundRobinPolicy()) - .addContactPoints(addresses).build(); + //.withLoadBalancingPolicy(new RoundRobinPolicy()) + .addContactPoints(addresses).build(); Metadata metadata = cluster.getMetadata(); logger.info(EELFLoggerDelegate.applicationLogger, "Connected to cassa cluster " @@ -230,13 +229,12 @@ public class MusicDataStore { logger.info(EELFLoggerDelegate.applicationLogger, "Building with credentials "+MusicUtil.getCassName()+" & "+MusicUtil.getCassPwd()); cluster = Cluster.builder().withPort(MusicUtil.getCassandraPort()) - .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd()) - //.withLoadBalancingPolicy(new RoundRobinPolicy()) - .withoutJMXReporting() - .withPoolingOptions(poolingOptions) - .addContactPoints(addresses).build(); - } - else { + .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd()) + //.withLoadBalancingPolicy(new RoundRobinPolicy()) + .withoutJMXReporting() + .withPoolingOptions(poolingOptions) + .addContactPoints(addresses).build(); + } else { cluster = Cluster.builder().withPort(MusicUtil.getCassandraPort()) //.withLoadBalancingPolicy(new RoundRobinPolicy()) .withoutJMXReporting() @@ -288,6 +286,17 @@ public class MusicDataStore { KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace); return ks.getTable(tableName); } + + /** + * + * @param keyspace + * @param tableName + * @return TableMetadata + */ + public KeyspaceMetadata returnKeyspaceMetadata(String keyspace) { + KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace); + return ks; + } /** @@ -363,10 +372,10 @@ public class MusicDataStore { if(definition.getType().toString().toLowerCase().contains("blob")) { resultOutput.put(definition.getName(), getBlobValue(row, definition.getName(), definition.getType())); - } - else + } else { resultOutput.put(definition.getName(), getColValue(row, definition.getName(), definition.getType())); + } } } resultMap.put("row " + counter, resultOutput); @@ -406,23 +415,6 @@ public class MusicDataStore { "In preprared Execute Put: the actual insert query:" + queryObject.getQuery() + "; the values" + queryObject.getValues()); -/*<<<<<<< HEAD - PreparedStatement preparedInsert = null; - try { - - preparedInsert = session.prepare(queryObject.getQuery()); - - } catch(InvalidQueryException iqe) { - logger.error("Exception", iqe); - logger.error(EELFLoggerDelegate.errorLogger, iqe.getMessage(),AppMessages.QUERYERROR, ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); - throw new MusicQueryException(iqe.getMessage()); - }catch(Exception e) { - logger.error("Exception", e); - logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.QUERYERROR, ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); - throw new MusicQueryException(e.getMessage()); - } - -=======*/ SimpleStatement preparedInsert = null; try { @@ -434,7 +426,7 @@ public class MusicDataStore { logger.info(EELFLoggerDelegate.applicationLogger, "Executing simple put query"); if(queryObject.getConsistency() == null) preparedInsert.setConsistencyLevel(ConsistencyLevel.ONE); - else + else preparedInsert.setConsistencyLevel(MusicUtil.getConsistencyLevel(queryObject.getConsistency())); } else if (consistency.equalsIgnoreCase(MusicUtil.ONE)) { preparedInsert.setConsistencyLevel(ConsistencyLevel.ONE); @@ -456,9 +448,9 @@ public class MusicDataStore { throw new MusicServiceException(ae.getMessage()); } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.SESSIONFAILED+ " [" + - queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR, e); - throw new MusicQueryException("Executing Session Failure for Request = " + "[" + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.SESSIONFAILED + " [" + + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR, e); + throw new MusicServiceException("Executing Session Failure for Request = " + "[" + queryObject.getQuery() + "]" + " Reason = " + e.getMessage()); } @@ -496,11 +488,10 @@ public class MusicDataStore { } if(queryObject.getConsistency() == null) { preparedEventualGet.setConsistencyLevel(ConsistencyLevel.ONE); + } else { + preparedEventualGet.setConsistencyLevel(MusicUtil.getConsistencyLevel(queryObject.getConsistency())); } - else { - preparedEventualGet.setConsistencyLevel(MusicUtil.getConsistencyLevel(queryObject.getConsistency())); - } - results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray())); + results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray())); } catch (Exception ex) { logger.error("Exception", ex); @@ -555,10 +546,9 @@ public class MusicDataStore { if (consistencyLevel.equalsIgnoreCase(CONSISTENCY_LEVEL_ONE)) { if(queryObject.getConsistency() == null) { statement.setConsistencyLevel(ConsistencyLevel.ONE); + } else { + statement.setConsistencyLevel(MusicUtil.getConsistencyLevel(queryObject.getConsistency())); } - else { - statement.setConsistencyLevel(MusicUtil.getConsistencyLevel(queryObject.getConsistency())); - } } else if (consistencyLevel.equalsIgnoreCase(CONSISTENCY_LEVEL_QUORUM)) { statement.setConsistencyLevel(ConsistencyLevel.QUORUM); diff --git a/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java b/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java index dc1c43a8..b4412bf6 100644 --- a/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java +++ b/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java @@ -32,6 +32,7 @@ import org.onap.music.eelf.logging.EELFLoggerDelegate; import org.onap.music.exceptions.MusicServiceException; import org.onap.music.main.MusicUtil; +import com.datastax.driver.core.KeyspaceMetadata; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.TableMetadata; @@ -49,45 +50,45 @@ public class MusicDataStoreHandle { * @param remoteIp * @return */ - public static MusicDataStore getDSHandle(String remoteIp) { - logger.info(EELFLoggerDelegate.metricsLogger,"Acquiring data store handle"); - long start = System.currentTimeMillis(); - if (mDstoreHandle == null) { - mDstoreHandle = new MusicDataStore(remoteIp); - } - long end = System.currentTimeMillis(); - logger.info(EELFLoggerDelegate.metricsLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); - return mDstoreHandle; - } + public static MusicDataStore getDSHandle(String remoteIp) { + logger.info(EELFLoggerDelegate.metricsLogger,"Acquiring data store handle"); + long start = System.currentTimeMillis(); + if (mDstoreHandle == null) { + mDstoreHandle = new MusicDataStore(remoteIp); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.metricsLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); + return mDstoreHandle; + } /** * * @return * @throws MusicServiceException */ - public static MusicDataStore getDSHandle() throws MusicServiceException { - logger.info(EELFLoggerDelegate.metricsLogger,"Acquiring data store handle"); - long start = System.currentTimeMillis(); - if (mDstoreHandle == null) { - // Quick Fix - Best to put this into every call to getDSHandle? + public static MusicDataStore getDSHandle() throws MusicServiceException { + logger.info(EELFLoggerDelegate.metricsLogger,"Acquiring data store handle"); + long start = System.currentTimeMillis(); + if (mDstoreHandle == null) { + // Quick Fix - Best to put this into every call to getDSHandle? if (!"localhost".equals(MusicUtil.getMyCassaHost())) { - mDstoreHandle = new MusicDataStore(MusicUtil.getMyCassaHost()); - } else { - mDstoreHandle = new MusicDataStore(); - } - } - if(mDstoreHandle.getSession() == null) { - String message = "Connection to Cassandra has not been enstablished." - + " Please check connection properites and reboot."; - logger.info(EELFLoggerDelegate.applicationLogger, message); - throw new MusicServiceException(message); - } - long end = System.currentTimeMillis(); - logger.info(EELFLoggerDelegate.metricsLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); - return mDstoreHandle; - } - - + mDstoreHandle = new MusicDataStore(MusicUtil.getMyCassaHost()); + } else { + mDstoreHandle = new MusicDataStore(); + } + } + if(mDstoreHandle.getSession() == null) { + String message = "Connection to Cassandra has not been enstablished." + + " Please check connection properites and reboot."; + logger.info(EELFLoggerDelegate.applicationLogger, message); + throw new MusicServiceException(message); + } + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.metricsLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); + return mDstoreHandle; + } + + /** * * @param keyspace @@ -95,18 +96,29 @@ public class MusicDataStoreHandle { * @return * @throws MusicServiceException */ - public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException { - return getDSHandle().returnColumnMetadata(keyspace, tablename); - } - + public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException { + return getDSHandle().returnColumnMetadata(keyspace, tablename); + } + + /** + * + * @param keyspace + * @param tablename + * @return + * @throws MusicServiceException + */ + public static KeyspaceMetadata returnkeyspaceMetadata(String keyspace) throws MusicServiceException { + return getDSHandle().returnKeyspaceMetadata(keyspace); + } + /** * * @param results * @return * @throws MusicServiceException */ - public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) throws MusicServiceException { - return getDSHandle().marshalData(results); - } + public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) throws MusicServiceException { + return getDSHandle().marshalData(results); + } } diff --git a/src/main/java/org/onap/music/datastore/PreparedQueryObject.java b/src/main/java/org/onap/music/datastore/PreparedQueryObject.java index 9b109630..db317eb8 100644 --- a/src/main/java/org/onap/music/datastore/PreparedQueryObject.java +++ b/src/main/java/org/onap/music/datastore/PreparedQueryObject.java @@ -83,7 +83,7 @@ public class PreparedQueryObject { this.consistency = consistency; } - /** + /** * */ public PreparedQueryObject() { @@ -122,7 +122,4 @@ public class PreparedQueryObject { public String getQuery() { return this.query.toString(); } - - - } diff --git a/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java b/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java index 82993ebc..5b3bbd48 100755 --- a/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java +++ b/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java @@ -37,16 +37,16 @@ public class JsonOnboard { private String aid; private String keyspace; - @ApiModelProperty(value = "Application Keyspace") + @ApiModelProperty(value = "Application Keyspace") public String getKeyspace() { - return keyspace; - } + return keyspace; + } - public void setKeyspace_name(String keyspace) { - this.keyspace = keyspace; - } + public void setKeyspace_name(String keyspace) { + this.keyspace = keyspace; + } - @ApiModelProperty(value = "Application Password") + @ApiModelProperty(value = "Application Password") public String getPassword() { return password; } diff --git a/src/main/java/org/onap/music/datastore/jsonobjects/MusicResponse.java b/src/main/java/org/onap/music/datastore/jsonobjects/MusicResponse.java new file mode 100644 index 00000000..97131fd7 --- /dev/null +++ b/src/main/java/org/onap/music/datastore/jsonobjects/MusicResponse.java @@ -0,0 +1,87 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================= + * ==================================================================== + */ +package org.onap.music.datastore.jsonobjects; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.onap.music.rest.Application; + +public class MusicResponse implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List<Application> applicationList = new ArrayList<>(); + private String message; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + private String status; + + public void setSucces(boolean isSucces) { + this.isSucces = isSucces; + } + + private boolean isSucces; + + public boolean isSucces() { + return isSucces; + } + + public void setisSucces(boolean isSucces) { + this.isSucces = isSucces; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public List<Application> getApplicationList() { + return applicationList; + } + + public void setApplicationList(List<Application> applicationList) { + this.applicationList = applicationList; + } + + public void setResposne(String status, String message) { + this.status = status; + this.message = message; + } + + public void addAppToList(Application app) { + applicationList.add(app); + } +} diff --git a/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java b/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java index 079fc579..52e27be1 100644 --- a/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java +++ b/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java @@ -26,12 +26,14 @@ package org.onap.music.eelf.healthcheck; import java.util.UUID; +import org.onap.music.datastore.MusicDataStoreHandle; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.eelf.logging.EELFLoggerDelegate; import org.onap.music.eelf.logging.format.AppMessages; import org.onap.music.eelf.logging.format.ErrorSeverity; import org.onap.music.eelf.logging.format.ErrorTypes; import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicQueryException; import org.onap.music.exceptions.MusicServiceException; import org.onap.music.main.MusicUtil; import org.onap.music.main.ResultType; @@ -53,8 +55,9 @@ public class MusicHealthCheck { logger.info(EELFLoggerDelegate.applicationLogger, "Getting Status for Cassandra"); boolean result = false; + UUID randomUUID = UUID.randomUUID(); try { - result = getAdminKeySpace(consistency); + result = getAdminKeySpace(consistency, randomUUID); } catch(Exception e) { if(e.getMessage().toLowerCase().contains("unconfigured table healthcheck")) { logger.error("Error", e); @@ -62,7 +65,7 @@ public class MusicHealthCheck { boolean ksresult = createKeyspace(); if(ksresult) try { - result = getAdminKeySpace(consistency); + result = getAdminKeySpace(consistency, randomUUID); } catch (MusicServiceException e1) { logger.error(EELFLoggerDelegate.errorLogger, e1, AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.UNKNOWN); } @@ -71,6 +74,12 @@ public class MusicHealthCheck { return "One or more nodes are down or not responding."; } } + try { + cleanHealthCheckId(randomUUID); + } catch (MusicServiceException | MusicQueryException e) { + // TODO Auto-generated catch block + logger.error("Error while cleaning healthcheck record id...", e); + } if (result) { return "ACTIVE"; } else { @@ -79,14 +88,26 @@ public class MusicHealthCheck { } } - private Boolean getAdminKeySpace(String consistency) throws MusicServiceException { + private Boolean getAdminKeySpace(String consistency, UUID randomUUID) throws MusicServiceException { PreparedQueryObject pQuery = new PreparedQueryObject(); pQuery.appendQueryString("insert into admin.healthcheck (id) values (?)"); - pQuery.addValue(UUID.randomUUID()); + pQuery.addValue(randomUUID); ResultType rs = MusicCore.nonKeyRelatedPut(pQuery, consistency); logger.info(rs.toString()); return null != rs; + } + + private void cleanHealthCheckId(UUID randomUUID) throws MusicServiceException, MusicQueryException { + String cleanQuery = "delete from admin.healthcheck where id = ?"; + PreparedQueryObject deleteQueryObject = new PreparedQueryObject(); + deleteQueryObject.appendQueryString(cleanQuery); + deleteQueryObject.addValue(randomUUID); + MusicDataStoreHandle.getDSHandle().executePut(deleteQueryObject, "eventual"); + logger.info(EELFLoggerDelegate.applicationLogger, "Cassandra healthcheck responded and cleaned up."); + } + + private boolean createKeyspace() { PreparedQueryObject pQuery = new PreparedQueryObject(); @@ -108,4 +129,4 @@ public class MusicHealthCheck { this.cassandrHost = cassandrHost; } -} +}
\ No newline at end of file diff --git a/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java b/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java index 0afd9eea..91ee3473 100644 --- a/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java +++ b/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java @@ -67,7 +67,7 @@ public enum ErrorCodes { * [ERR509E] Lock not destroyed * [ERR510E] Lock not released * [ERR511E] Lock not deleted - * [ERR512E] Failed to get ZK Lock Handle + * [ERR512E] Failed to get Lock Handle * * * 600 - 699 - Music Service Errors diff --git a/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java b/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java index 4ed63575..7ff6a4d5 100644 --- a/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java +++ b/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java @@ -29,8 +29,10 @@ import java.util.List; import org.onap.music.datastore.MusicDataStore; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.exceptions.MusicLockingException; import org.onap.music.exceptions.MusicQueryException; import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.MusicUtil; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; @@ -98,7 +100,11 @@ public class CassaLockStore { * @throws MusicServiceException * @throws MusicQueryException */ - public String genLockRefandEnQueue(String keyspace, String table, String lockName) throws MusicServiceException, MusicQueryException { + public String genLockRefandEnQueue(String keyspace, String table, String lockName) throws MusicServiceException, MusicQueryException, MusicLockingException { + return genLockRefandEnQueue(keyspace, table, lockName, 0); + } + + private String genLockRefandEnQueue(String keyspace, String table, String lockName, int count) throws MusicServiceException, MusicQueryException, MusicLockingException { logger.info(EELFLoggerDelegate.applicationLogger, "Create lock reference for " + keyspace + "." + table + "." + lockName); String lockTable =""; @@ -143,10 +149,20 @@ public class CassaLockStore { queryObject.addValue(String.valueOf(lockEpochMillis)); queryObject.addValue("0"); queryObject.appendQueryString(insQuery); - dsHandle.executePut(queryObject, "critical"); - return "$"+keyspace+"."+table+"."+lockName+"$"+ lockRef; + boolean pResult = dsHandle.executePut(queryObject, "critical"); + if (!pResult) {//couldn't create lock ref, retry + count++; + if (count>MusicUtil.getRetryCount()) { + logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to create lock reference"); + throw new MusicLockingException("Unable to create lock reference"); + } + return genLockRefandEnQueue(keyspace, table, lockName, count); + } + return "$" + keyspace + "." + table + "." + lockName + "$" + String.valueOf(lockRef); } + + /** * Returns a result set containing the list of clients waiting for a particular lock * @param keyspace @@ -200,7 +216,7 @@ public class CassaLockStore { * @param keyspace of the application. * @param table of the application. * @param key is the primary key of the application table - * @return the UUID lock reference. + * @return the UUID lock reference. Returns null if there is no owner or the lock doesn't exist * @throws MusicServiceException * @throws MusicQueryException */ @@ -213,6 +229,9 @@ public class CassaLockStore { queryObject.appendQueryString(selectQuery); ResultSet results = dsHandle.executeOneConsistencyGet(queryObject); Row row = results.one(); + if (row==null || row.isNull("lockReference")) { + return null; + } String lockReference = "" + row.getLong("lockReference"); String createTime = row.getString("createTime"); String acquireTime = row.getString("acquireTime"); @@ -229,14 +248,31 @@ public class CassaLockStore { * @param lockReference the lock reference that needs to be dequeued. * @throws MusicServiceException * @throws MusicQueryException + * @throws MusicLockingException */ - public void deQueueLockRef(String keyspace, String table, String key, String lockReference) throws MusicServiceException, MusicQueryException{ - table = table_prepend_name+table; + public void deQueueLockRef(String keyspace, String table, String key, String lockReference, int n) throws MusicServiceException, MusicQueryException, MusicLockingException{ + String prependTable = table_prepend_name+table; PreparedQueryObject queryObject = new PreparedQueryObject(); - Long lockReferenceL = Long.parseLong(lockReference.substring(lockReference.lastIndexOf('$')+1)); - String deleteQuery = "delete from "+keyspace+"."+table+" where key='"+key+"' AND lockReference ="+lockReferenceL+" IF EXISTS;"; + Long lockReferenceL = Long.parseLong(lockReference.substring(lockReference.lastIndexOf("$")+1)); + String deleteQuery = "delete from "+keyspace+"."+prependTable+" where key='"+key+"' AND lockReference ="+lockReferenceL+" IF EXISTS;"; queryObject.appendQueryString(deleteQuery); - dsHandle.executePut(queryObject, "critical"); + logger.info(EELFLoggerDelegate.applicationLogger, "Removing lock for key: "+key+ " and reference: "+lockReference); + try { + dsHandle.executePut(queryObject, "critical"); + logger.info(EELFLoggerDelegate.applicationLogger, "Lock removed for key: "+key+ " and reference: "+lockReference); + }catch(MusicServiceException ex) { + logger.error(logger, ex.getMessage(),ex); + logger.error(EELFLoggerDelegate.applicationLogger,"Exception while deQueueLockRef for lockname: " + key + " reference:" +lockReference); + if(n>1) { + logger.info(EELFLoggerDelegate.applicationLogger, "Trying again..."); + deQueueLockRef(keyspace, table, key, lockReference, n-1); + } + else { + logger.error(EELFLoggerDelegate.applicationLogger,"deQueueLockRef failed for lockname: " + key + " reference:" +lockReference); + logger.error(logger, ex.getMessage(),ex); + throw new MusicLockingException("Error while deQueueLockRef: "+ex.getMessage()); + } + } } diff --git a/src/main/java/org/onap/music/main/MusicCore.java b/src/main/java/org/onap/music/main/MusicCore.java index 221e680b..df718379 100644 --- a/src/main/java/org/onap/music/main/MusicCore.java +++ b/src/main/java/org/onap/music/main/MusicCore.java @@ -66,7 +66,7 @@ public class MusicCore { return musicCore.acquireLockWithLease(key, lockId, leasePeriod); } - public static String createLockReference(String fullyQualifiedKey) { + public static String createLockReference(String fullyQualifiedKey) throws MusicLockingException { return musicCore.createLockReference(fullyQualifiedKey); } @@ -83,7 +83,7 @@ public class MusicCore { return musicCore.whoseTurnIsIt(fullyQualifiedKey); } - public static void destroyLockRef(String lockId) { + public static void destroyLockRef(String lockId) throws MusicLockingException { musicCore.destroyLockRef(lockId); } @@ -154,9 +154,9 @@ public class MusicCore { return musicCore.validateLock(lockName); } - public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) { + public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) throws MusicLockingException { return musicCore.releaseLock(lockId, voluntaryRelease); } -}
\ No newline at end of file +} diff --git a/src/main/java/org/onap/music/main/MusicUtil.java b/src/main/java/org/onap/music/main/MusicUtil.java index 07612aa0..da5da239 100755 --- a/src/main/java/org/onap/music/main/MusicUtil.java +++ b/src/main/java/org/onap/music/main/MusicUtil.java @@ -112,19 +112,25 @@ public class MusicUtil { private static int cacheObjectMaxLife = -1; private static String lockUsing = MusicUtil.CASSANDRA; private static boolean isCadi = false; + private static boolean isKeyspaceActive = false; private static boolean debug = true; - private static String version = "2.3.0"; + private static String version = "0.0.0"; + private static String build = ""; private static String musicRestIp = LOCALHOST; private static String musicPropertiesFilePath = PROPERTIES_FILE; private static long defaultLockLeasePeriod = 6000; + private static int retryCount = 3; private static final String[] propKeys = new String[] { "cassandra.host", "music.ip", "debug", - "version", "music.rest.ip", "music.properties", "lock.lease.period", "id", "all.ids", "public.ip", - "all.pubic.ips", "cassandra.user", "cassandra.password", "aaf.endpoint.url","admin.username","admin.password","aaf.admin.url", - "music.namespace","admin.aaf.role","cassandra.port","lock.using"}; + "version", "music.rest.ip", "music.properties", "lock.lease.period", "id", "all.ids", + "public.ip","all.pubic.ips", "cassandra.user", "cassandra.password", "aaf.endpoint.url", + "admin.username","admin.password","aaf.admin.url","music.namespace","admin.aaf.role", + "cassandra.port","lock.using","retry.count"}; private static final String[] cosistencyLevel = new String[] { - "ALL","EACH_QUORUM","QUORUM","LOCAL_QUORUM","ONE","TWO","THREE","LOCAL_ONE","ANY","SERIAL","LOCAL_SERIAL"}; + "ALL","EACH_QUORUM","QUORUM","LOCAL_QUORUM","ONE","TWO", + "THREE","LOCAL_ONE","ANY","SERIAL","LOCAL_SERIAL"}; private static final Map<String,ConsistencyLevel> consistencyName = new HashMap<>(); + static { consistencyName.put("ONE",ConsistencyLevel.ONE); consistencyName.put("TWO",ConsistencyLevel.TWO); @@ -145,8 +151,8 @@ public class MusicUtil { private static String adminId = "username"; private static String adminPass= "password"; private static String aafAdminUrl= null; - private static String musicNamespace= "com.att.music.api"; - private static String adminAafRole= "com.att.music.api.admin_api"; + private static String musicNamespace= "org.onap.music.api"; + private static String adminAafRole= "org.onap.music.api.admin_api"; public static final long MusicEternityEpochMillis = 1533081600000L; // Wednesday, August 1, 2018 12:00:00 AM @@ -213,7 +219,6 @@ public class MusicUtil { MusicUtil.adminPass = adminPass; } - private MusicUtil() { throw new IllegalStateException("Utility Class"); } @@ -419,7 +424,7 @@ public class MusicUtil { } /** - * Return the version property file value - version + * Return the version property file value - version. * * @return */ @@ -428,6 +433,23 @@ public class MusicUtil { } /** + * Set the build of project which is a combination of the + * version and the date. + * + * @param build - version-date. + */ + public static void setBuild(String build) { + MusicUtil.build = build; + } + + /** + * Return the build version-date. + */ + public static String getBuild() { + return build; + } + + /** * Get MyCassHost - Cassandra Hostname - Default = localhost property file * value - cassandra.host * @@ -440,7 +462,7 @@ public class MusicUtil { /** * Set MyCassHost - Cassandra Hostname * - * @param myCassaHost + * @param myCassaHost . */ public static void setMyCassaHost(String myCassaHost) { MusicUtil.myCassaHost = myCassaHost; @@ -458,24 +480,56 @@ public class MusicUtil { /** * Set DefaultMusicIp * - * @param defaultMusicIp + * @param defaultMusicIp . */ public static void setDefaultMusicIp(String defaultMusicIp) { MusicUtil.defaultMusicIp = defaultMusicIp; } - + /** - * + * Gey default retry count * @return */ + public static int getRetryCount() { + return retryCount; + } + + /** + * Set retry count + * @param retryCount . + */ + public static void setRetryCount(int retryCount) { + MusicUtil.retryCount = retryCount; + } + + + /** + * This is used to turn keyspace creation api on/off. + * + */ + public static void setKeyspaceActive(Boolean keyspaceActive) { + MusicUtil.isKeyspaceActive = keyspaceActive; + } + + /** + * This is used to turn keyspace creation api on/off. + * @return boolean isKeyspaceActive + */ + public static boolean isKeyspaceActive() { + return isKeyspaceActive; + } + + /** + * . + * @return String + */ public static String getTestType() { String testType = ""; try { Scanner fileScanner = new Scanner(new File("")); testType = fileScanner.next();// ignore the my id line @SuppressWarnings("unused") - String batchSize = fileScanner.next();// ignore the my public ip - // line + String batchSize = fileScanner.next();// ignore the my public ip line fileScanner.close(); } catch (FileNotFoundException e) { logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e); @@ -592,8 +646,8 @@ public class MusicUtil { } public static ByteBuffer convertToActualDataType(DataType colType, byte[] valueObj) { - ByteBuffer buffer = ByteBuffer.wrap(valueObj); - return buffer; + ByteBuffer buffer = ByteBuffer.wrap(valueObj); + return buffer; } /** diff --git a/src/main/java/org/onap/music/main/PropertiesLoader.java b/src/main/java/org/onap/music/main/PropertiesLoader.java index db04ff4b..af4e14e3 100644 --- a/src/main/java/org/onap/music/main/PropertiesLoader.java +++ b/src/main/java/org/onap/music/main/PropertiesLoader.java @@ -48,6 +48,9 @@ public class PropertiesLoader implements InitializingBean { @Value("${version}") public String version; + + @Value("${build}") + public String build; @Value("${music.rest.ip}") public String musicRestIp; @@ -106,6 +109,12 @@ public class PropertiesLoader implements InitializingBean { @Value("${cadi}") public String isCadi; + @Value("${keyspace.active}") + public String isKeyspaceActive; + + @Value("${retry.count}") + public String rertryCount; + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PropertiesLoader.class); @Bean @@ -117,23 +126,30 @@ public class PropertiesLoader implements InitializingBean { return pspc; } - public void loadProperties () { - if(aafAdminUrl != null && !aafAdminUrl.equals("${aaf.admin.url}")) + /** + * . + */ + public void loadProperties() { + if (aafAdminUrl != null && !aafAdminUrl.equals("${aaf.admin.url}")) { MusicUtil.setAafAdminUrl(aafAdminUrl); - if(aafEndpointUrl != null && !aafEndpointUrl.equals("${aaf.endpoint.url}")) + } + if (aafEndpointUrl != null && !aafEndpointUrl.equals("${aaf.endpoint.url}")) { MusicUtil.setAafEndpointUrl(aafEndpointUrl); - if(adminAafRole != null && !adminAafRole.equals("${admin.aaf.role}")) + } + if (adminAafRole != null && !adminAafRole.equals("${admin.aaf.role}")) { MusicUtil.setAdminAafRole(adminAafRole); - //MusicUtil.setAdminId(adminId); - if(adminPassword != null && !adminPassword.equals("${admin.password}")) + } + if (adminPassword != null && !adminPassword.equals("${admin.password}")) { MusicUtil.setAdminPass(adminPassword); - if(adminUsername != null && !adminUsername.equals("${admin.username}")) + } + if (adminUsername != null && !adminUsername.equals("${admin.username}")) { MusicUtil.setAdminId(adminUsername); - if(allIds != null && !allIds.equals("${all.ids}")) { + } + if (allIds != null && !allIds.equals("${all.ids}")) { String[] ids = allIds.split(":"); MusicUtil.setAllIds(new ArrayList<String>(Arrays.asList(ids))); } - if(allPublicIps != null && !allPublicIps.equals("${all.public.ips}")) { + if (allPublicIps != null && !allPublicIps.equals("${all.public.ips}")) { String[] ips = allPublicIps.split(":"); if (ips.length == 1) { // Future use @@ -142,39 +158,63 @@ public class PropertiesLoader implements InitializingBean { new ArrayList<String>(Arrays.asList(ips))); } } - if(cassandraPort != null && !cassandraPort.equals("${cassandra.port}")) + if (cassandraPort != null && !cassandraPort.equals("${cassandra.port}")) { MusicUtil.setCassandraPort(Integer.parseInt(cassandraPort)); - if(cassandraUser != null && !cassandraUser.equals("${cassandra.user}")) + } + if (cassandraUser != null && !cassandraUser.equals("${cassandra.user}")) { MusicUtil.setCassName(cassandraUser); - if(cassandraPassword != null && !cassandraPassword.equals("${cassandra.password}")) + } + if (cassandraPassword != null && !cassandraPassword.equals("${cassandra.password}")) { MusicUtil.setCassPwd(cassandraPassword); - if(debug != null && !debug.equals("${debug}")) + } + if (debug != null && !debug.equals("${debug}")) { MusicUtil.setDebug(Boolean.parseBoolean(debug)); - if(lockLeasePeriod != null && !lockLeasePeriod.equals("${lock.lease.period}")) + } + if (lockLeasePeriod != null && !lockLeasePeriod.equals("${lock.lease.period}")) { MusicUtil.setDefaultLockLeasePeriod(Long.parseLong(lockLeasePeriod)); - if(musicIp != null && !musicIp.equals("${music.ip}")) + } + if (musicIp != null && !musicIp.equals("${music.ip}")) { MusicUtil.setDefaultMusicIp(musicIp); - if(musicNamespace != null && !musicNamespace.equals("${music.namespace}")) + } + if (musicNamespace != null && !musicNamespace.equals("${music.namespace}")) { MusicUtil.setMusicNamespace(musicNamespace); - if(musicProperties != null && !musicProperties.equals("${music.properties}")) + } + if (musicProperties != null && !musicProperties.equals("${music.properties}")) { MusicUtil.setMusicPropertiesFilePath(musicProperties); - if(musicRestIp != null && !musicRestIp.equals("${music.rest.ip}")) + } + if (musicRestIp != null && !musicRestIp.equals("${music.rest.ip}")) { MusicUtil.setMusicRestIp(musicRestIp); - if(cassandraHost != null && !cassandraHost.equals("${cassandra.host}")) + } + if (cassandraHost != null && !cassandraHost.equals("${cassandra.host}")) { MusicUtil.setMyCassaHost(cassandraHost); - logger.info("#### Cassandra Host: " + MusicUtil.getMyCassaHost()); - if(myId != null && !myId.equals("${my.id}")) + } + if (myId != null && !myId.equals("${my.id}")) { MusicUtil.setMyId(Integer.parseInt(myId)); - if(notifyInterval != null && !notifyInterval.equals("${notify.interval}")) + } + if (notifyInterval != null && !notifyInterval.equals("${notify.interval}")) { MusicUtil.setNotifyInterval(Integer.parseInt(notifyInterval)); - if(notifyTimeout != null && !notifyTimeout.equals("${notify.timeout}")) + } + if (notifyTimeout != null && !notifyTimeout.equals("${notify.timeout}")) { MusicUtil.setNotifyTimeOut(Integer.parseInt(notifyTimeout)); - if(allPublicIps != null && !allPublicIps.equals("${public.ip}")) + } + if (allPublicIps != null && !allPublicIps.equals("${public.ip}")) { MusicUtil.setPublicIp(allPublicIps); - if(version != null && !version.equals("${version}")) + } + if (version != null && !version.equals("${version}")) { MusicUtil.setVersion(version); - if(isCadi != null && !isCadi.equals("${cadi}")) + } + if (build != null && !version.equals("${build}")) { + MusicUtil.setBuild(build); + } + if (isCadi != null && !isCadi.equals("${cadi}")) { MusicUtil.setIsCadi(Boolean.parseBoolean(isCadi)); + } + if (rertryCount != null && !rertryCount.equals("${retry.count}")) { + MusicUtil.setRetryCount(Integer.parseInt(rertryCount)); + } + if (isKeyspaceActive != null && !isKeyspaceActive.equals("${keyspace.active}")) { + MusicUtil.setKeyspaceActive(Boolean.parseBoolean(isKeyspaceActive)); + } } diff --git a/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java b/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java index 8e589efe..66fec9c2 100644 --- a/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java +++ b/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java @@ -44,6 +44,7 @@ public class JsonResponse { /* versioning */ private String musicVersion; + private String musicBuild; /* Data Fields */ private Map<String, HashMap<String, Object>> dataResult; @@ -65,7 +66,7 @@ public class JsonResponse { this.status = status; } - /** + /** * * @return */ @@ -122,7 +123,7 @@ public class JsonResponse { /** - * + * . * @return the music version */ public String getMusicVersion() { @@ -130,7 +131,7 @@ public class JsonResponse { } /** - * + * . * @param version of music * @return */ @@ -139,6 +140,25 @@ public class JsonResponse { return this; } + /** + * . + * @return the music version + */ + public String getMusicBuild() { + return this.musicBuild; + } + + /** + * . + * @param build of music + * @return + */ + public JsonResponse setMusicBuild(String build) { + this.musicBuild = build; + return this; + } + + public Map<String, HashMap<String, Object>> getDataResult() { return this.dataResult; } @@ -227,37 +247,37 @@ public class JsonResponse { public Map<String, Object> toMap() { Map<String, Object> fullMap = new HashMap<>(); fullMap.put("status", status); -/*<<<<<<< HEAD - if (error!=null) { - fullMap.put("error", error); + if (error != null && !"".equals(error)) { + fullMap.put("error", error); } - if (message!=null) { - fullMap.put("message", message); + if (message != null) { + fullMap.put("message", message); } -=======*/ - if (error!=null && !"".equals(error)) {fullMap.put("error", error);} - if (message!=null) {fullMap.put("message", message);} - if (musicVersion!=null) { + if (musicVersion != null) { fullMap.put("version", musicVersion); } - if (dataResult!=null) { + if (musicBuild != null) { + fullMap.put("build", musicBuild); + } + + if (dataResult != null) { fullMap.put("result", dataResult); } - if (lock!=null) { + if (lock != null) { Map<String, Object> lockMap = new HashMap<>(); - if (lock!=null) { + if (lock != null) { lockMap.put("lock", lock); } - if (lockStatus!=null) { + if (lockStatus != null) { lockMap.put("lock-status", lockStatus); } - if (lockHolder!=null) { + if (lockHolder != null) { lockMap.put("lock-holder", lockHolder); } - if (lockLease!=null) { + if (lockLease != null) { lockMap.put("lock-lease", lockLease); } fullMap.put("lock", lockMap); diff --git a/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java b/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java index fddeebff..664747f6 100755 --- a/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java @@ -27,6 +27,7 @@ package org.onap.music.rest; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -50,8 +51,10 @@ import org.mindrot.jbcrypt.BCrypt; import org.onap.music.authentication.CachingUtil; import org.onap.music.authentication.MusicAAFAuthentication; import org.onap.music.authentication.MusicAuthenticator; +import org.onap.music.datastore.MusicDataStoreHandle; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.datastore.jsonobjects.JsonOnboard; +import org.onap.music.datastore.jsonobjects.MusicResponse; import org.onap.music.eelf.logging.EELFLoggerDelegate; import org.onap.music.eelf.logging.format.AppMessages; import org.onap.music.eelf.logging.format.ErrorSeverity; @@ -61,10 +64,14 @@ import org.onap.music.main.MusicCore; import org.onap.music.main.MusicUtil; import org.onap.music.main.ResultType; import org.onap.music.response.jsonobjects.JsonResponse; +import org.springframework.beans.factory.config.YamlProcessor.ResolutionMethod; import com.datastax.driver.core.DataType; +import com.datastax.driver.core.KeyspaceMetadata; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; +import com.datastax.driver.core.TableMetadata; +import com.sun.xml.bind.v2.TODO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -73,8 +80,6 @@ import io.swagger.annotations.ApiParam; //import java.util.Base64.Decoder; @Path("/v2/admin") -// @Path("/v{version: [0-9]+}/admin") -// @Path("/admin") @Api(value = "Admin Api", hidden = true) public class RestMusicAdminAPI { private static EELFLoggerDelegate logger = @@ -110,11 +115,10 @@ public class RestMusicAdminAPI { Map<String, Object> resultMap = new HashMap<>(); String appName = jsonObj.getAppname(); String userId = jsonObj.getUserId(); - String isAAF = jsonObj.getIsAAF(); String password = jsonObj.getPassword(); String keyspace_name = jsonObj.getKeyspace(); - if (appName == null || userId == null || isAAF == null || password == null) { + if (appName == null || userId == null || password == null || keyspace_name == null) { logger.error(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check the request parameters. Some of the required values appName(ns), userId, password, isAAF are missing.", AppMessages.MISSINGINFO, ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); resultMap.put("Exception", @@ -123,18 +127,22 @@ public class RestMusicAdminAPI { } PreparedQueryObject pQuery = new PreparedQueryObject(); - /* - * pQuery.appendQueryString( - * "select uuid from admin.keyspace_master where application_name = ? allow filtering" - * ); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), - * appName)); ResultSet rs = MusicCore.get(pQuery); if (!rs.all().isEmpty()) { - * logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA - * ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); - * response.status(Status.BAD_REQUEST); return response.entity(new - * JsonResponse(ResultType.FAILURE).setError("Application " + appName + - * " has already been onboarded. Please contact admin.").toMap()).build(); } - */ - //pQuery = new PreparedQueryObject(); + + pQuery.appendQueryString( + "select uuid from admin.keyspace_master where application_name = ? and keyspace_name = ? allow filtering"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace_name)); + ResultSet rs = MusicCore.get(pQuery); + if (!rs.all().isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA, ErrorSeverity.CRITICAL, + ErrorTypes.GENERALSERVICEERROR); + response.status(Status.BAD_REQUEST); + return response.entity(new JsonResponse(ResultType.FAILURE) + .setError("Application " + appName + " has already been onboarded. Please contact admin.").toMap()) + .build(); + } + + pQuery = new PreparedQueryObject(); String uuid = MusicUtil.generateUUID(); pQuery.appendQueryString( "INSERT INTO admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " @@ -142,10 +150,10 @@ public class RestMusicAdminAPI { pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),keyspace_name)); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "False")); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "true")); String returnStr = MusicCore.eventualPut(pQuery).toString(); if (returnStr.contains("Failure")) { @@ -154,7 +162,7 @@ public class RestMusicAdminAPI { return response.entity(new JsonResponse(ResultType.FAILURE).setError("Oops. Something wrong with onboarding process. " + "Please retry later or contact admin.").toMap()).build(); } - CachingUtil.updateisAAFCache(appName, isAAF); + //CachingUtil.updateisAAFCache(appName, isAAF); resultMap.put("Success", "Your application " + appName + " has been onboarded with MUSIC."); resultMap.put("Generated AID", uuid); return response.status(Status.OK).entity(resultMap).build(); @@ -258,26 +266,27 @@ public class RestMusicAdminAPI { PreparedQueryObject pQuery = new PreparedQueryObject(); String consistency = MusicUtil.EVENTUAL; if (appName == null && aid == null) { - logger.error(EELFLoggerDelegate.errorLogger, "Please make sure either appName(ns) or Aid is present", AppMessages.MISSINGINFO, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + logger.error(EELFLoggerDelegate.errorLogger, + "Please make sure either appName(ns) or Aid is present", AppMessages.MISSINGINFO, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); resultMap.put("Exception", "Please make sure either appName(ns) or Aid is present"); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } if (aid != null) { - if ( KEYSPACE_ACTIVE ) { - pQuery.appendQueryString( - "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?"); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), - UUID.fromString(aid))); - Row row = MusicCore.get(pQuery).one(); - if (row != null) { - String ks = row.getString("keyspace_name"); - if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) { - PreparedQueryObject queryObject = new PreparedQueryObject(); - queryObject.appendQueryString("DROP KEYSPACE IF EXISTS " + ks + ";"); - MusicCore.nonKeyRelatedPut(queryObject, consistency); - } - } + if (MusicUtil.isKeyspaceActive()) { + pQuery.appendQueryString( + "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), + UUID.fromString(aid))); + Row row = MusicCore.get(pQuery).one(); + if (row != null) { + String ks = row.getString("keyspace_name"); + if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) { + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("DROP KEYSPACE IF EXISTS " + ks + ";"); + MusicCore.nonKeyRelatedPut(queryObject, consistency); + } + } } pQuery = new PreparedQueryObject(); pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ? IF EXISTS"); @@ -288,9 +297,11 @@ public class RestMusicAdminAPI { resultMap.put("Success", "Your application has been deleted successfully"); } else { resultMap.put("Exception", - "Oops. Something went wrong. Please make sure Aid is correct or Application is onboarded"); - logger.error(EELFLoggerDelegate.errorLogger, "Oops. Something went wrong. Please make sure Aid is correct or Application is onboarded", AppMessages.INCORRECTDATA, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + "Oops. Something went wrong. Please make sure Aid is correct or Application is onboarded"); + logger.error(EELFLoggerDelegate.errorLogger, + "Oops. Something went wrong. Please make sure Aid is correct or Application is onboarded", + AppMessages.INCORRECTDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } @@ -362,8 +373,7 @@ public class RestMusicAdminAPI { String aid = jsonObj.getAid(); String appName = jsonObj.getAppname(); String userId = jsonObj.getUserId(); - String isAAF = jsonObj.getIsAAF(); - String password = jsonObj.getPassword(); + String cassandraKeyspace=jsonObj.getKeyspace(); String consistency = "eventual"; PreparedQueryObject pQuery; @@ -374,7 +384,7 @@ public class RestMusicAdminAPI { return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } - if (appName == null && userId == null && password == null && isAAF == null) { + if (appName == null || userId == null || cassandraKeyspace == null) { resultMap.put("Exception", "No parameters found to update. Please update atleast one parameter."); logger.error(EELFLoggerDelegate.errorLogger, "No parameters found to update. Please update atleast one parameter.", AppMessages.MISSINGDATA, @@ -388,10 +398,10 @@ public class RestMusicAdminAPI { "select uuid from admin.keyspace_master where application_name = ? allow filtering"); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); ResultSet rs = MusicCore.get(pQuery); - if (!rs.all().isEmpty()) { + if (rs.all().isEmpty()) { resultMap.put("Exception", "Application " + appName - + " has already been onboarded. Please contact admin."); - logger.error(EELFLoggerDelegate.errorLogger, "Application " + appName+"has already been onboarded. Please contact admin.", AppMessages.ALREADYEXIST, + + " not found. Please contact admin."); + logger.error(EELFLoggerDelegate.errorLogger, "Application " + appName+"not found. Please contact admin.", AppMessages.ALREADYEXIST, ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } @@ -403,10 +413,8 @@ public class RestMusicAdminAPI { preCql.append(" application_name = ?,"); if (userId != null) preCql.append(" username = ?,"); - if (password != null) - preCql.append(" password = ?,"); - if (isAAF != null) - preCql.append(" is_aaf = ?,"); + if (cassandraKeyspace != null) + preCql.append(" keyspace_name = ?,"); preCql.deleteCharAt(preCql.length() - 1); preCql.append(" WHERE uuid = ? IF EXISTS"); pQuery.appendQueryString(preCql.toString()); @@ -414,10 +422,8 @@ public class RestMusicAdminAPI { pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); if (userId != null) pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); - if (password != null) - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); - if (isAAF != null) - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + if (cassandraKeyspace != null) + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), cassandraKeyspace)); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), UUID.fromString(aid))); ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency); @@ -438,22 +444,24 @@ public class RestMusicAdminAPI { //Dashboard related calls + //TODO Make return object Response. + @GET @Path("/getall") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - public List<Application> getall(@ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization) throws MusicServiceException{ - List<Application> appList = new ArrayList<>(); - ResponseBuilder response = - Response.noContent().header("X-latestVersion", MusicUtil.getVersion()); + public MusicResponse getall(@ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization) throws MusicServiceException{ + MusicResponse response = new MusicResponse(); if (!authenticator.authenticateAdmin(authorization)) { - logger.error(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check admin username,password and try again", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.CRITICAL, + logger.info(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check admin username,password and try again", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); - return appList; + response.setResposne("fail", "Auth failed for admin"); + return response; } PreparedQueryObject queryObject = new PreparedQueryObject(); queryObject.appendQueryString("SELECT * FROM " + "admin" + "." + "keyspace_master" + ";"); + try { ResultSet results = MusicCore.get(queryObject); for(Row row : results) { Application app = new Application(); @@ -463,36 +471,165 @@ public class RestMusicAdminAPI { app.setUsername(row.getString("username")); app.setKeyspace_name(row.getString("keyspace_name")); app.setUuid(row.getUUID("uuid").toString()); - appList.add(app); + response.addAppToList(app); } - return appList; - - //return app; + }catch(Exception ex) { + response.setResposne("fail", ex.getMessage()); + } + return response; } + + @DELETE @Path("/delete") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - public boolean delete(@ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + public MusicResponse delete(@ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "uuid", required = true) @HeaderParam("uuid") String uuid) throws Exception { - ResponseBuilder response = - Response.noContent().header("X-latestVersion", MusicUtil.getVersion()); + MusicResponse response = new MusicResponse(); if (!authenticator.authenticateAdmin(authorization)) { - logger.error(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check admin username,password and try again", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.CRITICAL, + logger.info(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check admin username,password and try again", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); - return false; + response.setResposne("fail", "Auth failed for admin"); + return response; } PreparedQueryObject queryObject = new PreparedQueryObject(); queryObject.appendQueryString("delete from admin.keyspace_master where uuid=?"); queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),uuid)); ResultType result; try { - result = MusicCore.nonKeyRelatedPut(queryObject, "eventual"); + result = MusicCore.nonKeyRelatedPut(queryObject, "eventual"); + response.setResposne("success", "Application deleted successfully. Please contact ops team to delete keyspace"); }catch(Exception ex) { logger.error(EELFLoggerDelegate.errorLogger, ex); - return false; + response.setResposne("fail", ex.getMessage()); + return response; + } + return response; + } + + @POST + @Path("/onboard") + @ApiOperation(value = "Onboard application", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public MusicResponse onboard(JsonOnboard jsonObj, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization) throws Exception { + logger.info(EELFLoggerDelegate.errorLogger, "oboarding app"); + MusicResponse response = new MusicResponse(); + if (!authenticator.authenticateAdmin(authorization)) { + logger.info(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check admin username,password and try again", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.CRITICAL, + ErrorTypes.AUTHENTICATIONERROR); + response.setResposne("fail", "auth error"); } - return true; + PreparedQueryObject pQurey = new PreparedQueryObject(); + pQurey.appendQueryString("Describe keyspace + ?"); + pQurey.addValue(MusicUtil.convertToActualDataType(DataType.text(),jsonObj.getKeyspace())); + KeyspaceMetadata keyspaceInfo = null; + //authenticator.checkOnbaordUserAccess(jsonObj.getUserId(), jsonObj.getAppname()); + try { + keyspaceInfo = MusicDataStoreHandle.returnkeyspaceMetadata(jsonObj.getKeyspace()); + }catch (Exception e) { + logger.info(EELFLoggerDelegate.applicationLogger,"Application onbaord failed for "+ jsonObj.getKeyspace()); + + } + if(keyspaceInfo == null) { + logger.info(EELFLoggerDelegate.applicationLogger,"Keyspace does not exist, contact music support to create a keyspace and onbaord again"); + response.setResposne("fail", "Keyspace does not exist, contact music support to create a keyspace and onboard again"); + return response; + } + Response result = null; + try { + result = onboardAppWithMusic(jsonObj, authorization); + if(result.getStatus()!= 200) { + response.setResposne("fail", result.getEntity().toString()); + }else { + response.setResposne("success", "Onboard Success"); + } + }catch(Exception ex) { + response.setResposne("fail", ex.getMessage()); + return response; + + } + return response; } + + @POST + @Path("/disable") + @ApiOperation(value = "Onboard application", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public MusicResponse disableApplicationAccess(@ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + @ApiParam(value = "uuid", required = true) @HeaderParam("uuid") String uuid) throws Exception { + logger.info(EELFLoggerDelegate.errorLogger, "oboarding app"); + MusicResponse response = new MusicResponse(); + if (!authenticator.authenticateAdmin(authorization)) { + logger.info(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check admin username,password and try again", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.CRITICAL, + ErrorTypes.AUTHENTICATIONERROR); + response.setResposne("fail", "Authorization failed for music admin"); + } + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("SELECT * from admin.keyspace_master where uuid = ?"); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + Row row = MusicDataStoreHandle.getDSHandle().executeGet(queryObject, "eventual").one(); + boolean toggleAccess = row.getBool("is_api"); + queryObject = null; + queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("UPDATE admin.keyspace_master SET is_api = ? WHERE uuid = ?"); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), !toggleAccess)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + try { + MusicDataStoreHandle.getDSHandle().executePut(queryObject, "eventual"); + response.setResposne("success","Access toggle success"); + }catch(Exception ex) { + response.setResposne("fail", ex.getMessage()); + } + + return response; + } + + @POST + @Path("/editApplication") + @ApiOperation(value = "Onboard application", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public MusicResponse editApplication(JsonOnboard jsonObj, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization) throws Exception { + logger.info(EELFLoggerDelegate.errorLogger, "oboarding app"); + MusicResponse response = new MusicResponse(); + if (!authenticator.authenticateAdmin(authorization)) { + logger.info(EELFLoggerDelegate.errorLogger, "Unauthorized: Please check admin username,password and try again", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.CRITICAL, + ErrorTypes.AUTHENTICATIONERROR); + response.setResposne("fail", "auth error"); + } + KeyspaceMetadata keyspaceInfo = null; + try { + keyspaceInfo = MusicDataStoreHandle.returnkeyspaceMetadata(jsonObj.getKeyspace()); + }catch (Exception e) { + logger.info(EELFLoggerDelegate.applicationLogger,"Application Update failed for "+ jsonObj.getKeyspace()); + + } + if(keyspaceInfo == null) { + logger.info(EELFLoggerDelegate.applicationLogger,"Keyspace does not exist, contact music support to create a keyspace and onbaord again"); + response.setResposne("fail", "Keyspace does not exist, contact music support to create a keyspace and update again"); + return response; + } + + try { + Response res = updateOnboardApp(jsonObj, authorization); + if(res.getStatus() != 200) { + response.setResposne("fail", res.getEntity().toString()); + }else + response.setResposne("success", "Update success"); + }catch(Exception ex){ + logger.info(EELFLoggerDelegate.errorLogger,"Exception while updating application"); + logger.info(EELFLoggerDelegate.errorLogger,ex.getMessage()); + response.setResposne("fail", ex.getMessage()); + + } + return response; + } + + } diff --git a/src/main/java/org/onap/music/rest/RestMusicDataAPI.java b/src/main/java/org/onap/music/rest/RestMusicDataAPI.java index 8500298b..5fa955e1 100755 --- a/src/main/java/org/onap/music/rest/RestMusicDataAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicDataAPI.java @@ -125,8 +125,8 @@ public class RestMusicDataAPI { public String primarKeyValue; public StringBuilder rowIdString; @SuppressWarnings("unused") - public PreparedQueryObject queryObject;// the string with all the row - // identifiers separated by AND + public PreparedQueryObject queryObject; // the string with all the row + // identifiers separated by AND public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString, PreparedQueryObject queryObject) { @@ -151,128 +151,130 @@ public class RestMusicDataAPI { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response createKeySpace( - @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, - @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - JsonKeySpace kspObject, - @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) { + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + JsonKeySpace kspObject, + @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) { try { - ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); - EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) "); - logger.info(EELFLoggerDelegate.applicationLogger,"In Create Keyspace " + keyspaceName); - if ( KEYSPACE_ACTIVE ) { - logger.info(EELFLoggerDelegate.applicationLogger,"Creating Keyspace " + keyspaceName); - Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); - String userId = userCredentials.get(MusicUtil.USERID); - String password = userCredentials.get(MusicUtil.PASSWORD); - Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password); - if (!authMap.isEmpty()) { - logger.error(EELFLoggerDelegate.errorLogger,authMap.get("Exception").toString(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); - response.status(Status.UNAUTHORIZED); - return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); - } - - if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CREATE_KEYSPACE)) { - return response.status(Status.UNAUTHORIZED) - .entity(new JsonResponse(ResultType.FAILURE) - .setError("Unauthorized: Please check username, password and make sure your app is onboarded") - .toMap()).build(); - } - - String consistency = MusicUtil.EVENTUAL;// for now this needs only - // eventual consistency - - if(kspObject == null || kspObject.getReplicationInfo() == null) { - response.status(Status.BAD_REQUEST); - return response.entity(new JsonResponse(ResultType.FAILURE).setError(ResultType.BODYMISSING.getResult()).toMap()).build(); - } - PreparedQueryObject queryObject = new PreparedQueryObject(); - if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && kspObject.getConsistencyInfo().get("consistency") != null) { - if(MusicUtil.isValidConsistency(kspObject.getConsistencyInfo().get("consistency"))) - queryObject.setConsistency(kspObject.getConsistencyInfo().get("consistency")); - else - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Invalid Consistency type").toMap()).build(); - } - long start = System.currentTimeMillis(); - Map<String, Object> replicationInfo = kspObject.getReplicationInfo(); - String repString = null; - try { - repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}"; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity - .CRITICAL, ErrorTypes.DATAERROR, e); - - } - queryObject.appendQueryString( - "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString); - if (kspObject.getDurabilityOfWrites() != null) { + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) "); + logger.info(EELFLoggerDelegate.applicationLogger,"In Create Keyspace " + keyspaceName); + if ( MusicUtil.isKeyspaceActive() ) { + logger.info(EELFLoggerDelegate.applicationLogger,"Creating Keyspace " + keyspaceName); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); + Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password); + if (!authMap.isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger,authMap.get("Exception").toString(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); + response.status(Status.UNAUTHORIZED); + return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build(); + } + + if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CREATE_KEYSPACE)) { + return response.status(Status.UNAUTHORIZED) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("Unauthorized: Please check username, password and make sure your app is onboarded") + .toMap()).build(); + } + + String consistency = MusicUtil.EVENTUAL;// for now this needs only + // eventual consistency + + if(kspObject == null || kspObject.getReplicationInfo() == null) { + response.status(Status.BAD_REQUEST); + return response.entity(new JsonResponse(ResultType.FAILURE).setError(ResultType.BODYMISSING.getResult()).toMap()).build(); + } + PreparedQueryObject queryObject = new PreparedQueryObject(); + if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && kspObject.getConsistencyInfo().get("consistency") != null) { + if (MusicUtil.isValidConsistency(kspObject.getConsistencyInfo().get("consistency"))) { + queryObject.setConsistency(kspObject.getConsistencyInfo().get("consistency")); + } else { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR) + .setError("Invalid Consistency type").toMap()).build(); + } + } + long start = System.currentTimeMillis(); + Map<String, Object> replicationInfo = kspObject.getReplicationInfo(); + String repString = null; + try { + repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}"; + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity + .CRITICAL, ErrorTypes.DATAERROR, e); + + } queryObject.appendQueryString( - " AND durable_writes = " + kspObject.getDurabilityOfWrites()); - } - - queryObject.appendQueryString(";"); - long end = System.currentTimeMillis(); - logger.info(EELFLoggerDelegate.applicationLogger, - "Time taken for setting up query in create keyspace:" + (end - start)); - - ResultType result = ResultType.FAILURE; - try { - result = MusicCore.nonKeyRelatedPut(queryObject, consistency); - logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result); - } catch ( MusicServiceException ex) { - logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity - .WARN, ErrorTypes.MUSICSERVICEERROR, ex); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build(); - } - - try { - queryObject = new PreparedQueryObject(); - queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId - + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;"); - MusicCore.nonKeyRelatedPut(queryObject, consistency); - queryObject = new PreparedQueryObject(); - queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName - + " to '" + userId + "'"); + "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString); + if (kspObject.getDurabilityOfWrites() != null) { + queryObject.appendQueryString( + " AND durable_writes = " + kspObject.getDurabilityOfWrites()); + } + queryObject.appendQueryString(";"); - MusicCore.nonKeyRelatedPut(queryObject, consistency); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity - .WARN, ErrorTypes.MUSICSERVICEERROR, e); - } - - try { - boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns)); - String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt()); - queryObject = new PreparedQueryObject(); - queryObject.appendQueryString( - "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " - + "password, username, is_aaf) values (?,?,?,?,?,?,?)"); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), aid)); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName)); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns)); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd)); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); - CachingUtil.updateMusicCache(keyspaceName, ns); - CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd); - MusicCore.eventualPut(queryObject); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity - .WARN, ErrorTypes.MUSICSERVICEERROR, e); - return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger, + "Time taken for setting up query in create keyspace:" + (end - start)); + + ResultType result = ResultType.FAILURE; + try { + result = MusicCore.nonKeyRelatedPut(queryObject, consistency); + logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result); + } catch ( MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity + .WARN, ErrorTypes.MUSICSERVICEERROR, ex); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build(); + } + + try { + queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId + + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;"); + MusicCore.nonKeyRelatedPut(queryObject, consistency); + queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName + + " to '" + userId + "'"); + queryObject.appendQueryString(";"); + MusicCore.nonKeyRelatedPut(queryObject, consistency); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity + .WARN, ErrorTypes.MUSICSERVICEERROR, e); + } + + try { + boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns)); + String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt()); + queryObject = new PreparedQueryObject(); + queryObject.appendQueryString( + "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " + + "password, username, is_aaf) values (?,?,?,?,?,?,?)"); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), aid)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); + CachingUtil.updateMusicCache(keyspaceName, ns); + CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd); + MusicCore.eventualPut(queryObject); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity + .WARN, ErrorTypes.MUSICSERVICEERROR, e); + return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } + + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build(); + } else { + String vError = "Keyspace Creation has been turned off. Contact DBA to create the keyspace or set keyspace.active to true."; + logger.info(EELFLoggerDelegate.applicationLogger,vError); + logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build(); } - - return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build(); - } else { - String vError = "Keyspace Creation no longer supported after versions 3.2.x. Contact DBA to create the keyspace."; - logger.info(EELFLoggerDelegate.applicationLogger,vError); - logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); - return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build(); - } } finally { EELFLoggerDelegate.mdcRemove("keyspace"); } @@ -291,69 +293,68 @@ public class RestMusicDataAPI { @ApiOperation(value = "Delete Keyspace", response = String.class,hidden=true) @Produces(MediaType.APPLICATION_JSON) public Response dropKeySpace( - @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, - @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception { + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception { try { - ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); - EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) "); - logger.info(EELFLoggerDelegate.applicationLogger,"In Drop Keyspace " + keyspaceName); - if ( KEYSPACE_ACTIVE ) { - if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DROP_KEYSPACE)) { - return response.status(Status.UNAUTHORIZED) + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + EELFLoggerDelegate.mdcPut("keyspace", "( " + keyspaceName + " ) "); + logger.info(EELFLoggerDelegate.applicationLogger,"In Drop Keyspace " + keyspaceName); + if (MusicUtil.isKeyspaceActive()) { + if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DROP_KEYSPACE)) { + return response.status(Status.UNAUTHORIZED) .entity(new JsonResponse(ResultType.FAILURE) - .setError("Unauthorized: Please check username, password and make sure your app is onboarded") - .toMap()).build(); - } - - String consistency = MusicUtil.EVENTUAL;// for now this needs only - // eventual - // consistency - String appName = CachingUtil.getAppName(keyspaceName); - String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName); - PreparedQueryObject pQuery = new PreparedQueryObject(); - pQuery.appendQueryString( - "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;"); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); - Row row = MusicCore.get(pQuery).one(); - long count = row.getLong(0); - - if (count == 0) { - logger.error(EELFLoggerDelegate.errorLogger,"Keyspace not found. Please make sure keyspace exists.", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build(); - // Admin Functions: - } else if (count == 1) { - pQuery = new PreparedQueryObject(); + .setError("Unauthorized: Please check username, password and make sure your app is onboarded") + .toMap()).build(); + } + String consistency = MusicUtil.EVENTUAL;// for now this needs only + // eventual + // consistency + String appName = CachingUtil.getAppName(keyspaceName); + String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName); + PreparedQueryObject pQuery = new PreparedQueryObject(); pQuery.appendQueryString( - "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;"); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), - MusicUtil.DEFAULTKEYSPACENAME)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); - MusicCore.nonKeyRelatedPut(pQuery, consistency); + "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); + Row row = MusicCore.get(pQuery).one(); + long count = row.getLong(0); + + if (count == 0) { + logger.error(EELFLoggerDelegate.errorLogger,"Keyspace not found. Please make sure keyspace exists.", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build(); + // Admin Functions: + } else if (count == 1) { + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), + MusicUtil.DEFAULTKEYSPACENAME)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + MusicCore.nonKeyRelatedPut(pQuery, consistency); + } else { + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?"); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); + MusicCore.nonKeyRelatedPut(pQuery, consistency); + } + + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";"); + ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency); + if ( result.equals(ResultType.FAILURE) ) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build(); } else { - pQuery = new PreparedQueryObject(); - pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?"); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); - MusicCore.nonKeyRelatedPut(pQuery, consistency); + String vError = "Keyspace deletion has been turned off. Contact DBA to delete the keyspace or set keyspace.active to true."; + logger.info(EELFLoggerDelegate.applicationLogger,vError); + logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build(); } - - PreparedQueryObject queryObject = new PreparedQueryObject(); - queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";"); - ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency); - if ( result.equals(ResultType.FAILURE) ) { - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build(); - } - return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build(); - } else { - String vError = "Keyspace Droping no longer supported after versions 3.2.x. Contact DBA to drop the keyspace."; - logger.info(EELFLoggerDelegate.applicationLogger,vError); - logger.error(EELFLoggerDelegate.errorLogger,vError, AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); - return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(vError).toMap()).build(); - } } finally { EELFLoggerDelegate.mdcRemove("keyspace"); } @@ -367,7 +368,7 @@ public class RestMusicDataAPI { * @param tablename * @param headers * @return - * @throws Exception + * @throws Exception - */ @POST @Path("/{keyspace: .*}/tables/{tablename: .*}") @@ -379,216 +380,215 @@ public class RestMusicDataAPI { @ApiResponse(code= 401, message = "Unautorized User") }) public Response createTable( - @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, - @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - JsonTable tableObj, - @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace, - @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception { + @ApiParam(value = "Major Version",required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, + @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonTable tableObj, + @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception { try { - ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); - if(keyspace == null || keyspace.isEmpty() || tablename == null || tablename.isEmpty()){ - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("One or more path parameters are not set, please check and try again." - + "Parameter values: keyspace='" + keyspace + "' tablename='" + tablename + "'") - .toMap()).build(); - } - EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); - if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_TABLE)) { - return response.status(Status.UNAUTHORIZED) - .entity(new JsonResponse(ResultType.FAILURE) - .setError("Unauthorized: Please check username, password and make sure your app is onboarded") + ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + if(keyspace == null || keyspace.isEmpty() || tablename == null || tablename.isEmpty()){ + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("One or more path parameters are not set, please check and try again." + + "Parameter values: keyspace='" + keyspace + "' tablename='" + tablename + "'") .toMap()).build(); - } - - String consistency = MusicUtil.EVENTUAL; - // for now this needs only eventual consistency - - String primaryKey = null; - String partitionKey = tableObj.getPartitionKey(); - String clusterKey = tableObj.getClusteringKey(); - String filteringKey = tableObj.getFilteringKey(); - if(filteringKey != null) { - clusterKey = clusterKey + "," + filteringKey; - } - primaryKey = tableObj.getPrimaryKey(); // get primaryKey if available - - PreparedQueryObject queryObject = new PreparedQueryObject(); - // first read the information about the table fields - Map<String, String> fields = tableObj.getFields(); - StringBuilder fieldsString = new StringBuilder("(vector_ts text,"); - int counter = 0; - for (Map.Entry<String, String> entry : fields.entrySet()) { - if (entry.getKey().equals("PRIMARY KEY")) { - primaryKey = entry.getValue(); // replaces primaryKey - primaryKey = primaryKey.trim(); - } else { - if (counter == 0 ) fieldsString.append("" + entry.getKey() + " " + entry.getValue() + ""); - else fieldsString.append("," + entry.getKey() + " " + entry.getValue() + ""); } + EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); + if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_TABLE)) { + return response.status(Status.UNAUTHORIZED) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("Unauthorized: Please check username, password and make sure your app is onboarded") + .toMap()).build(); + } + String consistency = MusicUtil.EVENTUAL; + // for now this needs only eventual consistency + String primaryKey = null; + String partitionKey = tableObj.getPartitionKey(); + String clusterKey = tableObj.getClusteringKey(); + String filteringKey = tableObj.getFilteringKey(); + if(filteringKey != null) { + clusterKey = clusterKey + "," + filteringKey; + } + primaryKey = tableObj.getPrimaryKey(); // get primaryKey if available - if (counter != (fields.size() - 1) ) { - - counter = counter + 1; - } else { + PreparedQueryObject queryObject = new PreparedQueryObject(); + // first read the information about the table fields + Map<String, String> fields = tableObj.getFields(); + if (fields == null) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Create Table Error: No fields in request").toMap()).build(); + } - if((primaryKey != null) && (partitionKey == null)) { + StringBuilder fieldsString = new StringBuilder("(vector_ts text,"); + int counter = 0; + for (Map.Entry<String, String> entry : fields.entrySet()) { + if (entry.getKey().equals("PRIMARY KEY")) { + primaryKey = entry.getValue(); // replaces primaryKey primaryKey = primaryKey.trim(); - int count1 = StringUtils.countMatches(primaryKey, ')'); - int count2 = StringUtils.countMatches(primaryKey, '('); - if (count1 != count2) { - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + } else { + if (counter == 0 ) fieldsString.append("" + entry.getKey() + " " + entry.getValue() + ""); + else fieldsString.append("," + entry.getKey() + " " + entry.getValue() + ""); + } + + if (counter != (fields.size() - 1) ) { + counter = counter + 1; + } else { + + if((primaryKey != null) && (partitionKey == null)) { + primaryKey = primaryKey.trim(); + int count1 = StringUtils.countMatches(primaryKey, ')'); + int count2 = StringUtils.countMatches(primaryKey, '('); + if (count1 != count2) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) .setError("Create Table Error: primary key '(' and ')' do not match, primary key=" + primaryKey) .toMap()).build(); - } + } - if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) ) - { - if (primaryKey.contains(",") ) { - partitionKey= primaryKey.substring(0,primaryKey.indexOf(',')); - partitionKey=partitionKey.replaceAll("[\\(]+",""); - clusterKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index - clusterKey=clusterKey.replaceAll("[)]+", ""); - } else { - partitionKey=primaryKey; - partitionKey=partitionKey.replaceAll("[\\)]+",""); + if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) ) { + if (primaryKey.contains(",") ) { + partitionKey= primaryKey.substring(0,primaryKey.indexOf(',')); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusterKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index + clusterKey=clusterKey.replaceAll("[)]+", ""); + } else { + partitionKey=primaryKey; + partitionKey=partitionKey.replaceAll("[\\)]+",""); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusterKey=""; + } + } else { // not null and has ) before the last char + partitionKey= primaryKey.substring(0,primaryKey.indexOf(')')); partitionKey=partitionKey.replaceAll("[\\(]+",""); - clusterKey=""; + partitionKey = partitionKey.trim(); + clusterKey= primaryKey.substring(primaryKey.indexOf(')')); + clusterKey=clusterKey.replaceAll("[\\(]+",""); + clusterKey=clusterKey.replaceAll("[\\)]+",""); + clusterKey = clusterKey.trim(); + if (clusterKey.indexOf(',') == 0) { + clusterKey=clusterKey.substring(1); + } + clusterKey = clusterKey.trim(); + if (clusterKey.equals(",") ) clusterKey=""; // print error if needed ( ... ),) } - } else { // not null and has ) before the last char - partitionKey= primaryKey.substring(0,primaryKey.indexOf(')')); - partitionKey=partitionKey.replaceAll("[\\(]+",""); - partitionKey = partitionKey.trim(); - clusterKey= primaryKey.substring(primaryKey.indexOf(')')); - clusterKey=clusterKey.replaceAll("[\\(]+",""); - clusterKey=clusterKey.replaceAll("[\\)]+",""); - clusterKey = clusterKey.trim(); - if (clusterKey.indexOf(',') == 0) clusterKey=clusterKey.substring(1); - clusterKey = clusterKey.trim(); - if (clusterKey.equals(",") ) clusterKey=""; // print error if needed ( ... ),) - } - if (!(partitionKey.isEmpty() || clusterKey.isEmpty()) + if (!(partitionKey.isEmpty() || clusterKey.isEmpty()) && (partitionKey.equalsIgnoreCase(clusterKey) || - clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) - { - logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey + " and primary key=" + primaryKey ); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError( + clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) { + logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey + " and primary key=" + primaryKey ); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError( "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ") of" - + " primary key=" + primaryKey) + + " primary key=" + primaryKey) .toMap()).build(); - } - - if (partitionKey.isEmpty() ) primaryKey=""; - else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")"; - else primaryKey=" (" + partitionKey + ")," + clusterKey; + } + if (partitionKey.isEmpty() ) primaryKey=""; + else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")"; + else primaryKey=" (" + partitionKey + ")," + clusterKey; - if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )"); + + if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )"); - } // end of length > 0 - else { - if (!(partitionKey.isEmpty() || clusterKey.isEmpty()) + } else { // end of length > 0 + + if (!(partitionKey.isEmpty() || clusterKey.isEmpty()) && (partitionKey.equalsIgnoreCase(clusterKey) || - clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) - { - logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError( + clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) { + logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError( "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ")") .toMap()).build(); - } + } - if (partitionKey.isEmpty() ) primaryKey=""; - else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")"; - else primaryKey=" (" + partitionKey + ")," + clusterKey; + if (partitionKey.isEmpty() ) primaryKey=""; + else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")"; + else primaryKey=" (" + partitionKey + ")," + clusterKey; + if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )"); + } + fieldsString.append(")"); + + } // end of last field check + + } // end of for each + // information about the name-value style properties + Map<String, Object> propertiesMap = tableObj.getProperties(); + StringBuilder propertiesString = new StringBuilder(); + if (propertiesMap != null) { + counter = 0; + for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) { + Object ot = entry.getValue(); + String value = ot + ""; + if (ot instanceof String) { + value = "'" + value + "'"; + } else if (ot instanceof Map) { + @SuppressWarnings("unchecked") + Map<String, Object> otMap = (Map<String, Object>) ot; + value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}"; + } - if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )"); - } - fieldsString.append(")"); + propertiesString.append(entry.getKey() + "=" + value + ""); + if (counter != propertiesMap.size() - 1) + propertiesString.append(" AND "); - } // end of last field check - - } // end of for each - // information about the name-value style properties - Map<String, Object> propertiesMap = tableObj.getProperties(); - StringBuilder propertiesString = new StringBuilder(); - if (propertiesMap != null) { - counter = 0; - for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) { - Object ot = entry.getValue(); - String value = ot + ""; - if (ot instanceof String) { - value = "'" + value + "'"; - } else if (ot instanceof Map) { - @SuppressWarnings("unchecked") - Map<String, Object> otMap = (Map<String, Object>) ot; - value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}"; + counter = counter + 1; } - - propertiesString.append(entry.getKey() + "=" + value + ""); - if (counter != propertiesMap.size() - 1) - propertiesString.append(" AND "); - - counter = counter + 1; } - } - String clusteringOrder = tableObj.getClusteringOrder(); + String clusteringOrder = tableObj.getClusteringOrder(); - if (clusteringOrder != null && !(clusteringOrder.isEmpty())) { - String[] arrayClusterOrder = clusteringOrder.split("[,]+"); + if (clusteringOrder != null && !(clusteringOrder.isEmpty())) { + String[] arrayClusterOrder = clusteringOrder.split("[,]+"); - for (int i = 0; i < arrayClusterOrder.length; i++) { - String[] clusterS = arrayClusterOrder[i].trim().split("[ ]+"); - if ( (clusterS.length ==2) && (clusterS[1].equalsIgnoreCase("ASC") || clusterS[1].equalsIgnoreCase("DESC"))) { - continue; - } else { - return response.status(Status.BAD_REQUEST) - .entity(new JsonResponse(ResultType.FAILURE) - .setError("createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:"+ clusteringOrder+".") - .toMap()).build(); + for (int i = 0; i < arrayClusterOrder.length; i++) { + String[] clusterS = arrayClusterOrder[i].trim().split("[ ]+"); + if ( (clusterS.length ==2) && (clusterS[1].equalsIgnoreCase("ASC") || clusterS[1].equalsIgnoreCase("DESC"))) { + continue; + } else { + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:"+ clusteringOrder+".") + .toMap()).build(); + } + // add validation for column names in cluster key } - // add validation for column names in cluster key - } - if (!(clusterKey.isEmpty())) { - clusteringOrder = "CLUSTERING ORDER BY (" +clusteringOrder +")"; - //cjc check if propertiesString.length() >0 instead propertiesMap - if (propertiesMap != null) { - propertiesString.append(" AND "+ clusteringOrder); + if (!(clusterKey.isEmpty())) { + clusteringOrder = "CLUSTERING ORDER BY (" +clusteringOrder +")"; + //cjc check if propertiesString.length() >0 instead propertiesMap + if (propertiesMap != null) { + propertiesString.append(" AND "+ clusteringOrder); + } else { + propertiesString.append(clusteringOrder); + } } else { - propertiesString.append(clusteringOrder); + logger.warn("Skipping clustering order=("+clusteringOrder+ ") since clustering key is empty "); } - } else { - logger.warn("Skipping clustering order=("+clusteringOrder+ ") since clustering key is empty "); - } - } //if non empty + } //if non empty - queryObject.appendQueryString( + queryObject.appendQueryString( "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString); - if (propertiesString != null && propertiesString.length()>0 ) - queryObject.appendQueryString(" WITH " + propertiesString); - queryObject.appendQueryString(";"); - ResultType result = ResultType.FAILURE; - try { - result = MusicCore.createTable(keyspace, tablename, queryObject, consistency); - } catch (MusicServiceException ex) { - logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity - .CRITICAL, ErrorTypes.MUSICSERVICEERROR, ex); - response.status(Status.BAD_REQUEST); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); - } - if ( result.equals(ResultType.FAILURE) ) { - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build(); - } - return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename.trim() + " Created under keyspace " + keyspace.trim()).toMap()).build(); + if (propertiesString != null && propertiesString.length()>0 ) + queryObject.appendQueryString(" WITH " + propertiesString); + queryObject.appendQueryString(";"); + ResultType result = ResultType.FAILURE; + try { + result = MusicCore.createTable(keyspace, tablename, queryObject, consistency); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR); + response.status(Status.BAD_REQUEST); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + if ( result.equals(ResultType.FAILURE) ) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build(); + } + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename.trim() + " Created under keyspace " + keyspace.trim()).toMap()).build(); } finally { EELFLoggerDelegate.mdcRemove("keyspace"); } @@ -621,8 +621,8 @@ public class RestMusicDataAPI { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty()) || (fieldName == null || fieldName.isEmpty())){ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("one or more path parameters are not set, please check and try again") - .toMap()).build(); + .setError("one or more path parameters are not set, please check and try again") + .toMap()).build(); } EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.CREATE_INDEX)) { @@ -688,8 +688,8 @@ public class RestMusicDataAPI { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("one or more path parameters are not set, please check and try again") - .toMap()).build(); + .setError("one or more path parameters are not set, please check and try again") + .toMap()).build(); } EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.INSERT_INTO_TABLE)) { @@ -699,7 +699,6 @@ public class RestMusicDataAPI { .toMap()).build(); } - Map<String, Object> valuesMap = insObj.getValues(); PreparedQueryObject queryObject = new PreparedQueryObject(); TableMetadata tableInfo = null; try { @@ -717,9 +716,14 @@ public class RestMusicDataAPI { String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); StringBuilder valueString = new StringBuilder("(" + "?" + ","); queryObject.addValue(vectorTs); + + Map<String, Object> valuesMap = insObj.getValues(); + if (valuesMap==null) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Nothing to insert. No values provided in request.").toMap()).build(); + } int counter = 0; String primaryKey = ""; - Map<String, byte[]> objectMap = insObj.getObjectMap(); for (Map.Entry<String, Object> entry : valuesMap.entrySet()) { fieldsString.append("" + entry.getKey()); Object valueObj = entry.getValue(); @@ -738,7 +742,7 @@ public class RestMusicDataAPI { Object formattedValue = null; try { - formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); + formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger,e); } @@ -757,38 +761,35 @@ public class RestMusicDataAPI { } //blobs.. + Map<String, byte[]> objectMap = insObj.getObjectMap(); if(objectMap != null) { - for (Map.Entry<String, byte[]> entry : objectMap.entrySet()) { - if(counter > 0) { - fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ","); - valueString.replace(valueString.length()-1, valueString.length(), ","); - } - fieldsString.append("" + entry.getKey()); - byte[] valueObj = entry.getValue(); - if (primaryKeyName.equals(entry.getKey())) { - primaryKey = entry.getValue() + ""; - primaryKey = primaryKey.replace("'", "''"); - } + for (Map.Entry<String, byte[]> entry : objectMap.entrySet()) { + if(counter > 0) { + fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ","); + valueString.replace(valueString.length()-1, valueString.length(), ","); + } + fieldsString.append("" + entry.getKey()); + byte[] valueObj = entry.getValue(); + if (primaryKeyName.equals(entry.getKey())) { + primaryKey = entry.getValue() + ""; + primaryKey = primaryKey.replace("'", "''"); + } - DataType colType = tableInfo.getColumn(entry.getKey()).getType(); + DataType colType = tableInfo.getColumn(entry.getKey()).getType(); - ByteBuffer formattedValue = null; + ByteBuffer formattedValue = null; - if(colType.toString().toLowerCase().contains("blob")) - formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); + if(colType.toString().toLowerCase().contains("blob")) + formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); - valueString.append("?"); + valueString.append("?"); - queryObject.addValue(formattedValue); - counter = counter + 1; - /*if (counter == valuesMap.size() - 1) { - fieldsString.append(")"); - valueString.append(")"); - } else {*/ + queryObject.addValue(formattedValue); + counter = counter + 1; fieldsString.append(","); valueString.append(","); - //} - } } + } + } if(primaryKey == null || primaryKey.length() <= 0) { logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName ); @@ -907,7 +908,7 @@ public class RestMusicDataAPI { if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) .setError("one or more path parameters are not set, please check and try again") - .toMap()).build(); + .toMap()).build(); } EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.UPDATE_TABLE)) { @@ -918,8 +919,8 @@ public class RestMusicDataAPI { } long startTime = System.currentTimeMillis(); - String operationId = UUID.randomUUID().toString();// just for infoging - // purposes. + String operationId = UUID.randomUUID().toString(); // just for infoging + // purposes. String consistency = updateObj.getConsistencyInfo().get("type"); logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency @@ -939,12 +940,11 @@ public class RestMusicDataAPI { } if (tableInfo == null) { logger.error(EELFLoggerDelegate.errorLogger,"Table information not found. Please check input for table name= "+tablename, AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("Table information not found. Please check input for table name= " - + keyspace + "." + tablename).toMap()).build(); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Table information not found. Please check input for table name= " + + keyspace + "." + tablename).toMap()).build(); } - String vectorTs = - String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); + String vectorTs = String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); StringBuilder fieldValueString = new StringBuilder("vector_ts=?,"); queryObject.addValue(vectorTs); int counter = 0; @@ -959,7 +959,7 @@ public class RestMusicDataAPI { } Object valueString = null; try { - valueString = MusicUtil.convertToActualDataType(colType, valueObj); + valueString = MusicUtil.convertToActualDataType(colType, valueObj); } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger,e); } @@ -974,7 +974,6 @@ public class RestMusicDataAPI { queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " "); if ((ttl != null) && (timestamp != null)) { - logger.info("both there"); queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?"); queryObject.addValue(Integer.parseInt(ttl)); @@ -1013,11 +1012,11 @@ public class RestMusicDataAPI { Condition conditionInfo; if (updateObj.getConditions() == null) conditionInfo = null; - else {// to avoid parsing repeatedly, just send the select query to - // obtain row + else { + // to avoid parsing repeatedly, just send the select query to obtain row PreparedQueryObject selectQuery = new PreparedQueryObject(); selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE " - + rowId.rowIdString + ";"); + + rowId.rowIdString + ";"); selectQuery.addValue(rowId.primarKeyValue); conditionInfo = new Condition(updateObj.getConditions(), selectQuery); } @@ -1047,20 +1046,19 @@ public class RestMusicDataAPI { } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) { // this function is mainly for the benchmarks try { - operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, - rowId.primarKeyValue, queryObject, conditionInfo); + operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, + rowId.primarKeyValue, queryObject, conditionInfo); } catch (MusicLockingException e) { logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); } } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) { try { - operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue, - queryObject, conditionInfo); + operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue, + queryObject, conditionInfo); } catch (MusicLockingException e) { - logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, - ErrorTypes.GENERALSERVICEERROR, e); + logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e); return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); } }else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) { @@ -1083,7 +1081,7 @@ public class RestMusicDataAPI { if (operationResult==null) { logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build(); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build(); } if ( operationResult.getResult() == ResultType.SUCCESS ) { return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build(); @@ -1134,7 +1132,7 @@ public class RestMusicDataAPI { if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) .setError("one or more path parameters are not set, please check and try again") - .toMap()).build(); + .toMap()).build(); } EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DELETE_FROM_TABLE)) { @@ -1146,7 +1144,7 @@ public class RestMusicDataAPI { if(delObj == null) { logger.error(EELFLoggerDelegate.errorLogger,"Required HTTP Request body is missing.", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build(); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build(); } PreparedQueryObject queryObject = new PreparedQueryObject(); StringBuilder columnString = new StringBuilder(); @@ -1189,10 +1187,11 @@ public class RestMusicDataAPI { } // get the conditional, if any Condition conditionInfo; - if (delObj.getConditions() == null) + if (delObj.getConditions() == null) { conditionInfo = null; - else {// to avoid parsing repeatedly, just send the select query to - // obtain row + } else { + // to avoid parsing repeatedly, just send the select query to + // obtain row PreparedQueryObject selectQuery = new PreparedQueryObject(); selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";"); @@ -1234,9 +1233,8 @@ public class RestMusicDataAPI { operationResult = MusicCore.eventualPut_nb(queryObject, keyspace, tablename, rowId.primarKeyValue); } } catch (MusicLockingException e) { - logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes - .GENERALSERVICEERROR, e); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) .setError("Unable to perform Delete operation. Exception from music").toMap()).build(); } if (operationResult==null) { @@ -1247,7 +1245,7 @@ public class RestMusicDataAPI { return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build(); } else { logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build(); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build(); } } finally { EELFLoggerDelegate.mdcRemove("keyspace"); @@ -1284,8 +1282,8 @@ public class RestMusicDataAPI { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("one or more path parameters are not set, please check and try again") - .toMap()).build(); + .setError("one or more path parameters are not set, please check and try again") + .toMap()).build(); } EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.DROP_TABLE)) { @@ -1345,8 +1343,8 @@ public class RestMusicDataAPI { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("one or more path parameters are not set, please check and try again") - .toMap()).build(); + .setError("one or more path parameters are not set, please check and try again") + .toMap()).build(); } EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT_CRITICAL)) { @@ -1369,24 +1367,27 @@ public class RestMusicDataAPI { return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); } queryObject.appendQueryString( - "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";"); + "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";"); ResultSet results = null; String consistency = selObj.getConsistencyInfo().get("type"); - + try { if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) { if(lockId == null) { logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or" - + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR); + + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock " - + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build(); + + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build(); } - results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject, - lockId); + results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,lockId); } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) { results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject); } + }catch(Exception ex) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); + } + if(results!=null && results.getAvailableWithoutFetching() >0) { return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build(); } @@ -1429,8 +1430,8 @@ public class RestMusicDataAPI { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); if((keyspace == null || keyspace.isEmpty()) || (tablename == null || tablename.isEmpty())){ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("one or more path parameters are not set, please check and try again") - .toMap()).build(); + .setError("one or more path parameters are not set, please check and try again") + .toMap()).build(); } EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspace+" ) "); if (!authenticator.authenticateUser(ns, authorization, keyspace, aid, Operation.SELECT)) { @@ -1531,10 +1532,10 @@ public class RestMusicDataAPI { DataType colType = null; Object formattedValue = null; try { - colType = tableInfo.getColumn(entry.getKey()).getType(); - formattedValue = MusicUtil.convertToActualDataType(colType, indValue); + colType = tableInfo.getColumn(entry.getKey()).getType(); + formattedValue = MusicUtil.convertToActualDataType(colType, indValue); } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger,e); + logger.error(EELFLoggerDelegate.errorLogger,e); } if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey())) primaryKey.append(indValue); diff --git a/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java b/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java index 77c6ef1f..49b2d816 100644 --- a/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java @@ -47,6 +47,7 @@ import org.onap.music.eelf.logging.EELFLoggerDelegate; import org.onap.music.eelf.logging.format.AppMessages; import org.onap.music.eelf.logging.format.ErrorSeverity; import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicLockingException; import org.onap.music.lockingservice.cassandra.MusicLockState; import org.onap.music.main.MusicCore; import org.onap.music.main.MusicUtil; @@ -67,7 +68,7 @@ public class RestMusicLocksAPI { private static final String XMINORVERSION = "X-minorVersion"; private static final String XPATCHVERSION = "X-patchVersion"; private static final String VERSION = "v2"; - + private MusicAuthenticator authenticator = new MusicAAFAuthentication(); /** @@ -113,7 +114,12 @@ public class RestMusicLocksAPI { } ResultType status = ResultType.SUCCESS; - String lockId = MusicCore.createLockReference(lockName); + String lockId; + try { + lockId= MusicCore.createLockReference(lockName); + } catch (MusicLockingException e) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build(); + } if (lockId == null) { status = ResultType.FAILURE; @@ -328,28 +334,13 @@ public class RestMusicLocksAPI { return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build(); } finally { EELFLoggerDelegate.mdcRemove("keyspace"); - } - - //MusicLockState mls = MusicZKCore.getMusicLockState(lockName); -// Map<String,Object> returnMap = null; -// JsonResponse jsonResponse = new JsonResponse(ResultType.FAILURE).setLock(lockName); -// if(mls == null) { -// jsonResponse.setError(""); -// jsonResponse.setMessage("No lock object created yet.."); -// logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); -// return response.status(Status.BAD_REQUEST).entity(jsonResponse.toMap()).build(); -// } else { -// jsonResponse.setStatus(ResultType.SUCCESS); -// jsonResponse.setLockStatus(mls.getLockStatus()); -// jsonResponse.setLockHolder(mls.getLockHolder()); -// return response.status(Status.OK).entity(jsonResponse.toMap()).build(); -// } + } } /** * - * deletes the process from the zk queue + * deletes the process from the lock queue * * @param lockId * @throws Exception @@ -357,7 +348,7 @@ public class RestMusicLocksAPI { @DELETE @Path("/release/{lockreference}") @ApiOperation(value = "Release Lock", - notes = "deletes the process from the zk queue", + notes = "deletes the process from the lock queue", response = Map.class) @Produces(MediaType.APPLICATION_JSON) public Response unLock(@PathParam("lockreference") String lockId, @@ -412,14 +403,15 @@ public class RestMusicLocksAPI { } /** - * + * @deprecated * @param lockName * @throws Exception */ @DELETE @Path("/delete/{lockname}") - @ApiOperation(value = "Delete Lock", response = Map.class) - @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete Lock", response = Map.class, hidden = true, notes = "Deprecated") + @Produces(MediaType.APPLICATION_JSON) + @Deprecated public Response deleteLock(@PathParam("lockname") String lockName, @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, diff --git a/src/main/java/org/onap/music/rest/RestMusicQAPI.java b/src/main/java/org/onap/music/rest/RestMusicQAPI.java index f3df9350..3940c84a 100755 --- a/src/main/java/org/onap/music/rest/RestMusicQAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicQAPI.java @@ -70,8 +70,8 @@ import io.swagger.annotations.ApiParam; @Api(value = "Q Api") public class RestMusicQAPI { - private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicQAPI.class); - + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicQAPI.class); + /** * @@ -81,138 +81,135 @@ public class RestMusicQAPI { * @throws Exception */ - @POST - @Path("/keyspaces/{keyspace}/{qname}") // qname same as tablename - @ApiOperation(value = "Create Q", response = String.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response createQ( - @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version", - required = false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value = "Patch Version", - required = false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - JsonTable tableObj, - @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @POST + @Path("/keyspaces/{keyspace}/{qname}") // qname same as tablename + @ApiOperation(value = "Create Q", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonTable tableObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception { - ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); - Map<String, String> fields = tableObj.getFields(); + Map<String, String> fields = tableObj.getFields(); if (fields == null) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) - .entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ/Required table fields are empty or not set").toMap()) - .build(); - } - - String primaryKey = tableObj.getPrimaryKey(); - String partitionKey = tableObj.getPartitionKey(); - String clusteringKey = tableObj.getClusteringKey(); - String filteringKey = tableObj.getFilteringKey(); - String clusteringOrder = tableObj.getClusteringOrder(); - - if(primaryKey == null) { - primaryKey = tableObj.getFields().get("PRIMARY KEY"); - } - - if ((primaryKey == null) && (partitionKey == null)) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) + return response.status(Status.BAD_REQUEST) .entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ: Partition key cannot be empty").toMap()) + .setError("CreateQ/Required table fields are empty or not set").toMap()) .build(); - } + } - if ((primaryKey == null) && (clusteringKey == null)) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) - .entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ: Clustering key cannot be empty").toMap()) - .build(); - } + String primaryKey = tableObj.getPrimaryKey(); + String partitionKey = tableObj.getPartitionKey(); + String clusteringKey = tableObj.getClusteringKey(); + String filteringKey = tableObj.getFilteringKey(); + String clusteringOrder = tableObj.getClusteringOrder(); - if (clusteringOrder == null) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) - .entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ: Clustering Order cannot be empty").toMap()) - .build(); - } + if(primaryKey == null) { + primaryKey = tableObj.getFields().get("PRIMARY KEY"); + } - if ((primaryKey!=null) && (partitionKey == null)) { - primaryKey = primaryKey.trim(); - int count1 = StringUtils.countMatches(primaryKey,')'); - int count2 = StringUtils.countMatches(primaryKey,'('); - if (count1 != count2) { - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ Error: primary key '(' and ')' do not match, primary key=" + primaryKey) - .toMap()).build(); + if ((primaryKey == null) && (partitionKey == null)) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Partition key cannot be empty").toMap()) + .build(); } - if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) ) - { - if (primaryKey.contains(",") ) { - partitionKey= primaryKey.substring(0,primaryKey.indexOf(',')); - partitionKey=partitionKey.replaceAll("[\\(]+",""); - clusteringKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index - clusteringKey=clusteringKey.replaceAll("[)]+", ""); + if ((primaryKey == null) && (clusteringKey == null)) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Clustering key cannot be empty").toMap()) + .build(); + } + + if (clusteringOrder == null) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Clustering Order cannot be empty").toMap()) + .build(); + } + + if ((primaryKey!=null) && (partitionKey == null)) { + primaryKey = primaryKey.trim(); + int count1 = StringUtils.countMatches(primaryKey,')'); + int count2 = StringUtils.countMatches(primaryKey,'('); + if (count1 != count2) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ Error: primary key '(' and ')' do not match, primary key=" + primaryKey) + .toMap()).build(); + } + + if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(')') +1) == primaryKey.length() ) ) { + if (primaryKey.contains(",") ) { + partitionKey= primaryKey.substring(0,primaryKey.indexOf(',')); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusteringKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index + clusteringKey=clusteringKey.replaceAll("[)]+", ""); + } else { + partitionKey=primaryKey; + partitionKey=partitionKey.replaceAll("[\\)]+",""); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusteringKey=""; + } } else { - partitionKey=primaryKey; - partitionKey=partitionKey.replaceAll("[\\)]+",""); - partitionKey=partitionKey.replaceAll("[\\(]+",""); - clusteringKey=""; - } - } else { - partitionKey= primaryKey.substring(0,primaryKey.indexOf(')')); - partitionKey=partitionKey.replaceAll("[\\(]+",""); - partitionKey = partitionKey.trim(); - clusteringKey= primaryKey.substring(primaryKey.indexOf(')')); - clusteringKey=clusteringKey.replaceAll("[\\(]+",""); - clusteringKey=clusteringKey.replaceAll("[\\)]+",""); - clusteringKey = clusteringKey.trim(); - if (clusteringKey.indexOf(',') == 0) clusteringKey=clusteringKey.substring(1); - clusteringKey = clusteringKey.trim(); - if (clusteringKey.equals(",") ) clusteringKey=""; // print error if needed ( ... ),) - } - } + partitionKey= primaryKey.substring(0,primaryKey.indexOf(')')); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + partitionKey = partitionKey.trim(); + clusteringKey= primaryKey.substring(primaryKey.indexOf(')')); + clusteringKey=clusteringKey.replaceAll("[\\(]+",""); + clusteringKey=clusteringKey.replaceAll("[\\)]+",""); + clusteringKey = clusteringKey.trim(); + if (clusteringKey.indexOf(',') == 0) clusteringKey=clusteringKey.substring(1); + clusteringKey = clusteringKey.trim(); + if (clusteringKey.equals(",") ) clusteringKey=""; // print error if needed ( ... ),) + } + } - if (partitionKey.trim().isEmpty()) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + if (partitionKey.trim().isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) + return response.status(Status.BAD_REQUEST) .entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ: Partition key cannot be empty").toMap()) + .setError("CreateQ: Partition key cannot be empty").toMap()) .build(); - } + } - if (clusteringKey.trim().isEmpty()) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + if (clusteringKey.trim().isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) + return response.status(Status.BAD_REQUEST) .entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ: Clustering key cannot be empty").toMap()) + .setError("CreateQ: Clustering key cannot be empty").toMap()) .build(); - } + } - if((filteringKey != null) && (filteringKey.equalsIgnoreCase(partitionKey))) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + if((filteringKey != null) && (filteringKey.equalsIgnoreCase(partitionKey))) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) + return response.status(Status.BAD_REQUEST) .entity(new JsonResponse(ResultType.FAILURE) - .setError("CreateQ: Filtering key cannot be same as Partition Key").toMap()) + .setError("CreateQ: Filtering key cannot be same as Partition Key").toMap()) .build(); - } + } - return new RestMusicDataAPI().createTable(version, minorVersion, patchVersion, aid, ns, authorization, tableObj, keyspace, tablename); - } + return new RestMusicDataAPI().createTable(version, minorVersion, patchVersion, aid, ns, authorization, tableObj, keyspace, tablename); + } /** * @@ -221,234 +218,225 @@ public class RestMusicQAPI { * @param tablename * @throws Exception */ - @POST - @Path("/keyspaces/{keyspace}/{qname}/rows") - @ApiOperation(value = "", response = Void.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - // public Map<String, Object> insertIntoQ( - public Response insertIntoQ( - @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version", - required = false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value = "Patch Version", - required = false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - JsonInsert insObj, - @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, - @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) - { - ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); - if (insObj.getValues().isEmpty()) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("Required HTTP Request body is missing.").toMap()).build(); - } - return new RestMusicDataAPI().insertIntoTable(version, minorVersion, patchVersion, aid, ns, + @POST + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "", response = Void.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + // public Map<String, Object> insertIntoQ( + public Response insertIntoQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonInsert insObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) { + + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + if (insObj.getValues().isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Required HTTP Request body is missing.").toMap()).build(); + } + return new RestMusicDataAPI().insertIntoTable(version, minorVersion, patchVersion, aid, ns, authorization, insObj, keyspace, tablename); - } - - /** - * - * @param updateObj - * @param keyspace - * @param tablename - * @param info - * @return - * @throws Exception - */ - @PUT - @Path("/keyspaces/{keyspace}/{qname}/rows") - @ApiOperation(value = "updateQ", response = String.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response updateQ( - @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version", - required = false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value = "Patch Version", - required = false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - JsonUpdate updateObj, - @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, - @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, - @Context UriInfo info) throws MusicServiceException, MusicQueryException { - - ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); - if (updateObj.getValues().isEmpty()) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST) - .entity(new JsonResponse(ResultType.FAILURE).setError( - "Required HTTP Request body is missing. JsonUpdate updateObj.getValues() is empty. ") - .toMap()) - .build(); - - } - return new RestMusicDataAPI().updateTable(version, minorVersion, patchVersion, aid, ns, - authorization,updateObj, keyspace, tablename, info); - } - /** - * - * @param delObj - * @param keyspace - * @param tablename - * @param info - * - * @return - * @throws Exception - */ + /** + * + * @param updateObj + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @PUT + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "updateQ", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonUpdate updateObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + @Context UriInfo info) throws MusicServiceException, MusicQueryException { + + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + if (updateObj.getValues().isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("Required HTTP Request body is missing. JsonUpdate updateObj.getValues() is empty. ") + .toMap()) + .build(); + } + return new RestMusicDataAPI().updateTable(version, minorVersion, patchVersion, aid, ns, + authorization,updateObj, keyspace, tablename, info); + } - @DELETE - @Path("/keyspaces/{keyspace}/{qname}/rows") - @ApiOperation(value = "deleteQ", response = String.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response deleteFromQ( - @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version", - required = false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value = "Patch Version", - required = false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - JsonDelete delObj, - @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, - @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + /** + * + * @param delObj + * @param keyspace + * @param tablename + * @param info + * + * @return + * @throws Exception + */ + + @DELETE + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "deleteQ", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteFromQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonDelete delObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, @Context UriInfo info) throws MusicServiceException, MusicQueryException { // added checking as per RestMusicDataAPI ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); if (delObj == null) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, - ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) - .setError("deleteFromQ JsonDelete delObjis empty").toMap()).build(); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("deleteFromQ JsonDelete delObjis empty").toMap()).build(); } - return new RestMusicDataAPI().deleteFromTable(version, minorVersion, patchVersion, aid, ns, - authorization, delObj, keyspace, tablename, info); - } + return new RestMusicDataAPI().deleteFromTable(version, minorVersion, patchVersion, aid, ns, + authorization, delObj, keyspace, tablename, info); + } - /** - * - * @param keyspace - * @param tablename - * @param info - * @return - * @throws Exception - */ - @GET - @Path("/keyspaces/{keyspace}/{qname}/peek") - @ApiOperation(value = "", response = Map.class) - @Produces(MediaType.APPLICATION_JSON) - //public Map<String, HashMap<String, Object>> peek( - public Response peek( - @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version", - required = false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value = "Patch Version", - required = false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, - @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + /** + * + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @GET + @Path("/keyspaces/{keyspace}/{qname}/peek") + @ApiOperation(value = "", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + //public Map<String, HashMap<String, Object>> peek( + public Response peek( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, @Context UriInfo info) { - int limit =1; //peek must return just the top row - Map<String ,String> auth = new HashMap<>(); - String userId =auth.get(MusicUtil.USERID); - String password =auth.get(MusicUtil.PASSWORD); - ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); - - PreparedQueryObject queryObject = new PreparedQueryObject(); - if (info.getQueryParameters() == null ) //|| info.getQueryParameters().isEmpty()) - queryObject.appendQueryString( - "SELECT * FROM " + keyspace + "." + tablename + " LIMIT " + limit + ";"); - else { - - try { - queryObject = new RestMusicDataAPI().selectSpecificQuery(keyspace, tablename, info, limit); - } catch (MusicServiceException ex) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR, + int limit =1; //peek must return just the top row + Map<String ,String> auth = new HashMap<>(); + String userId =auth.get(MusicUtil.USERID); + String password =auth.get(MusicUtil.PASSWORD); + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + + PreparedQueryObject queryObject = new PreparedQueryObject(); + if (info.getQueryParameters() == null ) { //|| info.getQueryParameters().isEmpty()) + queryObject.appendQueryString( + "SELECT * FROM " + keyspace + "." + tablename + " LIMIT " + limit + ";"); + } else { + try { + queryObject = new RestMusicDataAPI().selectSpecificQuery(keyspace, tablename, info, limit); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR, ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, ex); - return response.status(Status.BAD_REQUEST) + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()) + .build(); + } + } + + try { + ResultSet results = MusicCore.get(queryObject); + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS) + .setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build(); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR, + ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR, ex); + return response.status(Status.BAD_REQUEST) .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()) .build(); - } + } } - try { - ResultSet results = MusicCore.get(queryObject); - return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS) - .setDataResult(MusicDataStoreHandle.marshallResults(results)).toMap()).build(); - } catch (MusicServiceException ex) { - logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR, - ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR, ex); - return response.status(Status.BAD_REQUEST) - .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()) - .build(); - } - } + /** + * + * + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @GET + @Path("/keyspaces/{keyspace}/{qname}/filter") + @ApiOperation(value = "filter", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + // public Map<String, HashMap<String, Object>> filter( + public Response filter( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + @Context UriInfo info) throws Exception { + + return new RestMusicDataAPI().select(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename, info);// , limit) - /** - * - * - * @param keyspace - * @param tablename - * @param info - * @return - * @throws Exception - */ - @GET - @Path("/keyspaces/{keyspace}/{qname}/filter") - @ApiOperation(value = "filter", response = Map.class) - @Produces(MediaType.APPLICATION_JSON) - // public Map<String, HashMap<String, Object>> filter( - public Response filter( - @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version", required = false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value = "Patch Version", required = false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, - @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, - @Context UriInfo info) throws Exception { - return new RestMusicDataAPI().select(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename, info);// , limit) - - } + } - /** - * - * @param tabObj - * @param keyspace - * @param tablename - * @throws Exception - */ - @DELETE - @ApiOperation(value = "DropQ", response = String.class) - @Path("/keyspaces/{keyspace}/{qname}") - @Produces(MediaType.APPLICATION_JSON) - public Response dropQ( - @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, - @ApiParam(value = "Minor Version", - required = false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value = "Patch Version", - required = false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, - @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, - @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + /** + * + * @param tabObj + * @param keyspace + * @param tablename + * @throws Exception + */ + @DELETE + @ApiOperation(value = "DropQ", response = String.class) + @Path("/keyspaces/{keyspace}/{qname}") + @Produces(MediaType.APPLICATION_JSON) + public Response dropQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = false) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) throws Exception { - return new RestMusicDataAPI().dropTable(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename); - } + return new RestMusicDataAPI().dropTable(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename); + + } } diff --git a/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java b/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java index 74b8e5dd..94540eb1 100644 --- a/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java @@ -47,10 +47,10 @@ import io.swagger.annotations.ApiOperation; @Api(value="Version Api") public class RestMusicVersionAPI { - private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicVersionAPI.class); + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicVersionAPI.class); /** - * Get the version of MUSIC + * Get the version of MUSIC. * @return */ @GET @@ -59,6 +59,25 @@ public class RestMusicVersionAPI { public Map<String,Object> version(@Context HttpServletResponse response) { logger.info("Replying to request for MUSIC version with MUSIC:" + MusicUtil.getVersion()); response.addHeader("X-latestVersion",MusicUtil.getVersion()); - return new JsonResponse(ResultType.SUCCESS).setMusicVersion("MUSIC:" + MusicUtil.getVersion()).toMap(); + return new JsonResponse(ResultType.SUCCESS). + setMusicVersion("MUSIC:" + MusicUtil.getVersion()).toMap(); } + + /** + * Get the version of MUSIC. + * @return + */ + @GET + @Path("/build") + @ApiOperation(value = "Get Version", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Map<String,Object> build(@Context HttpServletResponse response) { + logger.info("Replying to request for MUSIC build with MUSIC:" + MusicUtil.getBuild()); + response.addHeader("X-latestVersion",MusicUtil.getVersion()); + return new JsonResponse(ResultType.SUCCESS) + .setMusicBuild("MUSIC:" + MusicUtil.getBuild()) + .setMusicVersion("MUSIC:" + MusicUtil.getVersion()).toMap(); + } + + }
\ No newline at end of file diff --git a/src/main/java/org/onap/music/service/MusicCoreService.java b/src/main/java/org/onap/music/service/MusicCoreService.java index affdc7f2..61e4905e 100644 --- a/src/main/java/org/onap/music/service/MusicCoreService.java +++ b/src/main/java/org/onap/music/service/MusicCoreService.java @@ -47,47 +47,47 @@ public interface MusicCoreService { public ReturnType eventualPut_nb(PreparedQueryObject queryObject,String keyspace,String tablename,String primaryKey); public ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject, String lockId, Condition conditionInfo); + PreparedQueryObject queryObject, String lockId, Condition conditionInfo); public ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) - throws MusicServiceException; + throws MusicServiceException; public ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException; public ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException, MusicQueryException; + PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException, MusicQueryException; public ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException; + PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException; public ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException; + PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException; public ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject, Condition conditionInfo) - throws MusicLockingException, MusicQueryException, MusicServiceException; + PreparedQueryObject queryObject, Condition conditionInfo) + throws MusicLockingException, MusicQueryException, MusicServiceException; public ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject, String lockId) throws MusicServiceException; + PreparedQueryObject queryObject, String lockId) throws MusicServiceException; // Core Music Locking Service Methods - public String createLockReference(String fullyQualifiedKey); // lock name + public String createLockReference(String fullyQualifiedKey) throws MusicLockingException; // lock name public ReturnType acquireLockWithLease(String key, String lockReference, long leasePeriod) - throws MusicLockingException, MusicQueryException, MusicServiceException; // key,lock id,time + throws MusicLockingException, MusicQueryException, MusicServiceException; // key,lock id,time public ReturnType acquireLock(String key, String lockReference) - throws MusicLockingException, MusicQueryException, MusicServiceException; // key,lock id + throws MusicLockingException, MusicQueryException, MusicServiceException; // key,lock id public ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject, - String consistency) throws MusicServiceException; + String consistency) throws MusicServiceException; public ResultSet quorumGet(PreparedQueryObject query); public String whoseTurnIsIt(String fullyQualifiedKey);// lock name - public void destroyLockRef(String lockId); + public void destroyLockRef(String lockId) throws MusicLockingException; //public MusicLockState destroyLockRef(String fullyQualifiedKey, String lockReference); // lock name, lock id @@ -99,12 +99,12 @@ public interface MusicCoreService { //public MusicLockState forciblyReleaseLock(String fullyQualifiedKey, String lockReference) throws MusicLockingException, MusicServiceException, MusicQueryException; public List<String> getLockQueue(String fullyQualifiedKey) - throws MusicServiceException, MusicQueryException, MusicLockingException; + throws MusicServiceException, MusicQueryException, MusicLockingException; - public long getLockQueueSize(String fullyQualifiedKey) - throws MusicServiceException, MusicQueryException, MusicLockingException; + public long getLockQueueSize(String fullyQualifiedKey) + throws MusicServiceException, MusicQueryException, MusicLockingException; public Map<String, Object> validateLock(String lockName); - public MusicLockState releaseLock(String lockId, boolean voluntaryRelease); + public MusicLockState releaseLock(String lockId, boolean voluntaryRelease) throws MusicLockingException; } diff --git a/src/main/java/org/onap/music/service/impl/MusicCassaCore.java b/src/main/java/org/onap/music/service/impl/MusicCassaCore.java index 2c10c91a..ed5005c1 100644 --- a/src/main/java/org/onap/music/service/impl/MusicCassaCore.java +++ b/src/main/java/org/onap/music/service/impl/MusicCassaCore.java @@ -29,6 +29,7 @@ import java.io.StringWriter; import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.concurrent.TimeUnit; import org.onap.music.datastore.MusicDataStore; import org.onap.music.datastore.MusicDataStoreHandle; @@ -49,6 +50,7 @@ import org.onap.music.main.ResultType; import org.onap.music.main.ReturnType; import org.onap.music.service.MusicCoreService; +import com.att.eelf.configuration.EELFLogger; import com.datastax.driver.core.DataType; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; @@ -93,7 +95,7 @@ public class MusicCassaCore implements MusicCoreService { - public String createLockReference(String fullyQualifiedKey) { + public String createLockReference(String fullyQualifiedKey) throws MusicLockingException { String[] splitString = fullyQualifiedKey.split("\\."); String keyspace = splitString[0]; String table = splitString[1]; @@ -102,11 +104,15 @@ public class MusicCassaCore implements MusicCoreService { logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName); long start = System.currentTimeMillis(); String lockReference = null; + try { lockReference = "" + getLockingServiceHandle().genLockRefandEnQueue(keyspace, table, lockName); } catch (MusicLockingException | MusicServiceException | MusicQueryException e) { e.printStackTrace(); + throw new MusicLockingException("Unable to create lock reference. " + e.getMessage()); + } catch (Exception e) { logger.error(EELFLoggerDelegate.applicationLogger, e); + throw new MusicLockingException("Unable to create lock reference. " + e.getMessage()); } long end = System.currentTimeMillis(); logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms"); @@ -115,7 +121,7 @@ public class MusicCassaCore implements MusicCoreService { public ReturnType acquireLockWithLease(String fullyQualifiedKey, String lockReference, long leasePeriod) throws MusicLockingException, MusicQueryException, MusicServiceException { - evictExpiredLockHolder(fullyQualifiedKey,leasePeriod); + evictExpiredLockHolder(fullyQualifiedKey,leasePeriod); return acquireLock(fullyQualifiedKey, lockReference); } @@ -127,21 +133,28 @@ public class MusicCassaCore implements MusicCoreService { String primaryKeyValue = splitString[2]; LockObject currentLockHolderObject = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue); - - /* Release the lock of the previous holder if it has expired. if the update to the acquire time has not reached due to network delays, simply use the create time as the + + if (currentLockHolderObject==null) { //no lock holder + return; + } + /* Release the lock of the previous holder if it has expired. if the update to the acquire time has not reached due to network delays, simply use the create time as the * reference*/ - long referenceTime = Math.max(Long.parseLong(currentLockHolderObject.acquireTime), Long.parseLong(currentLockHolderObject.createTime)); if((System.currentTimeMillis() - referenceTime) > leasePeriod) { forciblyReleaseLock(fullyQualifiedKey, currentLockHolderObject.lockRef+""); logger.info(EELFLoggerDelegate.applicationLogger, currentLockHolderObject.lockRef+" forcibly released"); - } + } } - + private static ReturnType isTopOfLockStore(String keyspace, String table, String primaryKeyValue, String lockReference) throws MusicLockingException, MusicQueryException, MusicServiceException { - //return failure to lock holders too early or already evicted from the lock store - String topOfLockStoreS = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue).lockRef; + LockObject topOfLockStore = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue); + if (topOfLockStore==null) { + logger.info(EELFLoggerDelegate.applicationLogger, lockReference+" is not the lock holder yet"); + return new ReturnType(ResultType.FAILURE, "No lock holder!"); + } + + String topOfLockStoreS = topOfLockStore.lockRef; long topOfLockStoreL = Long.parseLong(topOfLockStoreS); long lockReferenceL = Long.parseLong(lockReference); @@ -150,13 +163,12 @@ public class MusicCassaCore implements MusicCoreService { return new ReturnType(ResultType.FAILURE, lockReference+" is not the lock holder yet"); } - if(lockReferenceL < topOfLockStoreL) { logger.info(EELFLoggerDelegate.applicationLogger, lockReference+" is no longer/or was never in the lock store queue"); return new ReturnType(ResultType.FAILURE, lockReference+" is no longer/or was never in the lock store queue"); - } + } - return new ReturnType(ResultType.SUCCESS, lockReference+" is top of lock store"); + return new ReturnType(ResultType.SUCCESS, lockReference+" is top of lock store"); } public ReturnType acquireLock(String fullyQualifiedKey, String lockId) @@ -185,12 +197,12 @@ public class MusicCassaCore implements MusicCoreService { syncQuorum(keyspace, table, primaryKeyValue); } catch (Exception e) { StringWriter sw = new StringWriter(); - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ", - ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR, e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ", + ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR, e); String exceptionAsString = sw.toString(); return new ReturnType(ResultType.FAILURE, "Exception thrown while syncing key:\n" + exceptionAsString); } - String cleanQuery = "delete from music_internal.unsynced_keys where key='"+localFullyQualifiedKey+"';"; + String cleanQuery = "delete from " + syncTable + " where key='"+localFullyQualifiedKey+"';"; PreparedQueryObject deleteQueryObject = new PreparedQueryObject(); deleteQueryObject.appendQueryString(cleanQuery); MusicDataStoreHandle.getDSHandle().executePut(deleteQueryObject, "critical"); @@ -252,8 +264,8 @@ public class MusicCassaCore implements MusicCoreService { // get the primary key d TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, table); - String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single - // primary key + String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName(); // we only support single + // primary key DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType(); Object cqlFormattedPrimaryKeyValue = MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue); @@ -296,7 +308,11 @@ public class MusicCassaCore implements MusicCoreService { String table = splitString[1]; String primaryKeyValue = splitString[2]; try { - return "$" + fullyQualifiedKey + "$" + LockObject lockOwner = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue); + if (lockOwner==null) { + return "No lock holder!"; + } + return "$" + fullyQualifiedKey + "$" + getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue).lockRef; } catch (MusicLockingException | MusicServiceException | MusicQueryException e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+fullyQualifiedKey @@ -316,7 +332,7 @@ public class MusicCassaCore implements MusicCoreService { } @Override - public void destroyLockRef(String lockId) { + public void destroyLockRef(String lockId) throws MusicLockingException { long start = System.currentTimeMillis(); String fullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$")); String lockRef = lockId.substring(lockId.lastIndexOf('$')+1); @@ -325,26 +341,28 @@ public class MusicCassaCore implements MusicCoreService { String table = splitString[1]; String primaryKeyValue = splitString[2]; try { - getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockRef); + getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockRef,MusicUtil.getRetryCount()); } catch (MusicLockingException | MusicServiceException | MusicQueryException e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockRef , + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockRef, ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR, e); + throw new MusicLockingException(e.getMessage()); } long end = System.currentTimeMillis(); logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms"); } - public MusicLockState destroyLockRef(String fullyQualifiedKey, String lockReference) { + public MusicLockState destroyLockRef(String fullyQualifiedKey, String lockReference) throws MusicLockingException { long start = System.currentTimeMillis(); String[] splitString = fullyQualifiedKey.split("\\."); String keyspace = splitString[0]; String table = splitString[1]; String primaryKeyValue = splitString[2]; try { - getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockReference); + getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockReference,MusicUtil.getRetryCount()); } catch (MusicLockingException | MusicServiceException | MusicQueryException e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockReference , - ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR, e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK + lockReference, + ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR,e); + throw new MusicLockingException(e.getMessage()); } long end = System.currentTimeMillis(); logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms"); @@ -352,7 +370,7 @@ public class MusicCassaCore implements MusicCoreService { } @Override - public MusicLockState releaseLock(String lockId, boolean voluntaryRelease) { + public MusicLockState releaseLock(String lockId, boolean voluntaryRelease) throws MusicLockingException { String fullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$")); String lockRef = lockId.substring(lockId.lastIndexOf('$')+1); if (voluntaryRelease) { @@ -362,11 +380,19 @@ public class MusicCassaCore implements MusicCoreService { } } - public MusicLockState voluntaryReleaseLock(String fullyQualifiedKey, String lockReference) { - return destroyLockRef(fullyQualifiedKey, lockReference); + public MusicLockState voluntaryReleaseLock(String fullyQualifiedKey, String lockReference) throws MusicLockingException { + MusicLockState result = null; + try { + result = destroyLockRef(fullyQualifiedKey, lockReference); + } + catch(Exception ex) { + logger.info(EELFLoggerDelegate.applicationLogger,"Exception in voluntaryReleaseLock() for "+ fullyQualifiedKey + "ref: " + lockReference); + throw new MusicLockingException(ex.getMessage()); + } + return result; } - public MusicLockState forciblyReleaseLock(String fullyQualifiedKey, String lockReference) { + public MusicLockState forciblyReleaseLock(String fullyQualifiedKey, String lockReference) throws MusicLockingException { String[] splitString = fullyQualifiedKey.split("\\."); String keyspace = splitString[0]; String table = splitString[1]; @@ -394,9 +420,10 @@ public class MusicCassaCore implements MusicCoreService { * @param lockName * @throws MusicLockingException */ + @Deprecated public void deleteLock(String lockName) throws MusicLockingException { - //deprecated - } + throw new MusicLockingException("Depreciated Method Delete Lock"); + } // Prepared Query Additions. @@ -411,7 +438,7 @@ public class MusicCassaCore implements MusicCoreService { try { result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL); } catch (MusicServiceException | MusicQueryException ex) { - logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " " + ex); return new ReturnType(ResultType.FAILURE, ex.getMessage()); } @@ -457,8 +484,9 @@ public class MusicCassaCore implements MusicCoreService { try { result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL); } catch (MusicServiceException | MusicQueryException ex) { - logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); - logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause(), ex); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(),"[ERR512E] Failed to get Lock Handle ", + ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " ", ex); return new ReturnType(ResultType.FAILURE, ex.getMessage()); } if (result) { @@ -488,21 +516,20 @@ public class MusicCassaCore implements MusicCoreService { if (conditionInfo != null) try { - if (conditionInfo.testCondition() == false) - return new ReturnType(ResultType.FAILURE, - "Lock acquired but the condition is not true"); + if (conditionInfo.testCondition() == false) + return new ReturnType(ResultType.FAILURE, + "Lock acquired but the condition is not true"); } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, e); - return new ReturnType(ResultType.FAILURE, - "Exception thrown while checking the condition, check its sanctity:\n" - + e.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger, e); + return new ReturnType(ResultType.FAILURE, + "Exception thrown while checking the condition, check its sanctity:\n" + + e.getMessage()); } - - String query = queryObject.getQuery(); - long timeOfWrite = System.currentTimeMillis(); - long lockOrdinal = Long.parseLong(lockId.substring(lockId.lastIndexOf("$")+1)); - long ts = MusicUtil.v2sTimeStampInMicroseconds(lockOrdinal, timeOfWrite); - // TODO: use Statement instead of modifying query + String query = queryObject.getQuery(); + long timeOfWrite = System.currentTimeMillis(); + long lockOrdinal = Long.parseLong(lockId.substring(lockId.lastIndexOf("$")+1)); + long ts = MusicUtil.v2sTimeStampInMicroseconds(lockOrdinal, timeOfWrite); + // TODO: use Statement instead of modifying query if (!queryObject.getQuery().contains("USING TIMESTAMP")) { if (queryObject.getOperation().equalsIgnoreCase("delete")) query = query.replaceFirst("WHERE", " USING TIMESTAMP " + ts + " WHERE "); @@ -511,18 +538,18 @@ public class MusicCassaCore implements MusicCoreService { else query = query.replaceFirst("SET", "USING TIMESTAMP " + ts + " SET"); } - queryObject.replaceQueryString(query); - MusicDataStore dsHandle = MusicDataStoreHandle.getDSHandle(); - dsHandle.executePut(queryObject, MusicUtil.CRITICAL); - long end = System.currentTimeMillis(); - logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms"); + queryObject.replaceQueryString(query); + MusicDataStore dsHandle = MusicDataStoreHandle.getDSHandle(); + dsHandle.executePut(queryObject, MusicUtil.CRITICAL); + long end = System.currentTimeMillis(); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms"); }catch (MusicQueryException | MusicServiceException | MusicLockingException e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), e); return new ReturnType(ResultType.FAILURE, - "Exception thrown while doing the critical put\n" - + e.getMessage()); + "Exception thrown while doing the critical put\n" + + e.getMessage()); } - return new ReturnType(ResultType.SUCCESS, "Update performed"); + return new ReturnType(ResultType.SUCCESS, "Update performed"); } @@ -613,33 +640,55 @@ public class MusicCassaCore implements MusicCoreService { String fullyQualifiedKey = keyspaceName + "." + tableName + "." + primaryKey; String lockId = createLockReference(fullyQualifiedKey); long lockCreationTime = System.currentTimeMillis(); - ReturnType lockAcqResult = acquireLock(fullyQualifiedKey, lockId); + ReturnType lockAcqResult = null; + logger.info(EELFLoggerDelegate.applicationLogger,"***Acquiring lock for atomicPut() query : " + queryObject.getQuery() + " : "+ primaryKey); + logger.info(EELFLoggerDelegate.applicationLogger,"***Acquiring lock for atomicPut() values: " + queryObject.getValues().toString()); + if(conditionInfo!=null) + logger.info(EELFLoggerDelegate.applicationLogger,"***Acquiring lock for atomicPut() conditions: " + conditionInfo.toString()); + try { + lockAcqResult = acquireLockWithLease(fullyQualifiedKey, lockId,MusicUtil.getDefaultLockLeasePeriod()); + }catch(MusicLockingException ex) { + logger.error(EELFLoggerDelegate.errorLogger,"Exception while acquireLockWithLease() in atomic put for key: "+primaryKey); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage()); + throw new MusicServiceException("Cannot perform atomic put for key: "+primaryKey+ " : "+ ex.getMessage()); + } long lockAcqTime = System.currentTimeMillis(); - if (!lockAcqResult.getResult().equals(ResultType.SUCCESS)) { - logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); - voluntaryReleaseLock(fullyQualifiedKey,lockId); - return lockAcqResult; - } + /* + * if (!lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + * logger.info(EELFLoggerDelegate. + * applicationLogger,"unable to acquire lock, id " + lockId); + * voluntaryReleaseLock(fullyQualifiedKey,lockId); return lockAcqResult; } + */ logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); String lockRef = lockId.substring(lockId.lastIndexOf("$")); - ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, - queryObject, lockRef, conditionInfo); - long criticalPutTime = System.currentTimeMillis(); - voluntaryReleaseLock(fullyQualifiedKey,lockId); - long lockDeleteTime = System.currentTimeMillis(); - String timingInfo = "|lock creation time:" + (lockCreationTime - start) - + "|lock accquire time:" + (lockAcqTime - lockCreationTime) - + "|critical put time:" + (criticalPutTime - lockAcqTime) + ReturnType criticalPutResult = null ; + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, queryObject, lockRef, + conditionInfo); + long criticalPutTime = System.currentTimeMillis(); + long lockDeleteTime = System.currentTimeMillis(); + String timingInfo = "|lock creation time:" + (lockCreationTime - start) + "|lock accquire time:" + + (lockAcqTime - lockCreationTime) + "|critical put time:" + (criticalPutTime - lockAcqTime) + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|"; - criticalPutResult.setTimingInfo(timingInfo); + criticalPutResult.setTimingInfo(timingInfo); + }else { + logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); + criticalPutResult = lockAcqResult; + } + try { + voluntaryReleaseLock(fullyQualifiedKey, lockId); + + } catch (MusicLockingException ex) { + logger.info(EELFLoggerDelegate.applicationLogger,"Exception occured while deleting lock after atomic put for key: "+primaryKey); + criticalPutResult.setMessage(criticalPutResult.getMessage()+ "Lock release failed"); + } return criticalPutResult; } - /** * This method performs DDL operation on cassasndra, when the lock for the resource is acquired. * @@ -657,19 +706,32 @@ public class MusicCassaCore implements MusicCoreService { String fullyQualifiedKey = keyspaceName + "." + tableName + "." + primaryKey; String lockId = createLockReference(fullyQualifiedKey); long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); - ReturnType lockAcqResult = acquireLock(fullyQualifiedKey, lockId); + ReturnType lockAcqResult = null; + ResultSet result =null; + logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock for atomicGet() : " + queryObject.getQuery()); + try { + lockAcqResult = acquireLockWithLease(fullyQualifiedKey, lockId,MusicUtil.getDefaultLockLeasePeriod()); + }catch(MusicLockingException ex) { + logger.error(EELFLoggerDelegate.errorLogger,"Exception while acquireLockWithLease() in atomic get for key: "+primaryKey); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage()); + throw new MusicServiceException("Cannot perform atomic get for key: "+primaryKey+ " : "+ ex.getMessage()); + } if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); String lockRef = lockId.substring(lockId.lastIndexOf("$")); - ResultSet result = - criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockRef); - voluntaryReleaseLock(fullyQualifiedKey,lockId); - return result; + result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockRef); } else { - voluntaryReleaseLock(fullyQualifiedKey,lockId); logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); - return null; + } + try { + voluntaryReleaseLock(fullyQualifiedKey,lockId); + }catch(MusicLockingException ex) { + logger.info(EELFLoggerDelegate.applicationLogger,"Exception occured while deleting lock after atomic put for key: "+primaryKey); + throw new MusicLockingException(ex.getMessage()); + } + + return result; } @@ -683,14 +745,15 @@ public class MusicCassaCore implements MusicCoreService { } @Override + @Deprecated public ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException { - //Deprecated + PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException { return null; } + @Override public List<String> getLockQueue(String fullyQualifiedKey) - throws MusicServiceException, MusicQueryException, MusicLockingException { + throws MusicServiceException, MusicQueryException, MusicLockingException { String[] splitString = fullyQualifiedKey.split("\\."); String keyspace = splitString[0]; String table = splitString[1]; @@ -700,7 +763,7 @@ public class MusicCassaCore implements MusicCoreService { } @Override public long getLockQueueSize(String fullyQualifiedKey) - throws MusicServiceException, MusicQueryException, MusicLockingException { + throws MusicServiceException, MusicQueryException, MusicLockingException { String[] splitString = fullyQualifiedKey.split("\\."); String keyspace = splitString[0]; String table = splitString[1]; @@ -708,7 +771,9 @@ public class MusicCassaCore implements MusicCoreService { return getLockingServiceHandle().getLockQueueSize(keyspace, table, primaryKeyValue); } + @Override + @Deprecated public ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey, PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException { //deprecated diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 02e9c1a9..8b905be6 100755 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,8 @@ server.port=8080 -server.servlet.context-path=/MUSIC/rest
\ No newline at end of file +server.servlet.context-path=/MUSIC/rest +security.require-ssl=true +server.ssl.key-store=/opt/app/aafcertman/keystore.jks +server.ssl.key-store-password=changeit +server.ssl.key-store-provider=SUN +server.ssl.key-store-type=JKS +httpPort=8081 diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 8d3164f0..4f9c4358 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -1,302 +1,273 @@ <!-- - ============LICENSE_START========================================== - org.onap.music - =================================================================== - Copyright (c) 2017 AT&T Intellectual Property - =================================================================== - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ============LICENSE_END============================================= - ==================================================================== + ============LICENSE_START========================================== + org.onap.music + =================================================================== + Copyright (c) 2017 AT&T Intellectual Property + =================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ============LICENSE_END============================================= + ==================================================================== --> <configuration scan="true" scanPeriod="3 seconds"> - <!--<jmxConfigurator /> --> - <!-- directory path for all other type logs --> - <property name="logDir" value="/opt/app/music/logs" /> - - <!-- directory path for debugging type logs --> - <property name="debugDir" value="debug-logs" /> - - <!-- specify the component name --> - <!-- <property name="componentName" value="EELF"></property> --> - <property name="componentName" value="MUSIC"></property> - - <!-- log file names --> - <property name="generalLogName" value="music" /> - <property name="securityLogName" value="security" /> - <property name="errorLogName" value="error" /> - <property name="metricsLogName" value="metrics" /> - <property name="auditLogName" value="audit" /> - <property name="debugLogName" value="debug" /> - <property name="defaultPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" /> - <!-- <property name="applicationLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n" /> --> - <property name="applicationLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level %X{keyspace} - %msg%n" /> - <property name="auditLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" /> - <property name="metricsLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" /> - <!-- <property name="errorLoggerPattern" value= "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n " /> --> - <property name="errorLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level %X{keyspace} - %msg%n" /> - <property name="debugLoggerPattern" value="%date{ISO8601,UTC}|%X{RequestId}| %msg%n" ></property> - <property name="logDirectory" value="${logDir}/${componentName}" /> - <property name="debugLogDirectory" value="${debugDir}/${componentName}" /> - <!-- Example evaluator filter applied against console appender --> - <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <!--<jmxConfigurator /> --> + <!-- directory path for all other type logs --> + <property name="logDir" value="/opt/app/music/logs" /> + + <!-- directory path for debugging type logs --> + <property name="debugDir" value="debug-logs" /> + + <!-- specify the component name --> + <!-- <property name="componentName" value="EELF"></property> --> + <property name="componentName" value="MUSIC"></property> + + <!-- log file names --> + <property name="generalLogName" value="music" /> + <property name="securityLogName" value="security" /> + <property name="errorLogName" value="error" /> + <property name="metricsLogName" value="metrics" /> + <property name="auditLogName" value="audit" /> + <property name="debugLogName" value="debug" /> + <property name="defaultPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" /> + <!-- <property name="applicationLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n" /> --> + <property name="applicationLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level %X{keyspace} - %msg%n" /> + <property name="auditLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" /> + <property name="metricsLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" /> + <!-- <property name="errorLoggerPattern" value= "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n " /> --> + <property name="errorLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level %X{keyspace} - %msg%n" /> + <property name="debugLoggerPattern" value="%date{ISO8601,UTC}|%X{RequestId}| %msg%n" ></property> + <property name="logDirectory" value="${logDir}/${componentName}" /> + <property name="debugLogDirectory" value="${debugDir}/${componentName}" /> + <!-- Example evaluator filter applied against console appender --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- <encoder> - <pattern>${defaultPattern}</pattern> + <pattern>${defaultPattern}</pattern> </encoder> --> <layout class=""> - <pattern> - %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n - </pattern> - </layout> - </appender> - - <!-- ============================================================================ --> - <!-- EELF Appenders --> - <!-- ============================================================================ --> -<!-- <appender name="EELF" - class="ch.qos.logback.core.rolling.RollingFileAppender"> + <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> + </layout> + </appender> + + <!-- ============================================================================ --> + <!-- EELF Appenders --> + <!-- ============================================================================ --> + <!-- <appender name="EELF" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${logDirectory}/${generalLogName}.log</file> - <rollingPolicy - class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${logDirectory}/${generalLogName}.%i.log.zip - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>9</maxIndex> - </rollingPolicy> - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>100MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>${applicationLoggerPattern}</pattern> - </encoder> - </appender> --> - - <!-- <appender name="EELF" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${generalLogName}.%i.log.zip</fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>100MB</maxFileSize> + </triggeringPolicy> + <encoder> + <pattern>${applicationLoggerPattern}</pattern> + </encoder> + </appender> --> + + <!-- <appender name="EELF" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${logDirectory}/${generalLogName}.log</file> - <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> - daily rollover - <fileNamePattern>${logDirectory}/${generalLogName}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> - <maxFileSize>1GB</maxFileSize> - <maxHistory>5</maxHistory> - <totalSizeCap>5GB</totalSizeCap> - </rollingPolicy> - <encoder> - <pattern>${applicationLoggerPattern}</pattern> - </encoder> - </appender> --> - - - <appender name="EELF" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + daily rollover + <fileNamePattern>${logDirectory}/${generalLogName}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> + <maxFileSize>1GB</maxFileSize> + <maxHistory>5</maxHistory> + <totalSizeCap>5GB</totalSizeCap> + </rollingPolicy> + <encoder> + <pattern>${applicationLoggerPattern}</pattern> + </encoder> + </appender> --> + + + <appender name="EELF" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${logDirectory}/${generalLogName}.log</file> - <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> - <!-- daily rollover --> - <fileNamePattern>${logDirectory}/${generalLogName}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> - <maxFileSize>1GB</maxFileSize> - <maxHistory>5</maxHistory> - <totalSizeCap>5GB</totalSizeCap> - </rollingPolicy> - <encoder> - <pattern>${applicationLoggerPattern}</pattern> - </encoder> - </appender> - - <appender name="asyncEELF" class="ch.qos.logback.classic.AsyncAppender"> - <queueSize>256</queueSize> - <includeCallerData>true</includeCallerData> - <appender-ref ref="EELF" /> - </appender> - - <!-- EELF Security Appender. This appender is used to record security events + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <!-- daily rollover --> + <fileNamePattern>${logDirectory}/${generalLogName}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> + <maxFileSize>1GB</maxFileSize> + <maxHistory>5</maxHistory> + <totalSizeCap>5GB</totalSizeCap> + </rollingPolicy> + <encoder> + <pattern>${applicationLoggerPattern}</pattern> + </encoder> + </appender> + + <appender name="asyncEELF" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <includeCallerData>true</includeCallerData> + <appender-ref ref="EELF" /> + </appender> + + <!-- EELF Security Appender. This appender is used to record security events to the security log file. Security events are separate from other loggers in EELF so that security log records can be captured and managed in a secure way separate from the other logs. This appender is set to never discard any events. --> - <appender name="EELFSecurity" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${logDirectory}/${securityLogName}.log</file> - <rollingPolicy - class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${logDirectory}/${securityLogName}.%i.log.zip - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>9</maxIndex> - </rollingPolicy> - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>5MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n </pattern> - </encoder> - </appender> - - <appender name="asyncEELFSecurity" class="ch.qos.logback.classic.AsyncAppender"> - <queueSize>256</queueSize> - <discardingThreshold>0</discardingThreshold> - <appender-ref ref="EELFSecurity" /> - </appender> - - - - - <!-- EELF Audit Appender. This appender is used to record audit engine + <appender name="EELFSecurity" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/${securityLogName}.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${securityLogName}.%i.log.zip</fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n </pattern> + </encoder> + </appender> + + <appender name="asyncEELFSecurity" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <discardingThreshold>0</discardingThreshold> + <appender-ref ref="EELFSecurity" /> + </appender> + + + + + <!-- EELF Audit Appender. This appender is used to record audit engine related logging events. The audit logger and appender are specializations of the EELF application root logger and appender. This can be used to segregate Policy engine events from other components, or it can be eliminated to record these events as part of the application root log. --> - - <appender name="EELFAudit" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${logDirectory}/${auditLogName}.log</file> - <rollingPolicy - class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>9</maxIndex> - </rollingPolicy> - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>5MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>${auditLoggerPattern}</pattern> - </encoder> - </appender> - <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender"> - <queueSize>256</queueSize> - <appender-ref ref="EELFAudit" /> - </appender> - -<appender name="EELFMetrics" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${logDirectory}/${metricsLogName}.log</file> - <rollingPolicy - class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>9</maxIndex> - </rollingPolicy> - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>5MB</maxFileSize> - </triggeringPolicy> - <encoder> - <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - - %msg%n"</pattern> --> - <pattern>${metricsLoggerPattern}</pattern> - </encoder> - </appender> - - - <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender"> - <queueSize>256</queueSize> - <appender-ref ref="EELFMetrics"/> - </appender> - - <appender name="EELFError" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${logDirectory}/${errorLogName}.log</file> - <rollingPolicy - class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>9</maxIndex> - </rollingPolicy> - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>5MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>${errorLoggerPattern}</pattern> - </encoder> - </appender> - - <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender"> - <queueSize>256</queueSize> - <appender-ref ref="EELFError"/> - </appender> - - <appender name="EELFDebug" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${debugLogDirectory}/${debugLogName}.log</file> - <rollingPolicy - class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>9</maxIndex> - </rollingPolicy> - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>5MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>${debugLoggerPattern}</pattern> - </encoder> - </appender> - - <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender"> - <queueSize>256</queueSize> - <appender-ref ref="EELFDebug" /> - <includeCallerData>true</includeCallerData> - </appender> - - - <!-- ============================================================================ --> - <!-- EELF loggers --> - <!-- ============================================================================ --> - <logger name="com.att.eelf" level="info" additivity="false"> - <appender-ref ref="asyncEELF" /> - - </logger> - <logger name="com.att.eelf.security" level="info" additivity="false"> - <appender-ref ref="asyncEELFSecurity" /> - - </logger> + <appender name="EELFAudit" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/${auditLogName}.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip</fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <pattern>${auditLoggerPattern}</pattern> + </encoder> + </appender> + <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="EELFAudit" /> + </appender> - <logger name="com.att.eelf.audit" level="info" additivity="false"> - <appender-ref ref="asyncEELFAudit" /> - - </logger> - - <logger name="com.att.eelf.metrics" level="info" additivity="false"> + <appender name="EELFMetrics" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/${metricsLogName}.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n"</pattern> --> + <pattern>${metricsLoggerPattern}</pattern> + </encoder> + </appender> + + + <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="EELFMetrics"/> + </appender> + + <appender name="EELFError" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/${errorLogName}.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip</fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <pattern>${errorLoggerPattern}</pattern> + </encoder> + </appender> + + <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="EELFError"/> + </appender> + + <appender name="EELFDebug" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${debugLogDirectory}/${debugLogName}.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip</fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <pattern>${debugLoggerPattern}</pattern> + </encoder> + </appender> + + <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="EELFDebug" /> + <includeCallerData>true</includeCallerData> + </appender> + + + <!-- ============================================================================ --> + <!-- EELF loggers --> + <!-- ============================================================================ --> + <logger name="com.att.eelf" level="info" additivity="false"> + <appender-ref ref="asyncEELF" /> + </logger> + + <logger name="com.att.eelf.security" level="info" additivity="false"> + <appender-ref ref="asyncEELFSecurity" /> + </logger> + + + <logger name="com.att.eelf.audit" level="info" additivity="false"> + <appender-ref ref="asyncEELFAudit" /> + </logger> + + <logger name="com.att.eelf.metrics" level="info" additivity="false"> <appender-ref ref="asyncEELFMetrics" /> - - </logger> - - - <logger name="com.att.eelf.error" level="error" additivity="false"> - <appender-ref ref="asyncEELFError" /> - - </logger> - - <logger name="com.att.eelf.debug" level="debug" additivity="false"> + </logger> + + + <logger name="com.att.eelf.error" level="error" additivity="false"> + <appender-ref ref="asyncEELFError" /> + </logger> + + <logger name="com.att.eelf.debug" level="debug" additivity="false"> <appender-ref ref="asyncEELFDebug" /> - - </logger> - - <root level="INFO"> - <appender-ref ref="asyncEELF" /> - <appender-ref ref="STDOUT" /> - </root> - - <!-- Conductor Specific additions to squash WARNING and INFO --> - <logger name="com.datastax.driver.core.Cluster" level="ERROR"/> - <logger name="org.onap.music.main.MusicCore" level="ERROR"/> + + </logger> + + <root level="INFO"> + <appender-ref ref="asyncEELF" /> + <appender-ref ref="STDOUT" /> + </root> + + <!-- Conductor Specific additions to squash WARNING and INFO --> + <logger name="com.datastax.driver.core.Cluster" level="ERROR"/> + <logger name="org.onap.music.main.MusicCore" level="ERROR"/> </configuration> diff --git a/src/main/resources/project.properties b/src/main/resources/project.properties index 199afa33..69b99adc 100644 --- a/src/main/resources/project.properties +++ b/src/main/resources/project.properties @@ -1,4 +1,5 @@ version=${project.version} artifactId=${project.artifactId} +build=${project.version}-${timestamp} music.properties=/opt/app/music/etc/music.properties |