diff options
9 files changed, 234 insertions, 303 deletions
diff --git a/src/main/java/org/onap/music/JerseyConfig.java b/src/main/java/org/onap/music/JerseyConfig.java index 74958363..1b5f034a 100755 --- a/src/main/java/org/onap/music/JerseyConfig.java +++ b/src/main/java/org/onap/music/JerseyConfig.java @@ -1,64 +1,55 @@ -/* - * Copyright 2012-2015 the original author or authors. - * - * 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. - */ - -package org.onap.music; - -import javax.annotation.PostConstruct; -import javax.ws.rs.ApplicationPath; -import org.glassfish.jersey.server.ResourceConfig; -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; +/* + * Copyright 2012-2015 the original author or authors. + * + * 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. + */ + +package org.onap.music; + import io.swagger.jaxrs.config.BeanConfig; import io.swagger.jaxrs.listing.ApiListingResource; -import io.swagger.jaxrs.listing.SwaggerSerializers; - -@Component -public class JerseyConfig extends ResourceConfig { - - @Value("${spring.jersey.application-path:/}") - private String apiPath; - - public JerseyConfig() { +import io.swagger.jaxrs.listing.SwaggerSerializers; +import org.glassfish.jersey.server.ResourceConfig; +import org.onap.music.rest.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component public class JerseyConfig extends ResourceConfig { + + @Value("${spring.jersey.application-path:/}") private String apiPath; + + public JerseyConfig() { this.registerEndpoints(); - } - - @PostConstruct - public void init() { + } + + @PostConstruct public void init() { this.configureSwagger(); } - + private void registerEndpoints() { - register(RestMusicAdminAPI.class); - register(RestMusicDataAPI.class); - register(RestMusicLocksAPI.class); - register(RestMusicQAPI.class); - register(RestMusicTestAPI.class); + register(RestMusicAdminAPI.class); + register(RestMusicDataAPI.class); + register(RestMusicLocksAPI.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); @@ -67,11 +58,11 @@ public class JerseyConfig extends ResourceConfig { config.setTitle("MUSIC"); config.setVersion("v2"); config.setContact("Thomas Nelson"); - config.setSchemes(new String[] { "http", "https" }); + config.setSchemes(new String[] {"http", "https"}); config.setBasePath("/MUSIC/rest"); config.setResourcePackage("org.onap.music"); config.setPrettyPrint(true); config.setScan(true); } - + } 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 93c44468..3e962a02 100644 --- a/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java +++ b/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java @@ -3,6 +3,8 @@ * org.onap.music * =================================================================== * Copyright (c) 2017 AT&T Intellectual Property + * + * Modifications Copyright (C) 2019 IBM. * =================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,9 +67,7 @@ public class MusicHealthCheck { try { result = getAdminKeySpace(consistency); } catch (MusicServiceException e1) { - // TODO Auto-generated catch block - logger.error("Error", e); - e1.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.UNKNOWN); } } else { logger.error("Error", e); @@ -106,9 +106,7 @@ public class MusicHealthCheck { try { rs = MusicCore.nonKeyRelatedPut(pQuery, ConsistencyLevel.ONE.toString()); } catch (MusicServiceException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - logger.error("Error", e); + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.UNKNOWN); } if(rs != null && rs.getResult().toLowerCase().contains("success")) return true; diff --git a/src/main/java/org/onap/music/main/CachingUtil.java b/src/main/java/org/onap/music/main/CachingUtil.java index 9c975191..db74aceb 100755 --- a/src/main/java/org/onap/music/main/CachingUtil.java +++ b/src/main/java/org/onap/music/main/CachingUtil.java @@ -5,6 +5,7 @@ * Copyright (c) 2017 AT&T Intellectual Property * =================================================================== * Modifications Copyright (c) 2018 IBM + * Modifications Copyright (c) 2019 Samsung * =================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,10 +37,6 @@ 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.datastore.PreparedQueryObject; import org.onap.music.eelf.logging.EELFLoggerDelegate; @@ -47,7 +44,6 @@ 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.MusicServiceException; -import org.onap.music.service.impl.MusicZKCore; import com.datastax.driver.core.DataType; import com.datastax.driver.core.PreparedStatement; @@ -133,7 +129,6 @@ public class CachingUtil implements Runnable { pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), false)); } catch (Exception e1) { logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(),AppMessages.CACHEERROR, ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); - e1.printStackTrace(); } ResultSet rs = MusicCore.get(pQuery); Iterator<Row> it = rs.iterator(); @@ -158,7 +153,6 @@ public class CachingUtil implements Runnable { } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.INFO, ErrorTypes.GENERALSERVICEERROR); logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Something at AAF was changed for ns: " + nameSpace+" So not updating Cache for the namespace. "); - e.printStackTrace(); } } @@ -317,7 +311,6 @@ public class CachingUtil implements Runnable { appNameCache.put(namespace, isAAF); } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR,ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); - e.printStackTrace(); } } return isAAF; @@ -334,8 +327,7 @@ public class CachingUtil implements Runnable { try { uuid = rs.getUUID("uuid").toString(); } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger,"Exception occured during uuid retrieval from DB."+e.getMessage()); - e.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger,"Exception occurred during uuid retrieval from DB."+e.getMessage()); } } return uuid; @@ -352,7 +344,6 @@ public class CachingUtil implements Runnable { appName = rs.getString("application_name"); } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR, ErrorSeverity.ERROR, ErrorTypes.QUERYERROR); - e.printStackTrace(); } return appName; } @@ -398,9 +389,9 @@ public class CachingUtil implements Runnable { try { rs = MusicCore.get(queryObject).one(); } catch (MusicServiceException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - resultMap.put("Exception", "Unable to process operation. Error is "+e.getMessage()); + String errorMsg = "Unable to process operation. Error is "+e.getMessage(); + logger.error(EELFLoggerDelegate.errorLogger, errorMsg); + resultMap.put("Exception", errorMsg); return resultMap; } catch (InvalidQueryException e) { logger.error(EELFLoggerDelegate.errorLogger,"Exception admin keyspace not configured."+e.getMessage()); @@ -443,14 +434,15 @@ public class CachingUtil implements Runnable { try { queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace)); } catch (Exception e) { - e.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger,"Adding value to query object failed: " + e.getMessage()); } Row rs = null; try { rs = MusicCore.get(queryObject).one(); } catch (MusicServiceException e) { - e.printStackTrace(); - resultMap.put("Exception", "Unable to process operation. Error is "+e.getMessage()); + String errMsg = "Unable to process operation. Error is "+e.getMessage(); + logger.error(EELFLoggerDelegate.errorLogger, errMsg); + resultMap.put("Exception", errMsg); return resultMap; } if(rs == null) { @@ -486,7 +478,8 @@ public class CachingUtil implements Runnable { try { MusicCore.nonKeyRelatedPut(pQuery, "eventual"); } catch (Exception e) { - e.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), "Deleting keys from " + + "DB failed."); } } } diff --git a/src/main/java/org/onap/music/main/CronJobManager.java b/src/main/java/org/onap/music/main/CronJobManager.java index 9cd9f33f..ea2fa685 100644 --- a/src/main/java/org/onap/music/main/CronJobManager.java +++ b/src/main/java/org/onap/music/main/CronJobManager.java @@ -4,6 +4,8 @@ * =================================================================== * Copyright (c) 2017 AT&T Intellectual Property * =================================================================== + * Modifications Copyright (c) 2019 Samsung + * =================================================================== * 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 @@ -25,12 +27,6 @@ package org.onap.music.main; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Iterator; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.eelf.logging.EELFLoggerDelegate; @@ -52,13 +48,13 @@ public class CronJobManager { private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); - + @Scheduled(cron = "0 0 0 * * ?") public void scheduleTaskWithFixedRate() { logger.info("Executing cronjob to cleanup locks..", dateTimeFormatter.format(LocalDateTime.now()) ); deleteLocksFromDB(); } - + public void deleteLocksFromDB() { PreparedQueryObject pQuery = new PreparedQueryObject(); String consistency = MusicUtil.EVENTUAL; @@ -69,10 +65,9 @@ public class CronJobManager { logger.error(EELFLoggerDelegate.errorLogger,"Error creating Admin.locks table.",AppMessages.QUERYERROR,ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); } } catch (MusicServiceException e1) { - logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(),AppMessages.QUERYERROR,ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); - e1.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger,e1,AppMessages.QUERYERROR,ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); } - + pQuery = new PreparedQueryObject(); pQuery.appendQueryString( "select * from admin.locks"); @@ -82,7 +77,7 @@ public class CronJobManager { StringBuilder deleteKeys = new StringBuilder(); Boolean expiredKeys = false; while (it.hasNext()) { - Row row = (Row) it.next(); + Row row = it.next(); String id = row.getString("lock_id"); long ctime = Long.parseLong(row.getString("ctime")); if(System.currentTimeMillis() >= ctime + 24 * 60 * 60 * 1000) { @@ -102,8 +97,7 @@ public class CronJobManager { CachingUtil.deleteKeysFromDB(deleteKeys.toString()); } } catch (MusicServiceException e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(),AppMessages.CACHEERROR,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); - e.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger,e,AppMessages.CACHEERROR,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); } } } diff --git a/src/main/java/org/onap/music/main/MusicUtil.java b/src/main/java/org/onap/music/main/MusicUtil.java index 805f459f..dd089683 100755 --- a/src/main/java/org/onap/music/main/MusicUtil.java +++ b/src/main/java/org/onap/music/main/MusicUtil.java @@ -4,7 +4,8 @@ * =================================================================== * Copyright (c) 2017 AT&T Intellectual Property * =================================================================== - * Modifications Copyright (c) 2018 IBM. + * Modifications Copyright (c) 2018 IBM. + * Modifications Copyright (c) 2019 Samsung. * =================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,10 @@ package org.onap.music.main; +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.ColumnDefinitions.Definition; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -44,8 +49,12 @@ import java.util.concurrent.ConcurrentMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; +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.MusicQueryException; import org.onap.music.exceptions.MusicServiceException; import org.onap.music.service.MusicCoreService; @@ -809,6 +818,42 @@ public class MusicUtil { // TODO Auto-generated method stub MusicUtil.isCadi = isCadi; } + + public static void writeBackToQuorum(PreparedQueryObject selectQuery, String primaryKeyName, + PreparedQueryObject updateQuery, String keyspace, String table, + Object cqlFormattedPrimaryKeyValue) + throws Exception { + try { + ResultSet results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(selectQuery); + // write it back to a quorum + Row row = results.one(); + ColumnDefinitions colInfo = row.getColumnDefinitions(); + int totalColumns = colInfo.size(); + int counter = 1; + StringBuilder fieldValueString = new StringBuilder(""); + for (Definition definition : colInfo) { + String colName = definition.getName(); + if (colName.equals(primaryKeyName)) + continue; + DataType colType = definition.getType(); + Object valueObj = MusicDataStoreHandle.getDSHandle().getColValue(row, colName, colType); + Object valueString = MusicUtil.convertToActualDataType(colType, valueObj); + fieldValueString.append(colName + " = ?"); + updateQuery.addValue(valueString); + if (counter != (totalColumns - 1)) + fieldValueString.append(","); + counter = counter + 1; + } + updateQuery.appendQueryString("UPDATE " + keyspace + "." + table + " SET " + + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";"); + updateQuery.addValue(cqlFormattedPrimaryKeyValue); + + MusicDataStoreHandle.getDSHandle().executePut(updateQuery, "critical"); + } catch (MusicServiceException | MusicQueryException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery , + ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR); + } + } public static boolean getIsCadi() { return MusicUtil.isCadi; diff --git a/src/main/java/org/onap/music/rest/RestMusicDataAPI.java b/src/main/java/org/onap/music/rest/RestMusicDataAPI.java index 507bcd40..0010ed1a 100755 --- a/src/main/java/org/onap/music/rest/RestMusicDataAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicDataAPI.java @@ -4,6 +4,8 @@ * =================================================================== * Copyright (c) 2017 AT&T Intellectual Property * =================================================================== + * Modifications Copyright (c) 2019 Samsung + * =================================================================== * 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 @@ -404,9 +406,10 @@ public class RestMusicDataAPI { @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception { try { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); - if((keyspace == null || keyspace == null) || (tablename.isEmpty() || tablename.isEmpty())){ + 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") + .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+" ) "); 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 8737a060..21b4874b 100644 --- a/src/main/java/org/onap/music/service/impl/MusicCassaCore.java +++ b/src/main/java/org/onap/music/service/impl/MusicCassaCore.java @@ -3,6 +3,9 @@ * org.onap.music * =================================================================== * Copyright (c) 2017 AT&T Intellectual Property + * Modifications Copyright (c) 2018 IBM. + * =================================================================== + * Modifications Copyright (c) 2019 Samsung * =================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +26,6 @@ package org.onap.music.service.impl; import java.io.StringWriter; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; @@ -47,13 +49,10 @@ import org.onap.music.main.ResultType; import org.onap.music.main.ReturnType; import org.onap.music.service.MusicCoreService; -import com.datastax.driver.core.ColumnDefinitions; -import com.datastax.driver.core.ColumnDefinitions.Definition; import com.datastax.driver.core.DataType; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.TableMetadata; -import com.google.common.util.concurrent.Monitor.Guard; import org.onap.music.datastore.*; @@ -63,18 +62,18 @@ public class MusicCassaCore implements MusicCoreService { private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCassaCore.class); private static boolean unitTestRun=true; private static MusicCassaCore musicCassaCoreInstance = null; - + private MusicCassaCore() { - + } public static MusicCassaCore getInstance() { - + if(musicCassaCoreInstance == null) { musicCassaCoreInstance = new MusicCassaCore(); } return musicCassaCoreInstance; } - + public static CassaLockStore getLockingServiceHandle() throws MusicLockingException { logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle"); long start = System.currentTimeMillis(); @@ -127,19 +126,19 @@ 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 + + /* 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; long topOfLockStoreL = Long.parseLong(topOfLockStoreS); @@ -149,36 +148,36 @@ public class MusicCassaCore implements MusicCoreService { logger.info(EELFLoggerDelegate.applicationLogger, lockReference+" is not the lock holder yet"); 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"); } - + public ReturnType acquireLock(String fullyQualifiedKey, String lockId) throws MusicLockingException, MusicQueryException, MusicServiceException { String[] splitString = lockId.split("\\."); String keyspace = splitString[0].substring(1);//remove '$' String table = splitString[1]; String primaryKeyValue = splitString[2].substring(0, splitString[2].lastIndexOf("$")); - fullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$")); + String localFullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$")); String lockRef = lockId.substring(lockId.lastIndexOf("$")+1); //lockRef is "$" to end - + ReturnType result = isTopOfLockStore(keyspace, table, primaryKeyValue, lockRef); - + if(result.getResult().equals(ResultType.FAILURE)) return result;//not top of the lock store q - + //check to see if the value of the key has to be synced in case there was a forceful release String syncTable = keyspace+".unsyncedKeys_"+table; - String query = "select * from "+syncTable+" where key='"+fullyQualifiedKey+"';"; + String query = "select * from "+syncTable+" where key='"+localFullyQualifiedKey+"';"; PreparedQueryObject readQueryObject = new PreparedQueryObject(); readQueryObject.appendQueryString(query); - ResultSet results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(readQueryObject); + ResultSet results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(readQueryObject); if (results.all().size() != 0) { logger.info("In acquire lock: Since there was a forcible release, need to sync quorum!"); try { @@ -187,54 +186,54 @@ public class MusicCassaCore implements MusicCoreService { StringWriter sw = new StringWriter(); logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); String exceptionAsString = sw.toString(); - return new ReturnType(ResultType.FAILURE, "Exception thrown while syncing key:\n" + exceptionAsString); + return new ReturnType(ResultType.FAILURE, "Exception thrown while syncing key:\n" + exceptionAsString); } - String cleanQuery = "delete from music_internal.unsynced_keys where key='"+fullyQualifiedKey+"';"; + String cleanQuery = "delete from music_internal.unsynced_keys where key='"+localFullyQualifiedKey+"';"; PreparedQueryObject deleteQueryObject = new PreparedQueryObject(); deleteQueryObject.appendQueryString(cleanQuery); MusicDataStoreHandle.getDSHandle().executePut(deleteQueryObject, "critical"); } - + getLockingServiceHandle().updateLockAcquireTime(keyspace, table, primaryKeyValue, lockRef); - + return new ReturnType(ResultType.SUCCESS, lockRef+" is the lock holder for the key"); } /** - * + * * @param tableQueryObject * @param consistency * @return Boolean Indicates success or failure - * @throws MusicServiceException - * - * + * @throws MusicServiceException + * + * */ public ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject, String consistency) throws MusicServiceException { boolean result = false; - + try { - //create shadow locking table + //create shadow locking table result = getLockingServiceHandle().createLockQueue(keyspace, table); - if(result == false) + if(result == false) return ResultType.FAILURE; - + result = false; - + //create table to track unsynced_keys - table = "unsyncedKeys_"+table; - + table = "unsyncedKeys_"+table; + String tabQuery = "CREATE TABLE IF NOT EXISTS "+keyspace+"."+table + " ( key text,PRIMARY KEY (key) );"; System.out.println(tabQuery); - PreparedQueryObject queryObject = new PreparedQueryObject(); - + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString(tabQuery); result = false; result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, "eventual"); - + //create actual table result = MusicDataStoreHandle.getDSHandle().executePut(tableQueryObject, consistency); } catch (MusicQueryException | MusicServiceException | MusicLockingException ex) { @@ -261,43 +260,13 @@ public class MusicCassaCore implements MusicCoreService { selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + table + " WHERE " + primaryKeyName + "= ?" + ";"); selectQuery.addValue(cqlFormattedPrimaryKeyValue); - ResultSet results = null; - try { - results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(selectQuery); - // write it back to a quorum - Row row = results.one(); - ColumnDefinitions colInfo = row.getColumnDefinitions(); - int totalColumns = colInfo.size(); - int counter = 1; - StringBuilder fieldValueString = new StringBuilder(""); - for (Definition definition : colInfo) { - String colName = definition.getName(); - if (colName.equals(primaryKeyName)) - continue; - DataType colType = definition.getType(); - Object valueObj = MusicDataStoreHandle.getDSHandle().getColValue(row, colName, colType); - Object valueString = MusicUtil.convertToActualDataType(colType, valueObj); - fieldValueString.append(colName + " = ?"); - updateQuery.addValue(valueString); - if (counter != (totalColumns - 1)) - fieldValueString.append(","); - counter = counter + 1; - } - updateQuery.appendQueryString("UPDATE " + keyspace + "." + table + " SET " - + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";"); - updateQuery.addValue(cqlFormattedPrimaryKeyValue); + MusicUtil.writeBackToQuorum(selectQuery, primaryKeyName, updateQuery, keyspace, table, + cqlFormattedPrimaryKeyValue); - MusicDataStoreHandle.getDSHandle().executePut(updateQuery, "critical"); - } catch (MusicServiceException | MusicQueryException e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR); - } } - - - /** - * + * * @param query * @return ResultSet */ @@ -307,16 +276,14 @@ public class MusicCassaCore implements MusicCoreService { results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(query); } catch (MusicServiceException | MusicQueryException e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR); - + } return results; } - - /** - * + * * @param fullyQualifiedKey lockName * @return */ @@ -326,7 +293,7 @@ public class MusicCassaCore implements MusicCoreService { String table = splitString[1]; String primaryKeyValue = splitString[2]; try { - return "$" + fullyQualifiedKey + "$" + return "$" + fullyQualifiedKey + "$" + getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue).lockRef; } catch (MusicLockingException | MusicServiceException | MusicQueryException e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+fullyQualifiedKey ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); @@ -335,7 +302,7 @@ public class MusicCassaCore implements MusicCoreService { } /** - * + * * @param lockReference * @return */ @@ -357,11 +324,11 @@ public class MusicCassaCore implements MusicCoreService { getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockRef); } catch (MusicLockingException | MusicServiceException | MusicQueryException e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockRef ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); - } + } long end = System.currentTimeMillis(); logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms"); } - + public MusicLockState destroyLockRef(String fullyQualifiedKey, String lockReference) { long start = System.currentTimeMillis(); String[] splitString = fullyQualifiedKey.split("\\."); @@ -372,7 +339,7 @@ public class MusicCassaCore implements MusicCoreService { getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockReference); } catch (MusicLockingException | MusicServiceException | MusicQueryException e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockReference ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); - } + } long end = System.currentTimeMillis(); logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms"); return new MusicLockState(LockStatus.UNLOCKED, ""); @@ -388,7 +355,7 @@ public class MusicCassaCore implements MusicCoreService { return forciblyReleaseLock(fullyQualifiedKey, lockRef); } } - + public MusicLockState voluntaryReleaseLock(String fullyQualifiedKey, String lockReference) { return destroyLockRef(fullyQualifiedKey, lockReference); } @@ -399,7 +366,7 @@ public class MusicCassaCore implements MusicCoreService { String table = splitString[1]; //leave a signal that this key could potentially be unsynchronized - String syncTable = keyspace+".unsyncedKeys_"+table; + String syncTable = keyspace+".unsyncedKeys_"+table; PreparedQueryObject queryObject = new PreparedQueryObject(); String values = "(?)"; queryObject.addValue(fullyQualifiedKey); @@ -408,18 +375,18 @@ public class MusicCassaCore implements MusicCoreService { try { MusicDataStoreHandle.getDSHandle().executePut(queryObject, "critical"); } catch (Exception e) { - logger.error("Cannot forcibly release lock: " + fullyQualifiedKey + " " + lockReference + ". " + logger.error("Cannot forcibly release lock: " + fullyQualifiedKey + " " + lockReference + ". " + e.getMessage()); } - + //now release the lock return destroyLockRef(fullyQualifiedKey, lockReference); } /** - * + * * @param lockName - * @throws MusicLockingException + * @throws MusicLockingException */ public void deleteLock(String lockName) throws MusicLockingException { //deprecated @@ -428,7 +395,7 @@ public class MusicCassaCore implements MusicCoreService { // Prepared Query Additions. /** - * + * * @param queryObject * @return ReturnType * @throws MusicServiceException @@ -448,9 +415,9 @@ public class MusicCassaCore implements MusicCoreService { return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform"); } } - + /** - * + * * @param queryObject * @return ReturnType * @throws MusicServiceException @@ -477,10 +444,10 @@ public class MusicCassaCore implements MusicCoreService { } queryObject.replaceQueryString(query); } - + } catch (MusicServiceException | MusicQueryException e) { logger.error(EELFLoggerDelegate.applicationLogger,e.getMessage()); - } + } try { result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL); } catch (MusicServiceException | MusicQueryException ex) { @@ -494,9 +461,9 @@ public class MusicCassaCore implements MusicCoreService { return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform"); } } - + /** - * + * * @param keyspace * @param table * @param primaryKeyValue @@ -523,7 +490,7 @@ public class MusicCassaCore implements MusicCoreService { "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)); @@ -551,15 +518,15 @@ public class MusicCassaCore implements MusicCoreService { return new ReturnType(ResultType.SUCCESS, "Update performed"); } - + /** - * + * * @param queryObject * @param consistency * @return Boolean Indicates success or failure - * @throws MusicServiceException - * - * + * @throws MusicServiceException + * + * */ public ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException { // this is mainly for some functions like keyspace creation etc which does not @@ -577,10 +544,10 @@ public class MusicCassaCore implements MusicCoreService { /** * This method performs DDL operation on cassandra. - * + * * @param queryObject query object containing prepared query and values * @return ResultSet - * @throws MusicServiceException + * @throws MusicServiceException */ public ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException { ResultSet results = null; @@ -596,7 +563,7 @@ public class MusicCassaCore implements MusicCoreService { /** * This method performs DDL operations on cassandra, if the the resource is available. Lock ID * is used to check if the resource is free. - * + * * @param keyspace name of the keyspace * @param table name of the table * @param primaryKeyValue primary key value @@ -607,9 +574,9 @@ public class MusicCassaCore implements MusicCoreService { public ResultSet criticalGet(String keyspace, String table, String primaryKeyValue, PreparedQueryObject queryObject, String lockId) throws MusicServiceException { ResultSet results = null; - + try { - ReturnType result = isTopOfLockStore(keyspace, table, primaryKeyValue, + ReturnType result = isTopOfLockStore(keyspace, table, primaryKeyValue, lockId.substring(lockId.lastIndexOf("$")+1)); if(result.getResult().equals(ResultType.FAILURE)) return null;//not top of the lock store q @@ -622,15 +589,15 @@ public class MusicCassaCore implements MusicCoreService { /** * This method performs DML operation on cassandra, when the lock of the dd is acquired. - * + * * @param keyspaceName name of the keyspace * @param tableName name of the table * @param primaryKey primary key value * @param queryObject query object containing prepared query and values * @return ReturnType - * @throws MusicLockingException - * @throws MusicServiceException - * @throws MusicQueryException + * @throws MusicLockingException + * @throws MusicServiceException + * @throws MusicQueryException */ public ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException, MusicQueryException, MusicServiceException { @@ -661,21 +628,21 @@ public class MusicCassaCore implements MusicCoreService { criticalPutResult.setTimingInfo(timingInfo); return criticalPutResult; } - + /** * This method performs DDL operation on cassasndra, when the lock for the resource is acquired. - * + * * @param keyspaceName name of the keyspace * @param tableName name of the table * @param primaryKey primary key value * @param queryObject query object containing prepared query and values * @return ResultSet * @throws MusicServiceException - * @throws MusicLockingException - * @throws MusicQueryException + * @throws MusicLockingException + * @throws MusicQueryException */ public ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey, PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException, MusicQueryException { @@ -697,34 +664,15 @@ public class MusicCassaCore implements MusicCoreService { } } - - + + /** * @param lockName * @return */ public Map<String, Object> validateLock(String lockName) { - Map<String, Object> resultMap = new HashMap<>(); - String[] locks = lockName.split("\\."); - if(locks.length < 3) { - resultMap.put("Error", "Invalid lock. Please make sure lock is of the type keyspaceName.tableName.primaryKey"); - return resultMap; - } - String keyspace= locks[0]; - if(keyspace.startsWith("$")) - keyspace = keyspace.substring(1); - resultMap.put("keyspace",keyspace); - return resultMap; + return MusicUtil.validateLock(lockName); } - - - public static void main(String[] args) { - String x = "axe top"; - x = x.replaceFirst("top", "sword"); - System.out.print(x); //returns sword pickaxe - } - - @Override public ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey, diff --git a/src/main/java/org/onap/music/service/impl/MusicZKCore.java b/src/main/java/org/onap/music/service/impl/MusicZKCore.java index 1662b20c..93c5abc8 100644 --- a/src/main/java/org/onap/music/service/impl/MusicZKCore.java +++ b/src/main/java/org/onap/music/service/impl/MusicZKCore.java @@ -4,6 +4,8 @@ * =================================================================== * Copyright (c) 2017 AT&T Intellectual Property * =================================================================== + * Modifications Copyright (c) 2019 Samsung + * =================================================================== * 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 @@ -24,17 +26,12 @@ package org.onap.music.service.impl; import java.io.StringWriter; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; -import javax.ws.rs.core.MediaType; - -import org.apache.commons.jcs.access.CacheAccess; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.KeeperException.NoNodeException; -import org.onap.music.datastore.MusicDataStore; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.datastore.jsonobjects.JsonKeySpace; import org.onap.music.eelf.logging.EELFLoggerDelegate; @@ -53,15 +50,10 @@ import org.onap.music.main.ReturnType; import org.onap.music.service.MusicCoreService; import org.onap.music.datastore.*; -import com.datastax.driver.core.ColumnDefinitions; -import com.datastax.driver.core.ColumnDefinitions.Definition; import com.datastax.driver.core.DataType; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.TableMetadata; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; /** * This class ..... @@ -73,18 +65,18 @@ public class MusicZKCore implements MusicCoreService { public static MusicLockingService mLockHandle = null; private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicZKCore.class); private static MusicZKCore musicZKCoreInstance = null; - + private MusicZKCore() { - + } public static MusicZKCore getInstance() { - + if(musicZKCoreInstance == null) { musicZKCoreInstance = new MusicZKCore(); } return musicZKCoreInstance; } - + @@ -344,36 +336,8 @@ public class MusicZKCore implements MusicCoreService { selectQuery.appendQueryString("SELECT * FROM " + keyspaceName + "." + tableName + " WHERE " + primaryKeyName + "= ?" + ";"); selectQuery.addValue(cqlFormattedPrimaryKeyValue); - ResultSet results = null; - try { - results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(selectQuery); - // write it back to a quorum - Row row = results.one(); - ColumnDefinitions colInfo = row.getColumnDefinitions(); - int totalColumns = colInfo.size(); - int counter = 1; - StringBuilder fieldValueString = new StringBuilder(""); - for (Definition definition : colInfo) { - String colName = definition.getName(); - if (colName.equals(primaryKeyName)) - continue; - DataType colType = definition.getType(); - Object valueObj = MusicDataStoreHandle.getDSHandle().getColValue(row, colName, colType); - Object valueString = MusicUtil.convertToActualDataType(colType, valueObj); - fieldValueString.append(colName + " = ?"); - updateQuery.addValue(valueString); - if (counter != (totalColumns - 1)) - fieldValueString.append(","); - counter = counter + 1; - } - updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET " - + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";"); - updateQuery.addValue(cqlFormattedPrimaryKeyValue); - - MusicDataStoreHandle.getDSHandle().executePut(updateQuery, "critical"); - } catch (MusicServiceException | MusicQueryException e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR); - } + MusicUtil.writeBackToQuorum(selectQuery, primaryKeyName, updateQuery, keyspaceName, tableName, + cqlFormattedPrimaryKeyValue); } @@ -843,47 +807,34 @@ public class MusicZKCore implements MusicCoreService { * @return */ public Map<String, Object> validateLock(String lockName) { - Map<String, Object> resultMap = new HashMap<>(); - String[] locks = lockName.split("\\."); - if(locks.length < 3) { - resultMap.put("Error", "Invalid lock. Please make sure lock is of the type keyspaceName.tableName.primaryKey"); - return resultMap; - } - String keyspace= locks[0]; - if(keyspace.startsWith("$")) - keyspace = keyspace.substring(1); - resultMap.put("keyspace",keyspace); - return resultMap; + return MusicUtil.validateLock(lockName); } - - @Override public ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject, String consistency) throws MusicServiceException { boolean result = false; - try { - //create shadow locking table - result = createLockQueue(keyspace, table); - if(result == false) - return ResultType.FAILURE; + //create shadow locking table + //result = createLockQueue(keyspace, table); + if(result == false) + return ResultType.FAILURE; result = false; - + //create table to track unsynced_keys - table = "unsyncedKeys_"+table; - + table = "unsyncedKeys_"+table; + String tabQuery = "CREATE TABLE IF NOT EXISTS "+keyspace+"."+table + " ( key text,PRIMARY KEY (key) );"; System.out.println(tabQuery); - PreparedQueryObject queryObject = new PreparedQueryObject(); - + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString(tabQuery); result = false; result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, "eventual"); - + //create actual table result = MusicDataStoreHandle.getDSHandle().executePut(tableQueryObject, consistency); } catch (MusicQueryException | MusicServiceException ex) { @@ -892,17 +843,17 @@ public class MusicZKCore implements MusicCoreService { } return result?ResultType.SUCCESS:ResultType.FAILURE; } - + public static boolean createLockQueue(String keyspace, String table) throws MusicServiceException, MusicQueryException { logger.info(EELFLoggerDelegate.applicationLogger, "Create lock queue/table for " + keyspace+"."+table); - table = "lockQ_"+table; + table = "lockQ_"+table; String tabQuery = "CREATE TABLE IF NOT EXISTS "+keyspace+"."+table + " ( key text, lockReference bigint, createTime text, acquireTime text, guard bigint static, PRIMARY KEY ((key), lockReference) ) " + "WITH CLUSTERING ORDER BY (lockReference ASC);"; System.out.println(tabQuery); - PreparedQueryObject queryObject = new PreparedQueryObject(); - + PreparedQueryObject queryObject = new PreparedQueryObject(); + queryObject.appendQueryString(tabQuery); boolean result; result = MusicDataStoreHandle.mDstoreHandle.executePut(queryObject, "eventual"); diff --git a/src/test/java/org/onap/music/unittests/TestRestAdminData.java b/src/test/java/org/onap/music/unittests/TestRestAdminData.java index 0471d6f0..2708b64b 100644 --- a/src/test/java/org/onap/music/unittests/TestRestAdminData.java +++ b/src/test/java/org/onap/music/unittests/TestRestAdminData.java @@ -2568,4 +2568,12 @@ public class TestRestAdminData { appName, authorization, keyspaceName, tableNameConditional, json); assertEquals(401, response.getStatus()); } + @Test + public void Test8_HealthCheck_cassandra_musicHealthCheck() { + RestMusicHealthCheckAPI healthCheck = new RestMusicHealthCheckAPI(); + Response response = healthCheck.musicHealthCheck(); + assertEquals(200, response.getStatus()); + } + + }
\ No newline at end of file |