aboutsummaryrefslogtreecommitdiffstats
path: root/music-core
diff options
context:
space:
mode:
Diffstat (limited to 'music-core')
-rwxr-xr-xmusic-core/pom.xml459
-rw-r--r--music-core/src/main/java/LICENSE.txt24
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/Condition.java63
-rwxr-xr-xmusic-core/src/main/java/org/onap/music/datastore/MusicDataStore.java540
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java127
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/PreparedQueryObject.java176
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java37
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java313
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonIndex.java120
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java415
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java163
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java44
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLock.java49
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java208
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java363
-rw-r--r--music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java436
-rw-r--r--music-core/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java130
-rw-r--r--music-core/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java381
-rw-r--r--music-core/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java188
-rw-r--r--music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java107
-rw-r--r--music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java38
-rw-r--r--music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java46
-rw-r--r--music-core/src/main/java/org/onap/music/exceptions/MusicDeadlockException.java75
-rw-r--r--music-core/src/main/java/org/onap/music/exceptions/MusicLockingException.java75
-rw-r--r--music-core/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java82
-rw-r--r--music-core/src/main/java/org/onap/music/exceptions/MusicQueryException.java90
-rw-r--r--music-core/src/main/java/org/onap/music/exceptions/MusicServiceException.java88
-rw-r--r--music-core/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java613
-rw-r--r--music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockCleanUpDaemon.java133
-rw-r--r--music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockType.java30
-rw-r--r--music-core/src/main/java/org/onap/music/lockingservice/cassandra/MusicLockState.java144
-rw-r--r--music-core/src/main/java/org/onap/music/main/CipherUtil.java279
-rw-r--r--music-core/src/main/java/org/onap/music/main/CorePropertiesLoader.java120
-rw-r--r--music-core/src/main/java/org/onap/music/main/DeadlockDetectionUtil.java152
-rw-r--r--music-core/src/main/java/org/onap/music/main/MusicCore.java264
-rw-r--r--music-core/src/main/java/org/onap/music/main/MusicUtil.java881
-rw-r--r--music-core/src/main/java/org/onap/music/main/ResultType.java42
-rw-r--r--music-core/src/main/java/org/onap/music/main/ReturnType.java75
-rw-r--r--music-core/src/main/java/org/onap/music/service/MusicCoreService.java189
-rw-r--r--music-core/src/main/java/org/onap/music/service/impl/MusicCassaCore.java1236
-rw-r--r--music-core/src/main/resources/LICENSE.txt24
-rw-r--r--music-core/src/main/resources/Resources.properties50
-rw-r--r--music-core/src/main/resources/logback.xml273
-rw-r--r--music-core/src/main/resources/project.properties5
-rw-r--r--music-core/src/main/webapp/WEB-INF/.gitignore1
-rw-r--r--music-core/src/test/java/LICENSE.txt24
-rw-r--r--music-core/src/test/java/org/onap/music/cassandra/MusicUtilTest.java345
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/ConditionTest.java61
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/MusicDataStoreTest.java436
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/PreparedQueryObjectTest.java101
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JSONObjectTest.java54
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonDeleteTest.java113
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonIndexTest.java74
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonInsertTest.java176
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonKeySpaceTest.java72
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonLockTest.java50
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonSelectTest.java68
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonTableTest.java153
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonUpdateTest.java166
-rw-r--r--music-core/src/test/java/org/onap/music/datastore/jsonobjects/RowIdentifierTest.java60
-rw-r--r--music-core/src/test/java/org/onap/music/eelf/logging/format/AppMessagesTest.java65
-rw-r--r--music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorSeverityTest.java41
-rw-r--r--music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorTypesTest.java48
-rw-r--r--music-core/src/test/java/org/onap/music/exceptions/MusicDeadlockExceptionTest.java135
-rw-r--r--music-core/src/test/java/org/onap/music/exceptions/MusicLockingExceptionTest.java104
-rw-r--r--music-core/src/test/java/org/onap/music/exceptions/MusicPolicyVoilationExceptionTest.java106
-rw-r--r--music-core/src/test/java/org/onap/music/exceptions/MusicQueryExceptionTest.java118
-rw-r--r--music-core/src/test/java/org/onap/music/exceptions/MusicServiceExceptionTest.java145
-rw-r--r--music-core/src/test/java/org/onap/music/lockingservice/cassandra/CassaLockStoreTest.java311
-rw-r--r--music-core/src/test/java/org/onap/music/lockingservice/cassandra/MusicLockStateTest.java86
-rw-r--r--music-core/src/test/java/org/onap/music/main/CipherUtilTest.java55
-rw-r--r--music-core/src/test/java/org/onap/music/main/DeadlockDetectionUtilTest.java87
-rw-r--r--music-core/src/test/java/org/onap/music/main/MusicCoreTest.java391
-rw-r--r--music-core/src/test/java/org/onap/music/main/ResultTypeTest.java42
-rw-r--r--music-core/src/test/java/org/onap/music/main/ReturnTypeTest.java82
-rw-r--r--music-core/src/test/java/org/onap/music/service/impl/MusicCassaCoreTest.java485
-rw-r--r--music-core/src/test/java/org/onap/music/unittests/jsonobjects/JSONObjectTest.java44
-rw-r--r--music-core/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java47
-rw-r--r--music-core/src/test/java/org/onap/music/unittests/jsonobjects/MusicHealthCheckTest.java48
-rw-r--r--music-core/src/test/resources/LICENSE.txt24
-rw-r--r--music-core/src/test/resources/Resources.properties50
-rw-r--r--music-core/src/test/resources/application.properties2
-rw-r--r--music-core/src/test/resources/cache.ccf62
-rw-r--r--music-core/src/test/resources/logback.xml302
-rw-r--r--music-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker1
-rw-r--r--music-core/src/test/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider1
-rw-r--r--music-core/src/test/resources/project.properties4
87 files changed, 14187 insertions, 0 deletions
diff --git a/music-core/pom.xml b/music-core/pom.xml
new file mode 100755
index 00000000..cf7f59e9
--- /dev/null
+++ b/music-core/pom.xml
@@ -0,0 +1,459 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START==========================================
+ 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.
+ 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=============================================
+ ====================================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.onap.music</groupId>
+ <artifactId>MUSIC-core</artifactId>
+ <packaging>jar</packaging>
+ <version>3.2.40-SNAPSHOT</version>
+ <description>
+ This is the MUSIC core interface, packaged as a jar file.
+ </description>
+ <name>music-core</name>
+
+ <parent>
+ <groupId>org.onap.music</groupId>
+ <artifactId>MUSIC</artifactId>
+ <version>3.2.40-SNAPSHOT</version>
+ </parent>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java.version>1.8</java.version>
+ <jaxrs.version>2.0.1</jaxrs.version>
+ <cassandra.version>3.6.0</cassandra.version>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>onap-releases</id>
+ <name>ONAP - Release Repository</name>
+ <url>${nexusproxy}/${releaseNexusPath}</url>
+ </repository>
+ <repository>
+ <id>onap-staging</id>
+ <name>ONAP - Staging Repository</name>
+ <url>${nexusproxy}/${stagingNexusPath}</url>
+ </repository>
+ <repository>
+ <id>onap-snapshots</id>
+ <name>ONAP - Snapshot Repository</name>
+ <url>${nexusproxy}/${snapshotNexusPath}</url>
+ </repository>
+ <repository>
+ <id>onap-public</id>
+ <name>ONAP public Repository</name>
+ <url>${nexusproxy}/content/groups/public</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <finalName>${project.artifactId}</finalName>
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+ <testOutputDirectory>target/test-classes</testOutputDirectory>
+ <defaultGoal>validate</defaultGoal>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.properties</include>
+ <include>**/*.xml</include>
+ <include>**/*.ccf</include>
+ </includes>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>${project.basedir}/src/test/resources</directory>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <skip>${maven.check.skip}</skip>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <id>make-a-jar</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <excludes>
+ <exclude>**/Sample*</exclude>
+ </excludes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <id>core</id>
+ <phase>install</phase>
+ <goals>
+ <goal>install-file</goal>
+ </goals>
+ <configuration>
+ <packaging>jar</packaging>
+ <artifactId>${project.artifactId}</artifactId>
+ <groupId>${project.groupId}</groupId>
+ <version>${project.version}</version>
+ <file>${project.build.directory}/${project.artifactId}.jar</file>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- Logging -->
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <version>1.2.3</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.2.3</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ <version>1.0.1-oss</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- End Logging -->
+ <!-- Cassandra -->
+ <dependency>
+ <groupId>io.dropwizard.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ <version>4.1.0-rc3</version>
+ </dependency>
+ <dependency>
+ <groupId>com.datastax.cassandra</groupId>
+ <artifactId>cassandra-driver-core</artifactId>
+ <version>${cassandra.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.datastax.cassandra</groupId>
+ <artifactId>cassandra-driver-extras</artifactId>
+ <version>${cassandra.version}</version>
+ </dependency>
+ <!-- /Cassandra -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-jcs-core</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.11</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.8</version>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.cassandraunit</groupId>
+ <artifactId>cassandra-unit-spring</artifactId>
+ <version>3.5.0.1</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.cassandraunit</groupId>
+ <artifactId>cassandra-unit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.dropwizard.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.addthis.metrics</groupId>
+ <artifactId>reporter-config-base</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.cassandraunit</groupId>
+ <artifactId>cassandra-unit-shaded</artifactId>
+ <version>3.5.0.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>2.23.4</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- /Testing -->
+ <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 -->
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jsr310</artifactId>
+ <version>2.9.9</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>2.9.9.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>2.9.9</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>2.9.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-jersey-jaxrs</artifactId>
+ <version>1.5.22</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.jersey.contribs</groupId>
+ <artifactId>jersey-multipart</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey.contribs</groupId>
+ <artifactId>jersey-multipart</artifactId>
+ <version>1.19</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <version>2.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>de.svenkubiak</groupId>
+ <artifactId>jBCrypt</artifactId>
+ <version>0.4.1</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-handler</artifactId>
+ <version>4.1.33.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-buffer</artifactId>
+ <version>4.1.33.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec</artifactId>
+ <version>4.1.33.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ <version>4.1.33.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-resolver</artifactId>
+ <version>4.1.33.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport</artifactId>
+ <version>4.1.33.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-cadi-aaf</artifactId>
+ <version>2.1.7</version>
+ <exclusions>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-cadi-client</artifactId>
+ <version>2.1.7</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-cadi-core</artifactId>
+ <version>2.1.7</version>
+ <exclusions>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.8.5</version>
+ </dependency>
+ </dependencies>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10.3</version>
+ <configuration>
+ <author>true</author>
+ <breakiterator>true</breakiterator>
+ <version>true</version>
+ <links>
+ <link>https://docs.oracle.com/javase/7/docs/api/</link>
+ <link>https://tomcat.apache.org/tomcat-7.0-doc/jspapi/</link>
+ <link>http://docs.oracle.com/javaee/7/api/</link>
+ </links>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+
+ <distributionManagement>
+ <repository>
+ <id>ecomp-releases</id>
+ <name>Release Repository</name>
+ <url>${nexusproxy}/${releaseNexusPath}</url>
+ </repository>
+ <snapshotRepository>
+ <id>ecomp-snapshots</id>
+ <name>Snapshot Repository</name>
+ <url>${nexusproxy}/${snapshotNexusPath}</url>
+ </snapshotRepository>
+ <!-- added for javadoc -->
+ <site>
+ <id>ecomp-site</id>
+ <url>dav:${nexusproxy}${sitePath}</url>
+ </site>
+ </distributionManagement>
+</project>
diff --git a/music-core/src/main/java/LICENSE.txt b/music-core/src/main/java/LICENSE.txt
new file mode 100644
index 00000000..cc6cdea5
--- /dev/null
+++ b/music-core/src/main/java/LICENSE.txt
@@ -0,0 +1,24 @@
+
+The following license applies to all files in this and sub-directories. Licenses
+are included in individual source files where appropriate, and if it differs
+from this text, it supersedes this. Any file that does not have license text
+defaults to being covered by this text; not all files support the addition of
+licenses.
+#
+# -------------------------------------------------------------------------
+# 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.
+#
+# -------------------------------------------------------------------------
+# \ No newline at end of file
diff --git a/music-core/src/main/java/org/onap/music/datastore/Condition.java b/music-core/src/main/java/org/onap/music/datastore/Condition.java
new file mode 100644
index 00000000..c17d9c07
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/Condition.java
@@ -0,0 +1,63 @@
+/*
+ * ============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;
+
+import java.util.Map;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.main.MusicCore;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+
+public class Condition {
+ private Map<String, Object> conditions;
+ private PreparedQueryObject selectQueryForTheRow;
+
+ public Condition(Map<String, Object> conditions, PreparedQueryObject selectQueryForTheRow) {
+ this.conditions = conditions;
+ this.selectQueryForTheRow = selectQueryForTheRow;
+ }
+
+ public boolean testCondition() throws Exception {
+ // first generate the row
+ ResultSet results = quorumGet(selectQueryForTheRow);
+ Row row = null;
+ if(results != null) {
+ row = results.one();
+ }
+ if(row == null) {
+ throw new Exception(" No data found to update");
+ }
+ return getDSHandle().doesRowSatisfyCondition(row, conditions);
+ }
+
+ /* For JUnit testing only */
+ public ResultSet quorumGet(PreparedQueryObject selectQueryForTheRow) {
+ return MusicCore.quorumGet(selectQueryForTheRow);
+ }
+
+ /* For JUnit testing only */
+ public MusicDataStore getDSHandle() throws MusicServiceException {
+ return MusicDataStoreHandle.getDSHandle();
+ }
+ } \ No newline at end of file
diff --git a/music-core/src/main/java/org/onap/music/datastore/MusicDataStore.java b/music-core/src/main/java/org/onap/music/datastore/MusicDataStore.java
new file mode 100755
index 00000000..9ce73cc8
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/MusicDataStore.java
@@ -0,0 +1,540 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modifications Copyright (c) 2018-2019 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.
+ * 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;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+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.lockingservice.cassandra.LockType;
+import org.onap.music.main.CipherUtil;
+import org.onap.music.main.MusicUtil;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.ColumnDefinitions;
+import com.datastax.driver.core.ColumnDefinitions.Definition;
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.HostDistance;
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.Metadata;
+import com.datastax.driver.core.PoolingOptions;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.SocketOptions;
+import com.datastax.driver.core.TableMetadata;
+import com.datastax.driver.core.exceptions.AlreadyExistsException;
+import com.datastax.driver.core.exceptions.InvalidQueryException;
+import com.datastax.driver.extras.codecs.enums.EnumNameCodec;
+
+/**
+ * @author nelson24
+ *
+ */
+public class MusicDataStore {
+
+ public static final String CONSISTENCY_LEVEL_ONE = "ONE";
+ public static final String CONSISTENCY_LEVEL_QUORUM = "QUORUM";
+ public static final String CONSISTENCY_LEVEL_LOCAL_QUORUM = "LOCAL_QUORUM";
+ private Session session;
+ private Cluster cluster;
+
+
+ /**
+ * Connect to default Cassandra address
+ */
+ public MusicDataStore() {
+ try {
+ connectToCassaCluster(MusicUtil.getMyCassaHost());
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e);
+ }
+ }
+
+
+ /**
+ * @param cluster
+ * @param session
+ */
+ public MusicDataStore(Cluster cluster, Session session) {
+ this.session = session;
+ setCluster(cluster);
+ }
+
+
+ /**
+ * @param session
+ */
+ public void setSession(Session session) {
+ this.session = session;
+ }
+
+ /**
+ * @param session
+ */
+ public Session getSession() {
+ return session;
+ }
+
+ /**
+ * @param cluster
+ */
+ public void setCluster(Cluster cluster) {
+ EnumNameCodec<LockType> lockTypeCodec = new EnumNameCodec<LockType>(LockType.class);
+ cluster.getConfiguration().getCodecRegistry().register(lockTypeCodec);
+
+ this.cluster = cluster;
+ }
+
+ public Cluster getCluster() {
+ return this.cluster;
+ }
+
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicDataStore.class);
+
+
+ /**
+ *
+ * @param remoteIp
+ * @throws MusicServiceException
+ */
+ public MusicDataStore(String remoteIp) {
+ try {
+ connectToCassaCluster(remoteIp);
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e);
+ }
+ }
+
+ /**
+ *
+ */
+ public void close() {
+ session.close();
+ }
+
+ /**
+ * This method connects to cassandra cluster on specific address.
+ *
+ * @param address
+ */
+ private void connectToCassaCluster(String address) throws MusicServiceException {
+ String[] addresses = null;
+ addresses = address.split(",");
+ PoolingOptions poolingOptions = new PoolingOptions();
+ poolingOptions
+ .setConnectionsPerHost(HostDistance.LOCAL, 4, 10)
+ .setConnectionsPerHost(HostDistance.REMOTE, 2, 4);
+
+ Cluster cluster;
+ if(MusicUtil.getCassName() != null && MusicUtil.getCassPwd() != null) {
+ String cassPwd;
+ if (MusicUtil.getCipherEncKey() != null && !("").equals(MusicUtil.getCipherEncKey())) {
+ cassPwd = CipherUtil.decryptPKC(MusicUtil.getCassPwd());
+ } else {
+ cassPwd = MusicUtil.getCassPwd();
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Building with credentials "+MusicUtil.getCassName()+" & "+ MusicUtil.getCassPwd());
+ cluster = Cluster.builder().withPort(MusicUtil.getCassandraPort())
+ .withCredentials(MusicUtil.getCassName(), cassPwd)
+ //.withLoadBalancingPolicy(new RoundRobinPolicy())
+ .withoutJMXReporting()
+ .withPoolingOptions(poolingOptions)
+ .withSocketOptions(
+ new SocketOptions().setConnectTimeoutMillis(MusicUtil.getCassandraConnectTimeOutMS())
+ .setReadTimeoutMillis(MusicUtil.getCassandraReadTimeOutMS()))
+ .addContactPoints(addresses).build();
+ } else {
+ cluster = Cluster.builder().withPort(MusicUtil.getCassandraPort())
+ .withoutJMXReporting()
+ .withPoolingOptions(poolingOptions)
+ .withSocketOptions(new SocketOptions()
+ .setConnectTimeoutMillis(MusicUtil.getCassandraConnectTimeOutMS())
+ .setReadTimeoutMillis(MusicUtil.getCassandraReadTimeOutMS()))
+ .addContactPoints(addresses)
+ .build();
+ }
+
+ this.setCluster(cluster);
+ Metadata metadata = this.cluster.getMetadata();
+ logger.info(EELFLoggerDelegate.applicationLogger, "Connected to cassa cluster "
+ + metadata.getClusterName() + " at " + address);
+
+ try {
+ session = this.cluster.connect();
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.CASSANDRACONNECTIVITY,
+ ErrorSeverity.ERROR, ErrorTypes.SERVICEUNAVAILABLE, ex);
+ throw new MusicServiceException(
+ "Error while connecting to Cassandra cluster.. " + ex.getMessage());
+ }
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tableName
+ * @param columnName
+ * @return DataType
+ */
+ public DataType returnColumnDataType(String keyspace, String tableName, String columnName) {
+ KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace);
+ TableMetadata table = ks.getTable(tableName);
+ return table.getColumn(columnName).getType();
+
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tableName
+ * @return TableMetadata
+ */
+ public TableMetadata returnColumnMetadata(String keyspace, String tableName) {
+ KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace);
+ return ks.getTable(tableName);
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tableName
+ * @return TableMetadata
+ */
+ public KeyspaceMetadata returnKeyspaceMetadata(String keyspace) {
+ return cluster.getMetadata().getKeyspace(keyspace);
+ }
+
+
+ /**
+ * Utility function to return the Java specific object type.
+ *
+ * @param row
+ * @param colName
+ * @param colType
+ * @return
+ */
+ public Object getColValue(Row row, String colName, DataType colType) {
+
+ switch (colType.getName()) {
+ case VARCHAR:
+ return row.getString(colName);
+ case UUID:
+ return row.getUUID(colName);
+ case VARINT:
+ return row.getVarint(colName);
+ case BIGINT:
+ return row.getLong(colName);
+ case INT:
+ return row.getInt(colName);
+ case FLOAT:
+ return row.getFloat(colName);
+ case DOUBLE:
+ return row.getDouble(colName);
+ case BOOLEAN:
+ return row.getBool(colName);
+ case MAP:
+ return row.getMap(colName, String.class, String.class);
+ case LIST:
+ return row.getList(colName, String.class);
+ default:
+ return null;
+ }
+ }
+
+ public byte[] getBlobValue(Row row, String colName, DataType colType) {
+ ByteBuffer bb = row.getBytes(colName);
+ return bb.array();
+ }
+
+ public boolean doesRowSatisfyCondition(Row row, Map<String, Object> condition) throws Exception {
+ ColumnDefinitions colInfo = row.getColumnDefinitions();
+
+ for (Map.Entry<String, Object> entry : condition.entrySet()) {
+ String colName = entry.getKey();
+ DataType colType = colInfo.getType(colName);
+ Object columnValue = getColValue(row, colName, colType);
+ Object conditionValue = MusicUtil.convertToActualDataType(colType, entry.getValue());
+ if (columnValue.equals(conditionValue) == false)
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Utility function to store ResultSet values in to a MAP for output.
+ *
+ * @param results
+ * @return MAP
+ */
+ public Map<String, HashMap<String, Object>> marshalData(ResultSet results) {
+ Map<String, HashMap<String, Object>> resultMap =
+ new HashMap<>();
+ int counter = 0;
+ for (Row row : results) {
+ ColumnDefinitions colInfo = row.getColumnDefinitions();
+ HashMap<String, Object> resultOutput = new HashMap<>();
+ for (Definition definition : colInfo) {
+ if (!(("vector_ts").equals(definition.getName()))) {
+ if(definition.getType().toString().toLowerCase().contains("blob")) {
+ resultOutput.put(definition.getName(),
+ getBlobValue(row, definition.getName(), definition.getType()));
+ } else {
+ resultOutput.put(definition.getName(),
+ getColValue(row, definition.getName(), definition.getType()));
+ }
+ }
+ }
+ resultMap.put("row " + counter, resultOutput);
+ counter++;
+ }
+ return resultMap;
+ }
+
+
+ // Prepared Statements 1802 additions
+
+ public boolean executePut(PreparedQueryObject queryObject, String consistency)
+ throws MusicServiceException, MusicQueryException {
+ return executePut(queryObject, consistency, 0);
+ }
+ /**
+ * This Method performs DDL and DML operations on Cassandra using specified consistency level
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ * @param consistency Specify consistency level for data synchronization across cassandra
+ * replicas
+ * @return Boolean Indicates operation success or failure
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public boolean executePut(PreparedQueryObject queryObject, String consistency,long timeSlot)
+ throws MusicServiceException, MusicQueryException {
+
+ boolean result = false;
+ long timeOfWrite = System.currentTimeMillis();
+ if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) {
+ logger.error(EELFLoggerDelegate.errorLogger, queryObject.getQuery(),AppMessages.QUERYERROR, ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Ill formed queryObject for the request = " + "["
+ + queryObject.getQuery() + "]");
+ }
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "In preprared Execute Put: the actual insert query:"
+ + queryObject.getQuery() + "; the values"
+ + queryObject.getValues());
+ SimpleStatement preparedInsert = null;
+
+ try {
+ preparedInsert = new SimpleStatement(queryObject.getQuery(), queryObject.getValues().toArray());
+ if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Executing critical put query");
+ preparedInsert.setConsistencyLevel(ConsistencyLevel.QUORUM);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Executing simple put query");
+ if(queryObject.getConsistency() == null)
+ preparedInsert.setConsistencyLevel(ConsistencyLevel.ONE);
+ else
+ preparedInsert.setConsistencyLevel(MusicUtil.getConsistencyLevel(queryObject.getConsistency()));
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ONE)) {
+ preparedInsert.setConsistencyLevel(ConsistencyLevel.ONE);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.QUORUM)) {
+ preparedInsert.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ALL)) {
+ preparedInsert.setConsistencyLevel(ConsistencyLevel.ALL);
+ }
+ long timestamp = MusicUtil.v2sTimeStampInMicroseconds(timeSlot, timeOfWrite);
+ preparedInsert.setDefaultTimestamp(timestamp);
+
+ ResultSet rs = session.execute(preparedInsert);
+ result = rs.wasApplied();
+ } catch (AlreadyExistsException ae) {
+ throw new MusicServiceException("Already Exists Exception: " + ae.getMessage());
+ } catch (InvalidQueryException e) {
+ if (e.getMessage().contains("unconfigured table")) {
+ throw new MusicServiceException("Invalid Query Exception: " + e.getMessage());
+ } else {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Query Exception: " + e.getMessage(),
+ AppMessages.SESSIONFAILED + " [" + queryObject.getQuery() + "]", ErrorSeverity.INFO,
+ ErrorTypes.QUERYERROR, e);
+ throw new MusicServiceException("Query Exception: " + e.getMessage());
+ }
+ } catch (Exception e) {
+ 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());
+ }
+
+ return result;
+ }
+
+ /* *//**
+ * This method performs DDL operations on Cassandra using consistency level ONE.
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ * @return ResultSet
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ *//*
+ public ResultSet executeEventualGet(PreparedQueryObject queryObject)
+ throws MusicServiceException, MusicQueryException {
+ CacheAccess<String, PreparedStatement> queryBank = CachingUtil.getStatementBank();
+ PreparedStatement preparedEventualGet = null;
+ if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) {
+ logger.error(EELFLoggerDelegate.errorLogger, "",AppMessages.QUERYERROR+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Ill formed queryObject for the request = " + "["
+ + queryObject.getQuery() + "]");
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Executing Eventual get query:" + queryObject.getQuery());
+
+ ResultSet results = null;
+ try {
+ if(queryBank.get(queryObject.getQuery()) != null )
+ preparedEventualGet=queryBank.get(queryObject.getQuery());
+ else {
+ preparedEventualGet = session.prepare(queryObject.getQuery());
+ CachingUtil.updateStatementBank(queryObject.getQuery(), preparedEventualGet);
+ }
+ if(queryObject.getConsistency() == null) {
+ preparedEventualGet.setConsistencyLevel(ConsistencyLevel.ONE);
+ } else {
+ preparedEventualGet.setConsistencyLevel(MusicUtil.getConsistencyLevel(queryObject.getConsistency()));
+ }
+ results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray()));
+
+ } catch (Exception ex) {
+ logger.error("Exception", ex);
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR+ "[" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicServiceException(ex.getMessage());
+ }
+ return results;
+ }
+
+ *//**
+ *
+ * This method performs DDL operation on Cassandra using consistency level QUORUM.
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ * @return ResultSet
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ *//*
+ public ResultSet executeCriticalGet(PreparedQueryObject queryObject)
+ throws MusicServiceException, MusicQueryException {
+ if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) {
+ logger.error(EELFLoggerDelegate.errorLogger, "",AppMessages.QUERYERROR+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Error processing Prepared Query Object for the request = " + "["
+ + queryObject.getQuery() + "]");
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Executing Critical get query:" + queryObject.getQuery());
+ PreparedStatement preparedEventualGet = session.prepare(queryObject.getQuery());
+ preparedEventualGet.setConsistencyLevel(ConsistencyLevel.QUORUM);
+ ResultSet results = null;
+ try {
+ results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray()));
+ } catch (Exception ex) {
+ logger.error("Exception", ex);
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR+ "[" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicServiceException(ex.getMessage());
+ }
+ return results;
+
+ }
+ */
+ public ResultSet executeGet(PreparedQueryObject queryObject,String consistencyLevel) throws MusicQueryException, MusicServiceException {
+ if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) {
+ logger.error(EELFLoggerDelegate.errorLogger, "",AppMessages.QUERYERROR+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Error processing Prepared Query Object for the request = " + "["
+ + queryObject.getQuery() + "]");
+ }
+ ResultSet results = null;
+ try {
+ SimpleStatement statement = new SimpleStatement(queryObject.getQuery(), queryObject.getValues().toArray());
+ if (consistencyLevel.equalsIgnoreCase(CONSISTENCY_LEVEL_ONE)) {
+ statement.setConsistencyLevel(ConsistencyLevel.ONE);
+ } else if (consistencyLevel.equalsIgnoreCase(CONSISTENCY_LEVEL_QUORUM)) {
+ statement.setConsistencyLevel(ConsistencyLevel.QUORUM);
+ } else if (consistencyLevel.equalsIgnoreCase(CONSISTENCY_LEVEL_LOCAL_QUORUM)) {
+ statement.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);
+ }
+
+ results = session.execute(statement);
+
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Execute Get Error" + ex.getMessage(),AppMessages.UNKNOWNERROR+ "[" + queryObject
+ .getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR, ex);
+ throw new MusicServiceException("Execute Get Error" + ex.getMessage());
+ }
+
+ return results;
+
+ }
+
+ /**
+ * This method performs DDL operations on Cassandra using consistency level ONE.
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ */
+ public ResultSet executeOneConsistencyGet(PreparedQueryObject queryObject)
+ throws MusicServiceException, MusicQueryException {
+ return executeGet(queryObject, CONSISTENCY_LEVEL_ONE);
+ }
+
+ /**
+ *
+ * This method performs DDL operation on Cassandra using consistency level LOCAL_QUORUM.
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ */
+ public ResultSet executeLocalQuorumConsistencyGet(PreparedQueryObject queryObject)
+ throws MusicServiceException, MusicQueryException {
+ return executeGet(queryObject, CONSISTENCY_LEVEL_LOCAL_QUORUM);
+ }
+
+ /**
+ *
+ * This method performs DDL operation on Cassandra using consistency level QUORUM.
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ */
+ public ResultSet executeQuorumConsistencyGet(PreparedQueryObject queryObject)
+ throws MusicServiceException, MusicQueryException {
+ return executeGet(queryObject, CONSISTENCY_LEVEL_QUORUM);
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java b/music-core/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java
new file mode 100644
index 00000000..09fe0d35
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/MusicDataStoreHandle.java
@@ -0,0 +1,127 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * Modifications Copyright (C) 2019 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.
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+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;
+
+public class MusicDataStoreHandle {
+
+ private static MusicDataStore mDstoreHandle = null;
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicDataStoreHandle.class);
+
+ private MusicDataStoreHandle(){
+ throw new IllegalStateException("Utility class");
+ }
+
+ /**
+ *
+ * @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;
+ }
+
+ /**
+ *
+ * @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?
+ 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;
+ }
+
+ public static void setMDstoreHandle(MusicDataStore dsHandle) {
+ mDstoreHandle = dsHandle;
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @return
+ * @throws MusicServiceException
+ */
+ 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);
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/PreparedQueryObject.java b/music-core/src/main/java/org/onap/music/datastore/PreparedQueryObject.java
new file mode 100644
index 00000000..fdac50be
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/PreparedQueryObject.java
@@ -0,0 +1,176 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017-2019 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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author srupane
+ *
+ */
+public class PreparedQueryObject {
+
+
+ private List<Object> values;
+ private StringBuilder query;
+ private String consistency;
+ private String keyspaceName;
+ private String tableName;
+ private String operation;
+ private String primaryKeyValue;
+
+
+ /**
+ * Create PreparedQueryObject
+ */
+ public PreparedQueryObject() {
+ this.values = new ArrayList<>();
+ this.query = new StringBuilder();
+ }
+
+ /**
+ * Create PreparedQueryObject
+ * @param query query portion of the prepared query
+ */
+ public PreparedQueryObject(String query) {
+ this.values = new ArrayList<>();
+ this.query = new StringBuilder(query);
+ }
+
+ /**
+ * Create PreparedQueryObject
+ * @param query query portion of the prepared query
+ * @param values to be added to the query string as prepared query
+ */
+ public PreparedQueryObject(String query, Object...values) {
+ this.query = new StringBuilder(query);
+ this.values = new ArrayList<>();
+ for (Object value: values) {
+ this.values.add(value);
+ }
+ }
+
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String getOperation() {
+ if (operation!=null) return operation;
+ if (query.length()==0) return null;
+ String queryStr = query.toString().toLowerCase();
+ String firstOp = null;
+ int firstOpChar = query.length();
+ if (queryStr.indexOf("insert")>-1 && queryStr.indexOf("insert")<firstOpChar) {
+ firstOp = "insert";
+ firstOpChar = queryStr.indexOf("insert");
+ }
+ if (queryStr.indexOf("update")>-1 && queryStr.indexOf("update")<firstOpChar) {
+ firstOp = "update";
+ firstOpChar = queryStr.indexOf("update");
+ }
+ if (queryStr.indexOf("delete")>-1 && queryStr.indexOf("delete")<firstOpChar) {
+ firstOp = "delete";
+ firstOpChar = queryStr.indexOf("delete");
+ }
+ if (queryStr.indexOf("select")>-1 && queryStr.indexOf("select")<firstOpChar) {
+ firstOp = "select";
+ firstOpChar = queryStr.indexOf("select");
+ }
+ return firstOp;
+ }
+
+ public void setOperation(String operation) {
+ this.operation = operation;
+ }
+
+ public String getPrimaryKeyValue() {
+ return primaryKeyValue;
+ }
+
+ public void setPrimaryKeyValue(String primaryKeyValue) {
+ this.primaryKeyValue = primaryKeyValue;
+ }
+
+ public String getConsistency() {
+ return consistency;
+ }
+
+ public void setConsistency(String consistency) {
+ this.consistency = consistency;
+ }
+
+ /**
+ * @return values to be set as part of the prepared query
+ */
+ public List<Object> getValues() {
+ return values;
+ }
+
+ /**
+ * @param o object to be added as a value to the prepared query, in order
+ */
+ public void addValue(Object o) {
+ this.values.add(o);
+ }
+
+ /**
+ * Add values to the preparedQuery
+ * @param objs ordered list of objects to be added as values to the prepared query
+ */
+ public void addValues(Object... objs) {
+ for (Object obj: objs) {
+ this.values.add(obj);
+ }
+ }
+
+ /**
+ * @param s
+ */
+ public void appendQueryString(String s) {
+ this.query.append(s);
+ }
+ public void replaceQueryString(String s) {
+ this.query.replace(0, query.length(), s);
+ }
+
+ /**
+ * @return the query
+ */
+ public String getQuery() {
+ return this.query.toString();
+ }
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java
new file mode 100644
index 00000000..a1524cc6
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java
@@ -0,0 +1,37 @@
+package org.onap.music.datastore.jsonobjects;
+/*
+ * ============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=============================================
+ * ====================================================================
+ */
+
+
+public class JSONObject {
+
+ private String data;
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java
new file mode 100644
index 00000000..988ba3a8
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java
@@ -0,0 +1,313 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ===================================================================
+ * 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.
+ * 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.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.music.datastore.Condition;
+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.main.MusicUtil;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.TableMetadata;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Json model for delete")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonDelete {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonDelete.class);
+
+ private List<String> columns = null;
+ private Map<String, String> consistencyInfo;
+ private Map<String, Object> conditions;
+ private String ttl;
+ private String timestamp;
+ private String keyspaceName;
+ private String tableName;
+ private StringBuilder rowIdString;
+ private String primarKeyValue;
+
+
+ @ApiModelProperty(value = "Conditions")
+ public Map<String, Object> getConditions() {
+ return conditions;
+ }
+
+ public void setConditions(Map<String, Object> conditions) {
+ this.conditions = conditions;
+ }
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Column values")
+ public List<String> getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List<String> columns) {
+ this.columns = columns;
+ }
+
+
+ @ApiModelProperty(value = "Time to live information")
+ public String getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(String ttl) {
+ this.ttl = ttl;
+ }
+
+ @ApiModelProperty(value = "Time stamp")
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public StringBuilder getRowIdString() {
+ return rowIdString;
+ }
+
+ public void setRowIdString(StringBuilder rowIdString) {
+ this.rowIdString = rowIdString;
+ }
+
+ public String getPrimarKeyValue() {
+ return primarKeyValue;
+ }
+
+ public void setPrimarKeyValue(String primarKeyValue) {
+ this.primarKeyValue = primarKeyValue;
+ }
+
+
+ public PreparedQueryObject genDeletePreparedQueryObj(MultivaluedMap<String, String> rowParams) throws MusicQueryException {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Coming inside genUpdatePreparedQueryObj method " + this.getKeyspaceName());
+ logger.debug("Coming inside genUpdatePreparedQueryObj method " + this.getTableName());
+ }
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ if((this.getKeyspaceName() == null || this.getKeyspaceName().isEmpty())
+ || (this.getTableName() == null || this.getTableName().isEmpty())){
+
+
+ throw new MusicQueryException("one or more path parameters are not set, please check and try again",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+
+ EELFLoggerDelegate.mdcPut("keyspace", "( "+this.getKeyspaceName()+" ) ");
+
+ if(this == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Required HTTP Request body is missing.", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
+
+ throw new MusicQueryException("Required HTTP Request body is missing.",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ StringBuilder columnString = new StringBuilder();
+
+ int counter = 0;
+ List<String> columnList = this.getColumns();
+ if (columnList != null) {
+ for (String column : columnList) {
+ columnString.append(column);
+ if (counter != columnList.size() - 1)
+ columnString.append(",");
+ counter = counter + 1;
+ }
+ }
+
+ // get the row specifier
+ RowIdentifier rowId = null;
+ try {
+ rowId = getRowIdentifier(this.getKeyspaceName(), this.getTableName(), rowParams, queryObject);
+ this.setRowIdString(rowId.rowIdString);
+ this.setPrimarKeyValue(rowId.primarKeyValue);
+ if(rowId == null || rowId.primarKeyValue.isEmpty()) {
+
+ throw new MusicQueryException("Mandatory WHERE clause is missing. Please check the input request.",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
+ .GENERALSERVICEERROR, ex);
+ /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();*/
+ throw new MusicQueryException(AppMessages.UNKNOWNERROR.toString(), Status.BAD_REQUEST.getStatusCode());
+ }
+ String rowSpec = rowId.rowIdString.toString();
+
+ if ((columnList != null) && (!rowSpec.isEmpty())) {
+ queryObject.appendQueryString("DELETE " + columnString + " FROM " + this.getKeyspaceName() + "."
+ + this.getTableName() + " WHERE " + rowSpec + ";");
+ }
+
+ if ((columnList == null) && (!rowSpec.isEmpty())) {
+ queryObject.appendQueryString("DELETE FROM " + this.getKeyspaceName() + "." + this.getTableName() + " WHERE "
+ + rowSpec + ";");
+ }
+
+ if ((columnList != null) && (rowSpec.isEmpty())) {
+ queryObject.appendQueryString(
+ "DELETE " + columnString + " FROM " + this.getKeyspaceName() + "." + rowSpec + ";");
+ }
+ // get the conditional, if any
+ Condition conditionInfo;
+ if (this.getConditions() == null) {
+ conditionInfo = null;
+ } else {
+ // to avoid parsing repeatedly, just send the select query to
+ // obtain row
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ selectQuery.appendQueryString("SELECT * FROM " + this.getKeyspaceName() + "." + this.getTableName() + " WHERE "
+ + rowId.rowIdString + ";");
+ selectQuery.addValue(rowId.primarKeyValue);
+ conditionInfo = new Condition(this.getConditions(), selectQuery);
+ }
+
+ String consistency = this.getConsistencyInfo().get("type");
+
+
+ if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && this.getConsistencyInfo().get("consistency")!=null) {
+ if(MusicUtil.isValidConsistency(this.getConsistencyInfo().get("consistency"))) {
+ queryObject.setConsistency(this.getConsistencyInfo().get("consistency"));
+ } else {
+ throw new MusicQueryException("Invalid Consistency type", Status.BAD_REQUEST.getStatusCode());
+ }
+ }
+
+ queryObject.setOperation("delete");
+
+ return queryObject;
+ }
+
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @param rowParams
+ * @param queryObject
+ * @return
+ * @throws MusicServiceException
+ */
+ private RowIdentifier getRowIdentifier(String keyspace, String tablename,
+ MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
+ throws MusicServiceException {
+ StringBuilder rowSpec = new StringBuilder();
+ int counter = 0;
+ TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
+ if (tableInfo == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ throw new MusicServiceException(
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ }
+ StringBuilder primaryKey = new StringBuilder();
+ for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
+ String keyName = entry.getKey();
+ List<String> valueList = entry.getValue();
+ String indValue = valueList.get(0);
+ DataType colType = null;
+ Object formattedValue = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e);
+ }
+ if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey())) {
+ primaryKey.append(indValue);
+ }
+ rowSpec.append(keyName + "= ?");
+ queryObject.addValue(formattedValue);
+ if (counter != rowParams.size() - 1) {
+ rowSpec.append(" AND ");
+ }
+ counter = counter + 1;
+ }
+ return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
+ }
+
+ private class RowIdentifier {
+ private String primarKeyValue;
+ private StringBuilder rowIdString;
+ @SuppressWarnings("unused")
+ public PreparedQueryObject queryObject; // the string with all the row
+ // identifiers separated by AND
+
+ public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
+ PreparedQueryObject queryObject) {
+ this.primarKeyValue = primaryKeyValue;
+ this.rowIdString = rowIdString;
+ this.queryObject = queryObject;
+ }
+ }
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonIndex.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonIndex.java
new file mode 100644
index 00000000..a06e8ea9
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonIndex.java
@@ -0,0 +1,120 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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 org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@ApiModel(value = "JsonIndex", description = "Index Object")
+public class JsonIndex {
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonIndex.class);
+
+ private String indexName;
+ private String keyspaceName;
+ private String tableName;
+ private String fieldName;
+
+ public JsonIndex(String indexName,String keyspaceName,String tableName,String fieldName) {
+ this.indexName = indexName;
+ this.keyspaceName= keyspaceName;
+ this.tableName = tableName;
+ this.fieldName = fieldName;
+ }
+
+ @ApiModelProperty(value = "Index Name")
+ public String getIndexName() {
+ return indexName;
+ }
+
+ public JsonIndex setIndexName(String indexName) {
+ this.indexName = indexName;
+ return this;
+ }
+
+ @ApiModelProperty(value = "Keyspace name")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public JsonIndex setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ return this;
+ }
+
+ public JsonIndex setTableName(String tableName) {
+ this.tableName = tableName;
+ return this;
+ }
+
+ @ApiModelProperty(value = "Table name")
+ public String getTableName() {
+ return tableName;
+ }
+
+ public JsonIndex setFieldName(String fieldName) {
+ this.fieldName = fieldName;
+ return this;
+ }
+
+ @ApiModelProperty(value = "Field name")
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public PreparedQueryObject genCreateIndexQuery() {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Came inside genCreateIndexQuery method");
+ }
+
+ logger.info("genCreateIndexQuery indexName ::" + indexName);
+ logger.info("genCreateIndexQuery keyspaceName ::" + keyspaceName);
+ logger.info("genCreateIndexQuery tableName ::" + tableName);
+ logger.info("genCreateIndexQuery fieldName ::" + fieldName);
+
+ long start = System.currentTimeMillis();
+
+ PreparedQueryObject query = new PreparedQueryObject();
+ query.appendQueryString("Create index if not exists " + this.getIndexName() + " on " + this.getKeyspaceName() + "."
+ + this.getTableName() + " (" + this.getFieldName() + ");");
+
+ long end = System.currentTimeMillis();
+
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Time taken for setting up query in create index:" + (end - start));
+
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ " create index query :" + query.getQuery());
+
+ return query;
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java
new file mode 100644
index 00000000..2f685cfe
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java
@@ -0,0 +1,415 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response.Status;
+
+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.main.MusicUtil;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.TableMetadata;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "InsertTable", description = "Json model for table vlaues insert")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonInsert implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private String keyspaceName;
+ private String tableName;
+ private transient Map<String, Object> values;
+ private String ttl;
+ private String timestamp;
+ private transient Map<String, Object> rowSpecification;
+ private Map<String, String> consistencyInfo;
+ private Map<String, byte[]> objectMap;
+ private String primaryKeyVal;
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonInsert.class);
+
+ @ApiModelProperty(value = "objectMap",hidden = true)
+ public Map<String, byte[]> getObjectMap() {
+ return objectMap;
+ }
+
+ public void setObjectMap(Map<String, byte[]> objectMap) {
+ this.objectMap = objectMap;
+ }
+
+ @ApiModelProperty(value = "keyspace")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ @ApiModelProperty(value = "Table name")
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Columns and tables support an optional "
+ + "expiration period called TTL (time-to-live) in seconds.",
+ notes="TTL precision is one second, which is calculated by the coordinator "
+ + "node. When using TTL, ensure that all nodes in the cluster have synchronized clocks.",allowEmptyValue = true)
+ public String getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(String ttl) {
+ this.ttl = ttl;
+ }
+
+ @ApiModelProperty(value = "Time stamp (epoch_in_microseconds)",
+ notes = "Marks inserted data (write time) with TIMESTAMP. "
+ + "Enter the time since epoch (January 1, 1970) in microseconds."
+ + "By default, the actual time of write is used.", allowEmptyValue = true)
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @ApiModelProperty(value = "Json Object of key/values", notes="Where key is the column name and value is the data value for that column.",
+ example = "{'emp_id': 'df98a3d40cd6','emp_name': 'john',"
+ + "'emp_salary': 50,'address':{'street' : '1 Some way','city' : 'New York'}}")
+ public Map<String, Object> getValues() {
+ return values;
+ }
+
+ public void setValues(Map<String, Object> values) {
+ this.values = values;
+ }
+
+ @ApiModelProperty(value = "Information for selecting specific rows for insert",hidden = true)
+ public Map<String, Object> getRowSpecification() {
+ return rowSpecification;
+ }
+
+ public void setRowSpecification(Map<String, Object> rowSpecification) {
+ this.rowSpecification = rowSpecification;
+ }
+
+ public String getPrimaryKeyVal() {
+ return primaryKeyVal;
+ }
+
+ public void setPrimaryKeyVal(String primaryKeyVal) {
+ this.primaryKeyVal = primaryKeyVal;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e, AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.DATAERROR);
+ }
+ return bos.toByteArray();
+ }
+
+ /**
+ * Generate TableInsertQuery
+ * @return
+ * @throws MusicQueryException
+ */
+ public PreparedQueryObject genInsertPreparedQueryObj() throws MusicQueryException {
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ TableMetadata tableInfo = null;
+ try {
+ tableInfo = MusicDataStoreHandle.returnColumnMetadata(this.getKeyspaceName(), this.getTableName());
+ if(tableInfo == null) {
+ throw new MusicQueryException("Table name doesn't exists. Please check the table name.",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e, AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ throw new MusicQueryException(e.getMessage(),Status.BAD_REQUEST.getStatusCode());
+
+ }
+ String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
+ StringBuilder fieldsString = new StringBuilder("(vector_ts,");
+ String vectorTs =
+ String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
+ StringBuilder valueString = new StringBuilder("(" + "?" + ",");
+ queryObject.addValue(vectorTs);
+
+ Map<String, Object> valuesMap = this.getValues();
+ if (valuesMap==null) {
+ throw new MusicQueryException("Nothing to insert. No values provided in request.",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ int counter = 0;
+ String primaryKey = "";
+ for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
+ fieldsString.append("" + entry.getKey());
+ Object valueObj = entry.getValue();
+ if (primaryKeyName.equals(entry.getKey())) {
+ primaryKey = entry.getValue() + "";
+ primaryKey = primaryKey.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);
+ throw new MusicQueryException("Invalid column name : " + entry.getKey(),
+ Status.BAD_REQUEST.getStatusCode());
+ }
+
+ Object formattedValue = null;
+ try {
+ formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e);
+ }
+ valueString.append("?");
+
+ queryObject.addValue(formattedValue);
+
+ if (counter == valuesMap.size() - 1) {
+ fieldsString.append(")");
+ valueString.append(")");
+ } else {
+ fieldsString.append(",");
+ valueString.append(",");
+ }
+ counter = counter + 1;
+ }
+
+ //blobs..
+ Map<String, byte[]> objectMap = this.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("'", "''");
+ }
+ DataType colType = tableInfo.getColumn(entry.getKey()).getType();
+ ByteBuffer formattedValue = null;
+ if(colType.toString().toLowerCase().contains("blob")) {
+ formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
+ }
+ valueString.append("?");
+ queryObject.addValue(formattedValue);
+ counter = counter + 1;
+ fieldsString.append(",");
+ valueString.append(",");
+ }
+ }
+ this.setPrimaryKeyVal(primaryKey);
+ if(primaryKey == null || primaryKey.length() <= 0) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
+ throw new MusicQueryException("Some required partition key parts are missing: " + primaryKeyName,
+ Status.BAD_REQUEST.getStatusCode());
+ }
+
+ fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ")");
+ valueString.replace(valueString.length()-1, valueString.length(), ")");
+
+ queryObject.appendQueryString("INSERT INTO " + this.getKeyspaceName() + "." + this.getTableName() + " "
+ + fieldsString + " VALUES " + valueString);
+
+ String ttl = this.getTtl();
+ String timestamp = this.getTimestamp();
+
+ if ((ttl != null) && (timestamp != null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "both there");
+ queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ if ((ttl != null) && (timestamp == null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
+ queryObject.appendQueryString(" USING TTL ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ }
+
+ if ((ttl == null) && (timestamp != null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
+ queryObject.appendQueryString(" USING TIMESTAMP ?");
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ queryObject.appendQueryString(";");
+
+ String consistency = this.getConsistencyInfo().get("type");
+ if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && this.getConsistencyInfo().get("consistency") != null) {
+ if(MusicUtil.isValidConsistency(this.getConsistencyInfo().get("consistency"))) {
+ queryObject.setConsistency(this.getConsistencyInfo().get("consistency"));
+ } else {
+ throw new MusicQueryException("Invalid Consistency type", Status.BAD_REQUEST.getStatusCode());
+ }
+ }
+ queryObject.setOperation("insert");
+
+ logger.info("Data insert Query ::::: " + queryObject.getQuery());
+
+ return queryObject;
+ }
+
+ /**
+ *
+ * @param rowParams
+ * @return
+ * @throws MusicQueryException
+ */
+ public PreparedQueryObject genSelectCriticalPreparedQueryObj(MultivaluedMap<String, String> rowParams) throws MusicQueryException {
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ if((this.getKeyspaceName() == null || this.getKeyspaceName().isEmpty())
+ || (this.getTableName() == null || this.getTableName().isEmpty())){
+ throw new MusicQueryException("one or more path parameters are not set, please check and try again",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ EELFLoggerDelegate.mdcPut("keyspace", "( "+this.getKeyspaceName()+" ) ");
+ RowIdentifier rowId = null;
+ try {
+ rowId = getRowIdentifier(this.getKeyspaceName(), this.getTableName(), rowParams, queryObject);
+ this.setPrimaryKeyVal(rowId.primarKeyValue);
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
+ .GENERALSERVICEERROR, ex);
+ throw new MusicQueryException(ex.getMessage(), Status.BAD_REQUEST.getStatusCode());
+ }
+
+ queryObject.appendQueryString(
+ "SELECT * FROM " + this.getKeyspaceName() + "." + this.getTableName() + " WHERE " + rowId.rowIdString + ";");
+
+ return queryObject;
+ }
+
+ private class RowIdentifier {
+ public String primarKeyValue;
+ public StringBuilder rowIdString;
+ @SuppressWarnings("unused")
+ public PreparedQueryObject queryObject; // the string with all the row
+ // identifiers separated by AND
+
+ public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
+ PreparedQueryObject queryObject) {
+ this.primarKeyValue = primaryKeyValue;
+ this.rowIdString = rowIdString;
+ this.queryObject = queryObject;
+ }
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @param rowParams
+ * @param queryObject
+ * @return
+ * @throws MusicServiceException
+ */
+ private RowIdentifier getRowIdentifier(String keyspace, String tablename,
+ MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
+ throws MusicServiceException {
+ StringBuilder rowSpec = new StringBuilder();
+ int counter = 0;
+ TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
+ if (tableInfo == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ throw new MusicServiceException(
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ }
+ StringBuilder primaryKey = new StringBuilder();
+ for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
+ String keyName = entry.getKey();
+ List<String> valueList = entry.getValue();
+ String indValue = valueList.get(0);
+ DataType colType = null;
+ Object formattedValue = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e);
+ }
+ if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey())) {
+ primaryKey.append(indValue);
+ }
+ rowSpec.append(keyName + "= ?");
+ queryObject.addValue(formattedValue);
+ if (counter != rowParams.size() - 1) {
+ rowSpec.append(" AND ");
+ }
+ counter = counter + 1;
+ }
+ return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
+ }
+
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java
new file mode 100644
index 00000000..cada1c00
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java
@@ -0,0 +1,163 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.util.Map;
+
+import javax.ws.rs.core.Response.Status;
+
+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.main.MusicUtil;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Json model creating new keyspace")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonKeySpace {
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonKeySpace.class);
+ private String keyspaceName;
+ private Map<String, Object> replicationInfo;
+ private String durabilityOfWrites;
+ private Map<String, String> consistencyInfo;
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Replication information")
+ public Map<String, Object> getReplicationInfo() {
+ return replicationInfo;
+ }
+
+ public void setReplicationInfo(Map<String, Object> replicationInfo) {
+ this.replicationInfo = replicationInfo;
+ }
+
+ @ApiModelProperty(value = "Durability", allowableValues = "true,false")
+ public String getDurabilityOfWrites() {
+ return durabilityOfWrites;
+ }
+
+ public void setDurabilityOfWrites(String durabilityOfWrites) {
+ this.durabilityOfWrites = durabilityOfWrites;
+ }
+
+ @ApiModelProperty(value = "Keyspace name")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ /**
+ * Will generate query to create Keyspacce.
+ *
+ * @throws MusicQueryException
+ */
+ @SuppressWarnings("deprecation")
+ public PreparedQueryObject genCreateKeyspaceQuery() throws MusicQueryException {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Came inside createKeyspace method");
+ }
+
+ String keyspaceName = this.getKeyspaceName();
+ String durabilityOfWrites = this.getDurabilityOfWrites();
+ String consistency = MusicUtil.EVENTUAL;
+
+ logger.info("genCreateKeyspaceQuery keyspaceName ::" + keyspaceName);
+ logger.info("genCreateKeyspaceQuery class :: " + this.getReplicationInfo().get("class"));
+ logger.info("genCreateKeyspaceQuery replication_factor :: " + this.getReplicationInfo().get("replication_factor"));
+ logger.info("genCreateKeyspaceQuery durabilityOfWrites :: " + durabilityOfWrites);
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && this.getConsistencyInfo().get("consistency") != null) {
+ if(MusicUtil.isValidConsistency(this.getConsistencyInfo().get("consistency"))) {
+ queryObject.setConsistency(this.getConsistencyInfo().get("consistency"));
+ }else {
+ throw new MusicQueryException("Invalid Consistency type",Status.BAD_REQUEST.getStatusCode());
+ }
+ }
+
+ long start = System.currentTimeMillis();
+ Map<String, Object> replicationInfo = this.getReplicationInfo();
+ String repString = null;
+ try {
+ repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.MISSINGDATA,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ }
+ queryObject.appendQueryString("CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
+ if (this.getDurabilityOfWrites() != null) {
+ queryObject.appendQueryString(" AND durable_writes = " + this.getDurabilityOfWrites());
+ }
+ queryObject.appendQueryString(";");
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Time taken for setting up query in create keyspace:" + (end - start));
+
+ return queryObject;
+ }
+
+ /**
+ * Will generate Query to drop a keyspace.
+ *
+ * @return
+ */
+ public PreparedQueryObject genDropKeyspaceQuery() {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Coming inside genDropKeyspaceQuery method "+this.getKeyspaceName());
+ }
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("DROP KEYSPACE " + this.getKeyspaceName() + ";");
+
+ return queryObject;
+ }
+
+ @Override
+ public String toString() {
+ return "CassaKeyspaceObject [keyspaceName=" + keyspaceName + ", replicationInfo=" + replicationInfo
+ + "durabilityOfWrites=" + durabilityOfWrites + "]";
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java
new file mode 100644
index 00000000..86bbe3dc
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java
@@ -0,0 +1,44 @@
+/*
+ * ============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 com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "Json Leasesd Lock", description = "model for leased lock")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonLeasedLock {
+ private long leasePeriod;
+
+ @ApiModelProperty(value = "Lease period")
+ public long getLeasePeriod() {
+ return leasePeriod;
+ }
+
+ public void setLeasePeriod(long leasePeriod) {
+ this.leasePeriod = leasePeriod;
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLock.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLock.java
new file mode 100644
index 00000000..f353c018
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonLock.java
@@ -0,0 +1,49 @@
+/*
+ * ============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 org.onap.music.lockingservice.cassandra.LockType;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "Json Lock Type", description = "Model for Lock Type")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonLock {
+ private LockType locktype;
+
+ @ApiModelProperty(
+ value = "Type of music lock",
+ name = "lockType",
+ allowEmptyValue = false,
+ allowableValues = "READ|WRITE")
+ public LockType getLocktype() {
+ return this.locktype;
+ }
+
+ public void setLockType(LockType locktype) {
+ this.locktype = locktype;
+ }
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java
new file mode 100644
index 00000000..e354b4b0
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java
@@ -0,0 +1,208 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response.Status;
+
+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.main.MusicUtil;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.TableMetadata;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonSelect implements Serializable {
+ private Map<String, String> consistencyInfo;
+ private String keyspaceName;
+ private String tableName;
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonSelect.class);
+
+
+
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e);
+ }
+ return bos.toByteArray();
+ }
+
+ /**
+ * genSelectQuery
+ *
+ * @return
+ * @throws MusicQueryException
+ */
+ public PreparedQueryObject genSelectQuery(MultivaluedMap<String, String> rowParams) throws MusicQueryException {
+
+ if((this.getKeyspaceName() == null || this.getKeyspaceName().isEmpty())
+ || (this.getTableName() == null || this.getTableName().isEmpty())){
+ throw new MusicQueryException("one or more path parameters are not set, please check and try again",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ EELFLoggerDelegate.mdcPut("keyspace", "( " + this.getKeyspaceName() + " ) ");
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ if (rowParams.isEmpty()) { // select all
+ queryObject.appendQueryString("SELECT * FROM " + this.getKeyspaceName() + "." + this.getTableName() + ";");
+ } else {
+ int limit = -1; // do not limit the number of results
+ try {
+ queryObject = selectSpecificQuery(this.getKeyspaceName(), this.getTableName(), rowParams, limit);
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
+ ErrorTypes.GENERALSERVICEERROR, ex);
+
+ throw new MusicQueryException(ex.getMessage(), Status.BAD_REQUEST.getStatusCode());
+ }
+ }
+
+ return queryObject;
+ }
+
+ public PreparedQueryObject selectSpecificQuery(String keyspace,
+ String tablename, MultivaluedMap<String, String> rowParams, int limit)
+ throws MusicServiceException {
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ StringBuilder rowIdString = getRowIdentifier(keyspace,
+ tablename,rowParams,queryObject).rowIdString;
+ queryObject.appendQueryString(
+ "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
+ if (limit != -1) {
+ queryObject.appendQueryString(" LIMIT " + limit);
+ }
+ queryObject.appendQueryString(";");
+ return queryObject;
+ }
+
+ private class RowIdentifier {
+ public String primarKeyValue;
+ public StringBuilder rowIdString;
+ @SuppressWarnings("unused")
+ public PreparedQueryObject queryObject; // the string with all the row
+ // identifiers separated by AND
+
+ public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
+ PreparedQueryObject queryObject) {
+ this.primarKeyValue = primaryKeyValue;
+ this.rowIdString = rowIdString;
+ this.queryObject = queryObject;
+ }
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @param rowParams
+ * @param queryObject
+ * @return
+ * @throws MusicServiceException
+ */
+ private RowIdentifier getRowIdentifier(String keyspace, String tablename,
+ MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
+ throws MusicServiceException {
+ StringBuilder rowSpec = new StringBuilder();
+ int counter = 0;
+ TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
+ if (tableInfo == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ throw new MusicServiceException(
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ }
+ StringBuilder primaryKey = new StringBuilder();
+ for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
+ String keyName = entry.getKey();
+ List<String> valueList = entry.getValue();
+ String indValue = valueList.get(0);
+ DataType colType = null;
+ Object formattedValue = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e);
+ }
+ if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey())) {
+ primaryKey.append(indValue);
+ }
+ rowSpec.append(keyName + "= ?");
+ queryObject.addValue(formattedValue);
+ if (counter != rowParams.size() - 1) {
+ rowSpec.append(" AND ");
+ }
+ counter = counter + 1;
+ }
+ return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java
new file mode 100644
index 00000000..0ba1a7ef
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java
@@ -0,0 +1,363 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.util.Map;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.commons.lang3.StringUtils;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.main.MusicUtil;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Defines the Json for Creating a new Table.")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonTable {
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonTable.class);
+
+ private String keyspaceName;
+ private String tableName;
+
+ private Map<String, String> fields;
+ private Map<String, Object> properties;
+ private String primaryKey;
+ private String partitionKey;
+ private String clusteringKey;
+ private String filteringKey;
+ private String clusteringOrder;
+ private Map<String, String> consistencyInfo;
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Properties")
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ @ApiModelProperty(value = "Fields")
+ public Map<String, String> getFields() {
+ return fields;
+ }
+
+ public void setFields(Map<String, String> fields) {
+ this.fields = fields;
+ }
+
+ @ApiModelProperty(value = "KeySpace Name")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ @ApiModelProperty(value = "Table Name")
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @ApiModelProperty(value = "Clustering Order", notes = "")
+ public String getClusteringOrder() {
+ return clusteringOrder;
+ }
+
+ public void setClusteringOrder(String clusteringOrder) {
+ this.clusteringOrder = clusteringOrder;
+ }
+
+ @ApiModelProperty(value = "Primary Key")
+ public String getPrimaryKey() {
+ return primaryKey;
+ }
+
+ public void setPrimaryKey(String primaryKey) {
+ this.primaryKey = primaryKey;
+ }
+
+ public String getClusteringKey() {
+ return clusteringKey;
+ }
+
+ public void setClusteringKey(String clusteringKey) {
+ this.clusteringKey = clusteringKey;
+ }
+
+ public String getFilteringKey() {
+ return filteringKey;
+ }
+
+ public void setFilteringKey(String filteringKey) {
+ this.filteringKey = filteringKey;
+ }
+
+ public String getPartitionKey() {
+ return partitionKey;
+ }
+
+ public void setPartitionKey(String partitionKey) {
+ this.partitionKey = partitionKey;
+ }
+
+ public PreparedQueryObject genCreateTableQuery() throws MusicQueryException {
+ String primaryKey = null;
+ String partitionKey = this.getPartitionKey();
+ String clusterKey = this.getClusteringKey();
+ String filteringKey = this.getFilteringKey();
+ if (filteringKey != null) {
+ clusterKey = clusterKey + "," + filteringKey;
+ }
+ primaryKey = this.getPrimaryKey(); // get primaryKey if available
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ // first read the information about the table fields
+ Map<String, String> fields = this.getFields();
+ if (fields == null) {
+ throw new MusicQueryException(
+ "Create Table Error: No fields in request", Status.BAD_REQUEST.getStatusCode());
+ }
+ 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() + "");
+ }
+
+ 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) {
+ throw new MusicQueryException(
+ "Create Table Error: primary key '(' and ')' do not match, primary key=" + primaryKey,
+ Status.BAD_REQUEST.getStatusCode());
+ }
+
+ 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("[\\(]+","");
+ 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())
+ && (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(
+ "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ") of"
+ + " primary key=" + primaryKey)
+ .toMap()).build();*/
+ throw new MusicQueryException("Create Table primary key error: clusterKey(" + clusterKey
+ + ") equals/contains/overlaps partitionKey(" + partitionKey + ") of" + " primary key="
+ + primaryKey, Status.BAD_REQUEST.getStatusCode());
+
+ }
+
+ if (partitionKey.isEmpty() )
+ primaryKey="";
+ else if (clusterKey.isEmpty() )
+ primaryKey=" (" + partitionKey + ")";
+ else
+ primaryKey=" (" + partitionKey + ")," + clusterKey;
+
+
+ if (primaryKey != null)
+ fieldsString.append(", PRIMARY KEY (" + primaryKey + " )");
+
+ } 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(
+ "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ")")
+ .toMap()).build();*/
+ throw new MusicQueryException(
+ "Create Table primary key error: clusterKey(" + clusterKey
+ + ") equals/contains/overlaps partitionKey(" + partitionKey + ")",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+
+ 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 = this.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;
+ try {
+ value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
+ } catch (Exception e) {
+ throw new MusicQueryException(e.getMessage(),
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ }
+
+ propertiesString.append(entry.getKey() + "=" + value + "");
+ if (counter != propertiesMap.size() - 1)
+ propertiesString.append(" AND ");
+
+ counter = counter + 1;
+ }
+ }
+
+ String clusteringOrder = this.getClusteringOrder();
+
+ 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();*/
+
+ throw new MusicQueryException(
+ "createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:"
+ + clusteringOrder + ".",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ // 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);
+ } else {
+ propertiesString.append(clusteringOrder);
+ }
+ } else {
+ logger.warn("Skipping clustering order=("+clusteringOrder+ ") since clustering key is empty ");
+ }
+ } //if non empty
+
+ queryObject.appendQueryString(
+ "CREATE TABLE " + this.getKeyspaceName() + "." + this.getTableName() + " " + fieldsString);
+
+
+ if (propertiesString != null && propertiesString.length()>0 )
+ queryObject.appendQueryString(" WITH " + propertiesString);
+ queryObject.appendQueryString(";");
+
+ return queryObject;
+ }
+
+ /**
+ * genDropTableQuery
+ *
+ * @return PreparedQueryObject
+ */
+ public PreparedQueryObject genDropTableQuery() {
+ PreparedQueryObject query = new PreparedQueryObject();
+ query.appendQueryString("DROP TABLE " + this.getKeyspaceName() + "." + this.getTableName() + ";");
+ logger.info("Delete Query ::::: " + query.getQuery());
+
+ return query;
+ }
+
+
+}
diff --git a/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java
new file mode 100644
index 00000000..29fdb1d4
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java
@@ -0,0 +1,436 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response.Status;
+
+import org.onap.music.datastore.Condition;
+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.main.MusicUtil;
+import org.onap.music.main.ReturnType;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.TableMetadata;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Json model for table update")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonUpdate implements Serializable {
+ private String keyspaceName;
+ private String tableName;
+ private transient Map<String, Object> values;
+ private String ttl;
+ private String timestamp;
+ private Map<String, String> consistencyInfo;
+ private transient Map<String, Object> conditions;
+ private transient Map<String, Object> rowSpecification;
+ private String rowIdString;
+ private String primarKeyValue;
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonUpdate.class);
+
+ @ApiModelProperty(value = "Conditions")
+ public Map<String, Object> getConditions() {
+ return conditions;
+ }
+
+ public void setConditions(Map<String, Object> conditions) {
+ this.conditions = conditions;
+ }
+
+ @ApiModelProperty(value = "Information for selecting sepcific rows")
+ public Map<String, Object> getRow_specification() {
+ return rowSpecification;
+ }
+
+ public void setRow_specification(Map<String, Object> rowSpecification) {
+ this.rowSpecification = rowSpecification;
+ }
+
+
+ @ApiModelProperty(value = "Keyspace name")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ @ApiModelProperty(value = "Table name")
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Time to live value")
+ public String getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(String ttl) {
+ this.ttl = ttl;
+ }
+
+ @ApiModelProperty(value = "Time stamp")
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @ApiModelProperty(value = "Column values")
+ public Map<String, Object> getValues() {
+ return values;
+ }
+
+ public void setValues(Map<String, Object> values) {
+ this.values = values;
+ }
+
+ public String getRowIdString() {
+ return rowIdString;
+ }
+
+ public void setRowIdString(String rowIdString) {
+ this.rowIdString = rowIdString;
+ }
+
+ public String getPrimarKeyValue() {
+ return primarKeyValue;
+ }
+
+ public void setPrimarKeyValue(String primarKeyValue) {
+ this.primarKeyValue = primarKeyValue;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e,AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.DATAERROR);
+ }
+ return bos.toByteArray();
+ }
+
+ /**
+ * Generate TableInsertQuery
+ * @return
+ * @throws MusicQueryException
+ */
+ public PreparedQueryObject genUpdatePreparedQueryObj(MultivaluedMap<String, String> rowParams) throws MusicQueryException {
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ if((this.getKeyspaceName() == null || this.getKeyspaceName().isEmpty()) ||
+ (this.getTableName() == null || this.getTableName().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();*/
+
+ throw new MusicQueryException("one or more path parameters are not set, please check and try again",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+
+ EELFLoggerDelegate.mdcPut("keyspace", "( "+this.getKeyspaceName()+" ) ");
+ String operationId = UUID.randomUUID().toString(); // just for infoging purposes.
+ String consistency = this.getConsistencyInfo().get("type");
+
+ logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
+ + " update-" + operationId + "-------------------------");
+ // obtain the field value pairs of the update
+
+ Map<String, Object> valuesMap = this.getValues();
+
+ TableMetadata tableInfo = getColumnMetadata(this.getKeyspaceName(), this.getTableName());
+
+ if (tableInfo == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Table information not found. Please check input for table name= "+this.getTableName(), 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= "
+ + this.getKeyspaceName() + "." + this.getTableName()).toMap()).build();*/
+
+ throw new MusicQueryException("Table information not found. Please check input for table name= "
+ + this.getKeyspaceName() + "." + this.getTableName(), Status.BAD_REQUEST.getStatusCode());
+ }
+
+ String vectorTs = String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
+ StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
+ queryObject.addValue(vectorTs);
+ int counter = 0;
+ for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
+ Object valueObj = entry.getValue();
+ DataType colType = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ } catch(NullPointerException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex, "Invalid column name : "+entry.getKey(), ex);
+ /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).
+ * setError("Invalid column name : "+entry.getKey()).toMap()).build();*/
+
+ throw new MusicQueryException("Invalid column name : " + entry.getKey(),Status.BAD_REQUEST.getStatusCode());
+ }
+ Object valueString = null;
+ try {
+ valueString = MusicUtil.convertToActualDataType(colType, valueObj);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e);
+ }
+ fieldValueString.append(entry.getKey() + "= ?");
+ queryObject.addValue(valueString);
+ if (counter != valuesMap.size() - 1) {
+ fieldValueString.append(",");
+ }
+ counter = counter + 1;
+ }
+ String ttl = this.getTtl();
+ String timestamp = this.getTimestamp();
+
+ queryObject.appendQueryString("UPDATE " + this.getKeyspaceName() + "." + this.getTableName() + " ");
+ if ((ttl != null) && (timestamp != null)) {
+ logger.info("both there");
+ queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ if ((ttl != null) && (timestamp == null)) {
+ logger.info("ONLY TTL there");
+ queryObject.appendQueryString(" USING TTL ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ }
+
+ if ((ttl == null) && (timestamp != null)) {
+ logger.info("ONLY timestamp there");
+ queryObject.appendQueryString(" USING TIMESTAMP ?");
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ // get the row specifier
+ RowIdentifier rowId = null;
+ try {
+ rowId = getRowIdentifier(this.getKeyspaceName(), this.getTableName(), rowParams, queryObject);
+ this.setRowIdString(rowId.rowIdString);
+ this.setPrimarKeyValue(rowId.primarKeyValue);
+ if(rowId == null || rowId.getPrimaryKeyValue().isEmpty()) {
+ /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
+ .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();*/
+
+ throw new MusicQueryException("Mandatory WHERE clause is missing. Please check the input request.",
+ Status.BAD_REQUEST.getStatusCode());
+ }
+ } catch (MusicQueryException ex) {
+ throw new MusicQueryException("Mandatory WHERE clause is missing. Please check the input request.",
+ Status.BAD_REQUEST.getStatusCode());
+
+ }catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes
+ .GENERALSERVICEERROR, ex);
+ /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();*/
+
+ throw new MusicQueryException(ex.getMessage(), Status.BAD_REQUEST.getStatusCode());
+
+ }
+
+
+
+ queryObject.appendQueryString(
+ " SET " + fieldValueString + " WHERE " + rowId.getRowIdString() + ";");
+
+
+
+ // get the conditional, if any
+ Condition conditionInfo;
+ if (this.getConditions() == null) {
+ conditionInfo = null;
+ } else {
+ // to avoid parsing repeatedly, just send the select query to obtain row
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ selectQuery.appendQueryString("SELECT * FROM " + this.getKeyspaceName() + "." + this.getTableName() + " WHERE "
+ + rowId.getRowIdString() + ";");
+ selectQuery.addValue(rowId.primarKeyValue);
+ conditionInfo = new Condition(this.getConditions(), selectQuery);
+ }
+
+ if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && this.getConsistencyInfo().get("consistency") != null) {
+ if(MusicUtil.isValidConsistency(this.getConsistencyInfo().get("consistency"))) {
+ queryObject.setConsistency(this.getConsistencyInfo().get("consistency"));
+ } else {
+ /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR)
+ .setError("Invalid Consistency type").toMap()).build();*/
+
+ logger.error("Invalid Consistency type");
+ throw new MusicQueryException("Invalid Consistency type", Status.BAD_REQUEST.getStatusCode());
+ }
+ }
+
+ queryObject.setOperation("update");
+
+ return queryObject;
+ }
+
+ TableMetadata getColumnMetadata(String keyspaceName, String tableName) throws MusicQueryException {
+ TableMetadata tableInfo;
+ try {
+ tableInfo = returnColumnMetadata(keyspaceName, tableName);
+ } catch (MusicServiceException 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();*/
+ throw new MusicQueryException(e.getMessage(), Status.BAD_REQUEST.getStatusCode());
+ }catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e, AppMessages.UNKNOWNERROR, ErrorSeverity.CRITICAL,
+ ErrorTypes.GENERALSERVICEERROR);
+ throw new MusicQueryException(e.getMessage(), Status.BAD_REQUEST.getStatusCode());
+ }
+ return tableInfo;
+ }
+
+ /** wrapper around static method for testing */
+ TableMetadata returnColumnMetadata(String keyspace, String tableName) throws MusicServiceException {
+ return MusicDataStoreHandle.returnColumnMetadata(keyspace, tableName);
+ }
+
+ class RowIdentifier {
+ private String primarKeyValue;
+ private String rowIdString;
+ @SuppressWarnings("unused")
+ public PreparedQueryObject queryObject; // the string with all the row
+ // identifiers separated by AND
+
+ public RowIdentifier(String primaryKeyValue, String rowIdString,
+ PreparedQueryObject queryObject) {
+ this.primarKeyValue = primaryKeyValue;
+ this.rowIdString = rowIdString;
+ this.queryObject = queryObject;
+ }
+
+ public String getPrimaryKeyValue() {
+ return this.primarKeyValue;
+ }
+
+ public void setPrimaryKeyValue(String primaryKeyValue) {
+ this.primarKeyValue = primaryKeyValue;
+ }
+
+ public String getRowIdString() {
+ return this.rowIdString;
+ }
+
+ public void setRowIdString(String rowIdString) {
+ this.rowIdString = rowIdString;
+ }
+
+ public PreparedQueryObject getQueryObject() {
+ return this.queryObject;
+ }
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @param rowParams
+ * @param queryObject
+ * @return
+ * @throws MusicServiceException
+ */
+ RowIdentifier getRowIdentifier(String keyspace, String tablename,
+ MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
+ throws MusicServiceException {
+ StringBuilder rowSpec = new StringBuilder();
+ int counter = 0;
+ TableMetadata tableInfo = returnColumnMetadata(keyspace, tablename);
+ if (tableInfo == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ throw new MusicServiceException(
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ }
+ StringBuilder primaryKey = new StringBuilder();
+ for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
+ String keyName = entry.getKey();
+ List<String> valueList = entry.getValue();
+ String indValue = valueList.get(0);
+ DataType colType = null;
+ Object formattedValue = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e);
+ }
+ if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey())) {
+ primaryKey.append(indValue);
+ }
+ rowSpec.append(keyName + "= ?");
+ queryObject.addValue(formattedValue);
+ if (counter != rowParams.size() - 1) {
+ rowSpec.append(" AND ");
+ }
+ counter = counter + 1;
+ }
+ return new RowIdentifier(primaryKey.toString(), rowSpec.toString(), queryObject);
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java b/music-core/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java
new file mode 100644
index 00000000..fbfc0de6
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java
@@ -0,0 +1,130 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.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.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.main.MusicUtil;
+import org.onap.music.main.ResultType;
+import org.onap.music.main.MusicCore;
+
+import com.datastax.driver.core.ConsistencyLevel;
+
+/**
+ * @author inam
+ *
+ */
+public class MusicHealthCheck {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class);
+
+ private String cassandrHost;
+
+ public String getCassandraStatus(String consistency) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Getting Status for Cassandra");
+
+ boolean result = false;
+ UUID randomUUID = UUID.randomUUID();
+ try {
+ result = getAdminKeySpace(consistency, randomUUID);
+ } catch( Exception e) {
+ if(e.getMessage().toLowerCase().contains("unconfigured table healthcheck")) {
+ logger.error("Error", e);
+ logger.debug("Creating table....");
+ try {
+ boolean ksresult = createKeyspace();
+ if(ksresult) {
+ result = getAdminKeySpace(consistency, randomUUID);
+ }
+ } catch (MusicServiceException e1) {
+ logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(), AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.UNKNOWN, e1);
+ } catch (MusicQueryException e1) {
+ logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(), AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.UNKNOWN,e1);
+ }
+ } else {
+ logger.error("Error", e);
+ return "One or more nodes are down or not responding.";
+ }
+ }
+ try {
+ cleanHealthCheckId(randomUUID);
+ } catch (MusicServiceException | MusicQueryException e) {
+ logger.error("Error while cleaning healthcheck record id...", e);
+ }
+ if (result) {
+ return "ACTIVE";
+ } else {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Cassandra Service is not responding");
+ return "INACTIVE";
+ }
+ }
+
+ private Boolean getAdminKeySpace(String consistency, UUID randomUUID) throws MusicServiceException,MusicQueryException {
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString("insert into admin.healthcheck (id) values (?)");
+ pQuery.addValue(randomUUID);
+ ResultType rs = null;
+ 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() throws MusicServiceException,MusicQueryException {
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString("CREATE TABLE admin.healthcheck (id uuid PRIMARY KEY)");
+ ResultType rs = null ;
+ rs = MusicCore.nonKeyRelatedPut(pQuery, ConsistencyLevel.ONE.toString());
+ return rs != null && rs.getResult().toLowerCase().contains("success");
+ }
+
+ public String getCassandrHost() {
+ return cassandrHost;
+ }
+
+ public void setCassandrHost(String cassandrHost) {
+ this.cassandrHost = cassandrHost;
+ }
+
+} \ No newline at end of file
diff --git a/music-core/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java b/music-core/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java
new file mode 100644
index 00000000..a8012c82
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java
@@ -0,0 +1,381 @@
+/*
+ * ============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.eelf.logging;
+
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+import java.net.InetAddress;
+import java.text.MessageFormat;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.servlet.http.HttpServletRequest;
+import org.slf4j.MDC;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.configuration.SLF4jWrapper;
+
+public class EELFLoggerDelegate extends SLF4jWrapper implements EELFLogger {
+
+ public static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
+ public static final EELFLogger applicationLogger =
+ EELFManager.getInstance().getApplicationLogger();
+ public static final EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
+ public static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+ public static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger();
+ public static final EELFLogger securityLogger = EELFManager.getInstance().getSecurityLogger();
+
+ private String className;
+ private static ConcurrentMap<String, EELFLoggerDelegate> classMap = new ConcurrentHashMap<>();
+
+ public EELFLoggerDelegate(final String className) {
+ super(className);
+ this.className = className;
+ }
+
+ /**
+ * Convenience method that gets a logger for the specified class.
+ *
+ * @see #getLogger(String)
+ *
+ * @param clazz
+ * @return Instance of EELFLoggerDelegate
+ */
+ public static EELFLoggerDelegate getLogger(Class<?> clazz) {
+ return getLogger(clazz.getName());
+ }
+
+ /**
+ * Gets a logger for the specified class name. If the logger does not already exist in the map,
+ * this creates a new logger.
+ *
+ * @param className If null or empty, uses EELFLoggerDelegate as the class name.
+ * @return Instance of EELFLoggerDelegate
+ */
+ public static EELFLoggerDelegate getLogger(final String className) {
+ String classNameNeverNull = className == null || "".equals(className)
+ ? EELFLoggerDelegate.class.getName()
+ : className;
+ EELFLoggerDelegate delegate = classMap.get(classNameNeverNull);
+ if (delegate == null) {
+ delegate = new EELFLoggerDelegate(className);
+ classMap.put(className, delegate);
+ }
+ return delegate;
+ }
+
+ /**
+ * Logs a message at the lowest level: trace.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void trace(EELFLogger logger, String msg) {
+ if (logger.isTraceEnabled()) {
+ logger.trace(msg);
+ }
+ }
+
+ /**
+ * Logs a message with parameters at the lowest level: trace.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void trace(EELFLogger logger, String msg, Object... arguments) {
+ if (logger.isTraceEnabled()) {
+ logger.trace(msg, arguments);
+ }
+ }
+
+ /**
+ * Logs a message and throwable at the lowest level: trace.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void trace(EELFLogger logger, String msg, Throwable th) {
+ if (logger.isTraceEnabled()) {
+ logger.trace(msg, th);
+ }
+ }
+
+ /**
+ * Logs a message at the second-lowest level: debug.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void debug(EELFLogger logger, String msg) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(msg);
+ }
+ }
+
+ /**
+ * Logs a message with parameters at the second-lowest level: debug.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void debug(EELFLogger logger, String msg, Object... arguments) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(msg, arguments);
+ }
+ }
+
+ /**
+ * Logs a message and throwable at the second-lowest level: debug.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void debug(EELFLogger logger, String msg, Throwable th) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(msg, th);
+ }
+ }
+
+ /**
+ * Logs a message at info level.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void info(EELFLogger logger, String msg) {
+ logger.info(className + " - "+msg);
+ }
+
+ /**
+ * Logs a message with parameters at info level.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void info(EELFLogger logger, String msg, Object... arguments) {
+ logger.info(msg, arguments);
+ }
+
+ /**
+ * Logs a message and throwable at info level.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void info(EELFLogger logger, String msg, Throwable th) {
+ logger.info(msg, th);
+ }
+
+ /**
+ * Logs a message at warn level.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void warn(EELFLogger logger, String msg) {
+ logger.warn(msg);
+ }
+
+ /**
+ * Logs a message with parameters at warn level.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void warn(EELFLogger logger, String msg, Object... arguments) {
+ logger.warn(msg, arguments);
+ }
+
+ /**
+ * Logs a message and throwable at warn level.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void warn(EELFLogger logger, String msg, Throwable th) {
+ logger.warn(msg, th);
+ }
+
+ /**
+ * Logs a message at error level.
+ *
+ * @param logger
+ * @param msg
+ *
+ */
+ public void error(EELFLogger logger, String msg) {
+ logger.error(className+ " - " + msg);
+ }
+
+ /**
+ * Logs a message at error level.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void error(EELFLogger logger, Exception e) {
+ logger.error(className+ " - ", e);
+ }
+
+ /**
+ * Logs a message with parameters at error level.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ *
+ */
+ public void error(EELFLogger logger, String msg, Object... arguments) {
+ logger.error(msg, arguments);
+ }
+
+ /**
+ * Logs a message with parameters at error level.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void error(EELFLogger logger, Exception e, Object... arguments) {
+ logger.error("Exception", e, arguments);
+ }
+
+ /**
+ * Logs a message and throwable at error level.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void error(EELFLogger logger, String msg, Throwable th) {
+ logger.error(msg, th);
+ }
+
+ /**
+ * Logs a message with the associated alarm severity at error level.
+ *
+ * @param logger
+ * @param msg
+ * @param severtiy
+ */
+ public void error(EELFLogger logger, String msg, Object /* AlarmSeverityEnum */ severtiy) {
+ logger.error(msg);
+ }
+
+ /**
+ * Initializes the logger context.
+ */
+ public void init() {
+ setGlobalLoggingContext();
+ final String msg =
+ "############################ Logging is started. ############################";
+ // These loggers emit the current date-time without being told.
+ info(applicationLogger, msg);
+ error(errorLogger, msg);
+ debug(debugLogger, msg);
+ info(auditLogger, msg);
+ info(metricsLogger, msg);
+ info(securityLogger, msg);
+
+ }
+
+ /**
+ * Builds a message using a template string and the arguments.
+ *
+ * @param message
+ * @param args
+ * @return
+ */
+ private String formatMessage(String message, Object... args) {
+ StringBuilder sbFormattedMessage = new StringBuilder();
+ if (args != null && args.length > 0 && message != null && message != "") {
+ MessageFormat mf = new MessageFormat(message);
+ sbFormattedMessage.append(mf.format(args));
+ } else {
+ sbFormattedMessage.append(message);
+ }
+
+ return sbFormattedMessage.toString();
+ }
+
+ /**
+ * Loads all the default logging fields into the MDC context.
+ */
+ private void setGlobalLoggingContext() {
+ MDC.put(MDC_SERVICE_INSTANCE_ID, "");
+ try {
+ MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
+ MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
+ } catch (Exception e) {
+ errorLogger.error("setGlobalLoggingContext failed", e);
+ }
+ }
+
+ public static void mdcPut(String key, String value) {
+ MDC.put(key, value);
+ }
+
+ public static String mdcGet(String key) {
+ return MDC.get(key);
+ }
+
+ public static void mdcRemove(String key) {
+ MDC.remove(key);
+ }
+
+ /**
+ * Loads the RequestId/TransactionId into the MDC which it should be receiving with an each
+ * incoming REST API request. Also, configures few other request based logging fields into the
+ * MDC context.
+ *
+ * @param req
+ * @param appName
+ */
+ public void setRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req,
+ String appName) {
+ // Load the default fields
+ setGlobalLoggingContext();
+
+ // Load the request based fields
+ if (req != null) {
+ // Rest Path
+ MDC.put(MDC_SERVICE_NAME, req.getServletPath());
+
+ // Client IPAddress i.e. IPAddress of the remote host who is making
+ // this request.
+ String clientIPAddress = req.getHeader("X-FORWARDED-FOR");
+ if (clientIPAddress == null) {
+ clientIPAddress = req.getRemoteAddr();
+ }
+ }
+ }
+}
diff --git a/music-core/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java b/music-core/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java
new file mode 100644
index 00000000..5af3661c
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java
@@ -0,0 +1,188 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * Copyright (c) 2019 IBM 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.eelf.logging.format;
+
+/**
+ * @author inam
+ *
+ */
+public enum AppMessages {
+
+
+
+ /*
+ * 100-199 Security/Permission Related - Authentication problems
+ * [ERR100E] Missing Information
+ * [ERR101E] Authentication error occured
+ *
+ * 200-299 Availability/Timeout Related/IO - connectivity error - connection timeout
+ * [ERR200E] Connectivity
+ * [ERR201E] Host not available
+ * [ERR202E] Error while connecting to Cassandra cluster
+ * [ERR203E] IO Error has occured
+ * [ERR204E] Execution Interrupted
+ * [ERR205E] Session Expired
+ * [ERR206E] Cache not authenticated
+ *
+ *
+ * 300-399 Data Access/Integrity Related
+ * [ERR300E] Incorrect data
+ *
+ * 400-499 - Cassandra Query Related
+ * [ERR400E] Error while processing prepared query object
+ * [ERR401E] Executing Session Failure for Request
+ * [ERR402E] Ill formed queryObject for the request
+ * [ERR403E] Error processing Prepared Query Object
+ *
+ * 500-599 - Locking Related
+ * [ERR500E] Invalid lock
+ * [ERR501E] Locking Error has occured
+ * [ERR502E] Deprecated
+ * [ERR503E] Failed to aquire lock store handle
+ * [ERR504E] Failed to create Lock Reference
+ * [ERR505E] Lock does not exist
+ * [ERR506E] Failed to aquire lock
+ * [ERR507E] Lock not aquired
+ * [ERR508E] Lock state not set
+ * [ERR509E] Lock not destroyed
+ * [ERR510E] Lock not released
+ * [ERR511E] Lock not deleted
+ * [ERR512E] Deprecated
+ *
+ *
+ * 600 - 699 - Music Service Errors
+ * [ERR600E] Error initializing the cache
+ *
+ * 700-799 Schema Interface Type/Validation - received Pay-load checksum is
+ * invalid - received JSON is not valid
+ *
+ * 800-899 Business/Flow Processing Related - check out to service is not
+ * allowed - Roll-back is done - failed to generate heat file
+ *
+ *
+ * 900-999 Unknown Errors - Unexpected exception
+ * [ERR900E] Unexpected error occured
+ * [ERR901E] Number format exception
+ *
+ *
+ * 1000-1099 Reserved - do not use
+ *
+ */
+
+
+
+
+ MISSINGINFO("[ERR100E]", "Missing Information ","Details: NA", "Please check application credentials and/or headers"),
+ AUTHENTICATIONERROR("[ERR101E]", "Authentication error occured ","Details: NA", "Please verify application credentials"),
+ CONNCECTIVITYERROR("[ERR200E]"," Connectivity error","Details: NA ","Please check connectivity to external resources"),
+ HOSTUNAVAILABLE("[ERR201E]","Host not available","Details: NA","Please verify the host details"),
+ CASSANDRACONNECTIVITY("[ERR202E]","Error while connecting to Cassandra cluster",""," Please check cassandra cluster details"),
+ IOERROR("[ERR203E]","IO Error has occured","","Please check IO"),
+ EXECUTIONINTERRUPTED("[ERR204E]"," Execution Interrupted","",""),
+ SESSIONEXPIRED("[ERR205E]"," Session Expired","","Session has expired."),
+ CACHEAUTHENTICATION("[ERR206E]","Cache not authenticated",""," Cache not authenticated"),
+
+ INCORRECTDATA("[ERR300E]"," Incorrect data",""," Please verify the request payload and try again"),
+ MULTIPLERECORDS("[ERR301E]"," Multiple records found",""," Please verify the request payload and try again"),
+ ALREADYEXIST("[ERR302E]"," Record already exist",""," Please verify the request payload and try again"),
+ MISSINGDATA("[ERR300E]"," Incorrect data",""," Please verify the request payload and try again"),
+
+ QUERYERROR("[ERR400E]","Error while processing prepared query object",""," Please verify the query"),
+ SESSIONFAILED("[ERR401E]","Executing Session Failure for Request","","Please verify the session and request"),
+
+ INVALIDLOCK("[ERR500E]"," Invalid lock or acquire failed",""," Lock is not valid to aquire"),
+ LOCKINGERROR("[ERR501E]"," Locking Error has occured",""," Locking Error has occured"),
+ LOCKHANDLE("[ERR503E]","Failed to aquire lock store handle",""," Failed to aquire lock store handle"),
+ CREATELOCK("[ERR504E]","Failed to aquire lock store handle ","","Failed to aquire lock store handle "),
+ LOCKSTATE("[ERR508E]"," Lock state not set",""," Lock state not set"),
+ DESTROYLOCK("[ERR509E]"," Lock not destroyed",""," Lock not destroyed"),
+ RELEASELOCK("[ERR510E]"," Lock not released",""," Lock not released"),
+ DELTELOCK("[ERR511E]",""," Lock not deleted "," Lock not deleted "),
+ CACHEERROR("[ERR600E]"," Error initializing the cache",""," Error initializing the cache"),
+
+ UNKNOWNERROR("[ERR900E]"," Unexpected error occured",""," Please check logs for details");
+
+
+
+
+ private ErrorTypes eType;
+ private ErrorSeverity alarmSeverity;
+ private ErrorSeverity errorSeverity;
+ private String errorCode;
+ private String errorDescription;
+ private String details;
+ private String resolution;
+
+
+ AppMessages(String errorCode, String errorDescription, String details,String resolution) {
+
+ this.errorCode = errorCode;
+ this.errorDescription = errorDescription;
+ this.details = details;
+ this.resolution = resolution;
+ }
+
+
+ public ErrorTypes getEType() {
+ return eType;
+ }
+
+ public ErrorSeverity getAlarmSeverity() {
+ return alarmSeverity;
+ }
+ public ErrorSeverity getErrorSeverity() {
+ return errorSeverity;
+ }
+
+ public void setDetails(String details){ this.details=details; }
+
+ public String getDetails() {
+ return this.details;
+ }
+
+ public void setResolution(String resolution){ this.resolution=resolution; }
+
+ public String getResolution() {
+ return this.resolution;
+ }
+
+ public void setErrorCode(String errorCode){ this.errorCode=errorCode; }
+
+ public String getErrorCode() {
+ return this.errorCode;
+ }
+
+ public void setErrorDescription(String errorDescription){ this.errorDescription=errorDescription; }
+
+ public String getErrorDescription() {
+ return this.errorDescription;
+ }
+
+
+
+
+
+
+
+}
diff --git a/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java b/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java
new file mode 100644
index 00000000..91ee3473
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java
@@ -0,0 +1,107 @@
+/*
+ * ============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.eelf.logging.format;
+
+
+
+/**
+ * @author inam
+ *
+ */
+public enum ErrorCodes {
+
+
+ /*
+ * 100-199 Security/Permission Related - Authentication problems
+ * [ERR100E] Missing Information
+ * [ERR101E] Authentication error occured
+ *
+ * 200-299 Availability/Timeout Related/IO - connectivity error - connection timeout
+ * [ERR200E] Connectivity
+ * [ERR201E] Host not available
+ * [ERR202E] Error while connecting to Cassandra cluster
+ * [ERR203E] IO Error has occured
+ * [ERR204E] Execution Interrupted
+ * [ERR205E] Session Expired
+ * [ERR206E] Cache not authenticated
+ *
+ *
+ * 300-399 Data Access/Integrity Related
+ *
+ * 400-499 - Cassandra Query Related
+ * [ERR400E] Error while processing prepared query object
+ * [ERR401E] Executing Session Failure for Request
+ * [ERR402E] Ill formed queryObject for the request
+ * [ERR403E] Error processing Prepared Query Object
+ *
+ * 500-599 - Zookeepr/Locking Related
+ * [ERR500E] Invalid lock
+ * [ERR501E] Locking Error has occured
+ * [ERR502E] Zookeeper error has occured
+ * [ERR503E] Failed to aquire lock store handle
+ * [ERR504E] Failed to create Lock Reference
+ * [ERR505E] Lock does not exist
+ * [ERR506E] Failed to aquire lock
+ * [ERR507E] Lock not aquired
+ * [ERR508E] Lock state not set
+ * [ERR509E] Lock not destroyed
+ * [ERR510E] Lock not released
+ * [ERR511E] Lock not deleted
+ * [ERR512E] Failed to get Lock Handle
+ *
+ *
+ * 600 - 699 - Music Service Errors
+ * [ERR600E] Error initializing the cache
+ *
+ * 700-799 Schema Interface Type/Validation - received Pay-load checksum is
+ * invalid - received JSON is not valid
+ *
+ * 800-899 Business/Flow Processing Related - check out to service is not
+ * allowed - Roll-back is done - failed to generate heat file
+ *
+ *
+ * 900-999 Unknown Errors - Unexpected exception
+ * [ERR900E] Unexpected error occured
+ * [ERR901E] Number format exception
+ *
+ *
+ * 1000-1099 Reserved - do not use
+ *
+ */
+
+ /*SUCCESS("Success"), FAILURE("Failure");
+
+ private String result;
+
+ ResultType(String result) {
+ this.result = result;
+ }
+
+ public String getResult() {
+ return result;
+ }
+*/
+
+
+
+}
diff --git a/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java b/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java
new file mode 100644
index 00000000..4e798239
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java
@@ -0,0 +1,38 @@
+/*
+ * ============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.eelf.logging.format;
+
+/**
+ * @author inam
+ *
+ */
+public enum ErrorSeverity {
+ INFO,
+ WARN,
+ ERROR,
+ FATAL,
+ CRITICAL,
+ MAJOR,
+ MINOR,
+ NONE,
+}
diff --git a/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java b/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java
new file mode 100644
index 00000000..9bdbf20f
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java
@@ -0,0 +1,46 @@
+/*
+ * ============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.eelf.logging.format;
+
+import com.att.eelf.i18n.EELFResolvableErrorEnum;
+
+/**
+ * @author inam
+ *
+ */
+public enum ErrorTypes implements EELFResolvableErrorEnum {
+
+
+ CONNECTIONERROR,
+ SESSIONEXPIRED,
+ AUTHENTICATIONERROR,
+ CACHEERROR,
+ SERVICEUNAVAILABLE,
+ QUERYERROR,
+ DATAERROR,
+ GENERALSERVICEERROR,
+ MUSICSERVICEERROR,
+ LOCKINGERROR,
+ UNKNOWN,
+
+}
diff --git a/music-core/src/main/java/org/onap/music/exceptions/MusicDeadlockException.java b/music-core/src/main/java/org/onap/music/exceptions/MusicDeadlockException.java
new file mode 100644
index 00000000..7a40ed91
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/exceptions/MusicDeadlockException.java
@@ -0,0 +1,75 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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.exceptions;
+
+public class MusicDeadlockException extends MusicLockingException {
+
+ private String owner = null;
+ private String keyspace = null;
+ private String table = null;
+ private String key = null;
+
+ public MusicDeadlockException() {
+ super();
+ }
+
+ public MusicDeadlockException(String message) {
+ super(message);
+ }
+
+ public MusicDeadlockException(Throwable cause) {
+ super(cause);
+ }
+
+ public MusicDeadlockException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public MusicDeadlockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public void setValues(String owner, String keyspace, String table, String key) {
+ this.owner = owner;
+ this.keyspace = keyspace;
+ this.table = table;
+ this.key = key;
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ public String getKeyspace() {
+ return keyspace;
+ }
+
+ public String getTable() {
+ return table;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+
+}
diff --git a/music-core/src/main/java/org/onap/music/exceptions/MusicLockingException.java b/music-core/src/main/java/org/onap/music/exceptions/MusicLockingException.java
new file mode 100644
index 00000000..ab70c54c
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/exceptions/MusicLockingException.java
@@ -0,0 +1,75 @@
+/*
+ * ============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.exceptions;
+
+/**
+ * @author inam
+ *
+ */
+public class MusicLockingException extends Exception {
+
+ /**
+ *
+ */
+ public MusicLockingException() {
+
+ }
+
+ /**
+ * @param message
+ */
+ public MusicLockingException(String message) {
+ super(message);
+
+ }
+
+ /**
+ * @param cause
+ */
+ public MusicLockingException(Throwable cause) {
+ super(cause);
+
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public MusicLockingException(String message, Throwable cause) {
+ super(message, cause);
+
+ }
+
+ /**
+ * @param message
+ * @param cause
+ * @param enableSuppression
+ * @param writableStackTrace
+ */
+ public MusicLockingException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java b/music-core/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java
new file mode 100644
index 00000000..f489cd45
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java
@@ -0,0 +1,82 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modifications Copyright (c) 2018 IBM
+ * ===================================================================
+ * 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.exceptions;
+
+/**
+ * @author inam
+ *
+ */
+public class MusicPolicyVoilationException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ */
+ public MusicPolicyVoilationException() {
+
+ }
+
+ /**
+ * @param message
+ */
+ public MusicPolicyVoilationException(String message) {
+ super(message);
+
+ }
+
+ /**
+ * @param cause
+ */
+ public MusicPolicyVoilationException(Throwable cause) {
+ super(cause);
+
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public MusicPolicyVoilationException(String message, Throwable cause) {
+ super(message, cause);
+
+ }
+
+ /**
+ * @param message
+ * @param cause
+ * @param enableSuppression
+ * @param writableStackTrace
+ */
+ public MusicPolicyVoilationException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/exceptions/MusicQueryException.java b/music-core/src/main/java/org/onap/music/exceptions/MusicQueryException.java
new file mode 100644
index 00000000..803f993f
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/exceptions/MusicQueryException.java
@@ -0,0 +1,90 @@
+/*
+ * ============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.exceptions;
+
+
+
+/**
+ * @author inam
+ *
+ */
+public class MusicQueryException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private int errorCode;
+
+
+ /**
+ *
+ */
+ public MusicQueryException() {
+ super();
+ }
+
+ /**
+ * @param message
+ */
+ public MusicQueryException(String message) {
+ super(message);
+ }
+
+
+
+ /**
+ * @param message
+ */
+ public MusicQueryException(String message, int errorCode) {
+ super(message);
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * @param cause
+ */
+ public MusicQueryException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public MusicQueryException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ * @param enableSuppression
+ * @param writableStackTrace
+ */
+ public MusicQueryException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/exceptions/MusicServiceException.java b/music-core/src/main/java/org/onap/music/exceptions/MusicServiceException.java
new file mode 100644
index 00000000..76e1f948
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/exceptions/MusicServiceException.java
@@ -0,0 +1,88 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ===================================================================
+ * 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.exceptions;
+
+/**
+ * @author inam
+ *
+ */
+public class MusicServiceException extends Exception {
+
+
+ private int errorCode;
+ private String errorMessage;
+
+ public MusicServiceException() {
+ super();
+ }
+
+
+ public MusicServiceException(String message) {
+ super(message);
+
+ }
+
+ public MusicServiceException(String message, int errorCode) {
+ super(message);
+ this.errorCode=errorCode;
+ }
+
+ public MusicServiceException(String message, int errorCode, String errorMessage) {
+ super(message);
+ this.errorCode=errorCode;
+ this.errorMessage=errorMessage;
+ }
+
+ public MusicServiceException(Throwable cause) {
+ super(cause);
+
+ }
+
+
+ public MusicServiceException(String message, Throwable cause) {
+ super(message, cause);
+
+ }
+
+
+ public MusicServiceException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+
+ }
+ public void setErrorCode(int errorCode) {
+ this.errorCode=errorCode;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage=errorMessage;
+ }
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+}
diff --git a/music-core/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java
new file mode 100644
index 00000000..9a69a9ba
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/CassaLockStore.java
@@ -0,0 +1,613 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.lockingservice.cassandra;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+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.DeadlockDetectionUtil;
+import org.onap.music.main.DeadlockDetectionUtil.OwnershipType;
+import org.onap.music.main.MusicUtil;
+import org.onap.music.main.ResultType;
+import org.onap.music.main.ReturnType;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+
+/*
+ * This is the lock store that is built on top of Cassandra that is used by MUSIC to maintain lock state.
+ */
+
+public class CassaLockStore {
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CassaLockStore.class);
+ public static final String table_prepend_name = "lockQ_";
+ private MusicDataStore dsHandle;
+
+ public CassaLockStore() {
+ dsHandle = new MusicDataStore();
+ }
+
+ public CassaLockStore(MusicDataStore dsHandle) {
+ this.dsHandle=dsHandle;
+ }
+ public class LockObject{
+ private boolean isLockOwner;
+ private String lockRef;
+ private String createTime;
+ private String acquireTime;
+ private LockType locktype;
+ // Owner is the self-declared client which "owns" this row. It is used for deadlock detection. It is not (directly) related to isLockOwner.
+ private String owner;
+ public LockObject(boolean isLockOwner, String lockRef, String createTime, String acquireTime, LockType locktype, String owner) {
+ this.setIsLockOwner(isLockOwner);
+ this.setLockRef(lockRef);
+ this.setAcquireTime(acquireTime);
+ this.setCreateTime(createTime);
+ this.setLocktype(locktype);
+ this.setOwner(owner);
+ }
+ public boolean getIsLockOwner() {
+ return isLockOwner;
+ }
+ public void setIsLockOwner(boolean isLockOwner) {
+ this.isLockOwner = isLockOwner;
+ }
+ public String getAcquireTime() {
+ return acquireTime;
+ }
+ public void setAcquireTime(String acquireTime) {
+ this.acquireTime = acquireTime;
+ }
+ public String getCreateTime() {
+ return createTime;
+ }
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
+ public String getLockRef() {
+ return lockRef;
+ }
+ public void setLockRef(String lockRef) {
+ this.lockRef = lockRef;
+ }
+ public LockType getLocktype() {
+ return locktype;
+ }
+ public void setLocktype(LockType locktype) {
+ this.locktype = locktype;
+ }
+ public String getOwner() {
+ return owner;
+ }
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+ }
+
+ /**
+ *
+ * This method creates a shadow locking table for every main table in Cassandra. This table tracks all information regarding locks.
+ * @param keyspace of the application.
+ * @param table of the application.
+ * @return true if the operation was successful.
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public boolean createLockQueue(String keyspace, String table) throws MusicServiceException, MusicQueryException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Create lock queue/table for " + keyspace+"."+table);
+ table = table_prepend_name+table;
+ String tabQuery = "CREATE TABLE IF NOT EXISTS "+keyspace+"."+table
+ + " ( key text, lockReference bigint, createTime text, acquireTime text, guard bigint static, "
+ + "lockType text, leasePeriodTime bigint, owner text, PRIMARY KEY ((key), lockReference) ) "
+ + "WITH CLUSTERING ORDER BY (lockReference ASC);";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ queryObject.appendQueryString(tabQuery);
+ boolean result;
+ result = dsHandle.executePut(queryObject, "eventual");
+ return result;
+ }
+
+ /**
+ * This method creates a lock reference for each invocation. The lock references are monotonically increasing timestamps.
+ * @param keyspace of the locks.
+ * @param table of the locks.
+ * @param lockName is the primary key of the lock table
+ * @param lockType is the type of lock (read/write)
+ * @param owner is the owner of the lock (optional, for deadlock detection)
+ * @return the UUID lock reference.
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public String genLockRefandEnQueue(String keyspace, String table, String lockName, LockType locktype, String owner) throws MusicServiceException, MusicQueryException, MusicLockingException {
+ return genLockRefandEnQueue(keyspace, table, lockName, locktype, owner, 0);
+ }
+
+ private String genLockRefandEnQueue(String keyspace, String table, String lockName, LockType locktype, String owner, int count) throws MusicServiceException, MusicQueryException, MusicLockingException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Create " + locktype + " lock reference for " + keyspace + "." + table + "." + lockName);
+ String lockTable ="";
+ lockTable = table_prepend_name+table;
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ String selectQuery = "SELECT guard FROM " + keyspace + "." + lockTable + " WHERE key=?;";
+
+ queryObject.addValue(lockName);
+ queryObject.appendQueryString(selectQuery);
+ ResultSet gqResult = dsHandle.executeOneConsistencyGet(queryObject);
+ List<Row> latestGuardRow = gqResult.all();
+
+ long prevGuard = 0;
+ long lockRef = 1;
+ if (!latestGuardRow.isEmpty()) {
+ prevGuard = latestGuardRow.get(0).getLong(0);
+ lockRef = prevGuard + 1;
+ }
+
+ long lockEpochMillis = System.currentTimeMillis();
+
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Created lock reference for " + keyspace + "." + lockTable + "." + lockName + ":" + lockRef);
+
+ queryObject = new PreparedQueryObject();
+
+ String insQuery = "BEGIN BATCH" +
+ " UPDATE " + keyspace + "." + lockTable +
+ " SET guard=? WHERE key=? IF guard = " + (prevGuard == 0 ? "NULL" : "?") +";" +
+ " INSERT INTO " + keyspace + "." + lockTable +
+ "(key, lockReference, createTime, acquireTime, lockType, owner) VALUES (?,?,?,?,?,?) IF NOT EXISTS; APPLY BATCH;";
+
+ queryObject.addValue(lockRef);
+ queryObject.addValue(lockName);
+ if (prevGuard != 0)
+ queryObject.addValue(prevGuard);
+
+ queryObject.addValue(lockName);
+ queryObject.addValue(lockRef);
+ queryObject.addValue(String.valueOf(lockEpochMillis));
+ queryObject.addValue("0");
+ queryObject.addValue(locktype);
+ queryObject.addValue(owner);
+ queryObject.appendQueryString(insQuery);
+ 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, locktype, owner, count);
+ }
+ return "$" + keyspace + "." + table + "." + lockName + "$" + String.valueOf(lockRef);
+ }
+
+ /**
+ * Returns a result set containing the list of clients waiting for a particular lock
+ *
+ * @param keyspace
+ * @param table
+ * @param key
+ * @return list of lockrefs in the queue
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public List<String> getLockQueue(String keyspace, String table, String key)
+ throws MusicServiceException, MusicQueryException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Getting the queue for " + keyspace + "." + table + "." + key);
+ table = table_prepend_name + table;
+ String selectQuery = "select * from " + keyspace + "." + table + " where key='" + key + "';";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ ResultSet rs = dsHandle.executeOneConsistencyGet(queryObject);
+ ArrayList<String> lockQueue = new ArrayList<>();
+ for (Row row : rs) {
+ lockQueue.add(Long.toString(row.getLong("lockReference")));
+ }
+ return lockQueue;
+ }
+
+
+ /**
+ * Returns a result set containing the list of clients waiting for a particular lock
+ *
+ * @param keyspace
+ * @param table
+ * @param key
+ * @return size of lockrefs queue
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public long getLockQueueSize(String keyspace, String table, String key)
+ throws MusicServiceException, MusicQueryException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Getting the queue size for " + keyspace + "." + table + "." + key);
+ table = table_prepend_name + table;
+ String selectQuery = "select count(*) from " + keyspace + "." + table + " where key='" + key + "';";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ ResultSet rs = dsHandle.executeOneConsistencyGet(queryObject);
+ return rs.one().getLong("count");
+ }
+
+
+ /**
+ * This method returns the top of lock table/queue for the key.
+ *
+ * @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. Returns LockObject.isLockOwner=false if there is no owner or the
+ * lock doesn't exist
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public LockObject peekLockQueue(String keyspace, String table, String key)
+ throws MusicServiceException, MusicQueryException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Peek in lock table for " + keyspace + "." + table + "." + key);
+ table = table_prepend_name + table;
+ String selectQuery = "select * from " + keyspace + "." + table + " where key='" + key + "' LIMIT 1;";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ ResultSet results = dsHandle.executeOneConsistencyGet(queryObject);
+ Row row = results.one();
+ if (row == null || row.isNull("lockReference")) {
+ return new LockObject(false, null, null, null, null, null);
+ }
+ String lockReference = "" + row.getLong("lockReference");
+ String createTime = row.getString("createTime");
+ String acquireTime = row.getString("acquireTime");
+ LockType locktype = row.get("lockType", LockType.class);
+ String owner = row.getString("owner");
+
+ return new LockObject(true, lockReference, createTime, acquireTime, locktype, owner);
+ }
+
+ public List<String> getCurrentLockHolders(String keyspace, String table, String key)
+ throws MusicServiceException, MusicQueryException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Getting lockholders in lock table for " + keyspace + "." + table + "." + key);
+ String origTable = table;
+ table = table_prepend_name + table;
+ String selectQuery = "select * from " + keyspace + "." + table + " where key=?;";
+ List<String> lockHolders = new ArrayList<>();
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ queryObject.addValue(key);
+ ResultSet rs = dsHandle.executeOneConsistencyGet(queryObject);
+ boolean topOfQueue = true;
+ StringBuilder lock = new StringBuilder().
+ append("$").append(keyspace).append(".").append(origTable).
+ append(".").append(key).append("$");
+ StringBuilder lockReference = new StringBuilder();
+ for (Row row : rs) {
+ if ( row.isNull("lockReference") ) {
+ return lockHolders;
+ }
+ lockReference.append(lock).append(row.getLong("lockReference"));
+ if (row.get("lockType", LockType.class)!=LockType.WRITE) {
+ if (topOfQueue) {
+ lockHolders.add(lockReference.toString());
+ break;
+ } else {
+ break;
+ }
+ }
+ // read lock
+ lockHolders.add(lockReference.toString());
+
+ topOfQueue = false;
+ lockReference.delete(0,lockReference.length());
+ }
+ return lockHolders;
+ }
+
+ /**
+ * Determine if the lock is a valid current lock holder.
+ *
+ * @param keyspace
+ * @param table
+ * @param key
+ * @param lockRef
+ * @return true if lockRef is a lock owner of key
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public boolean isLockOwner(String keyspace, String table, String key, String lockRef)
+ throws MusicServiceException, MusicQueryException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Checking in lock table for " + keyspace + "." + table + "." + key);
+ table = table_prepend_name + table;
+ String selectQuery =
+ "select * from " + keyspace + "." + table + " where key=?;";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ queryObject.addValue(key);
+ ResultSet rs = dsHandle.executeOneConsistencyGet(queryObject);
+
+ boolean topOfQueue = true;
+ for (Row row : rs) {
+ String lockReference = "" + row.getLong("lockReference");
+ if (row.get("lockType", LockType.class)==LockType.WRITE) {
+ if (topOfQueue && lockRef.equals(lockReference)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if (lockRef.equals(lockReference)) {
+ return true;
+ }
+ topOfQueue = false;
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger, "Could not find " + lockRef
+ + " in the lock queue. It has expired and no longer exists.");
+ return false;
+ }
+
+ /**
+ * Determine if the lock is a valid current lock holder.
+ *
+ * @param keyspace
+ * @param table
+ * @param key
+ * @param lockRef
+ * @return true if lockRef is a lock owner of key
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public LockObject getLockInfo(String keyspace, String table, String key, String lockRef)
+ throws MusicServiceException, MusicQueryException {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Checking in lock table for " + keyspace + "." + table + "." + key);
+ String lockQ_table = table_prepend_name + table;
+ String selectQuery =
+ "select * from " + keyspace + "." + lockQ_table + " where key=? and lockReference=?;";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ queryObject.addValue(key);
+ queryObject.addValue(Long.parseLong(lockRef));
+ ResultSet rs = dsHandle.executeOneConsistencyGet(queryObject);
+ Row row = rs.one();
+ if (row == null || row.isNull("lockReference")) {
+ return null;
+ }
+
+ String lockReference = "" + row.getLong("lockReference");
+ String createTime = row.getString("createTime");
+ String acquireTime = row.getString("acquireTime");
+ LockType locktype = row.get("lockType", LockType.class);
+ boolean isLockOwner = isLockOwner(keyspace, table, key, lockRef);
+ String owner = row.getString("owner");
+
+ return new LockObject(isLockOwner, lockReference, createTime, acquireTime, locktype, owner);
+ }
+
+
+
+ /**
+ * This method removes the lock ref from the lock table/queue for the key.
+ *
+ * @param keyspace of the application.
+ * @param table of the application.
+ * @param key is the primary key of the application table
+ * @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, 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 + "." + prependTable + " where key='" + key
+ + "' AND lockReference =" + lockReferenceL + " IF EXISTS;";
+ queryObject.appendQueryString(deleteQuery);
+ 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());
+ }
+ }
+ }
+
+
+ public void updateLockAcquireTime(String keyspace, String table, String key, String lockReference) {
+ table = table_prepend_name + table;
+ Long lockReferenceL = Long.parseLong(lockReference);
+ String updateQuery = "update " + keyspace + "." + table + " set acquireTime='" + System.currentTimeMillis()
+ + "' where key='" + key + "' AND lockReference = " + lockReferenceL + " IF EXISTS;";
+
+ //cannot use executePut because we need to ignore music timestamp adjustments for lock store
+ dsHandle.getSession().execute(updateQuery);
+ }
+
+ public boolean checkForDeadlock(String keyspace, String table, String lockName, LockType locktype, String owner, boolean forAcquire) throws MusicServiceException, MusicQueryException {
+ if (locktype.equals(LockType.READ))
+ return false;
+ if (owner==null || owner.length()==0)
+ return false;
+
+ String lockTable = table_prepend_name + table;
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("SELECT key, acquiretime, owner FROM " + keyspace + "." + lockTable);
+ queryObject.appendQueryString(" WHERE lockType = ? ALLOW FILTERING");
+ queryObject.addValue(LockType.WRITE);
+
+ DeadlockDetectionUtil ddu = getDeadlockDetectionUtil();
+
+ ResultSet rs = dsHandle.executeLocalQuorumConsistencyGet(queryObject);
+ logger.debug("rs has " + rs.getAvailableWithoutFetching() + (rs.isFullyFetched()?"":" (or more!)") );
+ Iterator<Row> it = rs.iterator();
+ while (it.hasNext()) {
+ Row row = it.next();
+ logger.debug("key = " + row.getString("key") + ", time = " + row.getString("acquiretime") + ", owner = " + row.getString("owner") );
+ ddu.setExisting(row.getString("key"), row.getString("owner"), ("0".equals(row.getString("acquiretime")))?OwnershipType.CREATED:OwnershipType.ACQUIRED);
+ }
+ boolean deadlock = ddu.checkForDeadlock(lockName, owner, forAcquire?OwnershipType.ACQUIRED:OwnershipType.CREATED);
+ if (deadlock)
+ logger.warn("Deadlock detected when " + owner + " tried to create lock on " + keyspace + "." + lockTable + "." + lockName);
+ return deadlock;
+ }
+
+ /**
+ * This is used for testing purpose
+ * @return new DeadlockDetectionUtil object
+ */
+ DeadlockDetectionUtil getDeadlockDetectionUtil() {
+ return new DeadlockDetectionUtil();
+ }
+
+ public List<String> getAllLocksForOwner(String ownerId, String keyspace, String table) throws MusicServiceException, MusicQueryException {
+ List<String> toRet = new ArrayList<>();
+ String lockTable = table_prepend_name + table;
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("SELECT key, lockreference FROM " + keyspace + "." + lockTable);
+ queryObject.appendQueryString(" WHERE owner = '" + ownerId + "' ALLOW FILTERING");
+
+ ResultSet rs = dsHandle.executeQuorumConsistencyGet(queryObject);
+ Iterator<Row> it = rs.iterator();
+ while (it.hasNext()) {
+ Row row = it.next();
+ toRet.add(row.getString("key") + "$" + row.getLong("lockreference"));
+ }
+ return toRet;
+ }
+
+ public ReturnType promoteLock(String keyspace, String table, String key, String lockRef)
+ throws MusicServiceException, MusicQueryException {
+ String lockqtable = table_prepend_name + table;
+ String selectQuery = "select * from " + keyspace + "." + lockqtable + " where key=?;";
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ queryObject.addValue(key);
+ ResultSet rs = dsHandle.executeOneConsistencyGet(queryObject);
+
+ long refToPromote = Long.parseLong(lockRef);
+
+ boolean topOfQueue = true;
+ boolean readBlock = false;
+ boolean seenLockToPromote = false;
+ boolean promotionOngoing = false;
+ long readBlockStart = 0;
+ long readBlockEnd = 0;
+
+
+ for (Row row : rs) {
+ long ref = row.getLong("lockreference");
+ LockType lockType = row.get("lockType", LockType.class);
+
+ if (refToPromote==ref) {
+ if (promotionOngoing) {
+ return new ReturnType(ResultType.FAILURE, "Can't promote, already promoting another lockref.");
+ }
+ seenLockToPromote = true;
+ if (!topOfQueue) {
+ readBlockStart = ref;
+ readBlockEnd = ref;
+ break;
+ }
+ } else if (!seenLockToPromote && refToPromote<ref) {
+ return new ReturnType(ResultType.FAILURE, "Lockref does not exist.");
+ }
+
+ if (lockType==LockType.READ || lockType==LockType.PROMOTING) {
+ if (!readBlock) {
+ readBlockStart = ref;
+ readBlock = true;
+ }
+ if (readBlock) {
+ readBlockEnd = ref;
+ }
+ if (lockType==LockType.PROMOTING) {
+ promotionOngoing = true;
+ }
+ }
+
+ if (lockType==LockType.WRITE) {
+ if (refToPromote==ref) {
+ return new ReturnType(ResultType.FAILURE, "Lockref is already write.");
+ }
+ if (readBlock) {
+ readBlock = false;
+ promotionOngoing = false;
+ if (seenLockToPromote) {
+ break;
+ }
+ //can no longer be lock holder after this
+ topOfQueue = false;
+ }
+ }
+ }
+
+ if (readBlockStart<=refToPromote && refToPromote<=readBlockEnd) {
+ if (readBlockStart==refToPromote && refToPromote==readBlockEnd) {
+ promoteLockTo(keyspace, lockqtable, key, lockRef, LockType.WRITE);
+ return new ReturnType(ResultType.SUCCESS, "Lock has successfully been upgraded.");
+ }
+ promoteLockTo(keyspace, lockqtable, key, lockRef, LockType.PROMOTING);
+ return new ReturnType(ResultType.FAILURE, "Your lock upgrade is in progress. Check again to see if successful.");
+ }
+
+ //shouldn't reach here?
+ return new ReturnType(ResultType.FAILURE,"Promotion failed.");
+ }
+
+ private void promoteLockTo(String keyspace, String table, String key, String lockRef, LockType newLockType)
+ throws MusicServiceException, MusicQueryException {
+ PreparedQueryObject queryObject =
+ new PreparedQueryObject("UPDATE " + keyspace + "." + table + " SET lockType=? WHERE key='" + key
+ + "' AND lockReference = " + lockRef + " IF EXISTS;", newLockType);
+
+ //cannot use executePut because we need to ignore music timestamp adjustments for lock store
+ dsHandle.executePut(queryObject, MusicUtil.QUORUM);
+ }
+
+
+
+}
diff --git a/music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockCleanUpDaemon.java b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockCleanUpDaemon.java
new file mode 100644
index 00000000..623a07c7
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockCleanUpDaemon.java
@@ -0,0 +1,133 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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.lockingservice.cassandra;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.onap.music.datastore.MusicDataStoreHandle;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.main.MusicCore;
+import org.onap.music.main.MusicUtil;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+
+public class LockCleanUpDaemon extends Thread {
+
+ boolean terminated = false;
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(LockCleanUpDaemon.class);
+
+
+ public LockCleanUpDaemon() {
+ }
+
+ @Override
+ public void run() {
+ if (MusicUtil.getLockDaemonSleepTimeMs()<0) {
+ terminate();
+ }
+ while (!terminated) {
+ try {
+ cleanupStaleLocks();
+ } catch (MusicServiceException e) {
+ logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to clean up locks", e);
+ }
+ try {
+ Thread.sleep(MusicUtil.getLockDaemonSleepTimeMs());
+ } catch (InterruptedException e) {
+ logger.warn(EELFLoggerDelegate.applicationLogger, "Interrupted exception", e);
+
+ }
+ }
+ }
+
+ private void cleanupStaleLocks() throws MusicServiceException {
+ Set<String> lockQTables = getLockQTables();
+ logger.info(EELFLoggerDelegate.applicationLogger, "Lock q tables found: " + lockQTables);
+ for(String lockTable: lockQTables) {
+ try {
+ cleanUpLocksFromTable(lockTable);
+ } catch (MusicServiceException e) {
+ logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to clear locks on table " + lockTable, e);
+ }
+ }
+ }
+
+
+ private Set<String> getLockQTables() throws MusicServiceException {
+ Set<String> keyspacesToCleanUp = MusicUtil.getKeyspacesToCleanLocks();
+ Set<String> lockQTables = new HashSet<>();
+
+ PreparedQueryObject query = new PreparedQueryObject();
+ query.appendQueryString("SELECT keyspace_name, table_name FROM system_schema.tables;");
+ ResultSet results = MusicCore.get(query);
+
+ for (Row row: results) {
+ if (keyspacesToCleanUp.contains(row.getString("keyspace_name"))
+ && row.getString("table_name").toLowerCase().startsWith(CassaLockStore.table_prepend_name.toLowerCase()) ) {
+ lockQTables.add(row.getString("keyspace_name") + "." + row.getString("table_name"));
+ }
+ }
+ return lockQTables;
+ }
+
+ private void cleanUpLocksFromTable(String lockTable) throws MusicServiceException {
+ PreparedQueryObject query = new PreparedQueryObject();
+ query.appendQueryString("SELECT * from " + lockTable);
+ ResultSet results = MusicCore.get(query);
+ for (Row lock: results) {
+ if (!lock.isNull("lockreference")) {
+ try {
+ deleteLockIfStale(lockTable, lock);
+ } catch (MusicServiceException e) {
+ logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to delete a potentially stale lock " + lock, e);
+ }
+ }
+ }
+ }
+
+
+ private void deleteLockIfStale(String lockTable, Row lock) throws MusicServiceException {
+ final String CREATETIME="createtime";
+ final String ACQUIRETIME="acquiretime";
+ if (lock.isNull(CREATETIME) && lock.isNull("acquiretime")) {
+ return;
+ }
+
+ long createTime = lock.isNull(CREATETIME) ? 0 : Long.parseLong(lock.getString(CREATETIME));
+ long acquireTime = lock.isNull(ACQUIRETIME) ? 0 : Long.parseLong(lock.getString(ACQUIRETIME));
+ long row_access_time = Math.max(createTime, acquireTime);
+ if (System.currentTimeMillis() > row_access_time + MusicUtil.getDefaultLockLeasePeriod()) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Stale lock detected and being removed: " + lock);
+ PreparedQueryObject query = new PreparedQueryObject();
+ query.appendQueryString("DELETE FROM " + lockTable + " WHERE key='" + lock.getString("key") + "' AND " +
+ "lockreference=" + lock.getLong("lockreference") + " IF EXISTS;");
+ MusicDataStoreHandle.getDSHandle().getSession().execute(query.getQuery());
+ }
+ }
+
+ public void terminate() {
+ terminated = true;
+ }
+}
diff --git a/music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockType.java b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockType.java
new file mode 100644
index 00000000..432b1c51
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/LockType.java
@@ -0,0 +1,30 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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.lockingservice.cassandra;
+
+
+public enum LockType {
+ WRITE, READ, PROMOTING;
+}
+
diff --git a/music-core/src/main/java/org/onap/music/lockingservice/cassandra/MusicLockState.java b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/MusicLockState.java
new file mode 100644
index 00000000..14fb8135
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/lockingservice/cassandra/MusicLockState.java
@@ -0,0 +1,144 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * 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
+ *
+ * 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.lockingservice.cassandra;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+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;
+
+// the state variable that will be stored in the locking service, capturing the transitions of
+public class MusicLockState implements Serializable {
+ // captures the state of the lock
+ public enum LockStatus {
+ UNLOCKED, BEING_LOCKED, LOCKED
+ }
+
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicLockState.class);
+ private LockStatus lockStatus;
+ private boolean needToSyncQuorum = false;
+ private String lockHolder;
+ private long leasePeriod = Long.MAX_VALUE;
+ private long leaseStartTime = -1;
+ private String errorMessage = null;
+
+ public MusicLockState(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public MusicLockState(LockStatus lockStatus, String lockHolder) {
+ this.lockStatus = lockStatus;
+ this.lockHolder = lockHolder;
+ }
+
+ public MusicLockState(LockStatus lockStatus, String lockHolder, boolean needToSyncQuorum) {
+ this.lockStatus = lockStatus;
+ this.lockHolder = lockHolder;
+ this.needToSyncQuorum = needToSyncQuorum;
+ }
+
+
+ public long getLeasePeriod() {
+ return leasePeriod;
+ }
+
+ public boolean isNeedToSyncQuorum() {
+ return needToSyncQuorum;
+ }
+
+
+
+ public void setLeasePeriod(long leasePeriod) {
+ this.leasePeriod = leasePeriod;
+ }
+
+
+ public long getLeaseStartTime() {
+ return leaseStartTime;
+ }
+
+
+ public void setLeaseStartTime(long leaseStartTime) {
+ this.leaseStartTime = leaseStartTime;
+ }
+
+
+
+ public LockStatus getLockStatus() {
+ return lockStatus;
+ }
+
+ public void setLockStatus(LockStatus lockStatus) {
+ this.lockStatus = lockStatus;
+ }
+
+ public String getLockHolder() {
+ return lockHolder;
+ }
+
+ public void setLockHolder(String lockHolder) {
+ this.lockHolder = lockHolder;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR,
+ ErrorTypes.CONNECTIONERROR, e);
+ }
+ return bos.toByteArray();
+ }
+
+ public static MusicLockState deSerialize(byte[] data) {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ Object o = null;
+ ObjectInput in = null;
+ try {
+ in = new ObjectInputStream(bis);
+ o = in.readObject();
+ } catch (ClassNotFoundException | IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity
+ .ERROR, ErrorTypes.UNKNOWN, e);
+ }
+ return (MusicLockState) o;
+ }
+}
diff --git a/music-core/src/main/java/org/onap/music/main/CipherUtil.java b/music-core/src/main/java/org/onap/music/main/CipherUtil.java
new file mode 100644
index 00000000..9a8ff69d
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/main/CipherUtil.java
@@ -0,0 +1,279 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modification 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.
+ * 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.main;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Scanner;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.ArrayUtils;
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+
+public class CipherUtil {
+
+
+ /**
+ * Default key.
+ */
+ private static String keyString = MusicUtil.getCipherEncKey();
+
+ private static final String ALGORITHM = "AES";
+ private static final String ALGORYTHM_DETAILS = ALGORITHM + "/CBC/PKCS5PADDING";
+ private static final int BLOCK_SIZE = 128;
+ @SuppressWarnings("unused")
+ private static SecretKeySpec secretKeySpec;
+ private static IvParameterSpec ivspec;
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CipherUtil.class);
+ /**
+ * @deprecated Please use {@link #encryptPKC(String)} to encrypt the text.
+ *
+ * Encrypts the text using the specified secret key.
+ *
+ * @param plainText
+ * Text to encrypt
+ * @param secretKey
+ * Key to use for encryption
+ * @return encrypted version of plain text.
+ * @
+ * if any encryption step fails
+ *
+ */
+ @Deprecated
+ public static String encrypt(String plainText, String secretKey) {
+ String encryptedString = null;
+ try {
+ byte[] encryptText = plainText.getBytes("UTF-8");
+ byte[] rawKey = Base64.decodeBase64(secretKey);
+ SecretKeySpec sKeySpec = new SecretKeySpec(rawKey, "AES");
+ Cipher cipher = Cipher.getInstance("AES");
+ cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
+ encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText));
+ } catch (BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException
+ | NoSuchPaddingException | UnsupportedEncodingException ex) {
+ }
+ return encryptedString;
+ }
+
+ /**
+ * @deprecated Please use {@link #encryptPKC(String)} to encrypt the text.
+ * Encrypts the text using the secret key in key.properties file.
+ *
+ * @param plainText
+ * Text to encrypt
+ * @return Encrypted Text
+ * @
+ * if any decryption step fails
+ */
+ @Deprecated
+ public static String encrypt(String plainText) {
+ return CipherUtil.encrypt(plainText, keyString);
+ }
+
+ /**
+ * Encrypts the text using a secret key.
+ *
+ * @param plainText
+ * Text to encrypt
+ * @return Encrypted Text
+ * @
+ * if any decryption step fails
+ */
+ public static String encryptPKC(String plainText) {
+ return CipherUtil.encryptPKC(plainText, keyString);
+ }
+
+ /**
+ *
+ * @deprecated Please use {@link #decryptPKC(String)} to Decryption the text.
+ *
+ * Decrypts the text using the specified secret key.
+ *
+ * @param encryptedText
+ * Text to decrypt
+ * @param secretKey
+ * Key to use for decryption
+ * @return plain text version of encrypted text
+ * @
+ * if any decryption step fails
+ *
+ */
+ @Deprecated
+ public static String decrypt(String encryptedText, String secretKey) {
+ String encryptedString = null;
+ try {
+ byte[] rawKey = Base64.decodeBase64(secretKey);
+ SecretKeySpec sKeySpec = new SecretKeySpec(rawKey, "AES");
+ byte[] encryptText = Base64.decodeBase64(encryptedText.getBytes("UTF-8"));
+ Cipher cipher = Cipher.getInstance("AES");
+ cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
+ encryptedString = new String(cipher.doFinal(encryptText));
+ } catch (BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException
+ | NoSuchPaddingException | UnsupportedEncodingException ex) {
+ }
+ return encryptedString;
+ }
+
+ private static SecretKeySpec getSecretKeySpec() {
+ byte[] key = Base64.decodeBase64(keyString);
+ return new SecretKeySpec(key, ALGORITHM);
+ }
+
+ private static SecretKeySpec getSecretKeySpec(String keyString) {
+ byte[] key = Base64.decodeBase64(keyString);
+ return new SecretKeySpec(key, ALGORITHM);
+ }
+
+ /**
+ * Encrypt the text using the secret key in key.properties file
+ *
+ * @param value
+ * @return The encrypted string
+ * @throws BadPaddingException
+ * @
+ * In case of issue with the encryption
+ */
+ public static String encryptPKC(String value, String skey) {
+ Cipher cipher = null;
+ byte[] iv = null;
+ byte[] finalByte = null;
+
+ try {
+ cipher = Cipher.getInstance(ALGORYTHM_DETAILS, "SunJCE");
+
+ SecureRandom r = SecureRandom.getInstance("SHA1PRNG");
+ iv = new byte[BLOCK_SIZE / 8];
+ r.nextBytes(iv);
+ ivspec = new IvParameterSpec(iv);
+ cipher.init(Cipher.ENCRYPT_MODE, getSecretKeySpec(skey), ivspec);
+ finalByte = cipher.doFinal(value.getBytes());
+
+ } catch (Exception ex) {
+
+ }
+ return Base64.encodeBase64String(ArrayUtils.addAll(iv, finalByte));
+ }
+
+ /**
+ * Decrypts the text using the secret key in key.properties file.
+ *
+ * @param message
+ * The encrypted string that must be decrypted using the ecomp
+ * Encryption Key
+ * @return The String decrypted
+ * @
+ * if any decryption step fails
+ */
+ public static String decryptPKC(String message, String skey) {
+ byte[] encryptedMessage = Base64.decodeBase64(message);
+ Cipher cipher;
+ byte[] decrypted = null;
+ try {
+ cipher = Cipher.getInstance(ALGORYTHM_DETAILS, "SunJCE");
+ ivspec = new IvParameterSpec(ArrayUtils.subarray(encryptedMessage, 0, BLOCK_SIZE / 8));
+ byte[] realData = ArrayUtils.subarray(encryptedMessage, BLOCK_SIZE / 8, encryptedMessage.length);
+ cipher.init(Cipher.DECRYPT_MODE, getSecretKeySpec(skey), ivspec);
+ decrypted = cipher.doFinal(realData);
+
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Error in decryptPKC", ex);
+
+ }
+
+ return new String(decrypted);
+ }
+
+ /**
+ * @deprecated Please use {@link #decryptPKC(String)} to Decrypt the text.
+ *
+ * Decrypts the text using the secret key in key.properties file.
+ *
+ * @param encryptedText
+ * Text to decrypt
+ * @return Decrypted text
+ * @
+ * if any decryption step fails
+ */
+ @Deprecated
+ public static String decrypt(String encryptedText) {
+ return CipherUtil.decrypt(encryptedText, keyString);
+ }
+
+ /**
+ *
+ * Decrypts the text using the secret key in key.properties file.
+ *
+ * @param encryptedText
+ * Text to decrypt
+ * @return Decrypted text
+ * @
+ * if any decryption step fails
+ */
+ public static String decryptPKC(String encryptedText) {
+ return CipherUtil.decryptPKC(encryptedText, keyString);
+ }
+
+
+ public static void readAndSetKeyString() {
+ try (Scanner in = new Scanner(new FileReader("/opt/app/music/etc/properties.txt"))) {
+
+ StringBuilder sb = new StringBuilder();
+ while(in.hasNext()) {
+ sb.append(in.next());
+ }
+ keyString = sb.toString();
+ } catch (FileNotFoundException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
+ }
+ }
+
+ public static void main(String[] args) {
+
+ if (args.length < 2) {
+ System.out.println("Usage: java -jar CipherUtil <key> <password>");
+ return;
+ }
+
+ keyString = args[0];
+ String password = args[1];
+
+ String enc = encryptPKC(password);
+ System.out.println("Encrypted password: " + enc);
+
+ System.out.println("Decrypted password (to verify): " + decryptPKC(enc));
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/main/CorePropertiesLoader.java b/music-core/src/main/java/org/onap/music/main/CorePropertiesLoader.java
new file mode 100644
index 00000000..2e5ca689
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/main/CorePropertiesLoader.java
@@ -0,0 +1,120 @@
+/*
+ * ============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.main;
+
+import java.util.Properties;
+
+public class CorePropertiesLoader {
+
+ public static void loadProperties(Properties properties) {
+ if (properties.getProperty("cassandra.host")!=null) {
+ MusicUtil.setMyCassaHost(properties.getProperty("cassandra.host"));
+ }
+
+ if (properties.getProperty("cassandra.port")!=null) {
+ MusicUtil.setCassandraPort(Integer.parseInt(properties.getProperty("cassandra.port")));
+ }
+
+ if (properties.getProperty("cassandra.user")!=null) {
+ MusicUtil.setCassName(properties.getProperty("cassandra.user"));
+ }
+
+ if (properties.getProperty("cassandra.password")!=null) {
+ MusicUtil.setCassPwd(properties.getProperty("cassandra.password"));
+ }
+
+ if (properties.getProperty("music.properties")!=null) {
+ MusicUtil.setMusicPropertiesFilePath(properties.getProperty("music.properties"));
+ }
+
+ if (properties.getProperty("debug")!=null) {
+ MusicUtil.setDebug(Boolean.parseBoolean(properties.getProperty("debug")));
+ }
+
+ if (properties.getProperty("version")!=null) {
+ MusicUtil.setVersion(properties.getProperty("version"));
+ }
+
+ if (properties.getProperty("build")!=null) {
+ MusicUtil.setBuild(properties.getProperty("build"));
+ }
+
+ if (properties.getProperty("lock.lease.period")!=null) {
+ MusicUtil.setDefaultLockLeasePeriod(Long.parseLong(properties.getProperty("lock.lease.period")));
+ }
+
+ if (properties.getProperty("cadi")!=null) {
+ MusicUtil.setIsCadi(Boolean.parseBoolean(properties.getProperty("cadi")));
+ }
+
+ if (properties.getProperty("keyspace.active")!=null) {
+ MusicUtil.setKeyspaceActive(Boolean.parseBoolean(properties.getProperty("keyspace.active")));
+ }
+
+ if (properties.getProperty("retry.count")!=null) {
+ MusicUtil.setRetryCount(Integer.parseInt(properties.getProperty("retry.count")));
+ }
+
+ if (properties.getProperty("transId.header.prefix")!=null) {
+ MusicUtil.setTransIdPrefix(properties.getProperty("transId.header.prefix"));
+ }
+
+ if (properties.getProperty("conversation.header.prefix")!=null) {
+ MusicUtil.setConversationIdPrefix(properties.getProperty("conversation.header.prefix"));
+ }
+
+ if (properties.getProperty("clientId.header.prefix")!=null) {
+ MusicUtil.setClientIdPrefix(properties.getProperty("clientId.header.prefix"));
+ }
+
+ if (properties.getProperty("messageId.header.prefix")!=null) {
+ MusicUtil.setMessageIdPrefix(properties.getProperty("messageId.header.prefix"));
+ }
+
+ if (properties.getProperty("transId.header.required")!=null) {
+ MusicUtil.setTransIdRequired(Boolean.parseBoolean(properties.getProperty("transId.header.required")));
+ }
+
+ if (properties.getProperty("conversation.header.required")!=null) {
+ MusicUtil.setConversationIdRequired(Boolean.parseBoolean(properties.getProperty("conversation.header.required")));
+ }
+
+ if (properties.getProperty("clientId.header.required")!=null) {
+ MusicUtil.setClientIdRequired(Boolean.parseBoolean(properties.getProperty("clientId.header.required")));
+ }
+
+ if (properties.getProperty("messageId.header.required")!=null) {
+ MusicUtil.setMessageIdRequired(Boolean.parseBoolean(properties.getProperty("messageId.header.required")));
+ }
+
+ if (properties.getProperty("music.aaf.ns")!=null) {
+ MusicUtil.setMusicAafNs(properties.getProperty("music.aaf.ns"));
+ }
+
+ if (properties.getProperty("cipher.enc.key")!=null) {
+ MusicUtil.setCipherEncKey(properties.getProperty("cipher.enc.key"));
+ }
+
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/main/DeadlockDetectionUtil.java b/music-core/src/main/java/org/onap/music/main/DeadlockDetectionUtil.java
new file mode 100644
index 00000000..004bd550
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/main/DeadlockDetectionUtil.java
@@ -0,0 +1,152 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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.main;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DeadlockDetectionUtil {
+ private Map<String, Node> nodeList = null;
+ public enum OwnershipType {NONE, CREATED, ACQUIRED};
+
+ private class Node implements Comparable<Node> {
+ private String id;
+ private List<Node> links;
+ private boolean visited = false;
+ private boolean onStack = false;
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ for (Node link : links)
+ sb.append(link.id);
+ return "Node [id=" + id + ", links=" + sb.toString() + ", visited=" + visited + ", onStack=" + onStack + "]";
+ }
+
+ public Node(String id) {
+ super();
+ this.id = id;
+ this.links = new ArrayList<>();
+ }
+
+ public List<Node> getLinks() {
+ return links;
+ }
+
+ public void addLink(Node link) {
+ this.links.add(link);
+ }
+
+ public void removeLink(Node link) {
+ this.links.remove(link);
+ }
+
+ public boolean isVisited() {
+ return visited;
+ }
+
+ public boolean isOnStack() {
+ return onStack;
+ }
+
+ public void setVisited(boolean visited) {
+ this.visited = visited;
+ }
+
+ public void setOnStack(boolean onStack) {
+ this.onStack = onStack;
+ }
+
+ @Override
+ public int compareTo(Node arg0) {
+ return id.compareTo(arg0.id);
+ }
+ }
+
+ public DeadlockDetectionUtil() {
+ this.nodeList = new HashMap<>();
+ }
+
+ public void listAllNodes() {
+ System.out.println("In DeadlockDetectionUtil: ");
+ for (String key : nodeList.keySet()) {
+ System.out.println(" " + key + " : " + nodeList.get(key));
+ }
+ }
+
+ public boolean checkForDeadlock(String resource, String owner, OwnershipType operation) {
+ setExisting(resource, owner, operation);
+
+ Node currentNode = null;
+ if (operation.equals(OwnershipType.ACQUIRED)) {
+ currentNode = nodeList.get("r" + resource);
+ } else if (operation.equals(OwnershipType.CREATED)) {
+ currentNode = nodeList.get("o" + owner);
+ }
+
+ return findCycle(currentNode);
+ }
+
+ private boolean findCycle(Node currentNode) {
+ if (currentNode==null)
+ return false;
+ if (currentNode.isOnStack())
+ return true;
+ if (currentNode.isVisited())
+ return false;
+ currentNode.setOnStack(true);
+ currentNode.setVisited(true);
+ for (Node childNode : currentNode.getLinks()) {
+ if (findCycle(childNode))
+ return true;
+ }
+ currentNode.setOnStack(false);
+ return false;
+ }
+
+ public void setExisting(String resource, String owner, OwnershipType operation) {
+ String resourceKey = "r" + resource;
+ Node resourceNode = nodeList.get(resourceKey);
+ if (resourceNode==null) {
+ resourceNode = new Node(resourceKey);
+ nodeList.put(resourceKey, resourceNode);
+ }
+
+ String ownerKey = "o" + owner;
+ Node ownerNode = nodeList.get(ownerKey);
+ if (ownerNode==null) {
+ ownerNode = new Node(ownerKey);
+ nodeList.put(ownerKey, ownerNode);
+ }
+
+ if (operation.equals(OwnershipType.ACQUIRED)) {
+ resourceNode.addLink(ownerNode);
+ ownerNode.removeLink(resourceNode);
+ } else if (operation.equals(OwnershipType.CREATED)) {
+ ownerNode.addLink(resourceNode);
+ resourceNode.removeLink(ownerNode);
+ }
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/main/MusicCore.java b/music-core/src/main/java/org/onap/music/main/MusicCore.java
new file mode 100644
index 00000000..30d2bc47
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/main/MusicCore.java
@@ -0,0 +1,264 @@
+/*
+ * ============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.main;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.onap.music.datastore.Condition;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonDelete;
+import org.onap.music.datastore.jsonobjects.JsonIndex;
+import org.onap.music.datastore.jsonobjects.JsonInsert;
+import org.onap.music.datastore.jsonobjects.JsonKeySpace;
+import org.onap.music.datastore.jsonobjects.JsonSelect;
+import org.onap.music.datastore.jsonobjects.JsonTable;
+import org.onap.music.datastore.jsonobjects.JsonUpdate;
+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.lockingservice.cassandra.CassaLockStore;
+import org.onap.music.lockingservice.cassandra.LockType;
+import org.onap.music.lockingservice.cassandra.MusicLockState;
+import org.onap.music.service.MusicCoreService;
+
+import com.datastax.driver.core.ResultSet;
+
+public class MusicCore {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCore.class);
+ private static MusicCoreService musicCore = MusicUtil.getMusicCoreService();
+ private static CassaLockStore mLockHandle;
+
+ public static CassaLockStore getmLockHandle() {
+ return mLockHandle;
+ }
+
+ public static void setmLockHandle(CassaLockStore mLockHandleIn) {
+ mLockHandle = mLockHandleIn;
+ }
+
+ /**
+ * Acquire lock
+ *
+ * @param fullyQualifiedKey DO NOT RELY ON THIS KEY WORKING. INCLUDE THE KEY IN THE LOCKID.
+ * @param lockId - the full lock id (key + lockRef)
+ * @return
+ * @throws MusicLockingException
+ * @throws MusicQueryException
+ * @throws MusicServiceException
+ */
+ public static ReturnType acquireLock(String fullyQualifiedKey, String lockId)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+ return musicCore.acquireLock(fullyQualifiedKey, lockId);
+ }
+
+ public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+ return musicCore.acquireLockWithLease(key, lockId, leasePeriod);
+ }
+
+ public static String createLockReferenceAtomic(String fullyQualifiedKey) throws MusicLockingException {
+ return musicCore.createLockReferenceAtomic(fullyQualifiedKey);
+ }
+
+ public static String createLockReference(String fullyQualifiedKey, String owner) throws MusicLockingException {
+ return musicCore.createLockReference(fullyQualifiedKey, owner);
+ }
+
+ public static String createLockReferenceAtomic(String fullyQualifiedKey, LockType locktype) throws MusicLockingException {
+ return musicCore.createLockReferenceAtomic(fullyQualifiedKey, locktype);
+ }
+
+ public static String createLockReference(String fullyQualifiedKey, LockType locktype, String owner) throws MusicLockingException {
+ return musicCore.createLockReference(fullyQualifiedKey, locktype, owner);
+ }
+
+ public static ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject,
+ String consistency) throws MusicServiceException {
+ return musicCore.createTable(keyspace, table, tableQueryObject, consistency);
+ }
+
+ public static ResultSet quorumGet(PreparedQueryObject query) {
+ return musicCore.quorumGet(query);
+ }
+
+ /**
+ * Gets the top of queue for fullyQualifiedKey
+ *
+ * @param fullyQualifiedKey
+ * @return
+ */
+ public static String whoseTurnIsIt(String fullyQualifiedKey) {
+ return musicCore.whoseTurnIsIt(fullyQualifiedKey);
+ }
+
+ /**
+ * Gets the current lockholder(s) for fullyQualifiedKey
+ *
+ * @param fullyQualifiedKey
+ * @return
+ */
+ public static List<String> getCurrentLockHolders(String fullyQualifiedKey) {
+ return musicCore.getCurrentLockHolders(fullyQualifiedKey);
+ }
+
+ public static ReturnType promoteLock(String lockIdToPromote) throws MusicLockingException {
+ return musicCore.promoteLock(lockIdToPromote);
+ }
+
+ public static void destroyLockRef(String lockId) throws MusicLockingException {
+ musicCore.destroyLockRef(lockId);
+ }
+
+ public static ReturnType eventualPut(PreparedQueryObject queryObject) {
+ return musicCore.eventualPut(queryObject);
+ }
+
+ public static ReturnType eventualPut_nb(PreparedQueryObject queryObject, String keyspace, String tablename,
+ String primaryKey) {
+ return musicCore.eventualPut_nb(queryObject, keyspace, tablename, primaryKey);
+ }
+
+ public static ReturnType criticalPut(String keyspace, String table, String primaryKeyValue,
+ PreparedQueryObject queryObject, String lockReference, Condition conditionInfo) {
+ return musicCore.criticalPut(keyspace, table, primaryKeyValue, queryObject, lockReference, conditionInfo);
+ }
+
+ public static ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency)
+ throws MusicServiceException,MusicQueryException {
+ return musicCore.nonKeyRelatedPut(queryObject, consistency);
+ }
+
+ public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
+ return musicCore.get(queryObject);
+ }
+
+ public static ResultSet criticalGet(String keyspace, String table, String primaryKeyValue,
+ PreparedQueryObject queryObject, String lockReference) throws MusicServiceException {
+ return musicCore.criticalGet(keyspace, table, primaryKeyValue, queryObject, lockReference);
+ }
+
+ public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, Condition conditionInfo)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+ return musicCore.atomicPut(keyspaceName, tableName, primaryKey, queryObject, conditionInfo);
+ }
+
+ public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException, MusicQueryException {
+ return musicCore.atomicGet(keyspaceName, tableName, primaryKey, queryObject);
+ }
+
+ public static List<String> getLockQueue(String fullyQualifiedKey)
+ throws MusicServiceException, MusicQueryException, MusicLockingException {
+ return musicCore.getLockQueue(fullyQualifiedKey);
+ }
+
+ public static long getLockQueueSize(String fullyQualifiedKey)
+ throws MusicServiceException, MusicQueryException, MusicLockingException {
+ return musicCore.getLockQueueSize(fullyQualifiedKey);
+ }
+
+ public static void deleteLock(String lockName) throws MusicLockingException {
+ musicCore.deleteLock(lockName);
+ }
+
+ public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
+ return musicCore.atomicPutWithDeleteLock(keyspaceName, tableName, primaryKey, queryObject, conditionInfo);
+ }
+
+ public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
+ return musicCore.atomicGetWithDeleteLock(keyspaceName, tableName, primaryKey, queryObject);
+ }
+
+ public static Map<String, Object> validateLock(String lockName) {
+ return musicCore.validateLock(lockName);
+ }
+
+ public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) throws MusicLockingException {
+ return musicCore.releaseLock(lockId, voluntaryRelease);
+ }
+
+ public static List<String> releaseAllLocksForOwner(String ownerId, String keyspace, String table) throws MusicLockingException, MusicServiceException, MusicQueryException {
+ return musicCore.releaseAllLocksForOwner(ownerId, keyspace, table);
+ }
+
+ //Added changes for orm implementation.
+
+ public static ResultType createKeyspace(JsonKeySpace jsonKeySpaceObject, String consistencyInfo)
+ throws MusicServiceException, MusicQueryException {
+ return musicCore.createKeyspace(jsonKeySpaceObject,consistencyInfo);
+ }
+
+ public static ResultType dropKeyspace(JsonKeySpace josnKeyspaceObject, String consistencyInfo)
+ throws MusicServiceException,MusicQueryException {
+ return musicCore.dropKeyspace(josnKeyspaceObject, consistencyInfo);
+ }
+
+ public static ResultType createTable(JsonTable jsonTableObject,String consistencyInfo)
+ throws MusicServiceException,MusicQueryException {
+ return musicCore.createTable(jsonTableObject, consistencyInfo);
+ }
+
+ public static ResultType dropTable(JsonTable jsonTableObject, String consistencyInfo)
+ throws MusicServiceException, MusicQueryException {
+ return musicCore.dropTable(jsonTableObject, consistencyInfo);
+ }
+
+ public static ResultType createIndex(JsonIndex jsonIndexObject, String consistencyInfo)
+ throws MusicServiceException,MusicQueryException {
+ return musicCore.createIndex(jsonIndexObject, consistencyInfo);
+ }
+
+ public static ResultSet select(JsonSelect jsonSelect, MultivaluedMap<String, String> rowParams)
+ throws MusicServiceException, MusicQueryException{
+ return musicCore.select(jsonSelect, rowParams);
+ }
+
+ public static ResultSet selectCritical(JsonInsert jsonInsertObj, MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException{
+ return musicCore.selectCritical(jsonInsertObj, rowParams);
+ }
+
+
+ public static ReturnType insertIntoTable(JsonInsert jsonInsert) throws MusicLockingException, MusicQueryException, MusicServiceException{
+ return musicCore.insertIntoTable(jsonInsert);
+ }
+
+ public static ReturnType updateTable(JsonUpdate jsonUpdateObj,MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException{
+ return musicCore.updateTable(jsonUpdateObj, rowParams);
+ }
+
+ public static ReturnType deleteFromTable(JsonDelete jsonDeleteObj,MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException{
+ return musicCore.deleteFromTable(jsonDeleteObj,rowParams);
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/main/MusicUtil.java b/music-core/src/main/java/org/onap/music/main/MusicUtil.java
new file mode 100644
index 00000000..4b8b1059
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/main/MusicUtil.java
@@ -0,0 +1,881 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modifications Copyright (c) 2019 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.
+ * 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.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.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.UUID;
+
+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;
+import org.onap.music.service.impl.MusicCassaCore;
+
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.DataType;
+
+/**
+ * @author nelson24
+ *
+ * Properties This will take Properties and load them into MusicUtil.
+ * This is a hack for now. Eventually it would bebest to do this in
+ * another way.
+ *
+ */
+public class MusicUtil {
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class);
+
+ // Consistancy Constants
+ public static final String ATOMIC = "atomic";
+ public static final String EVENTUAL = "eventual";
+ public static final String CRITICAL = "critical";
+ public static final String EVENTUAL_NB = "eventual_nb";
+ public static final String ALL = "all";
+ public static final String QUORUM = "quorum";
+ public static final String LOCAL_QUORUM = "local_quorum";
+ public static final String ONE = "one";
+ public static final String ATOMICDELETELOCK = "atomic_delete_lock";
+
+ // Header Constants
+ private static final String XLATESTVERSION = "X-latestVersion";
+ private static final String XMINORVERSION = "X-minorVersion";
+ private static final String XPATCHVERSION = "X-patchVersion";
+ public static final String AUTHORIZATION = "Authorization";
+
+ // CQL Constants
+ public static final String SELECT = "select";
+ public static final String INSERT = "insert";
+ public static final String UPDATE = "update";
+ public static final String UPSERT = "upsert";
+ public static final String USERID = "userId";
+ public static final String PASSWORD = "";
+ public static final String CASSANDRA = "cassandra";
+
+ private static final String LOCALHOST = "localhost";
+ private static final String PROPERTIES_FILE = "/opt/app/music/etc/music.properties";
+ public static final String DEFAULTKEYSPACENAME = "TBD";
+
+ private static long defaultLockLeasePeriod = 6000;
+ // Amount of times to retry to delete a lock in atomic.
+ private static int retryCount = 3;
+ private static String lockUsing = MusicUtil.CASSANDRA;
+ // Cadi OnOff
+ private static boolean isCadi = false;
+ // Keyspace Creation on/off
+ private static boolean isKeyspaceActive = false;
+ private static boolean debug = true;
+ private static String version = "0.0.0";
+ private static String build = "";
+ private static long lockDaemonSleepms = 1000;
+ private static Set<String> keyspacesToCleanLocks = new HashSet<>();
+
+ private static String musicPropertiesFilePath = PROPERTIES_FILE;
+ // private static final String[] propKeys = new String[] { MusicUtil.class.getDeclaredMethod(arg0, )"build","cassandra.host", "debug",
+ // "version", "music.properties", "lock.lease.period", "cassandra.user",
+ // "cassandra.password", "aaf.endpoint.url","admin.username","admin.password",
+ // "music.namespace","admin.aaf.role","cassandra.port","lock.using","retry.count",
+ // "transId.header.required","conversation.header.required","clientId.header.required",
+ // "messageId.header.required","transId.header.prefix","conversation.header.prefix",
+ // "clientId.header.prefix","messageId.header.prefix"};
+ // Consistency Constants and variables.
+ private static final String[] cosistencyLevel = new String[] {
+ "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);
+ consistencyName.put("THREE",ConsistencyLevel.THREE);
+ consistencyName.put("SERIAL",ConsistencyLevel.SERIAL);
+ consistencyName.put("ALL",ConsistencyLevel.ALL);
+ consistencyName.put("EACH_QUORUM",ConsistencyLevel.EACH_QUORUM);
+ consistencyName.put("QUORUM",ConsistencyLevel.QUORUM);
+ consistencyName.put("LOCAL_QUORUM",ConsistencyLevel.LOCAL_QUORUM);
+ consistencyName.put("LOCAL_ONE",ConsistencyLevel.LOCAL_ONE);
+ consistencyName.put("LOCAL_SERIAL",ConsistencyLevel.LOCAL_SERIAL);
+ }
+
+ // Cassandra Values
+ private static String cassName = "cassandra";
+ private static String cassPwd;
+ private static String myCassaHost = LOCALHOST;
+ private static int cassandraPort = 9042;
+ private static int cassandraConnectTimeOutMS;
+ private static int cassandraReadTimeOutMS;
+
+ // AAF
+ private static String musicAafNs = "org.onap.music.cadi";
+
+ // Locking
+ public static final long MusicEternityEpochMillis = 1533081600000L; // Wednesday, August 1, 2018 12:00:00 AM
+ public static final long MaxLockReferenceTimePart = 1000000000000L; // millis after eternity (eq sometime in 2050)
+ public static final long MaxCriticalSectionDurationMillis = 1L * 24 * 60 * 60 * 1000; // 1 day
+
+ // Response/Request tracking headers
+ private static String transIdPrefix = "false";
+ private static String conversationIdPrefix = "false";
+ private static String clientIdPrefix = "false";
+ private static String messageIdPrefix = "false";
+ private static Boolean transIdRequired = false;
+ private static Boolean conversationIdRequired = false;
+ private static Boolean clientIdRequired = false;
+ private static Boolean messageIdRequired = false;
+ private static String cipherEncKey = "";
+
+ private static long createLockWaitPeriod = 300;
+ private static int createLockWaitIncrement = 50;
+
+ public static long getCreateLockWaitPeriod() {
+ return createLockWaitPeriod;
+ }
+
+ public static void setCreateLockWaitPeriod(long createLockWaitPeriod) {
+ MusicUtil.createLockWaitPeriod = createLockWaitPeriod;
+ }
+
+ public static int getCreateLockWaitIncrement() {
+ return createLockWaitIncrement;
+ }
+
+ public static void setCreateLockWaitIncrement(int createLockWaitIncrement) {
+ MusicUtil.createLockWaitIncrement = createLockWaitIncrement;
+ }
+
+ public MusicUtil() {
+ throw new IllegalStateException("Utility Class");
+ }
+
+ public static String getLockUsing() {
+ return lockUsing;
+ }
+
+ public static void setLockUsing(String lockUsing) {
+ MusicUtil.lockUsing = lockUsing;
+ }
+
+ /**
+ *
+ * @return cassandra port
+ */
+ public static int getCassandraPort() {
+ return cassandraPort;
+ }
+
+ /**
+ * set cassandra port
+ * @param cassandraPort
+ */
+ public static void setCassandraPort(int cassandraPort) {
+ MusicUtil.cassandraPort = cassandraPort;
+ }
+ /**
+ * @return the cassName
+ */
+ public static String getCassName() {
+ return cassName;
+ }
+
+ /**
+ * @return the cassPwd
+ */
+ public static String getCassPwd() {
+ return cassPwd;
+ }
+
+ public static int getCassandraConnectTimeOutMS() {
+ return cassandraConnectTimeOutMS;
+ }
+
+ public static void setCassandraConnectTimeOutMS(int cassandraConnectTimeOutMS) {
+ MusicUtil.cassandraConnectTimeOutMS = cassandraConnectTimeOutMS;
+ }
+
+ public static int getCassandraReadTimeOutMS() {
+ return cassandraReadTimeOutMS;
+ }
+
+ public static void setCassandraReadTimeOutMS(int cassandraReadTimeOutMS) {
+ MusicUtil.cassandraReadTimeOutMS = cassandraReadTimeOutMS;
+ }
+
+ /**
+ * Returns An array of property names that should be in the Properties
+ * files.
+ *
+// * @return
+// */
+ // public static String[] getPropkeys() {
+ // return propKeys.clone();
+ // }
+
+ /**
+ * Get MusicPropertiesFilePath - Default = /opt/music/music.properties
+ * property file value - music.properties
+ *
+ * @return
+ */
+ public static String getMusicPropertiesFilePath() {
+ return musicPropertiesFilePath;
+ }
+
+ /**
+ * Set MusicPropertiesFilePath
+ *
+ * @param musicPropertiesFilePath
+ */
+ public static void setMusicPropertiesFilePath(String musicPropertiesFilePath) {
+ MusicUtil.musicPropertiesFilePath = musicPropertiesFilePath;
+ }
+
+ /**
+ * Get DefaultLockLeasePeriod - Default = 6000 property file value -
+ * lock.lease.period
+ *
+ * @return
+ */
+ public static long getDefaultLockLeasePeriod() {
+ return defaultLockLeasePeriod;
+ }
+
+ /**
+ * Set DefaultLockLeasePeriod
+ *
+ * @param defaultLockLeasePeriod
+ */
+ public static void setDefaultLockLeasePeriod(long defaultLockLeasePeriod) {
+ MusicUtil.defaultLockLeasePeriod = defaultLockLeasePeriod;
+ }
+
+ /**
+ * Set Debug
+ *
+ * @param debug
+ */
+ public static void setDebug(boolean debug) {
+ MusicUtil.debug = debug;
+ }
+
+ /**
+ * Is Debug - Default = true property file value - debug
+ *
+ * @return
+ */
+ public static boolean isDebug() {
+ return debug;
+ }
+
+ /**
+ * Set Version
+ *
+ * @param version
+ */
+ public static void setVersion(String version) {
+ MusicUtil.version = version;
+ }
+
+ /**
+ * Return the version property file value - version.
+ *
+ * @return
+ */
+ public static String getVersion() {
+ return version;
+ }
+
+ /**
+ * 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
+ *
+ * @return
+ */
+ public static String getMyCassaHost() {
+ return myCassaHost;
+ }
+
+ /**
+ * Set MyCassHost - Cassandra Hostname
+ *
+ * @param myCassaHost .
+ */
+ public static void setMyCassaHost(String myCassaHost) {
+ MusicUtil.myCassaHost = myCassaHost;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * This method depricated as its not used or needed.
+ *
+ * @return String
+ */
+ @Deprecated
+ 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
+ fileScanner.close();
+ } catch (FileNotFoundException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e);
+ }
+ return testType;
+
+ }
+
+ /**
+ * Method to do a Thread Sleep.
+ * Used for adding a delay.
+ *
+ * @param time
+ */
+ public static void sleep(long time) {
+ try {
+ Thread.sleep(time);
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e);
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
+ * Utility function to check if the query object is valid.
+ *
+ * @param withparams
+ * @param queryObject
+ * @return
+ */
+ public static boolean isValidQueryObject(boolean withparams, PreparedQueryObject queryObject) {
+ if (withparams) {
+ int noOfValues = queryObject.getValues().size();
+ int noOfParams = 0;
+ char[] temp = queryObject.getQuery().toCharArray();
+ for (int i = 0; i < temp.length; i++) {
+ if (temp[i] == '?')
+ noOfParams++;
+ }
+ return (noOfValues == noOfParams);
+ } else {
+ return !queryObject.getQuery().isEmpty();
+ }
+
+ }
+
+ public static void setCassName(String cassName) {
+ MusicUtil.cassName = cassName;
+ }
+
+ public static void setCassPwd(String cassPwd) {
+ MusicUtil.cassPwd = cassPwd;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static String convertToCQLDataType(DataType type, Object valueObj) throws Exception {
+
+ String value = "";
+ switch (type.getName()) {
+ case UUID:
+ value = valueObj + "";
+ break;
+ case TEXT:
+ case VARCHAR:
+ String valueString = valueObj + "";
+ valueString = valueString.replace("'", "''");
+ value = "'" + valueString + "'";
+ break;
+ case MAP: {
+ Map<String, Object> otMap = (Map<String, Object>) valueObj;
+ value = "{" + jsonMaptoSqlString(otMap, ",") + "}";
+ break;
+ }
+ default:
+ value = valueObj + "";
+ break;
+ }
+ return value;
+ }
+
+ /**
+ *
+ * @param colType
+ * @param valueObj
+ * @return
+ * @throws MusicTypeConversionException
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ public static Object convertToActualDataType(DataType colType, Object valueObj) throws Exception {
+ String valueObjString = valueObj + "";
+ switch (colType.getName()) {
+ case UUID:
+ return UUID.fromString(valueObjString);
+ case VARINT:
+ return BigInteger.valueOf(Long.parseLong(valueObjString));
+ case BIGINT:
+ return Long.parseLong(valueObjString);
+ case INT:
+ return Integer.parseInt(valueObjString);
+ case FLOAT:
+ return Float.parseFloat(valueObjString);
+ case DOUBLE:
+ return Double.parseDouble(valueObjString);
+ case BOOLEAN:
+ return Boolean.parseBoolean(valueObjString);
+ case MAP:
+ return (Map<String, Object>) valueObj;
+ case LIST:
+ return valueObj;
+ case BLOB:
+
+ default:
+ return valueObjString;
+ }
+ }
+
+ public static ByteBuffer convertToActualDataType(DataType colType, byte[] valueObj) {
+
+ return ByteBuffer.wrap(valueObj);
+ }
+
+ /**
+ *
+ * Utility function to parse json map into sql like string
+ *
+ * @param jMap
+ * @param lineDelimiter
+ * @return
+ */
+
+ public static String jsonMaptoSqlString(Map<String, Object> jMap, String lineDelimiter) throws Exception{
+ StringBuilder sqlString = new StringBuilder();
+ int counter = 0;
+ for (Map.Entry<String, Object> entry : jMap.entrySet()) {
+ Object ot = entry.getValue();
+ String value = ot + "";
+ if (ot instanceof String) {
+ value = "'" + value.replace("'", "''") + "'";
+ }
+ sqlString.append("'" + entry.getKey() + "':" + value);
+ if (counter != jMap.size() - 1)
+ sqlString.append(lineDelimiter);
+ counter = counter + 1;
+ }
+ return sqlString.toString();
+ }
+
+ @SuppressWarnings("unused")
+ public static String buildVersion(String major, String minor, String patch) {
+ if (minor != null) {
+ major += "." + minor;
+ if (patch != null) {
+ major += "." + patch;
+ }
+ }
+ return major;
+ }
+
+ /**
+ * Currently this will build a header with X-latestVersion, X-minorVersion and X-pathcVersion
+ * X-latestVerstion will be equal to the latest full version.
+ * X-minorVersion - will be equal to the latest minor version.
+ * X-pathVersion - will be equal to the latest patch version.
+ * Future plans will change this.
+ * @param response
+ * @param major
+ * @param minor
+ * @param patch
+ * @return
+ */
+ public static ResponseBuilder buildVersionResponse(String major, String minor, String patch) {
+ ResponseBuilder response = Response.noContent();
+ String versionIn = buildVersion(major,minor,patch);
+ String version = MusicUtil.getVersion();
+ String[] verArray = version.split("\\.",3);
+ if ( minor != null ) {
+ response.header(XMINORVERSION,minor);
+ } else {
+ response.header(XMINORVERSION,verArray[1]);
+ }
+ if ( patch != null ) {
+ response.header(XPATCHVERSION,patch);
+ } else {
+ response.header(XPATCHVERSION,verArray[2]);
+ }
+ response.header(XLATESTVERSION,version);
+ logger.info(EELFLoggerDelegate.auditLogger,"Version In:" + versionIn);
+ return response;
+ }
+
+ public static boolean isValidConsistency(String consistency) {
+ for (String string : cosistencyLevel) {
+ if (string.equalsIgnoreCase(consistency))
+ return true;
+ }
+ return false;
+
+ }
+
+ public static ConsistencyLevel getConsistencyLevel(String consistency) {
+ return consistencyName.get(consistency.toUpperCase());
+ }
+
+ /**
+ * Given the time of write for an update in a critical section, this method provides a transformed timestamp
+ * that ensures that a previous lock holder who is still alive can never corrupt a later critical section.
+ * The main idea is to us the lock reference to clearly demarcate the timestamps across critical sections.
+ * @param the UUID lock reference associated with the write.
+ * @param the long timeOfWrite which is the actual time at which the write took place
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public static long v2sTimeStampInMicroseconds(long ordinal, long timeOfWrite) throws MusicServiceException, MusicQueryException{
+ // TODO: use acquire time instead of music eternity epoch
+ return ordinal * MaxLockReferenceTimePart + (timeOfWrite - MusicEternityEpochMillis);
+ }
+
+ public static MusicCoreService getMusicCoreService() {
+ if(getLockUsing().equals(MusicUtil.CASSANDRA))
+ return MusicCassaCore.getInstance();
+ else
+ return MusicCassaCore.getInstance();
+ }
+
+ /**
+ * @param lockName
+ * @return
+ */
+ public static 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;
+ }
+
+
+ public static void setIsCadi(boolean isCadi) {
+ 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, e);
+ }
+ }
+
+ public static boolean getIsCadi() {
+ return MusicUtil.isCadi;
+ }
+
+
+ /**
+ * @return a random uuid
+ */
+ public static String generateUUID() {
+ String uuid = UUID.randomUUID().toString();
+ logger.info(EELFLoggerDelegate.applicationLogger,"New AID generated: "+uuid);
+ return uuid;
+ }
+
+ private static String checkPrefix(String prefix){
+ if (prefix == null || "".equals(prefix) || prefix.endsWith("-")) {
+ return prefix;
+ } else {
+ return prefix + "-";
+ }
+ }
+
+ /**
+ * @return the transIdPrefix
+ */
+ public static String getTransIdPrefix() {
+ return transIdPrefix;
+ }
+
+ /**
+ * @param transIdPrefix the transIdPrefix to set
+ */
+ public static void setTransIdPrefix(String transIdPrefix) {
+ MusicUtil.transIdPrefix = checkPrefix(transIdPrefix);
+ }
+
+ /**
+ * @return the conversationIdPrefix
+ */
+ public static String getConversationIdPrefix() {
+ return conversationIdPrefix;
+ }
+
+ /**
+ * @param conversationIdPrefix the conversationIdPrefix to set
+ */
+ public static void setConversationIdPrefix(String conversationIdPrefix) {
+ MusicUtil.conversationIdPrefix = checkPrefix(conversationIdPrefix);
+ }
+
+ /**
+ * @return the clientIdPrefix
+ */
+ public static String getClientIdPrefix() {
+ return clientIdPrefix;
+ }
+
+ /**
+ * @param clientIdPrefix the clientIdPrefix to set
+ */
+ public static void setClientIdPrefix(String clientIdPrefix) {
+ MusicUtil.clientIdPrefix = checkPrefix(clientIdPrefix);
+ }
+
+ /**
+ * @return the messageIdPrefix
+ */
+ public static String getMessageIdPrefix() {
+ return messageIdPrefix;
+ }
+
+ /**
+ * @param messageIdPrefix the messageIdPrefix to set
+ */
+ public static void setMessageIdPrefix(String messageIdPrefix) {
+ MusicUtil.messageIdPrefix = checkPrefix(messageIdPrefix);
+ }
+
+ /**
+ * @return the transIdRequired
+ */
+ public static Boolean getTransIdRequired() {
+ return transIdRequired;
+ }
+
+
+ /**
+ * @param transIdRequired the transIdRequired to set
+ */
+ public static void setTransIdRequired(Boolean transIdRequired) {
+ MusicUtil.transIdRequired = transIdRequired;
+ }
+
+
+ /**
+ * @return the conversationIdRequired
+ */
+ public static Boolean getConversationIdRequired() {
+ return conversationIdRequired;
+ }
+
+
+ /**
+ * @param conversationIdRequired the conversationIdRequired to set
+ */
+ public static void setConversationIdRequired(Boolean conversationIdRequired) {
+ MusicUtil.conversationIdRequired = conversationIdRequired;
+ }
+
+
+ /**
+ * @return the clientIdRequired
+ */
+ public static Boolean getClientIdRequired() {
+ return clientIdRequired;
+ }
+
+
+ /**
+ * @param clientIdRequired the clientIdRequired to set
+ */
+ public static void setClientIdRequired(Boolean clientIdRequired) {
+ MusicUtil.clientIdRequired = clientIdRequired;
+ }
+
+
+ /**
+ * @return the messageIdRequired
+ */
+ public static Boolean getMessageIdRequired() {
+ return messageIdRequired;
+ }
+
+ /**
+ * @param messageIdRequired the messageIdRequired to set
+ */
+ public static void setMessageIdRequired(Boolean messageIdRequired) {
+ MusicUtil.messageIdRequired = messageIdRequired;
+ }
+
+ /**
+ * @return the sleep time, in milliseconds, for the lock cleanup daemon
+ */
+ public static long getLockDaemonSleepTimeMs() {
+ return lockDaemonSleepms;
+ }
+
+ /**
+ * set the sleep time, in milliseconds, for the lock cleanup daemon
+ */
+ public static void setLockDaemonSleepTimeMs(long timeoutms) {
+ MusicUtil.lockDaemonSleepms = timeoutms;
+ }
+
+ public static Set<String> getKeyspacesToCleanLocks() {
+ return keyspacesToCleanLocks;
+ }
+
+ public static void setKeyspacesToCleanLocks(Set<String> keyspaces) {
+ MusicUtil.keyspacesToCleanLocks = keyspaces;
+ }
+
+ public static String getCipherEncKey() {
+ return MusicUtil.cipherEncKey;
+ }
+
+
+ public static void setCipherEncKey(String cipherEncKey) {
+ MusicUtil.cipherEncKey = cipherEncKey;
+ if ( null == cipherEncKey || cipherEncKey.equals("") ||
+ cipherEncKey.equals("nothing to see here")) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Missing Cipher Encryption Key.");
+ }
+ }
+
+ public static String getMusicAafNs() {
+ return MusicUtil.musicAafNs;
+ }
+
+
+ public static void setMusicAafNs(String musicAafNs) {
+ MusicUtil.musicAafNs = musicAafNs;
+ }
+
+
+
+}
+
diff --git a/music-core/src/main/java/org/onap/music/main/ResultType.java b/music-core/src/main/java/org/onap/music/main/ResultType.java
new file mode 100644
index 00000000..f5ef2070
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/main/ResultType.java
@@ -0,0 +1,42 @@
+/*
+ * ============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.main;
+
+public enum ResultType {
+ SUCCESS("Success"), FAILURE("Failure"),
+ SYNTAXERROR("SyntaxError"), EXCEPTION("Exception"),
+ BODYMISSING("Incomplete Request body. Please correct your input request and retry.");
+
+ private String result;
+
+ ResultType(String result) {
+ this.result = result;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+}
+
+
diff --git a/music-core/src/main/java/org/onap/music/main/ReturnType.java b/music-core/src/main/java/org/onap/music/main/ReturnType.java
new file mode 100644
index 00000000..f02dabbf
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/main/ReturnType.java
@@ -0,0 +1,75 @@
+/*
+ * ============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.main;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ReturnType {
+ private ResultType result;
+ private String message;
+
+ private String timingInfo;
+
+ public ReturnType(ResultType result, String message) {
+ super();
+ this.result = result;
+ this.message = message;
+ }
+
+ public String getTimingInfo() {
+ return timingInfo;
+ }
+
+ public void setTimingInfo(String timingInfo) {
+ this.timingInfo = timingInfo;
+ }
+
+ public ResultType getResult() {
+ return result;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String toJson() {
+ return "{ \"result\":\"" + result.getResult() + "\", \"message\":\"" + message + "\"}";
+ }
+
+ public String toString() {
+ return result + " | " + message;
+ }
+
+ public Map<String, Object> toMap() {
+ Map<String, Object> newMap = new HashMap<>();
+ newMap.put("result", result.getResult());
+ newMap.put("message", message);
+ return newMap;
+ }
+
+}
diff --git a/music-core/src/main/java/org/onap/music/service/MusicCoreService.java b/music-core/src/main/java/org/onap/music/service/MusicCoreService.java
new file mode 100644
index 00000000..753d9b28
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/service/MusicCoreService.java
@@ -0,0 +1,189 @@
+/*
+ * ============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.service;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.onap.music.datastore.Condition;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonDelete;
+import org.onap.music.datastore.jsonobjects.JsonIndex;
+import org.onap.music.datastore.jsonobjects.JsonInsert;
+import org.onap.music.datastore.jsonobjects.JsonKeySpace;
+import org.onap.music.datastore.jsonobjects.JsonSelect;
+import org.onap.music.datastore.jsonobjects.JsonTable;
+import org.onap.music.datastore.jsonobjects.JsonUpdate;
+import org.onap.music.exceptions.MusicLockingException;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.lockingservice.cassandra.LockType;
+import org.onap.music.lockingservice.cassandra.MusicLockState;
+import org.onap.music.main.ResultType;
+import org.onap.music.main.ReturnType;
+
+import com.datastax.driver.core.ResultSet;
+
+public interface MusicCoreService {
+
+
+ // Core Music Database Methods
+
+
+ public ReturnType eventualPut(PreparedQueryObject queryObject);
+
+ 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);
+
+ public ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency)
+ throws MusicServiceException,MusicQueryException;
+
+ public ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException;
+
+ public ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException, MusicQueryException;
+
+ public ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException;
+
+ public ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException;
+
+ public ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, Condition conditionInfo)
+ throws MusicLockingException, MusicQueryException, MusicServiceException;
+
+ public ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, String lockId) throws MusicServiceException;
+
+ // Core Music Locking Service Methods
+
+ /**
+ * Create a lock ref in the music lock store.
+ * Default is write as this is the safest semantically
+ *
+ * @param fullyQualifiedKey the key to create a lock on
+ * @see {@link #creatLockReference(String, LockType)}
+ */
+ public String createLockReferenceAtomic(String fullyQualifiedKey) throws MusicLockingException; // lock name
+
+ /**
+ * Create a lock ref in the music lock store
+ * @param fullyQualifiedKey the key to create a lock on
+ * @param owner the owner of the lock, for deadlock prevention
+ */
+ public String createLockReference(String fullyQualifiedKey, String owner) throws MusicLockingException;
+
+ /**
+ * Create a lock ref in the music lock store
+ * @param fullyQualifiedKey the key to create a lock on
+ * @param locktype the type of lock create, see {@link LockType}
+ */
+ public String createLockReferenceAtomic(String fullyQualifiedKey, LockType locktype) throws MusicLockingException;
+
+ /**
+ * Create a lock ref in the music lock store
+ * @param fullyQualifiedKey the key to create a lock on
+ * @param locktype the type of lock create, see {@link LockType}
+ * @param owner the owner of the lock, for deadlock prevention
+ */
+ public String createLockReference(String fullyQualifiedKey, LockType locktype, String owner) throws MusicLockingException;
+
+ public ReturnType acquireLockWithLease(String key, String lockReference, long leasePeriod)
+ throws MusicLockingException, MusicQueryException, MusicServiceException; // key,lock id,time
+
+ public ReturnType acquireLock(String key, String lockReference)
+ throws MusicLockingException, MusicQueryException, MusicServiceException; // key,lock id
+
+ public ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject,
+ String consistency) throws MusicServiceException;
+
+ public ResultSet quorumGet(PreparedQueryObject query);
+
+ /**
+ * Gets top of queue for fullyQualifiedKey
+ * @param fullyQualifiedKey
+ * @return
+ */
+ public String whoseTurnIsIt(String fullyQualifiedKey);// lock name
+
+ /**
+ * Gets the current lockholder(s) for lockName
+ * @param lockName
+ * @return
+ */
+ public List<String> getCurrentLockHolders(String fullyQualifiedKey);
+
+ public void destroyLockRef(String lockId) throws MusicLockingException;
+
+ public void deleteLock(String lockName) throws MusicLockingException;
+
+ public ReturnType promoteLock(String lockIdToPromote) throws MusicLockingException;
+
+ public List<String> getLockQueue(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) throws MusicLockingException;
+
+ public List<String> releaseAllLocksForOwner(String ownerId, String keyspace, String table) throws MusicLockingException, MusicServiceException, MusicQueryException;
+
+
+ //Methods added for orm
+
+
+ public ResultType createTable(JsonTable jsonTableObject, String consistencyInfo) throws MusicServiceException,MusicQueryException;
+
+ public ResultType dropTable(JsonTable jsonTableObject, String consistencyInfo)
+ throws MusicServiceException,MusicQueryException;
+
+ public ResultType createKeyspace(JsonKeySpace jsonKeySpaceObject,String consistencyInfo) throws MusicServiceException,MusicQueryException;
+
+ public ResultType dropKeyspace(JsonKeySpace jsonKeySpaceObject, String consistencyInfo)
+ throws MusicServiceException,MusicQueryException;
+
+ public ResultType createIndex(JsonIndex jsonIndexObject, String consistencyInfo) throws MusicServiceException,MusicQueryException;
+
+ public ResultSet select(JsonSelect jsonSelect, MultivaluedMap<String, String> rowParams) throws MusicServiceException, MusicQueryException;
+
+ public ResultSet selectCritical(JsonInsert jsonInsertObj, MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException;
+
+ public ReturnType insertIntoTable(JsonInsert jsonInsert) throws MusicLockingException, MusicQueryException, MusicServiceException;
+
+ public ReturnType updateTable(JsonUpdate jsonUpdateObj,MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException;
+
+ public ReturnType deleteFromTable(JsonDelete jsonDeleteObj,MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException;
+
+
+}
diff --git a/music-core/src/main/java/org/onap/music/service/impl/MusicCassaCore.java b/music-core/src/main/java/org/onap/music/service/impl/MusicCassaCore.java
new file mode 100644
index 00000000..8055a48d
--- /dev/null
+++ b/music-core/src/main/java/org/onap/music/service/impl/MusicCassaCore.java
@@ -0,0 +1,1236 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.service.impl;
+
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.onap.music.datastore.Condition;
+import org.onap.music.datastore.MusicDataStore;
+import org.onap.music.datastore.MusicDataStoreHandle;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonDelete;
+import org.onap.music.datastore.jsonobjects.JsonIndex;
+import org.onap.music.datastore.jsonobjects.JsonInsert;
+import org.onap.music.datastore.jsonobjects.JsonKeySpace;
+import org.onap.music.datastore.jsonobjects.JsonSelect;
+import org.onap.music.datastore.jsonobjects.JsonTable;
+import org.onap.music.datastore.jsonobjects.JsonUpdate;
+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.MusicDeadlockException;
+import org.onap.music.exceptions.MusicLockingException;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.lockingservice.cassandra.CassaLockStore;
+import org.onap.music.lockingservice.cassandra.CassaLockStore.LockObject;
+import org.onap.music.lockingservice.cassandra.LockType;
+import org.onap.music.lockingservice.cassandra.MusicLockState;
+import org.onap.music.lockingservice.cassandra.MusicLockState.LockStatus;
+import org.onap.music.main.MusicUtil;
+import org.onap.music.main.ResultType;
+import org.onap.music.main.ReturnType;
+import org.onap.music.service.MusicCoreService;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.TableMetadata;
+
+public class MusicCassaCore implements MusicCoreService {
+
+ private static CassaLockStore mLockHandle = null;
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCassaCore.class);
+ private static MusicCassaCore musicCassaCoreInstance = null;
+ private static Set<String> set = Collections.synchronizedSet(new HashSet<String>());
+ HashMap<String, Integer> map = new HashMap<>();
+ AtomicInteger wait = new AtomicInteger(0);
+
+ private MusicCassaCore() {
+ // not going to happen
+ }
+
+ public static CassaLockStore getmLockHandle() {
+ return mLockHandle;
+ }
+
+ //for unit testing purposes
+ static void setmLockHandle(CassaLockStore mLockHandle) {
+ MusicCassaCore.mLockHandle = mLockHandle;
+ }
+
+ 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();
+
+ if (mLockHandle == null) {
+ try {
+ mLockHandle = new CassaLockStore(MusicDataStoreHandle.getDSHandle());
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKHANDLE,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ throw new MusicLockingException("Failed to aquire Locl store handle " + e);
+ }
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms");
+ return mLockHandle;
+ }
+
+ public String createLockReferenceAtomic(String fullyQualifiedKey) throws MusicLockingException {
+ return createLockReferenceAtomic(fullyQualifiedKey, LockType.WRITE);
+ }
+ public String createLockReference(String fullyQualifiedKey, String owner) throws MusicLockingException {
+ return createLockReference(fullyQualifiedKey, LockType.WRITE, owner);
+ }
+
+
+ /**
+ * This will be called for Atomic calls
+ * it ensures that only one thread tries to create a lock on each key at a time
+ */
+ public String createLockReferenceAtomic(String fullyQualifiedKey, LockType locktype) throws MusicLockingException {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ if (splitString.length < 3) {
+ throw new MusicLockingException("Missing or incorrect lock details. Check table or key name.");
+ }
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String lockName = splitString[2];
+
+ logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
+ long start = 0L;
+ long end = 0L;
+ String lockReference = null;
+ LockObject peek = null;
+
+ /** Lets check for an existing lock.
+ * This will allow us to limit the amount of requests going forward.
+ */
+ start = System.currentTimeMillis();
+ try {
+ peek = getLockingServiceHandle().peekLockQueue(keyspace, table, lockName);
+ } catch (MusicServiceException | MusicQueryException e) {
+ //logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(),e);
+ throw new MusicLockingException("Error getting lockholder info for key [" + lockName +"]:" + e.getMessage());
+ }
+
+ if(peek!=null && (peek.getLocktype()!=null && peek.getLocktype().equals(LockType.WRITE)) && peek.getAcquireTime()!=null && peek.getLockRef()!=null) {
+ long currentTime = System.currentTimeMillis();
+ if((currentTime-Long.parseLong(peek.getAcquireTime()))<MusicUtil.getDefaultLockLeasePeriod()){
+ //logger.info(EELFLoggerDelegate.applicationLogger,"Lock holder exists and lease not expired. Please try again for key="+lockName);
+ throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. Please try again.");
+ }
+ }
+ end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to check for lock reference for key [" + lockName + "]:" + (end - start) + " ms");
+
+ start = System.currentTimeMillis();
+ /* We are Creating a Thread safe set and adding the key to the set.
+ * if a key exists then it wil be passed over and not go to the lock creation.
+ * If a key doesn't exist then it will set the value in the set and continue to create a lock.
+ *
+ * This will ensure that no 2 threads using the same key will be able to try to create a lock
+ * This wil in turn squash the amout of LWT Chatter in Cassandra an reduce the amount of
+ * WriteTimeoutExceptions being experiences on single keys.
+ */
+ if ( set.add(fullyQualifiedKey)) {
+ try {
+ lockReference = "" + getLockingServiceHandle().genLockRefandEnQueue(keyspace, table, lockName, locktype,null);
+ set.remove(fullyQualifiedKey);
+ } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
+ set.remove(fullyQualifiedKey);
+ throw new MusicLockingException(e.getMessage());
+ } catch (Exception e) {
+ set.remove(fullyQualifiedKey);
+ e.printStackTrace();
+ logger.error(EELFLoggerDelegate.applicationLogger,"Exception in creatLockEnforced:"+ e.getMessage(),e);
+ throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. " + e.getMessage());
+ }
+ } else {
+ throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. Please try again.");
+ }
+ end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.debugLogger,"### Set = " + set);
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference for key [" + lockName + "]:" + (end - start) + " ms");
+ return lockReference;
+
+ //return createLockReference(fullyQualifiedKey, locktype, null);
+ }
+
+ public String createLockReference(String fullyQualifiedKey, LockType locktype, String owner) throws MusicLockingException {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ if (splitString.length < 3) {
+ throw new MusicLockingException("Missing or incorrect lock details. Check table or key name.");
+ }
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String lockName = splitString[2];
+
+ logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
+ long start = 0L;
+ long end = 0L;
+ String lockReference = null;
+
+ /* Check for a Deadlock */
+ try {
+ boolean deadlock = getLockingServiceHandle().checkForDeadlock(keyspace, table, lockName, locktype, owner, false);
+ if (deadlock) {
+ MusicDeadlockException e = new MusicDeadlockException("Deadlock detected when " + owner + " tried to create lock on " + keyspace + "." + table + "." + lockName);
+ e.setValues(owner, keyspace, table, lockName);
+ throw e;
+ }
+ } catch (MusicDeadlockException e) {
+ //just threw this, no need to wrap it
+ throw e;
+ } catch (MusicServiceException | MusicQueryException e) {
+ logger.error(EELFLoggerDelegate.applicationLogger, e);
+ throw new MusicLockingException("Unable to check for deadlock. " + e.getMessage(), e);
+ }
+ end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to check for deadlock for key [" + lockName + "]:" + (end - start) + " ms");
+
+ start = System.currentTimeMillis();
+ try {
+ lockReference = "" + getLockingServiceHandle().genLockRefandEnQueue(keyspace, table, lockName, locktype, owner);
+ } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
+ logger.info(EELFLoggerDelegate.applicationLogger,e.getMessage(),e);
+ throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. Please try again: " + e.getMessage());
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.applicationLogger,e.getMessage(),e);
+ throw new MusicLockingException("Unable to create lock reference. " + e.getMessage(), e);
+ }
+ end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference for key [" + lockName + "]:" + (end - start) + " ms");
+ return lockReference;
+ }
+
+ public ReturnType promoteLock(String lockId) throws MusicLockingException {
+ String[] splitString = lockId.split("\\.");
+ String keyspace = splitString[0].substring(1);//remove '$'
+ String table = splitString[1];
+ String primaryKeyValue = splitString[2].substring(0, splitString[2].lastIndexOf("$"));
+ String lockRef = lockId.substring(lockId.lastIndexOf("$")+1); //lockRef is "$" to end
+
+ logger.info(EELFLoggerDelegate.applicationLogger,"Attempting to promote lock " + lockId);
+
+ try {
+ return getLockingServiceHandle().promoteLock(keyspace, table, primaryKeyValue, lockRef);
+ } catch (MusicServiceException e) {
+ throw new MusicLockingException("Unable to promote lock. ", e);
+ } catch (MusicQueryException e) {
+ throw new MusicLockingException("Unable to promote lock. ", e);
+ }
+
+ }
+
+
+ public ReturnType acquireLockWithLease(String fullyQualifiedKey, String lockReference, long leasePeriod)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+ evictExpiredLockHolder(fullyQualifiedKey,leasePeriod);
+ return acquireLock(fullyQualifiedKey, lockReference);
+ }
+
+ private void evictExpiredLockHolder(String fullyQualifiedKey, long leasePeriod)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String primaryKeyValue = splitString[2];
+
+ LockObject currentLockHolderObject = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue);
+
+ if (!currentLockHolderObject.getIsLockOwner()) { // 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.getAcquireTime()),
+ Long.parseLong(currentLockHolderObject.getCreateTime()));
+ if ((System.currentTimeMillis() - referenceTime) > leasePeriod) {
+ forciblyReleaseLock(fullyQualifiedKey, currentLockHolderObject.getLockRef() + "");
+ logger.info(EELFLoggerDelegate.applicationLogger, currentLockHolderObject.getLockRef() + " forcibly released");
+ }
+ }
+
+ 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("$"));
+ String localFullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$"));
+ String lockRef = lockId.substring(lockId.lastIndexOf("$")+1); //lockRef is "$" to end
+
+ LockObject lockInfo = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue, lockRef);
+
+ if (!lockInfo.getIsLockOwner()) {
+ return new ReturnType(ResultType.FAILURE, lockId + " is not a lock holder");//not top of the lock store q
+ }
+
+ if (getLockingServiceHandle().checkForDeadlock(keyspace, table, primaryKeyValue, lockInfo.getLocktype(), lockInfo.getOwner(), true)) {
+ MusicDeadlockException e = new MusicDeadlockException("Deadlock detected when " + lockInfo.getOwner() + " tried to create lock on " + keyspace + "." + table + "." + primaryKeyValue);
+ e.setValues(lockInfo.getOwner(), keyspace, table, primaryKeyValue);
+ throw e;
+ }
+
+ //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='"+localFullyQualifiedKey+"';";
+ PreparedQueryObject readQueryObject = new PreparedQueryObject();
+ readQueryObject.appendQueryString(query);
+ ResultSet results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(readQueryObject);
+ if (!results.all().isEmpty()) {
+ logger.info("In acquire lock: Since there was a forcible release, need to sync quorum!");
+ try {
+ 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);
+ String exceptionAsString = sw.toString();
+ return new ReturnType(ResultType.FAILURE, "Exception thrown while syncing key:\n" + exceptionAsString);
+ }
+ String cleanQuery = "delete from " + syncTable + " 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
+ *
+ */
+ public ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject,
+ String consistency) throws MusicServiceException {
+ boolean result = false;
+
+ try {
+ // create shadow locking table
+ result = getLockingServiceHandle().createLockQueue(keyspace, table);
+ if (result == false) {
+ return ResultType.FAILURE;
+ }
+ result = false;
+
+ // create table to track unsynced_keys
+ table = "unsyncedKeys_" + table;
+
+ String tabQuery =
+ "CREATE TABLE IF NOT EXISTS " + keyspace + "." + table + " ( key text,PRIMARY KEY (key) );";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ queryObject.appendQueryString(tabQuery);
+ result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, "eventual");
+ if (result == false) {
+ return ResultType.FAILURE;
+ }
+ result = false;
+
+ // create actual table
+ result = MusicDataStoreHandle.getDSHandle().executePut(tableQueryObject, consistency);
+ } catch (MusicQueryException | MusicServiceException | MusicLockingException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(), AppMessages.UNKNOWNERROR, ErrorSeverity.WARN,
+ ErrorTypes.MUSICSERVICEERROR);
+ throw new MusicServiceException(ex.getMessage());
+ }
+ return result ? ResultType.SUCCESS : ResultType.FAILURE;
+ }
+
+ private static void syncQuorum(String keyspace, String table, String primaryKeyValue) throws Exception {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---");
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ PreparedQueryObject updateQuery = new PreparedQueryObject();
+
+ // get the primary key d
+ TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, table);
+ 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);
+
+ // get the row of data from a quorum
+ selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + table + " WHERE "
+ + primaryKeyName + "= ?" + ";");
+ selectQuery.addValue(cqlFormattedPrimaryKeyValue);
+ MusicUtil.writeBackToQuorum(selectQuery, primaryKeyName, updateQuery, keyspace, table,
+ cqlFormattedPrimaryKeyValue);
+ }
+
+ /**
+ *
+ * @param query
+ * @return ResultSet
+ */
+ public ResultSet quorumGet(PreparedQueryObject query) {
+ ResultSet results = null;
+ try {
+ results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(query);
+ } catch (MusicServiceException | MusicQueryException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,
+ ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR, e);
+
+ }
+ return results;
+ }
+
+ public String whoseTurnIsIt(String fullyQualifiedKey) {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String primaryKeyValue = splitString[2];
+ try {
+ LockObject lockOwner = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue);
+ if (!lockOwner.getIsLockOwner()) {
+ return null;
+ }
+ return "$" + fullyQualifiedKey + "$" + lockOwner.getLockRef();
+ } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.LOCKINGERROR + fullyQualifiedKey,
+ ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ return null;
+ }
+
+ public List<String> getCurrentLockHolders(String fullyQualifiedKey) {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String primaryKeyValue = splitString[2];
+ try {
+ return getLockingServiceHandle().getCurrentLockHolders(keyspace, table, primaryKeyValue);
+ } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+fullyQualifiedKey ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param lockReference
+ * @return
+ */
+ public static String getLockNameFromId(String lockReference) {
+ StringTokenizer st = new StringTokenizer(lockReference);
+ return st.nextToken("$");
+ }
+
+ @Override
+ 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);
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String primaryKeyValue = splitString[2];
+ try {
+ getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockRef,MusicUtil.getRetryCount());
+ } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
+ 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) 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,MusicUtil.getRetryCount());
+ } catch (MusicLockingException | MusicServiceException | MusicQueryException 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");
+ return new MusicLockState(LockStatus.UNLOCKED, "");
+ }
+
+ @Override
+ 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) {
+ return voluntaryReleaseLock(fullyQualifiedKey, lockRef);
+ } else {
+ return forciblyReleaseLock(fullyQualifiedKey, lockRef);
+ }
+ }
+
+ 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) throws MusicLockingException {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ String keyspace = splitString[0];
+ String table = splitString[1];
+
+ //leave a signal that this key could potentially be unsynchronized
+ String syncTable = keyspace+".unsyncedKeys_"+table;
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ String values = "(?)";
+ queryObject.addValue(fullyQualifiedKey);
+ String insQuery = "insert into "+syncTable+" (key) values "+values+";";
+ queryObject.appendQueryString(insQuery);
+ try {
+ MusicDataStoreHandle.getDSHandle().executePut(queryObject, "critical");
+ } catch (Exception e) {
+ logger.error("Cannot forcibly release lock: " + fullyQualifiedKey + " " + lockReference + ". "
+ + e.getMessage(), e);
+ }
+
+ //now release the lock
+ return destroyLockRef(fullyQualifiedKey, lockReference);
+ }
+
+ @Override
+ public List<String> releaseAllLocksForOwner(String ownerId, String keyspace, String table) throws MusicLockingException, MusicServiceException, MusicQueryException {
+// System.out.println("IN RELEASEALLLOCKSFOROWNER, ");
+
+ List<String> lockIds = getLockingServiceHandle().getAllLocksForOwner(ownerId, keyspace, table);
+ for (String lockId : lockIds) {
+// System.out.println(" LOCKID = " + lockId);
+ //return "$" + keyspace + "." + table + "." + lockName + "$" + String.valueOf(lockRef);
+ releaseLock("$" + keyspace + "." + table + "." + lockId, true);
+ }
+ return lockIds;
+ }
+
+ /**
+ *
+ * @param lockName
+ * @throws MusicLockingException
+ */
+ @Deprecated
+ public void deleteLock(String lockName) throws MusicLockingException {
+ throw new MusicLockingException("Depreciated Method Delete Lock");
+ }
+
+ // Prepared Query Additions.
+
+ /**
+ *
+ * @param queryObject
+ * @return ReturnType
+ * @throws MusicServiceException
+ */
+ public ReturnType eventualPut(PreparedQueryObject queryObject) {
+ boolean result = false;
+ try {
+ result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
+ } catch (MusicServiceException | MusicQueryException 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) {
+ return new ReturnType(ResultType.SUCCESS, "Eventual Operation Successfully performed");
+ } else {
+ return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform");
+ }
+ }
+
+ /**
+ *
+ * @param queryObject
+ * @return ReturnType
+ * @throws MusicServiceException
+ */
+ public ReturnType eventualPut_nb(PreparedQueryObject queryObject,String keyspace,String tablename,String primaryKey) {
+ boolean result = false;
+ long guard = 0;
+ PreparedQueryObject getGaurd = new PreparedQueryObject();
+ getGaurd.appendQueryString("SELECT guard FROM "+keyspace+".lockq_"+tablename+ " WHERE key = ? ;");
+ getGaurd.addValue(primaryKey);
+ try {
+ ResultSet getGaurdResult = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(getGaurd);
+ Row row = getGaurdResult.one();
+ if (row != null) {
+ guard = row.getLong("guard");
+ long timeOfWrite = System.currentTimeMillis();
+ long ts = MusicUtil.v2sTimeStampInMicroseconds(guard, timeOfWrite);
+ String query = queryObject.getQuery();
+ if (!queryObject.getQuery().contains("USING TIMESTAMP")) {
+ if (queryObject.getOperation().equalsIgnoreCase("delete"))
+ query = query.replaceFirst("WHERE", " USING TIMESTAMP " + ts + " WHERE ");
+ else
+ query = query.replaceFirst("SET", "USING TIMESTAMP " + ts + " SET");
+ }
+ queryObject.replaceQueryString(query);
+ }
+
+ } catch (MusicServiceException | MusicQueryException e) {
+ logger.error(EELFLoggerDelegate.applicationLogger,e.getMessage(), e);
+ }
+ try {
+ result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
+ } catch (MusicServiceException | MusicQueryException 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) {
+ return new ReturnType(ResultType.SUCCESS, "Eventual Operation Successfully performed");
+ } else {
+ return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform");
+ }
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param table
+ * @param primaryKeyValue
+ * @param queryObject
+ * @param lockId
+ * @return
+ */
+ public ReturnType criticalPut(String keyspace, String table, String primaryKeyValue,
+ PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
+ long start = System.currentTimeMillis();
+ try {
+ String keyLock = lockId.substring(lockId.lastIndexOf(".") + 1,lockId.lastIndexOf("$"));
+ if (lockId.contains(".") && !keyLock.equals(primaryKeyValue)) {
+ return new ReturnType(ResultType.FAILURE,"Lock value '" + keyLock + "' and key value '"
+ + primaryKeyValue + "' not match. Please check your values: "
+ + lockId + " .");
+ }
+ LockObject lockObject = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue,
+ lockId.substring(lockId.lastIndexOf("$") + 1));
+
+ if ( lockObject == null ) {
+ return new ReturnType(ResultType.FAILURE, lockId + " does not exist.");
+ } else if (!lockObject.getIsLockOwner()) {
+ return new ReturnType(ResultType.FAILURE, lockId + " is not the lock holder");
+ } else if (lockObject.getLocktype() != LockType.WRITE) {
+ return new ReturnType(ResultType.FAILURE,
+ "Attempting to do write operation, but " + lockId + " is a read lock");
+ }
+
+ if (conditionInfo != null) {
+ try {
+ 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());
+ }
+ }
+ 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 ");
+ else if (queryObject.getOperation().equalsIgnoreCase("insert"))
+ query = query.replaceFirst(";", " USING TIMESTAMP " + ts + " ; ");
+ 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");
+ } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), e);
+ return new ReturnType(ResultType.FAILURE,
+ "Exception thrown while doing the critical put: "
+ + e.getMessage());
+ }
+ return new ReturnType(ResultType.SUCCESS, "Update performed");
+ }
+
+
+ /**
+ *
+ * @param queryObject
+ * @param consistency
+ * @return Boolean Indicates success or failure
+ * @throws MusicServiceException
+ *
+ *
+ */
+ public ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException,MusicQueryException {
+ // this is mainly for some functions like keyspace creation etc which does not
+ // really need the bells and whistles of Music locking.
+ boolean result = false;
+// try {
+ result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, consistency);
+// } catch (MusicQueryException | MusicServiceException ex) {
+ // logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(), AppMessages.UNKNOWNERROR,
+ // ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR, ex);
+// throw new MusicServiceException(ex.getMessage(),ex);
+// }
+ return result ? ResultType.SUCCESS : ResultType.FAILURE;
+ }
+
+ /**
+ * This method performs DDL operation on cassandra.
+ *
+ * @param queryObject query object containing prepared query and values
+ * @return ResultSet
+ * @throws MusicServiceException
+ */
+ public ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
+ ResultSet results = null;
+ try {
+ results = MusicDataStoreHandle.getDSHandle().executeOneConsistencyGet(queryObject);
+ } catch (MusicQueryException | MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e);
+ throw new MusicServiceException(e.getMessage());
+ }
+ return results;
+ }
+
+ /**
+ * 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
+ * @param queryObject query object containing prepared query and values
+ * @param lockId lock ID to check if the resource is free to perform the operation.
+ * @return ResultSet
+ */
+ public ResultSet criticalGet(String keyspace, String table, String primaryKeyValue,
+ PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
+ ResultSet results = null;
+ String keyLock = lockId.substring(lockId.lastIndexOf(".") + 1,lockId.lastIndexOf("$"));
+ try {
+ if (lockId.contains(".") && !keyLock.equals(primaryKeyValue)) {
+ throw new MusicLockingException("Lock value '" + keyLock + "' and key value '"
+ + primaryKeyValue + "' do not match. Please check your values: "
+ + lockId + " .");
+ }
+ LockObject lockObject = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue,
+ lockId.substring(lockId.lastIndexOf("$") + 1));
+ if (null == lockObject) {
+ throw new MusicLockingException("No Lock Object. Please check if lock name or key is correct."
+ + lockId + " .");
+ }
+ if ( !lockObject.getIsLockOwner()) {
+ return null;// not top of the lock store q
+ }
+ results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(queryObject);
+ } catch ( MusicLockingException e ) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
+ .WARN, ErrorTypes.MUSICSERVICEERROR);
+ throw new MusicServiceException(
+ "Cannot perform critical get for key: " + primaryKeyValue + " : " + e.getMessage());
+ } catch (MusicQueryException | MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
+ .WARN, ErrorTypes.MUSICSERVICEERROR, e);
+ throw new MusicServiceException(
+ "Cannot perform critical get for key: " + primaryKeyValue + " : " + e.getMessage());
+ }
+ return results;
+ }
+
+ /**
+ * 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
+ */
+ public ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, Condition conditionInfo)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+ long start = System.currentTimeMillis();
+ String fullyQualifiedKey = keyspaceName + "." + tableName + "." + primaryKey;
+ String lockId = createLockReferenceAtomic(fullyQualifiedKey, LockType.WRITE);
+ long lockCreationTime = System.currentTimeMillis();
+ 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; }
+ */
+
+ logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
+ String lockRef = lockId.substring(lockId.lastIndexOf("$"));
+ 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);
+ } 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.
+ *
+ * @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
+ */
+ public ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException, MusicQueryException {
+ String fullyQualifiedKey = keyspaceName + "." + tableName + "." + primaryKey;
+ String lockId = createLockReferenceAtomic(fullyQualifiedKey, LockType.READ);
+ 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("$"));
+ result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockRef);
+ } else {
+ logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
+ }
+ 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;
+ }
+
+
+
+ /**
+ * @param lockName
+ * @return
+ */
+ public Map<String, Object> validateLock(String lockName) {
+ return MusicUtil.validateLock(lockName);
+ }
+
+ @Override
+ @Deprecated
+ public ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
+ return null;
+ }
+
+ @Override
+ public List<String> getLockQueue(String fullyQualifiedKey)
+ throws MusicServiceException, MusicQueryException, MusicLockingException {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String primaryKeyValue = splitString[2];
+
+ return getLockingServiceHandle().getLockQueue(keyspace, table, primaryKeyValue);
+ }
+ @Override
+ public long getLockQueueSize(String fullyQualifiedKey)
+ throws MusicServiceException, MusicQueryException, MusicLockingException {
+ String[] splitString = fullyQualifiedKey.split("\\.");
+ String keyspace = splitString[0];
+ String table = splitString[1];
+ String primaryKeyValue = splitString[2];
+
+ return getLockingServiceHandle().getLockQueueSize(keyspace, table, primaryKeyValue);
+ }
+
+ @Override
+ @Deprecated
+ public ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
+ //deprecated
+ return null;
+ }
+
+ //Methods added for ORM changes
+
+ public ResultType createKeyspace(JsonKeySpace jsonKeySpaceObject,String consistencyInfo)
+ throws MusicServiceException,MusicQueryException {
+ ResultType result = nonKeyRelatedPut(jsonKeySpaceObject.genCreateKeyspaceQuery(), consistencyInfo);
+ logger.info(EELFLoggerDelegate.applicationLogger, " Keyspace Creation Process completed successfully");
+
+ return result;
+ }
+
+ public ResultType dropKeyspace(JsonKeySpace jsonKeySpaceObject, String consistencyInfo)
+ throws MusicServiceException,MusicQueryException {
+ ResultType result = nonKeyRelatedPut(jsonKeySpaceObject.genDropKeyspaceQuery(),
+ consistencyInfo);
+ logger.info(EELFLoggerDelegate.applicationLogger, " Keyspace deletion Process completed successfully");
+ return result;
+ }
+
+ public ResultType createTable(JsonTable jsonTableObject, String consistencyInfo)
+ throws MusicServiceException, MusicQueryException {
+ ResultType result = null;
+ try {
+ result = createTable(jsonTableObject.getKeyspaceName(),
+ jsonTableObject.getTableName(), jsonTableObject.genCreateTableQuery(), consistencyInfo);
+
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(), AppMessages.UNKNOWNERROR, ErrorSeverity.WARN,
+ ErrorTypes.MUSICSERVICEERROR);
+ throw new MusicServiceException(ex.getMessage());
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger, " Table Creation Process completed successfully ");
+ return result;
+ }
+
+ public ResultType dropTable(JsonTable jsonTableObject,String consistencyInfo)
+ throws MusicServiceException,MusicQueryException {
+ ResultType result = nonKeyRelatedPut(jsonTableObject.genDropTableQuery(),
+ consistencyInfo);
+ logger.info(EELFLoggerDelegate.applicationLogger, " Table deletion Process completed successfully ");
+
+ return result;
+ }
+
+ @Override
+ public ResultType createIndex(JsonIndex jsonIndexObject, String consistencyInfo)
+ throws MusicServiceException, MusicQueryException{
+ ResultType result = nonKeyRelatedPut(jsonIndexObject.genCreateIndexQuery(),
+ consistencyInfo);
+
+ logger.info(EELFLoggerDelegate.applicationLogger, " Index creation Process completed successfully ");
+ return result;
+ }
+
+ /**
+ * This method performs DDL operation on cassandra.
+ *
+ * @param queryObject query object containing prepared query and values
+ * @return ResultSet
+ * @throws MusicServiceException
+ */
+ public ResultSet select(JsonSelect jsonSelect, MultivaluedMap<String, String> rowParams)
+ throws MusicServiceException, MusicQueryException {
+ ResultSet results = null;
+ try {
+ results = get(jsonSelect.genSelectQuery(rowParams));
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
+ throw new MusicServiceException(e.getMessage());
+ }
+ return results;
+ }
+
+ /**
+ * Select Critical
+ */
+ public ResultSet selectCritical(JsonInsert jsonInsertObj, MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+
+ ResultSet results = null;
+ String consistency = "";
+ if(null != jsonInsertObj && null != jsonInsertObj.getConsistencyInfo()) {
+ consistency = jsonInsertObj.getConsistencyInfo().get("type");
+ }
+
+ String lockId = jsonInsertObj.getConsistencyInfo().get("lockId");
+
+ PreparedQueryObject queryObject = jsonInsertObj.genSelectCriticalPreparedQueryObj(rowParams);
+
+ if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ results = criticalGet(jsonInsertObj.getKeyspaceName(), jsonInsertObj.getTableName(),
+ jsonInsertObj.getPrimaryKeyVal(), queryObject,lockId);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ results = atomicGet(jsonInsertObj.getKeyspaceName(), jsonInsertObj.getTableName(),
+ jsonInsertObj.getPrimaryKeyVal(), queryObject);
+ }
+
+ return results;
+ }
+
+ /**
+ * this is insert row into Table
+ */
+ public ReturnType insertIntoTable(JsonInsert jsonInsertObj)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+
+ String consistency = "";
+ if(null != jsonInsertObj && null != jsonInsertObj.getConsistencyInfo()) {
+ consistency = jsonInsertObj.getConsistencyInfo().get("type");
+ }
+
+ ReturnType result = null;
+
+ try {
+
+ PreparedQueryObject queryObj = null;
+ queryObj = jsonInsertObj.genInsertPreparedQueryObj();
+
+ if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
+ result = eventualPut(jsonInsertObj.genInsertPreparedQueryObj());
+ } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ String lockId = jsonInsertObj.getConsistencyInfo().get("lockId");
+ if(lockId == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
+ + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
+ return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
+ + "and acquire lock or use ATOMIC instead of CRITICAL");
+ }
+ result = criticalPut(jsonInsertObj.getKeyspaceName(),
+ jsonInsertObj.getTableName(), jsonInsertObj.getPrimaryKeyVal(), jsonInsertObj.genInsertPreparedQueryObj(), lockId,null);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ result = atomicPut(jsonInsertObj.getKeyspaceName(), jsonInsertObj.getTableName(),
+ jsonInsertObj.getPrimaryKeyVal(), jsonInsertObj.genInsertPreparedQueryObj(), null);
+ }
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
+ .WARN, ErrorTypes.MUSICSERVICEERROR, ex);
+ return new ReturnType(ResultType.FAILURE, ex.getMessage());
+ }
+
+ return result;
+ }
+
+ /**
+ * This is insert row into Table
+ */
+ public ReturnType updateTable(JsonUpdate jsonUpdateObj, MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+
+ ReturnType result = null;
+ String consistency = "";
+ if(null != jsonUpdateObj && null != jsonUpdateObj.getConsistencyInfo()) {
+ consistency = jsonUpdateObj.getConsistencyInfo().get("type");
+ }
+ PreparedQueryObject queryObject = jsonUpdateObj.genUpdatePreparedQueryObj(rowParams);
+
+ Condition conditionInfo;
+ if (jsonUpdateObj.getConditions() == null) {
+ conditionInfo = null;
+ } else {
+ // to avoid parsing repeatedly, just send the select query to obtain row
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ selectQuery.appendQueryString("SELECT * FROM " + jsonUpdateObj.getKeyspaceName() + "." + jsonUpdateObj.getTableName() + " WHERE "
+ + jsonUpdateObj.getRowIdString() + ";");
+ selectQuery.addValue(jsonUpdateObj.getPrimarKeyValue());
+ conditionInfo = new Condition(jsonUpdateObj.getConditions(), selectQuery);
+ }
+
+
+ if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
+ result = eventualPut(queryObject);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ String lockId = jsonUpdateObj.getConsistencyInfo().get("lockId");
+ if(lockId == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
+ + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
+
+ return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
+ + "and acquire lock or use ATOMIC instead of CRITICAL");
+ }
+ result = criticalPut(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue(),
+ queryObject, lockId, conditionInfo);
+ } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
+ // this function is mainly for the benchmarks
+ try {
+ result = atomicPutWithDeleteLock(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(),
+ jsonUpdateObj.getPrimarKeyValue(), queryObject, conditionInfo);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
+ ErrorTypes.GENERALSERVICEERROR, e);
+ throw new MusicLockingException(AppMessages.UNKNOWNERROR.toString());
+
+ }
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ try {
+ result = atomicPut(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue(),
+ queryObject, conditionInfo);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e);
+ throw new MusicLockingException(AppMessages.UNKNOWNERROR.toString());
+ }
+ } else if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
+ try {
+ result = eventualPut_nb(queryObject, jsonUpdateObj.getKeyspaceName(),
+ jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue());
+ }catch (Exception e) {
+ return new ReturnType(ResultType.FAILURE, e.getMessage());
+ }
+
+ }
+
+ return result;
+ }
+
+ /**
+ * This method is for Delete From Table
+ */
+ public ReturnType deleteFromTable(JsonDelete jsonDeleteObj, MultivaluedMap<String, String> rowParams)
+ throws MusicLockingException, MusicQueryException, MusicServiceException {
+
+ ReturnType result = null;
+ String consistency = "";
+ if(null != jsonDeleteObj && null != jsonDeleteObj.getConsistencyInfo()) {
+ consistency = jsonDeleteObj.getConsistencyInfo().get("type");
+ }
+ PreparedQueryObject queryObject = jsonDeleteObj.genDeletePreparedQueryObj(rowParams);
+
+ // get the conditional, if any
+ Condition conditionInfo;
+ if (jsonDeleteObj.getConditions() == null) {
+ conditionInfo = null;
+ } else {
+ // to avoid parsing repeatedly, just send the select query to obtain row
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ selectQuery.appendQueryString("SELECT * FROM " + jsonDeleteObj.getKeyspaceName() + "." + jsonDeleteObj.getTableName() + " WHERE "
+ + jsonDeleteObj.getRowIdString() + ";");
+ selectQuery.addValue(jsonDeleteObj.getPrimarKeyValue());
+ conditionInfo = new Condition(jsonDeleteObj.getConditions(), selectQuery);
+ }
+
+ if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
+ result = eventualPut(queryObject);
+ else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ String lockId = jsonDeleteObj.getConsistencyInfo().get("lockId");
+ if(lockId == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
+ + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
+
+ return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
+ + "and acquire lock or use ATOMIC instead of CRITICAL");
+ }
+ result = criticalPut(jsonDeleteObj.getKeyspaceName(),
+ jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue(),
+ queryObject, lockId, conditionInfo);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ result = atomicPut(jsonDeleteObj.getKeyspaceName(),
+ jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue(),
+ queryObject, conditionInfo);
+ } else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
+ result = eventualPut_nb(queryObject, jsonDeleteObj.getKeyspaceName(),
+ jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue());
+ }
+
+ return result;
+ }
+
+
+}
diff --git a/music-core/src/main/resources/LICENSE.txt b/music-core/src/main/resources/LICENSE.txt
new file mode 100644
index 00000000..cc6cdea5
--- /dev/null
+++ b/music-core/src/main/resources/LICENSE.txt
@@ -0,0 +1,24 @@
+
+The following license applies to all files in this and sub-directories. Licenses
+are included in individual source files where appropriate, and if it differs
+from this text, it supersedes this. Any file that does not have license text
+defaults to being covered by this text; not all files support the addition of
+licenses.
+#
+# -------------------------------------------------------------------------
+# 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.
+#
+# -------------------------------------------------------------------------
+# \ No newline at end of file
diff --git a/music-core/src/main/resources/Resources.properties b/music-core/src/main/resources/Resources.properties
new file mode 100644
index 00000000..72269cb8
--- /dev/null
+++ b/music-core/src/main/resources/Resources.properties
@@ -0,0 +1,50 @@
+#============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=============================================
+#====================================================================
+#Resource key=Error Code|Message text|Resolution text |Description text
+LOADING_DEFAULT_LOG_CONFIGURATION=\
+ EELF0001I|\
+ Loading default logging configuration from system resource file "{0}"|\
+ No external logging configurations were defined or found, So verify the default logging configuration from system resource file (../logback.xml). |\
+ Loading default logging configuration from system resource file
+LOADING_LOG_CONFIGURATION=EELF0002I|\
+ Loading logging configuration from file "{0}"|\
+ Verify the correct logging configuration file is loaded. |\
+ Loading logging configuration for specific file
+LOGGING_ALREADY_INITIALIZED=\
+ EELF0003W|\
+ Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.|\
+ Verify the container logging definitions to ensure they represent your desired logging configuration. |\
+ Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.
+NO_LOG_CONFIGURATION=\
+ EELF0004E|\
+ No log configuration could be found or defaulted!|\
+ No external and default logging configuration file. |\
+ No log configuration could be found or defaulted!
+SEARCHING_LOG_CONFIGURATION=\
+ EELF0005I|\
+ Searching path "{0}" for log configuration file "{1}"|\
+ Verify the correct Path({user.home};etc;../etc) and filename (eelf.logging.file).|\
+ Searching path for specific log configuration file.
+UNSUPPORTED_LOGGING_FRAMEWORK=\
+ EELF0006E|\
+ An unsupported logging framework is bound to SLF4J. |\
+ Verify your logging frameworks.|\
+ An unsupported logging framework is bound to SLF4J.
+
diff --git a/music-core/src/main/resources/logback.xml b/music-core/src/main/resources/logback.xml
new file mode 100644
index 00000000..69d59ca3
--- /dev/null
+++ b/music-core/src/main/resources/logback.xml
@@ -0,0 +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=============================================
+ ====================================================================
+-->
+<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} [transactionId:%X{transactionId}] - %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>
+ </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">
+ <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">
+ <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">
+ <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
+ 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
+ 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>
+
+
+ <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">
+ <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"/>
+
+</configuration>
diff --git a/music-core/src/main/resources/project.properties b/music-core/src/main/resources/project.properties
new file mode 100644
index 00000000..69b99adc
--- /dev/null
+++ b/music-core/src/main/resources/project.properties
@@ -0,0 +1,5 @@
+version=${project.version}
+artifactId=${project.artifactId}
+build=${project.version}-${timestamp}
+music.properties=/opt/app/music/etc/music.properties
+
diff --git a/music-core/src/main/webapp/WEB-INF/.gitignore b/music-core/src/main/webapp/WEB-INF/.gitignore
new file mode 100644
index 00000000..840e7d31
--- /dev/null
+++ b/music-core/src/main/webapp/WEB-INF/.gitignore
@@ -0,0 +1 @@
+/classes/
diff --git a/music-core/src/test/java/LICENSE.txt b/music-core/src/test/java/LICENSE.txt
new file mode 100644
index 00000000..cc6cdea5
--- /dev/null
+++ b/music-core/src/test/java/LICENSE.txt
@@ -0,0 +1,24 @@
+
+The following license applies to all files in this and sub-directories. Licenses
+are included in individual source files where appropriate, and if it differs
+from this text, it supersedes this. Any file that does not have license text
+defaults to being covered by this text; not all files support the addition of
+licenses.
+#
+# -------------------------------------------------------------------------
+# 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.
+#
+# -------------------------------------------------------------------------
+# \ No newline at end of file
diff --git a/music-core/src/test/java/org/onap/music/cassandra/MusicUtilTest.java b/music-core/src/test/java/org/onap/music/cassandra/MusicUtilTest.java
new file mode 100644
index 00000000..b7245d78
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/cassandra/MusicUtilTest.java
@@ -0,0 +1,345 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.cassandra;
+
+import static org.junit.Assert.*;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.junit.Test;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.main.MusicUtil;
+//import org.onap.music.main.CorePropertiesLoader;
+import org.onap.music.service.MusicCoreService;
+
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.DataType;
+
+public class MusicUtilTest {
+
+ private static final String XLATESTVERSION = "X-latestVersion";
+ private static final String XMINORVERSION = "X-minorVersion";
+ private static final String XPATCHVERSION = "X-patchVersion";
+
+ @Test
+ public void testGetCassName() {
+ MusicUtil.setCassName("Cassandra");
+ assertTrue(MusicUtil.getCassName().equals("Cassandra"));
+ }
+
+ @Test
+ public void testGetCassPwd() {
+ MusicUtil.setCassPwd("Cassandra");
+ assertTrue(MusicUtil.getCassPwd().equals("Cassandra"));
+ }
+
+ @Test
+ public void testMusicAafNs() {
+ MusicUtil.setMusicAafNs("ns");
+ assertTrue("ns".equals(MusicUtil.getMusicAafNs()));
+ }
+
+ @Test
+ public void testMusicCoreService() {
+ MusicUtil.setLockUsing(MusicUtil.CASSANDRA);
+ MusicCoreService mc = null;
+ mc = MusicUtil.getMusicCoreService();
+ assertTrue(mc != null);
+ MusicUtil.setLockUsing("nothing");
+ mc = null;
+ mc = MusicUtil.getMusicCoreService();
+ assertTrue(mc != null);
+
+ }
+
+ @Test
+ public void testCipherEncKey() {
+ MusicUtil.setCipherEncKey("cipherEncKey");
+ assertTrue("cipherEncKey".equals(MusicUtil.getCipherEncKey()));
+ }
+
+ @Test
+ public void testGetMusicPropertiesFilePath() {
+ MusicUtil.setMusicPropertiesFilePath("filepath");
+ assertEquals(MusicUtil.getMusicPropertiesFilePath(),"filepath");
+ }
+
+ @Test
+ public void testGetDefaultLockLeasePeriod() {
+ MusicUtil.setDefaultLockLeasePeriod(5000);
+ assertEquals(MusicUtil.getDefaultLockLeasePeriod(),5000);
+ }
+
+ @Test
+ public void testIsDebug() {
+ MusicUtil.setDebug(true);
+ assertTrue(MusicUtil.isDebug());
+ }
+
+ @Test
+ public void testGetVersion() {
+ MusicUtil.setVersion("1.0.0");
+ assertEquals(MusicUtil.getVersion(),"1.0.0");
+ }
+
+ @Test
+ public void testBuildVersionA() {
+ assertEquals(MusicUtil.buildVersion("1","2","3"),"1.2.3");
+ }
+
+ @Test
+ public void testBuildVersionB() {
+ assertEquals(MusicUtil.buildVersion("1",null,"3"),"1");
+ }
+
+ @Test
+ public void testBuildVersionC() {
+ assertEquals(MusicUtil.buildVersion("1","2",null),"1.2");
+ }
+
+ /*
+ @Test
+ public void testBuileVersionResponse() {
+ assertTrue(MusicUtil.buildVersionResponse("1","2","3").getClass().getSimpleName().equals("Builder"));
+ assertTrue(MusicUtil.buildVersionResponse("1",null,"3").getClass().getSimpleName().equals("Builder"));
+ assertTrue(MusicUtil.buildVersionResponse("1","2",null).getClass().getSimpleName().equals("Builder"));
+ assertTrue(MusicUtil.buildVersionResponse(null,null,null).getClass().getSimpleName().equals("Builder"));
+ }
+ */
+ @Test
+ public void testGetConsistency() {
+ assertTrue(ConsistencyLevel.ONE.equals(MusicUtil.getConsistencyLevel("one")));
+ }
+
+ @Test
+ public void testRetryCount() {
+ MusicUtil.setRetryCount(1);
+ assertEquals(MusicUtil.getRetryCount(),1);
+ }
+
+ @Test
+ public void testIsCadi() {
+ MusicUtil.setIsCadi(true);
+ assertEquals(MusicUtil.getIsCadi(),true);
+ }
+
+
+ @Test
+ public void testGetMyCassaHost() {
+ MusicUtil.setMyCassaHost("10.0.0.2");
+ assertEquals(MusicUtil.getMyCassaHost(),"10.0.0.2");
+ }
+
+ @Test
+ public void testIsValidQueryObject() {
+ PreparedQueryObject myQueryObject = new PreparedQueryObject();
+ myQueryObject.appendQueryString("select * from apple where type = ?");
+ myQueryObject.addValue("macintosh");
+ assertTrue(MusicUtil.isValidQueryObject(true,myQueryObject));
+
+ myQueryObject.appendQueryString("select * from apple");
+ assertTrue(MusicUtil.isValidQueryObject(false,myQueryObject));
+
+ myQueryObject.appendQueryString("select * from apple where type = ?");
+ assertFalse(MusicUtil.isValidQueryObject(true,myQueryObject));
+
+ myQueryObject = new PreparedQueryObject();
+ myQueryObject.appendQueryString("");
+ System.out.println("#######" + myQueryObject.getQuery().isEmpty());
+ assertFalse(MusicUtil.isValidQueryObject(false,myQueryObject));
+
+
+ }
+
+
+
+
+ @Test(expected = IllegalStateException.class)
+ public void testMusicUtil() {
+ System.out.println("MusicUtil Constructor Test");
+ MusicUtil mu = new MusicUtil();
+ System.out.println(mu.toString());
+ }
+
+ @Test
+ public void testConvertToCQLDataType() throws Exception {
+ Map<String,Object> myMap = new HashMap<String,Object>();
+ myMap.put("name","tom");
+ assertEquals(MusicUtil.convertToCQLDataType(DataType.varchar(),"Happy People"),"'Happy People'");
+ assertEquals(MusicUtil.convertToCQLDataType(DataType.uuid(),UUID.fromString("29dc2afa-c2c0-47ae-afae-e72a645308ab")),"29dc2afa-c2c0-47ae-afae-e72a645308ab");
+ assertEquals(MusicUtil.convertToCQLDataType(DataType.blob(),"Hi"),"Hi");
+ assertEquals(MusicUtil.convertToCQLDataType(DataType.map(DataType.varchar(),DataType.varchar()),myMap),"{'name':'tom'}");
+ }
+
+ @Test
+ public void testConvertToActualDataType() throws Exception {
+ assertEquals(MusicUtil.convertToActualDataType(DataType.varchar(),"Happy People"),"Happy People");
+ assertEquals(MusicUtil.convertToActualDataType(DataType.uuid(),"29dc2afa-c2c0-47ae-afae-e72a645308ab"),UUID.fromString("29dc2afa-c2c0-47ae-afae-e72a645308ab"));
+ assertEquals(MusicUtil.convertToActualDataType(DataType.varint(),"1234"),BigInteger.valueOf(Long.parseLong("1234")));
+ assertEquals(MusicUtil.convertToActualDataType(DataType.bigint(),"123"),Long.parseLong("123"));
+ assertEquals(MusicUtil.convertToActualDataType(DataType.cint(),"123"),Integer.parseInt("123"));
+ assertEquals(MusicUtil.convertToActualDataType(DataType.cfloat(),"123.01"),Float.parseFloat("123.01"));
+ assertEquals(MusicUtil.convertToActualDataType(DataType.cdouble(),"123.02"),Double.parseDouble("123.02"));
+ assertEquals(MusicUtil.convertToActualDataType(DataType.cboolean(),"true"),Boolean.parseBoolean("true"));
+ List<String> myList = new ArrayList<String>();
+ List<String> newList = myList;
+ myList.add("TOM");
+ assertEquals(MusicUtil.convertToActualDataType(DataType.list(DataType.varchar()),myList),newList);
+ Map<String,Object> myMap = new HashMap<String,Object>();
+ myMap.put("name","tom");
+ Map<String,Object> newMap = myMap;
+ assertEquals(MusicUtil.convertToActualDataType(DataType.map(DataType.varchar(),DataType.varchar()),myMap),newMap);
+ }
+
+ @Test
+ public void testConvertToActualDataTypeByte() throws Exception {
+ byte[] testByte = "TOM".getBytes();
+ assertEquals(MusicUtil.convertToActualDataType(DataType.blob(),testByte),ByteBuffer.wrap(testByte));
+
+ }
+
+ @Test
+ public void testJsonMaptoSqlString() throws Exception {
+ Map<String,Object> myMap = new HashMap<>();
+ myMap.put("name","tom");
+ myMap.put("value",5);
+ String result = MusicUtil.jsonMaptoSqlString(myMap,",");
+ assertTrue(result.contains("name"));
+ assertTrue(result.contains("value"));
+ }
+
+ @Test
+ public void test_generateUUID() {
+ //this function shouldn't be in cachingUtil
+ System.out.println("Testing getUUID");
+ String uuid1 = MusicUtil.generateUUID();
+ String uuid2 = MusicUtil.generateUUID();
+ assertFalse(uuid1==uuid2);
+ }
+
+
+ @Test
+ public void testIsValidConsistency(){
+ assertTrue(MusicUtil.isValidConsistency("ALL"));
+ assertFalse(MusicUtil.isValidConsistency("TEST"));
+ }
+
+ @Test
+ public void testLockUsing() {
+ MusicUtil.setLockUsing("testlock");
+ assertEquals("testlock", MusicUtil.getLockUsing());
+ }
+
+ @Test
+ public void testCassaPort() {
+ MusicUtil.setCassandraPort(1234);
+ assertEquals(1234, MusicUtil.getCassandraPort());
+ }
+
+ @Test
+ public void testBuild() {
+ MusicUtil.setBuild("testbuild");
+ assertEquals("testbuild", MusicUtil.getBuild());
+ }
+
+ @Test
+ public void testTransId() {
+ MusicUtil.setTransIdPrefix("prefix");
+ assertEquals("prefix-", MusicUtil.getTransIdPrefix());
+ }
+
+
+ @Test
+ public void testConversationIdPrefix() {
+ MusicUtil.setConversationIdPrefix("prefix-");
+ assertEquals("prefix-", MusicUtil.getConversationIdPrefix());
+ }
+
+ @Test
+ public void testClientIdPrefix() {
+ MusicUtil.setClientIdPrefix("clientIdPrefix");
+ assertEquals("clientIdPrefix-", MusicUtil.getClientIdPrefix());
+ }
+
+ @Test
+ public void testMessageIdPrefix() {
+ MusicUtil.setMessageIdPrefix("clientIdPrefix");
+ assertEquals("clientIdPrefix-", MusicUtil.getMessageIdPrefix());
+ }
+
+ @Test
+ public void testTransIdPrefix() {
+ MusicUtil.setTransIdPrefix("transIdPrefix");
+ assertEquals("transIdPrefix-", MusicUtil.getTransIdPrefix());
+ }
+
+ @Test
+ public void testConvIdReq() {
+ MusicUtil.setConversationIdRequired(true);
+ assertEquals(true, MusicUtil.getConversationIdRequired());
+ }
+
+ @Test
+ public void testClientIdRequired() {
+ MusicUtil.setClientIdRequired(true);
+ assertEquals(true, MusicUtil.getClientIdRequired());
+ }
+
+ @Test
+ public void testMessageIdRequired() {
+ MusicUtil.setMessageIdRequired(true);
+ assertEquals(true, MusicUtil.getMessageIdRequired());
+ }
+
+ @Test
+ public void testTransIdRequired() {
+ MusicUtil.setTransIdRequired(true);
+ assertEquals(true,MusicUtil.getTransIdRequired());
+ }
+
+ @Test
+ public void testGetCassandraConnectTimeOutMS() {
+ MusicUtil.setCassandraConnectTimeOutMS(2000);
+ assertEquals(2000,MusicUtil.getCassandraConnectTimeOutMS());
+ }
+
+ @Test
+ public void testGetCassandraReadTimeOutMS() {
+ MusicUtil.setCassandraReadTimeOutMS(2000);
+ assertEquals(2000,MusicUtil.getCassandraReadTimeOutMS());
+ }
+
+ /*
+ @Test
+ public void testLoadProperties() {
+ PropertiesLoader pl = new PropertiesLoader();
+ pl.loadProperties();
+ }
+ */
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/ConditionTest.java b/music-core/src/test/java/org/onap/music/datastore/ConditionTest.java
new file mode 100644
index 00000000..2aac62af
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/ConditionTest.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * ============LICENSE_START========================================== org.onap.music
+ * =================================================================== Copyright (c) 2019 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;
+
+import org.onap.music.datastore.Condition;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.exceptions.MusicServiceException;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.spy;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+
+public class ConditionTest {
+
+ @Spy
+ private Condition condition;
+ private Map<String, Object> conditions;
+ private PreparedQueryObject selectQueryForTheRow;
+
+ @Before
+ public void setup() {
+ conditions = Mockito.mock(Map.class);
+ selectQueryForTheRow = Mockito.mock(PreparedQueryObject.class);
+ condition = spy(new Condition(conditions, selectQueryForTheRow));
+ }
+
+ @Test
+ public void testCondition() throws Exception {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Row row = Mockito.mock(Row.class);
+ MusicDataStore dsHandle = Mockito.mock(MusicDataStore.class);
+ Mockito.when(rs.one()).thenReturn(row);
+ Mockito.doReturn(rs).when(condition).quorumGet(Mockito.any());
+ boolean result = false;
+ Mockito.when(dsHandle.doesRowSatisfyCondition(Mockito.any(), Mockito.any())).thenReturn(true);
+ Mockito.doReturn(dsHandle).when(condition).getDSHandle();
+ result = condition.testCondition();
+ assertEquals(true, result);
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/MusicDataStoreTest.java b/music-core/src/test/java/org/onap/music/datastore/MusicDataStoreTest.java
new file mode 100644
index 00000000..9260cd92
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/MusicDataStoreTest.java
@@ -0,0 +1,436 @@
+/*******************************************************************************
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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;
+
+import static org.junit.Assert.*;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.Consumer;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.main.MusicUtil;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.CodecRegistry;
+import com.datastax.driver.core.ColumnDefinitions;
+import com.datastax.driver.core.ColumnDefinitions.Definition;
+import com.datastax.driver.core.exceptions.WriteTimeoutException;
+import com.datastax.driver.core.ColumnMetadata;
+import com.datastax.driver.core.Configuration;
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.Metadata;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+import com.datastax.driver.core.TableMetadata;
+import com.datastax.driver.core.WriteType;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MusicDataStoreTest {
+
+ MusicDataStore dataStore;
+
+ @Mock
+ Session session;
+
+ @Mock
+ Cluster cluster;
+
+ @Before
+ public void before() {
+ CodecRegistry cr = Mockito.mock(CodecRegistry.class);
+ Configuration config = Mockito.mock(Configuration.class);
+ Mockito.when(cluster.getConfiguration()).thenReturn(config);
+ Mockito.when(config.getCodecRegistry()).thenReturn(cr);
+ dataStore = new MusicDataStore(cluster, session);
+ }
+
+
+ @Test
+ public void testMusicDataStoreClusterSession() {
+ Session session = Mockito.mock(Session.class);
+ Cluster cluster = Mockito.mock(Cluster.class);
+
+ CodecRegistry cr = Mockito.mock(CodecRegistry.class);
+ Configuration config = Mockito.mock(Configuration.class);
+ Mockito.when(cluster.getConfiguration()).thenReturn(config);
+ Mockito.when(config.getCodecRegistry()).thenReturn(cr);
+
+
+ MusicDataStore mds = new MusicDataStore(cluster, session);
+ assertEquals(session, mds.getSession());
+ assertEquals(cluster, mds.getCluster());
+ }
+
+ @Test
+ public void testSession() {
+ Session session = Mockito.mock(Session.class);
+ dataStore.setSession(session);
+ assertEquals(session, dataStore.getSession());
+ }
+
+ @Test
+ public void testCluster() {
+ Cluster cluster = Mockito.mock(Cluster.class);
+ CodecRegistry cr = Mockito.mock(CodecRegistry.class);
+ Configuration config = Mockito.mock(Configuration.class);
+ Mockito.when(cluster.getConfiguration()).thenReturn(config);
+ Mockito.when(config.getCodecRegistry()).thenReturn(cr);
+
+ dataStore.setCluster(cluster);
+ assertEquals(cluster, dataStore.getCluster());
+ }
+
+ @Test
+ public void testClose() {
+ dataStore.close();
+ Mockito.verify(session).close();
+ }
+
+ @Test
+ public void testReturnColumnDataType() {
+ Metadata meta = Mockito.mock(Metadata.class);
+ Mockito.when(cluster.getMetadata()).thenReturn(meta);
+ KeyspaceMetadata ksmd = Mockito.mock(KeyspaceMetadata.class);
+ Mockito.when(meta.getKeyspace("keyspace")).thenReturn(ksmd);
+ TableMetadata tmd = Mockito.mock(TableMetadata.class);
+ Mockito.when(ksmd.getTable("table")).thenReturn(tmd);
+ ColumnMetadata cmd = Mockito.mock(ColumnMetadata.class);
+ Mockito.when(tmd.getColumn("columnName")).thenReturn(cmd);
+ Mockito.when(cmd.getType()).thenReturn(com.datastax.driver.core.DataType.text());
+
+ com.datastax.driver.core.DataType dt = dataStore.returnColumnDataType("keyspace", "table", "columnName");
+ assertEquals(com.datastax.driver.core.DataType.text(), dt);
+ }
+
+ @Test
+ public void testReturnColumnMetadata() {
+ Metadata meta = Mockito.mock(Metadata.class);
+ Mockito.when(cluster.getMetadata()).thenReturn(meta);
+ KeyspaceMetadata ksmd = Mockito.mock(KeyspaceMetadata.class);
+ Mockito.when(meta.getKeyspace("keyspace")).thenReturn(ksmd);
+ TableMetadata tmd = Mockito.mock(TableMetadata.class);
+ Mockito.when(ksmd.getTable("tableName")).thenReturn(tmd);
+
+ dataStore.returnColumnMetadata("keyspace", "tableName");
+ assertEquals(tmd, dataStore.returnColumnMetadata("keyspace", "tableName"));
+ }
+
+ @Test
+ public void testReturnKeyspaceMetadata() {
+ Metadata meta = Mockito.mock(Metadata.class);
+ Mockito.when(cluster.getMetadata()).thenReturn(meta);
+ KeyspaceMetadata ksmd = Mockito.mock(KeyspaceMetadata.class);
+ Mockito.when(meta.getKeyspace("keyspace")).thenReturn(ksmd);
+
+ assertEquals(ksmd, dataStore.returnKeyspaceMetadata("keyspace"));
+ }
+
+ @Test
+ public void testGetColValue() {
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.getString("columnName")).thenReturn("value");
+ UUID uuid = UUID.randomUUID();
+ Mockito.when(row.getUUID("columnName")).thenReturn(uuid);
+ Mockito.when(row.getVarint("columnName")).thenReturn(BigInteger.ONE);
+ Mockito.when(row.getLong("columnName")).thenReturn((long) 117);
+ Mockito.when(row.getInt("columnName")).thenReturn(5);
+ Mockito.when(row.getFloat("columnName")).thenReturn(Float.MAX_VALUE);
+ Mockito.when(row.getDouble("columnName")).thenReturn(Double.valueOf("2.5"));
+ Mockito.when(row.getBool("columnName")).thenReturn(true);
+ Mockito.when(row.getMap("columnName", String.class, String.class)).thenReturn(new HashMap<String, String>());
+ Mockito.when(row.getList("columnName", String.class)).thenReturn(new ArrayList<String>());
+
+
+ assertEquals("value", dataStore.getColValue(row, "columnName", DataType.varchar()));
+ assertEquals(uuid, dataStore.getColValue(row, "columnName", DataType.uuid()));
+ assertEquals(BigInteger.ONE, dataStore.getColValue(row, "columnName", DataType.varint()));
+ assertEquals((long) 117, dataStore.getColValue(row, "columnName", DataType.bigint()));
+ assertEquals(5, dataStore.getColValue(row, "columnName", DataType.cint()));
+ assertEquals(Float.MAX_VALUE, dataStore.getColValue(row, "columnName", DataType.cfloat()));
+ assertEquals(2.5, dataStore.getColValue(row, "columnName", DataType.cdouble()));
+ assertEquals(true, dataStore.getColValue(row, "columnName", DataType.cboolean()));
+ assertEquals(0, ((Map<String, String>) dataStore.getColValue(row, "columnName",
+ DataType.map(DataType.varchar(), DataType.varchar()))).size());
+ assertEquals(0,
+ ((List<String>) dataStore.getColValue(row, "columnName", DataType.list(DataType.varchar()))).size());
+ }
+
+ @Test
+ public void testGetBlobValue() {
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.getBytes("col")).thenReturn(ByteBuffer.allocate(16));
+
+ byte[] byteArray = dataStore.getBlobValue(row, "col", DataType.blob());
+ assertEquals(16, byteArray.length);
+ }
+
+ @Test
+ public void testDoesRowSatisfyCondition() throws Exception {
+ Row row = Mockito.mock(Row.class);
+ ColumnDefinitions cd = Mockito.mock(ColumnDefinitions.class);
+ Mockito.when(row.getColumnDefinitions()).thenReturn(cd);
+ Mockito.when(cd.getType("col1")).thenReturn(DataType.varchar());
+
+ Map<String, Object> condition = new HashMap<>();
+ condition.put("col1", "val1");
+
+ Mockito.when(row.getString("col1")).thenReturn("val1");
+
+ assertTrue(dataStore.doesRowSatisfyCondition(row, condition));
+
+ condition.put("col1", "val2");
+ assertFalse(dataStore.doesRowSatisfyCondition(row, condition));
+ }
+
+ @Test
+ public void testMarshalData() {
+ ResultSet results = Mockito.mock(ResultSet.class);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.getString("colName")).thenReturn("rowValue");
+ //mock for (Row row: results)
+ Iterator mockIterator = Mockito.mock(Iterator.class);
+ //Mockito.doCallRealMethod().when(results).forEach(Mockito.any(Consumer.class));
+ Mockito.when(results.iterator()).thenReturn(mockIterator);
+ Mockito.when(mockIterator.hasNext()).thenReturn(true, false);
+ Mockito.when(mockIterator.next()).thenReturn(row);
+
+ ColumnDefinitions cd = Mockito.mock(ColumnDefinitions.class);
+ Mockito.when(row.getColumnDefinitions()).thenReturn(cd);
+ //for (Definition: colDefinitions)
+ Iterator mockIterator2 = Mockito.mock(Iterator.class);
+ //Mockito.doCallRealMethod().when(cd).forEach(Mockito.any(Consumer.class));
+ Mockito.when(cd.iterator()).thenReturn(mockIterator2);
+ Mockito.when(mockIterator2.hasNext()).thenReturn(true, false);
+ Definition def = Mockito.mock(Definition.class);
+ Mockito.when(mockIterator2.next()).thenReturn(def);
+ Mockito.when(def.getType()).thenReturn(DataType.varchar());
+ Mockito.when(def.getName()).thenReturn("colName");
+
+ Map<String, HashMap<String, Object>> data = dataStore.marshalData(results);
+ System.out.println("Marshalled data: " + data);
+
+ assertTrue(data.containsKey("row 0"));
+ assertEquals("rowValue", data.get("row 0").get("colName"));
+ }
+
+ private ArgumentCaptor<SimpleStatement> sessionExecuteResponse() {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Mockito.when(session.execute(Mockito.any(Statement.class))).thenReturn(rs);
+
+ ArgumentCaptor<SimpleStatement> argument = ArgumentCaptor.forClass(SimpleStatement.class);
+ return argument;
+ }
+
+ @Test
+ public void testExecutePutPreparedQueryObjectString() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ String queryString = "INSERT INTO cycling.cyclist_name (lastname, firstname) VALUES (?,?);";
+ String lastName = "KRUIKSWIJK";
+ String firstName = "Steven";
+
+ PreparedQueryObject query = new PreparedQueryObject(queryString, lastName, firstName);
+ dataStore.executePut(query, MusicUtil.CRITICAL);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.QUORUM, argument.getValue().getConsistencyLevel());
+ assertEquals(queryString, argument.getValue().getQueryString());
+ assertEquals(2, argument.getValue().valuesCount());
+ }
+
+ @Test
+ public void testExecutePut_ONE() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ String queryString = "INSERT INTO cycling.cyclist_name (lastname, firstname) VALUES (?,?);";
+ String lastName = "KRUIKSWIJK";
+ String firstName = "Steven";
+
+ PreparedQueryObject query = new PreparedQueryObject(queryString, lastName, firstName);
+ dataStore.executePut(query, MusicUtil.ONE);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.ONE, argument.getValue().getConsistencyLevel());
+ assertEquals(queryString, argument.getValue().getQueryString());
+ assertEquals(2, argument.getValue().valuesCount());
+ }
+
+ @Test
+ public void testExecutePut_quorum() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ String queryString = "INSERT INTO cycling.cyclist_name (lastname, firstname) VALUES (?,?);";
+ String lastName = "KRUIKSWIJK";
+ String firstName = "Steven";
+
+ PreparedQueryObject query = new PreparedQueryObject(queryString, lastName, firstName);
+ dataStore.executePut(query, MusicUtil.QUORUM);
+
+ Mockito.verify(session).execute(argument.capture());
+ //should be quorum!
+ assertEquals(ConsistencyLevel.LOCAL_QUORUM, argument.getValue().getConsistencyLevel());
+ assertEquals(queryString, argument.getValue().getQueryString());
+ assertEquals(2, argument.getValue().valuesCount());
+ }
+
+ @Test
+ public void testExecutePut_ALL() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ String queryString = "INSERT INTO cycling.cyclist_name (lastname, firstname) VALUES (?,?);";
+ String lastName = "KRUIKSWIJK";
+ String firstName = "Steven";
+
+ PreparedQueryObject query = new PreparedQueryObject(queryString, lastName, firstName);
+ dataStore.executePut(query, MusicUtil.ALL);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.ALL, argument.getValue().getConsistencyLevel());
+ assertEquals(queryString, argument.getValue().getQueryString());
+ assertEquals(2, argument.getValue().valuesCount());
+ }
+
+ @Test(expected = MusicQueryException.class)
+ public void testExecutePut_BadQueryObj() throws Exception {
+ String queryString = "INSERT INTO cycling.cyclist_name (lastname, firstname) VALUES (?,?);";
+ String lastName = "KRUIKSWIJK";
+ String firstName = "Steven";
+
+ //Provide extra value here, middle initial
+ PreparedQueryObject query = new PreparedQueryObject(queryString, lastName, firstName, "P");
+ try {
+ dataStore.executePut(query, MusicUtil.CRITICAL);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ throw e;
+ }
+
+ fail("Should have throw error");
+ }
+
+ @Test
+ public void testExecutePutPreparedQueryObjectStringLong() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ String queryString = "INSERT INTO cycling.cyclist_name (lastname, firstname) VALUES ('KRUIKSWIJK','Steven');";
+
+
+ PreparedQueryObject query = new PreparedQueryObject(queryString);
+ dataStore.executePut(query, MusicUtil.EVENTUAL, 10);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.ONE, argument.getValue().getConsistencyLevel());
+ assertEquals(queryString, argument.getValue().getQueryString());
+ }
+
+ @Test
+ public void testExecuteGet() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM KEYSPACE.TABLE");
+
+ dataStore.executeGet(query, MusicUtil.ONE);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.ONE, argument.getValue().getConsistencyLevel());
+ assertEquals("SELECT * FROM KEYSPACE.TABLE", argument.getValue().getQueryString());
+ }
+
+ @Test (expected = MusicQueryException.class)
+ public void testExecuteGet_badQuery() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM KEYSPACE.TABLE", "broken");
+
+ dataStore.executeGet(query, MusicUtil.ONE);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.ONE, argument.getValue().getConsistencyLevel());
+ assertEquals("SELECT * FROM KEYSPACE.TABLE", argument.getValue().getQueryString());
+ }
+
+ @Test
+ public void testExecuteOneConsistencyGet() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM KEYSPACE.TABLE");
+
+ dataStore.executeOneConsistencyGet(query);
+
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.ONE, argument.getValue().getConsistencyLevel());
+ assertEquals("SELECT * FROM KEYSPACE.TABLE", argument.getValue().getQueryString());
+ }
+
+ @Test
+ public void testExecuteLocalQuorumConsistencyGet() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM KEYSPACE.TABLE");
+
+ dataStore.executeLocalQuorumConsistencyGet(query);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.LOCAL_QUORUM, argument.getValue().getConsistencyLevel());
+ assertEquals("SELECT * FROM KEYSPACE.TABLE", argument.getValue().getQueryString());
+ }
+
+ @Test
+ public void testExecuteQuorumConsistencyGet() throws Exception {
+ ArgumentCaptor<SimpleStatement> argument = sessionExecuteResponse();
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM KEYSPACE.TABLE");
+
+ dataStore.executeQuorumConsistencyGet(query);
+
+ Mockito.verify(session).execute(argument.capture());
+ assertEquals(ConsistencyLevel.QUORUM, argument.getValue().getConsistencyLevel());
+ assertEquals("SELECT * FROM KEYSPACE.TABLE", argument.getValue().getQueryString());
+ }
+
+
+ @Test
+ public void testExecutePut() {
+ Mockito.when(session.execute(Mockito.any(SimpleStatement.class)))
+ .thenThrow(new WriteTimeoutException(ConsistencyLevel.QUORUM, WriteType.CAS, 1, 3));
+
+ try {
+ dataStore.executePut(new PreparedQueryObject("Test query"), "critical");
+ } catch (MusicServiceException e) {
+ return;
+ } catch (MusicQueryException e) {
+ // should never reach here
+ fail();
+ }
+ fail();
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/PreparedQueryObjectTest.java b/music-core/src/test/java/org/onap/music/datastore/PreparedQueryObjectTest.java
new file mode 100644
index 00000000..7ab7d148
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/PreparedQueryObjectTest.java
@@ -0,0 +1,101 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * e
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class PreparedQueryObjectTest {
+
+ private PreparedQueryObject preparedQueryObject;
+
+ @Before
+ public void setUp()
+ {
+ preparedQueryObject = new PreparedQueryObject();
+ }
+
+ @Test
+ public void testKeyspaceName()
+ {
+ preparedQueryObject.setKeyspaceName("keyspaceName");
+ assertEquals("keyspaceName", preparedQueryObject.getKeyspaceName());
+ }
+
+ @Test
+ public void testConsistency()
+ {
+ preparedQueryObject.setConsistency("consistency");
+ assertEquals("consistency", preparedQueryObject.getConsistency());
+ }
+
+ @Test
+ public void testTableName()
+ {
+ preparedQueryObject.setTableName("tableName");
+ assertEquals("tableName", preparedQueryObject.getTableName());
+ }
+
+ @Test
+ public void testoperation()
+ {
+ preparedQueryObject.setOperation("operation");
+ assertEquals("operation", preparedQueryObject.getOperation());
+ }
+
+ @Test
+ public void testprimaryKeyValue()
+ {
+ preparedQueryObject.setPrimaryKeyValue("primaryKeyValue");
+ assertEquals("primaryKeyValue", preparedQueryObject.getPrimaryKeyValue());
+ }
+
+ @Test
+ public void testAddValue() {
+ preparedQueryObject.addValue("one");
+ assertEquals("one", preparedQueryObject.getValues().get(0));
+ }
+
+ @Test
+ public void testAddValues() {
+ preparedQueryObject.addValues("one", "two", "three");
+ assertEquals(3, preparedQueryObject.getValues().size());
+ assertEquals("two", preparedQueryObject.getValues().get(1));
+ }
+
+ @Test
+ public void testConstructorQuery() {
+ preparedQueryObject = new PreparedQueryObject("some query string");
+ assertEquals("some query string", preparedQueryObject.getQuery());
+ }
+
+ @Test
+ public void testConstructorQueryValues() {
+ preparedQueryObject = new PreparedQueryObject("another query string", "a", "b", "c");
+ assertEquals("another query string", preparedQueryObject.getQuery());
+ assertEquals(3, preparedQueryObject.getValues().size());
+ assertEquals("b", preparedQueryObject.getValues().get(1));
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JSONObjectTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JSONObjectTest.java
new file mode 100644
index 00000000..9fb549d2
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JSONObjectTest.java
@@ -0,0 +1,54 @@
+
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP MUSIC
+ * ===================================================================
+ * Copyright (C) 2020 IBM Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class JSONObjectTest {
+
+ @Test
+ public void testGetData(){
+ JSONObject js=new JSONObject();
+ js.setData("test");
+ assertEquals(js.getData(),"test");
+
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonDeleteTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonDeleteTest.java
new file mode 100644
index 00000000..5b9cef8b
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonDeleteTest.java
@@ -0,0 +1,113 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * 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
+ *
+ * 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 static org.junit.Assert.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+
+public class JsonDeleteTest {
+
+ JsonDelete jd = null;
+
+ @Before
+ public void init() {
+ jd = new JsonDelete();
+ }
+
+ @Test
+ public void testGetConditions() {
+ Map<String,Object> mapSo = new HashMap<>();
+ mapSo.put("key1","one");
+ mapSo.put("key2","two");
+ jd.setConditions(mapSo);
+ assertEquals("one",jd.getConditions().get("key1"));
+ }
+
+ @Test
+ public void testGetConsistencyInfo() {
+ Map<String,String> mapSs = new HashMap<>();
+ mapSs.put("key3","three");
+ mapSs.put("key4","four");
+ jd.setConsistencyInfo(mapSs);
+ assertEquals("three",jd.getConsistencyInfo().get("key3"));
+ }
+
+ @Test
+ public void testGetColumns() {
+ List<String> ary = new ArrayList<>();
+ ary.add("e1");
+ ary.add("e2");
+ ary.add("e3");
+ jd.setColumns(ary);
+ assertEquals("e1",jd.getColumns().get(0));
+ }
+
+ @Test
+ public void testGetTtl() {
+ jd.setTtl("2000");
+ assertEquals("2000",jd.getTtl());
+ }
+
+ @Test
+ public void testGetTimestamp() {
+ jd.setTimestamp("20:00");
+ assertEquals("20:00",jd.getTimestamp());
+
+ }
+
+ @Test
+ public void testGetKeyspaceName() {
+ jd.setKeyspaceName("keyspace");
+ assertEquals("keyspace",jd.getKeyspaceName());
+
+ }
+
+ @Test
+ public void testGetTableName() {
+ jd.setTableName("tablename");
+ assertEquals("tablename",jd.getTableName());
+
+ }
+
+ @Test
+ public void testGetPrimarKeyValue() {
+ jd.setPrimarKeyValue("primarykey");
+ assertEquals("primarykey",jd.getPrimarKeyValue());
+
+ }
+
+ @Test
+ public void testRowIdString() {
+ StringBuilder builder = new StringBuilder("testing");
+ jd.setRowIdString(builder);
+ assertEquals(jd.getRowIdString().toString(),builder.toString());
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonIndexTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonIndexTest.java
new file mode 100644
index 00000000..0d89a339
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonIndexTest.java
@@ -0,0 +1,74 @@
+/*
+ * ============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 static org.junit.Assert.*;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.music.datastore.PreparedQueryObject;
+
+public class JsonIndexTest {
+
+ JsonIndex ji = null;
+
+
+ @Before
+ public void init() {
+ ji = new JsonIndex(null, null, null, null);
+ }
+
+
+
+ @Test
+ public void testKeyspace() {
+ ji.setKeyspaceName("keyspaceName");
+ assertEquals("keyspaceName", ji.getKeyspaceName());
+ }
+
+ @Test
+ public void testIndexName() {
+ ji.setIndexName("indexName");
+ assertEquals("indexName", ji.getIndexName());
+ }
+
+ @Test
+ public void testFieldName() {
+ ji.setFieldName("field");
+ assertEquals("field", ji.getFieldName());
+ }
+
+ @Test
+ public void testTableName() {
+ ji.setTableName("table");
+ assertEquals("table", ji.getTableName());
+ }
+
+ @Test
+ public void testCreateIndexQuery() {
+ JsonIndex ji2 = new JsonIndex("index", "keyspace", "table", "field");
+ PreparedQueryObject query = ji2.genCreateIndexQuery();
+ assertEquals("Create index if not exists index on keyspace.table (field);", query.getQuery());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonInsertTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonInsertTest.java
new file mode 100644
index 00000000..ad71c9ea
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonInsertTest.java
@@ -0,0 +1,176 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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 static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.FieldSetter;
+import org.onap.music.datastore.MusicDataStore;
+import org.onap.music.datastore.MusicDataStoreHandle;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import com.datastax.driver.core.ColumnMetadata;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.Session;
+//import org.mockito.internal.util.reflection.Whitebox;
+import com.datastax.driver.core.TableMetadata;
+
+
+public class JsonInsertTest {
+
+ JsonInsert ji = new JsonInsert();
+
+ @Test
+ public void testGetKeyspaceName() {
+ ji.setKeyspaceName("keyspace");
+ assertEquals("keyspace",ji.getKeyspaceName());
+ }
+
+ @Test
+ public void testGetTableName() {
+ ji.setTableName("table");
+ assertEquals("table",ji.getTableName());
+ }
+
+ @Test
+ public void testGetConsistencyInfo() {
+ Map<String,String> cons = new HashMap<>();
+ cons.put("test","true");
+ ji.setConsistencyInfo(cons);
+ assertEquals("true",ji.getConsistencyInfo().get("test"));
+ }
+
+ @Test
+ public void testGetTtl() {
+ ji.setTtl("ttl");
+ assertEquals("ttl",ji.getTtl());
+ }
+
+ @Test
+ public void testGetTimestamp() {
+ ji.setTimestamp("10:30");
+ assertEquals("10:30",ji.getTimestamp());
+ }
+
+ @Test
+ public void testGetValues() {
+ Map<String,Object> cons = new HashMap<>();
+ cons.put("val1","one");
+ cons.put("val2","two");
+ ji.setValues(cons);
+ assertEquals("one",ji.getValues().get("val1"));
+ }
+
+ @Test
+ public void testGetRowSpecification() {
+ Map<String,Object> cons = new HashMap<>();
+ cons.put("val1","one");
+ cons.put("val2","two");
+ ji.setRowSpecification(cons);
+ assertEquals("two",ji.getRowSpecification().get("val2"));
+ }
+
+ @Test
+ public void testSerialize() {
+ Map<String,Object> cons = new HashMap<>();
+ cons.put("val1","one");
+ cons.put("val2","two");
+ ji.setTimestamp("10:30");
+ ji.setRowSpecification(cons);
+ byte[] test1 = ji.serialize();
+ byte[] ji1 = SerializationUtils.serialize(ji);
+ assertArrayEquals(ji1,test1);
+ }
+
+ @Test
+ public void testObjectMap()
+ {
+ Map<String, byte[]> map = new HashMap<>();
+ ji.setObjectMap(map);
+ assertEquals(map, ji.getObjectMap());
+ }
+
+ @Test
+ public void testPrimaryKey() {
+ ji.setPrimaryKeyVal("primKey");
+ assertEquals("primKey", ji.getPrimaryKeyVal());
+ }
+
+ @Test
+ public void testGenInsertPreparedQueryObj() throws Exception {
+ ji.setKeyspaceName("keyspace");
+ ji.setTableName("table");
+ ji.setPrimaryKeyVal("value");
+ Map<String,Object> rowSpec = new HashMap<>();
+ rowSpec.put("val1","one");
+ rowSpec.put("val2","two");
+ ji.setRowSpecification(rowSpec);
+ Map<String,Object> vals = new HashMap<>();
+ vals.put("val1","one");
+ vals.put("val2","two");
+ ji.setValues(vals);
+
+ Map<String,String> cons = new HashMap<>();
+ cons.put("type","quorum");
+ ji.setConsistencyInfo(cons);
+
+ MusicDataStore mds = Mockito.mock(MusicDataStore.class);
+ Session session = Mockito.mock(Session.class);
+ Mockito.when(mds.getSession()).thenReturn(session);
+ MusicDataStoreHandle mdsh = Mockito.mock(MusicDataStoreHandle.class);
+ FieldSetter.setField(mdsh, mdsh.getClass().getDeclaredField("mDstoreHandle"), mds);
+ TableMetadata tableMeta = Mockito.mock(TableMetadata.class);
+ Mockito.when(mds.returnColumnMetadata(Mockito.anyString(), Mockito.anyString()))
+ .thenReturn(tableMeta);
+
+ ColumnMetadata cmd = Mockito.mock(ColumnMetadata.class);
+ List<ColumnMetadata> listcmd = new ArrayList<>();
+ listcmd.add(cmd);
+ Mockito.when(tableMeta.getPrimaryKey()).thenReturn(listcmd);
+ Mockito.when(cmd.getName()).thenReturn("val1");
+ Mockito.when(tableMeta.getColumn("val1")).thenReturn(cmd);
+ Mockito.when(tableMeta.getColumn("val2")).thenReturn(cmd);
+ Mockito.when(cmd.getType()).thenReturn(DataType.text());
+
+ PreparedQueryObject query = ji.genInsertPreparedQueryObj();
+ System.out.println(query.getQuery());
+ System.out.println(query.getValues());
+
+
+ assertEquals("INSERT INTO keyspace.table (vector_ts,val2,val1) VALUES (?,?,?);", query.getQuery());
+ assertTrue(query.getValues().containsAll(vals.values()));
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonKeySpaceTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonKeySpaceTest.java
new file mode 100644
index 00000000..a3fa58e4
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonKeySpaceTest.java
@@ -0,0 +1,72 @@
+/*
+ * ============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 static org.junit.Assert.*;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+
+public class JsonKeySpaceTest {
+
+ JsonKeySpace jk = null;
+
+
+ @Before
+ public void init() {
+ jk = new JsonKeySpace();
+ }
+
+
+
+ @Test
+ public void testGetConsistencyInfo() {
+ Map<String, String> mapSs = new HashMap<>();
+ mapSs.put("k1", "one");
+ jk.setConsistencyInfo(mapSs);
+ assertEquals("one",jk.getConsistencyInfo().get("k1"));
+ }
+
+ @Test
+ public void testGetReplicationInfo() {
+ Map<String,Object> mapSo = new HashMap<>();
+ mapSo.put("k1", "one");
+ jk.setReplicationInfo(mapSo);
+ assertEquals("one",jk.getReplicationInfo().get("k1"));
+
+ }
+
+ @Test
+ public void testGetDurabilityOfWrites() {
+ jk.setDurabilityOfWrites("1");
+ assertEquals("1",jk.getDurabilityOfWrites());
+ }
+
+ @Test
+ public void testGetKeyspaceName() {
+ jk.setKeyspaceName("Keyspace");
+ assertEquals("Keyspace",jk.getKeyspaceName());
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonLockTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonLockTest.java
new file mode 100644
index 00000000..75db75e5
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonLockTest.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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 static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.music.lockingservice.cassandra.LockType;
+
+public class JsonLockTest {
+
+ JsonLock jsonLock;
+
+ @Before
+ public void setup() {
+ jsonLock = new JsonLock();
+ }
+
+ @Test
+ public void testSetLockType() {
+ jsonLock.setLockType(LockType.READ);
+ assertEquals(LockType.READ, jsonLock.getLocktype());
+
+ jsonLock.setLockType(LockType.WRITE);
+ assertEquals(LockType.WRITE, jsonLock.getLocktype());
+
+ jsonLock.setLockType(LockType.PROMOTING);
+ assertEquals(LockType.PROMOTING, jsonLock.getLocktype());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonSelectTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonSelectTest.java
new file mode 100644
index 00000000..baada1d5
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonSelectTest.java
@@ -0,0 +1,68 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modifications Copyright (c) 2018-2019 IBM
+ * ===================================================================
+ * 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 static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+public class JsonSelectTest {
+ JsonSelect js = new JsonSelect();
+
+ @Test
+ public void testGetConsistencyInfo() {
+ Map<String, String> mapSs = new HashMap<>();
+ mapSs.put("k1", "one");
+ js.setConsistencyInfo(mapSs);
+ assertEquals("one", js.getConsistencyInfo().get("k1"));
+ }
+
+ @Test
+ public void testSerialize() throws IOException {
+ Map<String, String> mapSs = new HashMap<>();
+ mapSs.put("Key", "Value");
+ js.setConsistencyInfo(mapSs);
+ js.serialize();
+ }
+
+ @Test
+ public void testGetKeyspaceName() {
+ js.setKeyspaceName("testkeyspace");
+ assertEquals("testkeyspace",js.getKeyspaceName());
+
+ }
+
+ @Test
+ public void testGetTableName() {
+ js.setTableName("testkeyspace");
+ assertEquals("testkeyspace",js.getTableName());
+
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonTableTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonTableTest.java
new file mode 100644
index 00000000..3ab32d40
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonTableTest.java
@@ -0,0 +1,153 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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 static org.junit.Assert.*;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.music.exceptions.MusicQueryException;
+
+public class JsonTableTest {
+
+ JsonTable jt = null;
+
+ @Before
+ public void init() {
+ jt = new JsonTable();
+ }
+
+ @Test
+ public void testGetConsistencyInfo() {
+ Map<String, String> mapSs = new HashMap<>();
+ mapSs.put("k1", "one");
+ jt.setConsistencyInfo(mapSs);
+ assertEquals("one",jt.getConsistencyInfo().get("k1"));
+ }
+
+ @Test
+ public void testGetProperties() {
+ Map<String, Object> properties = new HashMap<>();
+ properties.put("k1", "one");
+ jt.setProperties(properties);
+ assertEquals(properties.size(), jt.getProperties().size());
+ }
+
+ @Test
+ public void testGetFields() {
+ Map<String, String> fields = new HashMap<>();
+ fields.put("k1", "one");
+ jt.setFields(fields);
+ assertEquals("one",jt.getFields().get("k1"));
+ }
+
+ @Test
+ public void testGetKeyspaceName() {
+ String keyspace = "keyspace";
+ jt.setKeyspaceName(keyspace);
+ assertEquals(keyspace,jt.getKeyspaceName());
+ }
+
+ @Test
+ public void testGetTableName() {
+ String table = "table";
+ jt.setTableName(table);
+ assertEquals(table,jt.getTableName());
+ }
+
+ @Test
+ public void testGetClusteringOrder() {
+ String clusteringOrder = "clusteringOrder";
+ jt.setClusteringOrder(clusteringOrder);
+ assertEquals(clusteringOrder,jt.getClusteringOrder());
+ }
+
+ @Test
+ public void testGetClusterKey() {
+ String clusterKey = "clusterKey";
+ jt.setClusteringKey(clusterKey);
+ assertEquals(clusterKey, jt.getClusteringKey());
+ }
+
+ @Test
+ public void testGetPrimaryKey() {
+ String primaryKey = "primaryKey";
+ jt.setPrimaryKey(primaryKey);
+ assertEquals(primaryKey,jt.getPrimaryKey());
+ }
+
+ @Test
+ public void testFilteringKey() {
+ jt.setFilteringKey("FilteringKey");
+ assertEquals("FilteringKey",jt.getFilteringKey());
+ }
+
+ @Test
+ public void testPartitionKey() {
+ jt.setPartitionKey("ParitionKey");
+ assertEquals("ParitionKey",jt.getPartitionKey());
+ }
+
+ @Test
+ public void genCreateTableQuery() throws MusicQueryException {
+ JsonTable jt2 = new JsonTable();
+ jt2.setKeyspaceName("keyspace");
+ jt2.setTableName("table");
+ Map<String, String> fields = new HashMap<>();
+ fields.put("k1", "one");
+ jt2.setFields(fields);
+ jt2.setPrimaryKey("k1");
+ Map<String, String> mapSs = new HashMap<>();
+ mapSs.put("k1", "one");
+ jt2.setConsistencyInfo(mapSs);
+ String clusteringOrder = "clusteringOrder";
+ jt.setClusteringOrder(clusteringOrder);
+ String clusterKey = "clusterKey";
+ jt.setClusteringKey(clusterKey);
+
+ System.out.println(jt2.genCreateTableQuery().getQuery());
+ assertEquals("CREATE TABLE keyspace.table (vector_ts text,k1 one, PRIMARY KEY ( (k1) ));",
+ jt2.genCreateTableQuery().getQuery());
+ }
+
+ @Test
+ public void genDropTableQuery() throws MusicQueryException {
+ JsonTable jt2 = new JsonTable();
+ jt2.setKeyspaceName("keyspace");
+ jt2.setTableName("table");
+ Map<String, String> fields = new HashMap<>();
+ fields.put("k1", "one");
+ jt2.setFields(fields);
+ jt2.setPrimaryKey("k1");
+ Map<String, String> mapSs = new HashMap<>();
+ mapSs.put("k1", "one");
+ jt.setConsistencyInfo(mapSs);
+
+ System.out.println(jt2.genDropTableQuery().getQuery());
+ assertEquals("DROP TABLE keyspace.table;",
+ jt2.genDropTableQuery().getQuery());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonUpdateTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonUpdateTest.java
new file mode 100644
index 00000000..37c729f4
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/JsonUpdateTest.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2018 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.
+ * 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 static org.junit.Assert.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.MultivaluedMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.music.datastore.jsonobjects.JsonUpdate.RowIdentifier;
+import com.datastax.driver.core.ColumnMetadata;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.TableMetadata;
+
+public class JsonUpdateTest {
+
+ JsonUpdate ju = null;
+
+ @Before
+ public void init() {
+ ju = new JsonUpdate();
+ }
+
+
+ @Test
+ public void testGetConditions() {
+ Map<String,Object> mapSo = new HashMap<>();
+ mapSo.put("key1","one");
+ mapSo.put("key2","two");
+ ju.setConditions(mapSo);
+ assertEquals("one",ju.getConditions().get("key1"));
+ }
+
+ @Test
+ public void testGetRow_specification() {
+ Map<String,Object> mapSo = new HashMap<>();
+ mapSo.put("key1","one");
+ mapSo.put("key2","two");
+ ju.setRow_specification(mapSo);
+ assertEquals("one",ju.getRow_specification().get("key1"));
+ }
+
+ @Test
+ public void testGetKeyspaceName() {
+ String keyspace = "keyspace";
+ ju.setKeyspaceName(keyspace);
+ assertEquals(keyspace,ju.getKeyspaceName());
+ }
+
+ @Test
+ public void testGetTableName() {
+ String table = "table";
+ ju.setTableName(table);
+ assertEquals(table,ju.getTableName());
+ }
+
+ @Test
+ public void testGetConsistencyInfo() {
+ Map<String, String> mapSs = new HashMap<>();
+ mapSs.put("k1", "one");
+ ju.setConsistencyInfo(mapSs);
+ assertEquals("one",ju.getConsistencyInfo().get("k1"));
+ }
+
+ @Test
+ public void testGetTtl() {
+ ju.setTtl("2000");
+ assertEquals("2000",ju.getTtl());
+ }
+
+ @Test
+ public void testGetTimestamp() {
+ ju.setTimestamp("20:00");
+ assertEquals("20:00",ju.getTimestamp());
+
+ }
+
+ @Test
+ public void testGetValues() {
+ Map<String,Object> cons = new HashMap<>();
+ cons.put("val1","one");
+ cons.put("val2","two");
+ ju.setValues(cons);
+ assertEquals("one",ju.getValues().get("val1"));
+ }
+
+ @Test
+ public void testSerialize() {
+ assertTrue(ju.serialize() instanceof byte[]);
+ }
+
+ @Test
+ public void testRowIdString() {
+ ju.setRowIdString("testing");
+ assertEquals("testing", ju.getRowIdString());
+ }
+
+ @Test
+ public void testPrimaryKeyValue() {
+ ju.setPrimarKeyValue("primeKey");
+ assertEquals("primeKey", ju.getPrimarKeyValue());
+ }
+
+ @Test
+ public void testGenUpdatePreparedQueryObj() throws Exception {
+ JsonUpdate ju = Mockito.spy(JsonUpdate.class);
+ MultivaluedMap<String, String> rowParams = Mockito.mock(MultivaluedMap.class);
+
+ ju.setKeyspaceName("keyspace");
+ ju.setTableName("table");
+ ju.setPrimarKeyValue("primaryKeyValue");
+ Map<String, String> consistencyInfo = new HashMap<>();
+ consistencyInfo.put("type", "critical");
+ ju.setConsistencyInfo(consistencyInfo);
+ Map<String, Object> values = new HashMap<>();
+ values.put("col1", "val1");
+ ju.setValues(values);
+
+ TableMetadata tmd = Mockito.mock(TableMetadata.class);
+ Mockito.doReturn(tmd).when(ju).returnColumnMetadata(Mockito.anyString(), Mockito.anyString());
+ ColumnMetadata cmd = Mockito.mock(ColumnMetadata.class);
+ Mockito.when(tmd.getColumn("col1")).thenReturn(cmd);
+ List<ColumnMetadata> colList = new ArrayList<>();
+ colList.add(cmd);
+ Mockito.when(tmd.getPrimaryKey()).thenReturn(colList);
+ Mockito.when(cmd.getType()).thenReturn(DataType.varchar());
+
+ RowIdentifier rowId = Mockito.mock(RowIdentifier.class);
+ Mockito.doReturn(rowId).when(ju).getRowIdentifier(Mockito.anyString(), Mockito.anyString(), Mockito.any(),
+ Mockito.any());
+
+ Mockito.when(rowId.getRowIdString()).thenReturn("col1");
+ Mockito.when(rowId.getPrimaryKeyValue()).thenReturn("val1");
+
+
+ assertEquals("UPDATE keyspace.table SET vector_ts=?,col1= ? WHERE col1;",
+ ju.genUpdatePreparedQueryObj(rowParams).getQuery());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/datastore/jsonobjects/RowIdentifierTest.java b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/RowIdentifierTest.java
new file mode 100644
index 00000000..e29f0377
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/datastore/jsonobjects/RowIdentifierTest.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP MUSIC
+ * ===================================================================
+ * Copyright (C) 2020 IBM Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonUpdate;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class RowIdentifierTest {
+ String primarykey="primarykey";
+ String rowIdString="123";
+ PreparedQueryObject queryObject=new PreparedQueryObject("select * from employee");
+ JsonUpdate ju=new JsonUpdate();
+ JsonUpdate.RowIdentifier rowId= ju.new RowIdentifier(primarykey,rowIdString,queryObject);
+ @Test
+ public void testConstructor(){
+ rowId.setPrimaryKeyValue(primarykey);
+ rowId.setRowIdString(rowIdString);
+ assertEquals(rowId.getPrimaryKeyValue(),"primarykey");
+ assertEquals(rowId.getRowIdString(),"123");
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/eelf/logging/format/AppMessagesTest.java b/music-core/src/test/java/org/onap/music/eelf/logging/format/AppMessagesTest.java
new file mode 100644
index 00000000..cba9c7c2
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/eelf/logging/format/AppMessagesTest.java
@@ -0,0 +1,65 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.eelf.logging.format;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AppMessagesTest {
+
+ private AppMessages messages;
+
+ @Before
+ public void setUp() {
+ messages= AppMessages.ALREADYEXIST;
+ }
+
+ @Test
+ public void testDetails()
+ {
+ messages.setDetails("details");
+ assertEquals("details", messages.getDetails());
+ }
+
+ @Test
+ public void testResolution()
+ {
+ messages.setResolution("Resolution");
+ assertEquals("Resolution", messages.getResolution());
+ }
+
+ @Test
+ public void testErrorCode()
+ {
+ messages.setErrorCode("ErrorCode");
+ assertEquals("ErrorCode", messages.getErrorCode());
+ }
+
+ @Test
+ public void testErrorDescription()
+ {
+ messages.setErrorDescription("ErrorDescription");
+ assertEquals("ErrorDescription", messages.getErrorDescription());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorSeverityTest.java b/music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorSeverityTest.java
new file mode 100644
index 00000000..b2b0fafa
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorSeverityTest.java
@@ -0,0 +1,41 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.eelf.logging.format;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class ErrorSeverityTest {
+
+ @Test
+ public void TestErrorServerity()
+ {
+ assertEquals("INFO",ErrorSeverity.INFO.name());
+ assertEquals("WARN",ErrorSeverity.WARN.name());
+ assertEquals("ERROR",ErrorSeverity.ERROR.name());
+ assertEquals("FATAL",ErrorSeverity.FATAL.name());
+ assertEquals("CRITICAL",ErrorSeverity.CRITICAL.name());
+ assertEquals("MAJOR",ErrorSeverity.MAJOR.name());
+ assertEquals("MINOR",ErrorSeverity.MINOR.name());
+ assertEquals("NONE",ErrorSeverity.NONE.name());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorTypesTest.java b/music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorTypesTest.java
new file mode 100644
index 00000000..ff7b188b
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/eelf/logging/format/ErrorTypesTest.java
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START==========================================
+ * 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.
+ * 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.eelf.logging.format;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class ErrorTypesTest {
+
+ @Test
+ public void Test1()
+ {
+ assertEquals("CONNECTIONERROR",ErrorTypes.CONNECTIONERROR.name());
+ assertEquals("SESSIONEXPIRED",ErrorTypes.SESSIONEXPIRED.name());
+ assertEquals("AUTHENTICATIONERROR",ErrorTypes.AUTHENTICATIONERROR.name());
+ assertEquals("CACHEERROR",ErrorTypes.CACHEERROR.name());
+ assertEquals("SERVICEUNAVAILABLE",ErrorTypes.SERVICEUNAVAILABLE.name());
+ assertEquals("QUERYERROR",ErrorTypes.QUERYERROR.name());
+ assertEquals("DATAERROR",ErrorTypes.DATAERROR.name());
+ assertEquals("GENERALSERVICEERROR",ErrorTypes.GENERALSERVICEERROR.name());
+ assertEquals("MUSICSERVICEERROR",ErrorTypes.MUSICSERVICEERROR.name());
+ assertEquals("LOCKINGERROR",ErrorTypes.LOCKINGERROR.name());
+ assertEquals("UNKNOWN",ErrorTypes.UNKNOWN.name());
+
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/exceptions/MusicDeadlockExceptionTest.java b/music-core/src/test/java/org/onap/music/exceptions/MusicDeadlockExceptionTest.java
new file mode 100644
index 00000000..db0e10ea
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/exceptions/MusicDeadlockExceptionTest.java
@@ -0,0 +1,135 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.exceptions;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class MusicDeadlockExceptionTest {
+
+ private String owner = "tester";
+ private String keyspace = "testing";
+ private String table = "lockq";
+ private String key = "test";
+
+ @Test
+ public void TestException1() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicDeadlockException();
+ }
+ } catch (MusicDeadlockException mde) {
+ assertEquals("org.onap.music.exceptions.MusicDeadlockException", mde.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException6() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicDeadlockException("org.onap.music.exceptions.MusicDeadlockException");
+ }
+ } catch (MusicDeadlockException mde) {
+ assertEquals(mde.getMessage(),"org.onap.music.exceptions.MusicDeadlockException");
+ }
+
+ }
+
+ @Test
+ public void TestException2() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicDeadlockException("MusicDeadlockException Exception occured..");
+ }
+ } catch (MusicDeadlockException mde) {
+ assertEquals(mde.getMessage(), "MusicDeadlockException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException3() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicDeadlockException(new Throwable());
+ }
+ } catch (MusicDeadlockException mve) {
+ assertEquals("org.onap.music.exceptions.MusicDeadlockException", mve.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException4() {
+ String message = "Exception occured";
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicDeadlockException(message, new Throwable());
+ }
+ } catch (MusicDeadlockException mde) {
+ assertEquals("org.onap.music.exceptions.MusicDeadlockException", mde.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException5() {
+ String message = "Exception occured";
+ boolean enableSuppression = true;
+ boolean writableStackTrace = false;
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicDeadlockException(message, new Throwable(), enableSuppression,
+ writableStackTrace);
+ }
+ } catch (MusicDeadlockException mde) {
+ assertEquals("org.onap.music.exceptions.MusicDeadlockException", mde.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestSetValues()
+ {
+ MusicDeadlockException mde=new MusicDeadlockException();
+ mde.setValues(owner,keyspace,table,key);
+ assertEquals("tester",mde.getOwner());
+ assertEquals("testing",mde.getKeyspace());
+ assertEquals("lockq",mde.getTable());
+ assertEquals("test",mde.getKey());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/exceptions/MusicLockingExceptionTest.java b/music-core/src/test/java/org/onap/music/exceptions/MusicLockingExceptionTest.java
new file mode 100644
index 00000000..583a9fd4
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/exceptions/MusicLockingExceptionTest.java
@@ -0,0 +1,104 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.exceptions;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class MusicLockingExceptionTest {
+
+ @Test
+ public void TestException1() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicLockingException();
+ }
+ } catch (MusicLockingException mle) {
+ assertEquals("org.onap.music.exceptions.MusicLockingException", mle.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException2() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicLockingException("MusicLockingException Exception occured..");
+ }
+ } catch (MusicLockingException mle) {
+ assertEquals(mle.getMessage(), "MusicLockingException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException3() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicLockingException(new Throwable());
+ }
+ } catch (MusicLockingException mle) {
+ assertEquals("org.onap.music.exceptions.MusicLockingException", mle.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException4() {
+ String message = "Exception occured";
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicLockingException(message, new Throwable());
+ }
+ } catch (MusicLockingException mle) {
+ assertEquals("org.onap.music.exceptions.MusicLockingException", mle.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException5() {
+ String message = "Exception occured";
+ boolean enableSuppression = true;
+ boolean writableStackTrace = false;
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicLockingException(message, new Throwable(), enableSuppression, writableStackTrace);
+ }
+ } catch (MusicLockingException mle) {
+ assertEquals("org.onap.music.exceptions.MusicLockingException", mle.getClass().getName());
+ }
+
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/exceptions/MusicPolicyVoilationExceptionTest.java b/music-core/src/test/java/org/onap/music/exceptions/MusicPolicyVoilationExceptionTest.java
new file mode 100644
index 00000000..22e2d728
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/exceptions/MusicPolicyVoilationExceptionTest.java
@@ -0,0 +1,106 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.exceptions;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class MusicPolicyVoilationExceptionTest {
+
+ @Test
+ public void TestException1() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicPolicyVoilationException();
+ }
+ } catch (MusicPolicyVoilationException mve) {
+ assertEquals("org.onap.music.exceptions.MusicPolicyVoilationException", mve.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException2() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicPolicyVoilationException("MusicPolicyVoilationException Exception occured..");
+ }
+ } catch (MusicPolicyVoilationException mve) {
+ assertEquals(mve.getMessage(), "MusicPolicyVoilationException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException3() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicPolicyVoilationException(new Throwable());
+ }
+ } catch (MusicPolicyVoilationException mve) {
+ assertEquals("org.onap.music.exceptions.MusicPolicyVoilationException", mve.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException4() {
+ String message = "Exception occured";
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicPolicyVoilationException(message, new Throwable());
+ }
+ } catch (MusicPolicyVoilationException mve) {
+ assertEquals("org.onap.music.exceptions.MusicPolicyVoilationException", mve.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException5() {
+ String message = "Exception occured";
+ boolean enableSuppression = true;
+ boolean writableStackTrace = false;
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicPolicyVoilationException(message, new Throwable(), enableSuppression,
+ writableStackTrace);
+ }
+ } catch (MusicPolicyVoilationException mve) {
+ assertEquals("org.onap.music.exceptions.MusicPolicyVoilationException", mve.getClass().getName());
+ }
+
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/exceptions/MusicQueryExceptionTest.java b/music-core/src/test/java/org/onap/music/exceptions/MusicQueryExceptionTest.java
new file mode 100644
index 00000000..9096506a
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/exceptions/MusicQueryExceptionTest.java
@@ -0,0 +1,118 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.exceptions;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class MusicQueryExceptionTest {
+
+ @Test
+ public void TestException1() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicQueryException();
+ }
+ } catch (MusicQueryException mqe) {
+ assertEquals("org.onap.music.exceptions.MusicQueryException", mqe.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException2() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicQueryException("MusicQueryException Exception occured..");
+ }
+ } catch (MusicQueryException mqe) {
+ assertEquals(mqe.getMessage(), "MusicQueryException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException3() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicQueryException("MusicQueryException Exception occured..", 001);
+ }
+ } catch (MusicQueryException mqe) {
+ assertEquals(mqe.getMessage(), "MusicQueryException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException4() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicQueryException(new Throwable());
+ }
+ } catch (MusicQueryException mqe) {
+ assertEquals("org.onap.music.exceptions.MusicQueryException", mqe.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException5() {
+ String message = "Exception occured";
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicQueryException(message, new Throwable());
+ }
+ } catch (MusicQueryException mqe) {
+ assertEquals("org.onap.music.exceptions.MusicQueryException", mqe.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException6() {
+ String message = "Exception occured";
+ boolean enableSuppression = true;
+ boolean writableStackTrace = false;
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicQueryException(message, new Throwable(), enableSuppression, writableStackTrace);
+ }
+ } catch (MusicQueryException mqe) {
+ assertEquals("org.onap.music.exceptions.MusicQueryException", mqe.getClass().getName());
+ }
+
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/exceptions/MusicServiceExceptionTest.java b/music-core/src/test/java/org/onap/music/exceptions/MusicServiceExceptionTest.java
new file mode 100644
index 00000000..bf056b61
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/exceptions/MusicServiceExceptionTest.java
@@ -0,0 +1,145 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.exceptions;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class MusicServiceExceptionTest {
+ @Test
+ public void TestException1() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicServiceException();
+ }
+ } catch (MusicServiceException mse) {
+ assertEquals("org.onap.music.exceptions.MusicServiceException", mse.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException2() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicServiceException("MusicServiceException Exception occured..");
+ }
+ } catch (MusicServiceException mse) {
+ assertEquals(mse.getMessage(), "MusicServiceException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException3() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicServiceException("MusicServiceException Exception occured..", 001);
+ }
+ } catch (MusicServiceException mse) {
+ assertEquals(mse.getMessage(), "MusicServiceException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException4() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicServiceException("MusicServiceException Exception occured..", 001, "errorMsg");
+ }
+ } catch (MusicServiceException mse) {
+ assertEquals(mse.getMessage(), "MusicServiceException Exception occured..");
+ }
+
+ }
+
+ @Test
+ public void TestException5() {
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicServiceException(new Throwable());
+ }
+ } catch (MusicServiceException mse) {
+ assertEquals("org.onap.music.exceptions.MusicServiceException", mse.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException6() {
+ String message = "Exception occured";
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicServiceException(message, new Throwable());
+ }
+ } catch (MusicServiceException mse) {
+ assertEquals("org.onap.music.exceptions.MusicServiceException", mse.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void TestException7() {
+ String message = "Exception occured";
+ boolean enableSuppression = true;
+ boolean writableStackTrace = false;
+ String s1 = "Value1";
+ String s2 = "value2";
+ try {
+ if (!s1.equalsIgnoreCase(s2)) {
+ throw new MusicServiceException(message, new Throwable(), enableSuppression, writableStackTrace);
+ }
+ } catch (MusicServiceException mse) {
+ assertEquals("org.onap.music.exceptions.MusicServiceException", mse.getClass().getName());
+ }
+
+ }
+
+ @Test
+ public void testErrorCode() {
+ MusicServiceException musicServiceException = new MusicServiceException();
+ musicServiceException.setErrorCode(0001);
+ assertEquals(0001, musicServiceException.getErrorCode());
+ }
+
+ @Test
+ public void testSetErrorMsg() {
+ MusicServiceException musicServiceException = new MusicServiceException();
+ musicServiceException.setErrorMessage("errorMsg");
+ assertEquals("errorMsg", musicServiceException.getErrorMessage());
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/lockingservice/cassandra/CassaLockStoreTest.java b/music-core/src/test/java/org/onap/music/lockingservice/cassandra/CassaLockStoreTest.java
new file mode 100644
index 00000000..a608a970
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/lockingservice/cassandra/CassaLockStoreTest.java
@@ -0,0 +1,311 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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.lockingservice.cassandra;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.music.datastore.MusicDataStore;
+import org.onap.music.exceptions.MusicLockingException;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.main.DeadlockDetectionUtil;
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.WriteType;
+import com.datastax.driver.core.exceptions.WriteTimeoutException;
+
+public class CassaLockStoreTest {
+
+ private CassaLockStore cassaLockStore;
+ private CassaLockStore.LockObject lockObject;
+ private MusicDataStore dsHandle;
+
+ @Before
+ public void setUp() {
+ dsHandle = Mockito.mock(MusicDataStore.class);
+ cassaLockStore = new CassaLockStore(dsHandle);
+ lockObject = cassaLockStore.new LockObject(false, null, null, null, null, null);
+ }
+
+ @Test
+ public void testLockOwner() {
+ lockObject.setIsLockOwner(true);
+ assertEquals(true, lockObject.getIsLockOwner());
+
+ lockObject.setIsLockOwner(false);
+ assertEquals(false, lockObject.getIsLockOwner());
+ }
+
+ @Test
+ public void testAcquireTime() {
+ lockObject.setAcquireTime("2019-11-11T15:42:12+00:00");
+ assertEquals("2019-11-11T15:42:12+00:00", lockObject.getAcquireTime());
+ }
+
+ @Test
+ public void testCreateTime() {
+ lockObject.setCreateTime("2019-11-11T15:43:44+00:00");
+ assertEquals("2019-11-11T15:43:44+00:00", lockObject.getCreateTime());
+ }
+
+ @Test
+ public void testLockRef() {
+ lockObject.setLockRef("LockReference");
+ assertEquals("LockReference", lockObject.getLockRef());
+ }
+
+ @Test
+ public void testLockType() {
+ lockObject.setLocktype(LockType.READ);
+ assertEquals(LockType.READ, lockObject.getLocktype());
+ }
+
+ @Test
+ public void testOwner() {
+ lockObject.setOwner("Owner");
+ assertEquals("Owner", lockObject.getOwner());
+ }
+
+ @Test
+ public void testCreateLockQueue() {
+ try {
+ Mockito.when(dsHandle.executePut(Mockito.any(), Mockito.any())).thenReturn(true);
+ assertEquals(true, cassaLockStore.createLockQueue("keyspace1", "table1"));
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testGenLockRefandEnQueue() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ List<Row> latestGuardRow = Mockito.mock(List.class);
+ Mockito.when(latestGuardRow.isEmpty()).thenReturn(false);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(latestGuardRow.get(0)).thenReturn(row);
+ Mockito.when(row.getLong(0)).thenReturn((long) 4);
+ Mockito.when(resultSetMock.all()).thenReturn(latestGuardRow);
+ try {
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ Mockito.when(dsHandle.executePut(Mockito.any(), Mockito.any())).thenReturn(true);
+ assertEquals("$keyspace2.table2.lockName2$5",
+ cassaLockStore.genLockRefandEnQueue("keyspace2", "table2", "lockName2", LockType.READ, "owner2"));
+ } catch (MusicServiceException | MusicQueryException | MusicLockingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testGetLockQueue() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Iterator<Row> iterator = Mockito.mock(Iterator.class);
+ Mockito.when(iterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.getLong("lockReference")).thenReturn((long)1).thenReturn((long)2).thenReturn((long)3);
+ Mockito.when(row.get("lockType", LockType.class)).thenReturn(LockType.WRITE).thenReturn(LockType.WRITE).thenReturn(LockType.WRITE);
+ Mockito.when(iterator.next()).thenReturn(row).thenReturn(row).thenReturn(row);
+ Mockito.when(resultSetMock.iterator()).thenReturn(iterator);
+
+ try {
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ assertEquals("2", cassaLockStore.getLockQueue("keyspace2", "table2", "key2").get(1));
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testGetLockQueueSize() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(resultSetMock.one()).thenReturn(row);
+ Mockito.when(row.getLong("count")).thenReturn((long) 6);
+ try {
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ assertEquals(6, cassaLockStore.getLockQueueSize("keyspace3", "table3", "key3"));
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testPeekLockQueue() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.isNull("lockReference")).thenReturn(false);
+ Mockito.when(row.getLong("lockReference")).thenReturn((long) 6);
+ Mockito.when(row.getString("createTime")).thenReturn("2019-11-13T15:05:45+00:00");
+ Mockito.when(row.getString("acquireTime")).thenReturn("2019-11-13T15:05:45+00:00");
+ Mockito.when(row.isNull("lockReference")).thenReturn(false);
+ Mockito.when(resultSetMock.one()).thenReturn(row);
+ try {
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ assertEquals("6", cassaLockStore.peekLockQueue("keyspace4", "table4", "key4").getLockRef());
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testGetCurrentLockHolders() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Iterator<Row> iterator = Mockito.mock(Iterator.class);
+ Mockito.when(iterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.getLong("lockReference")).thenReturn((long) 5).thenReturn((long) 5);
+ Mockito.when(row.get("lockType", LockType.class)).thenReturn(LockType.WRITE);
+ Mockito.when(iterator.next()).thenReturn(row).thenReturn(row);
+ Mockito.when(resultSetMock.iterator()).thenReturn(iterator);
+ try {
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ assertEquals("$keyspace5.table5.key5$5", cassaLockStore.getCurrentLockHolders("keyspace5", "table5", "key5").get(1));
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testIsLockOwner() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Iterator<Row> iterator = Mockito.mock(Iterator.class);
+ Mockito.when(iterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.getLong("lockReference")).thenReturn((long) 5);
+ Mockito.when(row.get("lockType", LockType.class)).thenReturn(LockType.WRITE);
+ Mockito.when(iterator.next()).thenReturn(row).thenReturn(row);
+ Mockito.when(resultSetMock.iterator()).thenReturn(iterator);
+ try {
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ assertEquals(true, cassaLockStore.isLockOwner("keyspace5", "table5", "key5", "5"));
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testGetLockInfo() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.isNull("lockReference")).thenReturn(false);
+ Mockito.when(row.getLong("lockReference")).thenReturn((long) 6);
+ Mockito.when(row.getString("createTime")).thenReturn("2019-11-13T15:05:45+00:00");
+ Mockito.when(row.getString("acquireTime")).thenReturn("2019-11-13T15:05:45+00:00");
+ LockType locktype = Mockito.mock(LockType.class);
+ Mockito.when(row.get("lockType", LockType.class)).thenReturn(locktype);
+ Mockito.when(row.getString("owner")).thenReturn("owner6");
+ Mockito.when(resultSetMock.one()).thenReturn(row);
+
+ try {
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ CassaLockStore csLockStore = Mockito.spy(cassaLockStore);
+ Mockito.doReturn(true).when(csLockStore).isLockOwner(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
+ assertEquals("6", csLockStore.getLockInfo("keyspace6", "table6", "key6", "6").getLockRef());
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testCheckForDeadlock() {
+ DeadlockDetectionUtil ddu = Mockito.mock(DeadlockDetectionUtil.class);
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Iterator<Row> it = Mockito.mock(Iterator.class);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(it.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
+ Mockito.when(row.getString("key")).thenReturn("key8");
+ Mockito.when(row.getString("owner")).thenReturn("owner8");
+ Mockito.when(row.getString("acquiretime")).thenReturn("1");
+ Mockito.when(it.next()).thenReturn(row).thenReturn(row).thenReturn(row);
+ Mockito.when(resultSetMock.iterator()).thenReturn(it);
+ CassaLockStore csLockStore = Mockito.spy(cassaLockStore);
+ Mockito.doReturn(ddu).when(csLockStore).getDeadlockDetectionUtil();
+ Mockito.when(ddu.checkForDeadlock(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true);
+ try {
+ Mockito.when(dsHandle.executeLocalQuorumConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ assertEquals(false,
+ cassaLockStore.checkForDeadlock("keyspace8", "table8", "lockName8", LockType.WRITE, "owner8", true));
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testGetAllLocksForOwner() {
+ ResultSet resultSetMock = Mockito.mock(ResultSet.class);
+ Iterator<Row> it = Mockito.mock(Iterator.class);
+ Mockito.when(it.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(row.getString("key")).thenReturn("key10");
+ Mockito.when(row.getLong("lockreference")).thenReturn((long) 10);
+ Mockito.when(it.next()).thenReturn(row);
+ Mockito.when(resultSetMock.iterator()).thenReturn(it);
+ try {
+ Mockito.when(dsHandle.executeQuorumConsistencyGet(Mockito.any())).thenReturn(resultSetMock);
+ assertEquals("key10$10", cassaLockStore.getAllLocksForOwner("owneer10", "keyspace10", "table10").get(1));
+ } catch (MusicServiceException | MusicQueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testDequeueLockRef() throws Exception {
+ cassaLockStore.deQueueLockRef("keyspace1", "table1", "key6", "6", 2);
+
+ // note only expecting 1 call to this instance, expecting it to succeed
+ Mockito.verify(dsHandle, Mockito.times(1)).executePut(Mockito.any(), Mockito.anyString());
+ }
+
+ @Test
+ public void testDequeueLockRefWriteTimeout() throws Exception {
+ int retryCount = 22;
+ try {
+ Mockito.when(dsHandle.executePut(Mockito.any(), Mockito.anyString()))
+ .thenThrow(new MusicServiceException("Cassandra timeout during..."));
+ cassaLockStore.deQueueLockRef("keyspace1", "table1", "key6", "6", retryCount);
+
+ // Should never reach here
+ fail();
+ } catch (MusicServiceException | MusicQueryException | MusicLockingException e) {
+ // should throw an error
+ }
+
+ Mockito.verify(dsHandle, Mockito.times(retryCount)).executePut(Mockito.any(), Mockito.anyString());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/lockingservice/cassandra/MusicLockStateTest.java b/music-core/src/test/java/org/onap/music/lockingservice/cassandra/MusicLockStateTest.java
new file mode 100644
index 00000000..e5b655bd
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/lockingservice/cassandra/MusicLockStateTest.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 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.lockingservice.cassandra;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.music.lockingservice.cassandra.MusicLockState.LockStatus;
+
+public class MusicLockStateTest {
+
+ MusicLockState musicLockState;
+
+ @Before
+ public void setup() {
+ musicLockState = new MusicLockState(LockStatus.LOCKED, "", true);
+ }
+
+ @Test
+ public void testGetLeasePeriod() {
+ musicLockState.setLeasePeriod(200L);
+ assertEquals(200L, musicLockState.getLeasePeriod());
+ }
+
+ @Test
+ public void testIsNeedToSyncQuorum() {
+ assertEquals(true, musicLockState.isNeedToSyncQuorum());
+ }
+
+ @Test
+ public void testGetLeaseStartTime() {
+ musicLockState.setLeaseStartTime(200L);
+ assertEquals(200L, musicLockState.getLeaseStartTime());
+ }
+
+ @Test
+ public void testGetLockStatus() {
+ musicLockState.setLockStatus(LockStatus.LOCKED);
+ assertEquals(LockStatus.LOCKED, musicLockState.getLockStatus());
+ }
+
+ @Test
+ public void testGetLockHolder() {
+ musicLockState.setLockHolder("lockHolder");
+ assertEquals("lockHolder", musicLockState.getLockHolder());
+ }
+
+ @Test
+ public void testGetErrorMessage() {
+ MusicLockState musicLockState2 = new MusicLockState("This is error message");
+ assertEquals("This is error message", musicLockState2.getErrorMessage());
+ }
+
+ @Test
+ public void testSerialize() {
+ byte[] serializedBytes = musicLockState.serialize();
+ MusicLockState musicLockState3 = musicLockState.deSerialize(serializedBytes);
+ assertEquals(musicLockState.getLeasePeriod(),musicLockState3.getLeasePeriod());
+ assertEquals(musicLockState.isNeedToSyncQuorum(),musicLockState3.isNeedToSyncQuorum());
+ assertEquals(musicLockState.getLeaseStartTime(),musicLockState3.getLeaseStartTime());
+ assertEquals(musicLockState.getLockStatus(),musicLockState3.getLockStatus());
+ assertEquals(musicLockState.getLockHolder(),musicLockState3.getLockHolder());
+ assertEquals(musicLockState.getErrorMessage(),musicLockState3.getErrorMessage());
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/main/CipherUtilTest.java b/music-core/src/test/java/org/onap/music/main/CipherUtilTest.java
new file mode 100644
index 00000000..ff187ffd
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/main/CipherUtilTest.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.main;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class CipherUtilTest {
+
+ private CipherUtil cipherUtil;
+
+ @Before
+ public void setup() {
+ cipherUtil = new CipherUtil();
+ }
+
+ @Test
+ public void testEncryptPKC() {
+ String encryptedText = CipherUtil.encryptPKC("This is another string to be encrypted",
+ "4BFF9DCCD774F3650E20C4D3F69F8C99");
+ System.out.println("*************************" + encryptedText);
+ assertEquals(88, encryptedText.length());
+ }
+
+ @Test
+ public void testDecryptPKC() {
+ String encryptedText = CipherUtil.encryptPKC("This is another string to be encrypted",
+ "4BFF9DCCD774F3650E20C4D3F69F8C99");
+ assertEquals("This is another string to be encrypted",
+ CipherUtil.decryptPKC(encryptedText, "4BFF9DCCD774F3650E20C4D3F69F8C99"));
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/main/DeadlockDetectionUtilTest.java b/music-core/src/test/java/org/onap/music/main/DeadlockDetectionUtilTest.java
new file mode 100644
index 00000000..ab767e17
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/main/DeadlockDetectionUtilTest.java
@@ -0,0 +1,87 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2019 IBM 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.main;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.junit.Before;
+import org.junit.Test;
+//import org.junit.experimental.runners.Enclosed;
+//import org.junit.runner.RunWith;
+import org.onap.music.main.DeadlockDetectionUtil.OwnershipType;
+
+//@RunWith(Enclosed.class)
+public class DeadlockDetectionUtilTest {
+ private DeadlockDetectionUtil ddu;
+
+ @Before
+ public void setup() {
+ ddu = new DeadlockDetectionUtil();
+ }
+
+ @Test
+ public void testListAllNodes() {
+ ddu = new DeadlockDetectionUtil();
+ ddu.setExisting("r1", "o2", OwnershipType.ACQUIRED);
+ ddu.setExisting("r3", "o2", OwnershipType.ACQUIRED);
+
+ ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outContent));
+ ddu.listAllNodes();
+
+ /*
+ * String expectedOutput = "In DeadlockDetectionUtil: \n" +
+ * " o2 : Node [id=o2, links=r3, visited=false, onStack=false]\n" +
+ * " r3 : Node [id=r3, links=, visited=false, onStack=false]\n" +
+ * " r1 : Node [id=r1, links=o2, visited=false, onStack=false]\n";
+ * assertEquals(expectedOutput, outContent.toString());
+ *
+ * ddu = new DeadlockDetectionUtil(); ddu.setExisting("111", "222",
+ * OwnershipType.CREATED); ddu.setExisting("333", "222", OwnershipType.CREATED);
+ * outContent = new ByteArrayOutputStream(); System.setOut(new
+ * PrintStream(outContent)); ddu.listAllNodes(); expectedOutput =
+ * "In DeadlockDetectionUtil: \n" +
+ * " o222 : Node [id=o222, links=r111r333, visited=false, onStack=false]\n" +
+ * " r333 : Node [id=r333, links=, visited=false, onStack=false]\n" +
+ * " r111 : Node [id=r111, links=, visited=false, onStack=false]";
+ * assertEquals(expectedOutput, outContent.toString());
+ */
+ }
+
+ @Test
+ public void testcheckForDeadlock() {
+ ddu = new DeadlockDetectionUtil();
+ ddu.setExisting("111", "222", DeadlockDetectionUtil.OwnershipType.ACQUIRED);
+ ddu.setExisting("333", "444", DeadlockDetectionUtil.OwnershipType.ACQUIRED);
+ assertEquals(false, ddu.checkForDeadlock("111", "444", DeadlockDetectionUtil.OwnershipType.CREATED));
+
+ ddu = new DeadlockDetectionUtil();
+ ddu.setExisting("111", "222", DeadlockDetectionUtil.OwnershipType.ACQUIRED);
+ ddu.setExisting("333", "444", DeadlockDetectionUtil.OwnershipType.ACQUIRED);
+ ddu.setExisting("333", "222", DeadlockDetectionUtil.OwnershipType.CREATED);
+ assertEquals(true, ddu.checkForDeadlock("111", "444", DeadlockDetectionUtil.OwnershipType.CREATED));
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/main/MusicCoreTest.java b/music-core/src/test/java/org/onap/music/main/MusicCoreTest.java
new file mode 100644
index 00000000..4714778b
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/main/MusicCoreTest.java
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ * ============LICENSE_START========================================== org.onap.music
+ * =================================================================== Copyright (c) 2019 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.main;
+
+import static org.junit.Assert.assertEquals;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.MultivaluedMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.FieldSetter;
+import org.onap.music.datastore.Condition;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonDelete;
+import org.onap.music.datastore.jsonobjects.JsonIndex;
+import org.onap.music.datastore.jsonobjects.JsonInsert;
+import org.onap.music.datastore.jsonobjects.JsonKeySpace;
+import org.onap.music.datastore.jsonobjects.JsonSelect;
+import org.onap.music.datastore.jsonobjects.JsonTable;
+import org.onap.music.datastore.jsonobjects.JsonUpdate;
+import org.onap.music.exceptions.MusicLockingException;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.lockingservice.cassandra.CassaLockStore;
+import org.onap.music.lockingservice.cassandra.LockType;
+import org.onap.music.lockingservice.cassandra.MusicLockState;
+import org.onap.music.service.MusicCoreService;
+import com.datastax.driver.core.ResultSet;
+
+public class MusicCoreTest {
+
+ MusicCore mCore;
+ MusicCoreService musicCore;
+ CassaLockStore mLockHandle;
+
+ @Before
+ public void setup() {
+ mCore = new MusicCore();
+ musicCore = Mockito.mock(MusicCoreService.class);
+ mLockHandle = Mockito.mock(CassaLockStore.class);
+ try {
+ FieldSetter.setField(mCore, mCore.getClass().getDeclaredField("musicCore"), musicCore);
+ } catch (NoSuchFieldException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testAcquireLock() throws MusicLockingException, MusicQueryException, MusicServiceException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ Mockito.when(musicCore.acquireLock(Mockito.any(), Mockito.any())).thenReturn(returnType);
+ result = MusicCore.acquireLock("key1", "lockid1");
+ assertEquals(returnType, result);
+ }
+
+ @Test
+ public void testacquireLockWithLease() throws MusicLockingException, MusicQueryException, MusicServiceException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ Mockito.when(musicCore.acquireLockWithLease(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong()))
+ .thenReturn(returnType);
+ result = MusicCore.acquireLockWithLease("key1", "lockid1", 100L);
+ assertEquals(returnType, result);
+ }
+
+ @Test
+ public void testCreateLockReferenceAtomic() throws MusicLockingException {
+ String result = null;
+ Mockito.when(musicCore.createLockReferenceAtomic(Mockito.any())).thenReturn("lockreference1");
+ result = MusicCore.createLockReferenceAtomic("key2");
+ assertEquals("lockreference1", result);
+ }
+
+ @Test
+ public void testCreateLockReference() throws MusicLockingException {
+ String result = null;
+ Mockito.when(musicCore.createLockReference(Mockito.any(), Mockito.any())).thenReturn("lockreference2");
+ result = MusicCore.createLockReference("key3", "owner3");
+ assertEquals("lockreference2", result);
+ }
+
+ @Test
+ public void testCreateLockReferenceAtomic2() throws MusicLockingException {
+ String result = null;
+ Mockito.when(musicCore.createLockReferenceAtomic(Mockito.any(), Mockito.any())).thenReturn("lockreference3");
+ result = MusicCore.createLockReferenceAtomic("key4", LockType.READ);
+ assertEquals("lockreference3", result);
+ }
+
+ @Test
+ public void testCreateLockReference2() throws MusicLockingException {
+ String result = null;
+ Mockito.when(musicCore.createLockReference(Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn("lockreference4");
+ result = MusicCore.createLockReference("key4", LockType.READ, "owner4");
+ assertEquals("lockreference4", result);
+ }
+
+ @Test
+ public void testCreateTable() throws MusicServiceException {
+ ResultType resultType = Mockito.mock(ResultType.class);
+ ResultType result = null;
+ Mockito.when(musicCore.createTable(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn(resultType);
+ result = MusicCore.createTable("keyspace1", "table1", new PreparedQueryObject(), "consistency");
+ assertEquals(resultType, result);
+ }
+
+ @Test
+ public void testQuorumGet() {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Mockito.when(musicCore.quorumGet(Mockito.any())).thenReturn(rs);
+ assertEquals(rs, MusicCore.quorumGet(new PreparedQueryObject()));
+ }
+
+ @Test
+ public void testWhoseTurnIsIt() {
+ Mockito.when(musicCore.whoseTurnIsIt(Mockito.any())).thenReturn("turn");
+ assertEquals("turn", MusicCore.whoseTurnIsIt("key5"));
+ }
+
+ @Test
+ public void testGetCurrentLockHolders() {
+ List<String> result = Mockito.mock(List.class);
+ Mockito.when(musicCore.getCurrentLockHolders(Mockito.any())).thenReturn(result);
+ assertEquals(result, MusicCore.getCurrentLockHolders("key6"));
+ }
+
+ @Test
+ public void testPromoteLock() throws MusicLockingException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ Mockito.when(musicCore.promoteLock(Mockito.any())).thenReturn(returnType);
+ result = MusicCore.promoteLock("lockid2");
+ assertEquals(returnType, result);
+ }
+
+ @Test
+ public void testEventualPut() {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ Mockito.when(musicCore.eventualPut(Mockito.any())).thenReturn(returnType);
+ assertEquals(returnType, MusicCore.eventualPut(new PreparedQueryObject()));
+ }
+
+ @Test
+ public void testEventualPut_nb() {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ Mockito.when(musicCore.eventualPut_nb(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn(returnType);
+ assertEquals(returnType,
+ MusicCore.eventualPut_nb(new PreparedQueryObject(), "keyspace2", "table2", "primarykey1"));
+ }
+
+ @Test
+ public void testCriticalPut() {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ Mockito.when(musicCore.criticalPut(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
+ Mockito.any())).thenReturn(returnType);
+ assertEquals(returnType, MusicCore.criticalPut("keyspace3", "table3", "primarykey2", new PreparedQueryObject(),
+ "lockreference2", new Condition(new HashMap(), new PreparedQueryObject())));
+ }
+
+ @Test
+ public void testNonKeyRelatedPut() throws MusicServiceException, MusicQueryException {
+ ResultType resultType = Mockito.mock(ResultType.class);
+ ResultType result = null;
+ Mockito.when(musicCore.nonKeyRelatedPut(Mockito.any(), Mockito.any())).thenReturn(resultType);
+ result = MusicCore.nonKeyRelatedPut(new PreparedQueryObject(), "consistency2");
+ assertEquals(resultType, result);
+ }
+
+ @Test
+ public void testGet() throws MusicServiceException {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ ResultSet result = null;
+ Mockito.when(musicCore.get(Mockito.any())).thenReturn(rs);
+ result = MusicCore.get(new PreparedQueryObject());
+ assertEquals(rs, result);
+ }
+
+ @Test
+ public void testCriticalGet() throws MusicServiceException {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ ResultSet result = null;
+ Mockito.when(musicCore.criticalGet(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn(rs);
+ result = MusicCore.criticalGet("keyspace4", "table4", "primarykey3", new PreparedQueryObject(),
+ "lockreference3");
+ assertEquals(rs, result);
+ }
+
+ @Test
+ public void testAtomicPut() throws MusicLockingException, MusicQueryException, MusicServiceException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ Mockito.when(musicCore.atomicPut(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn(returnType);
+ result = MusicCore.atomicPut("keyspace5", "table5", "primarykey4", new PreparedQueryObject(),
+ new Condition(new HashMap(), new PreparedQueryObject()));
+ assertEquals(returnType, result);
+ }
+
+ @Test
+ public void testAtomicGet() throws MusicServiceException, MusicLockingException, MusicQueryException {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ ResultSet result = null;
+ Mockito.when(musicCore.atomicGet(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(rs);
+ result = MusicCore.atomicGet("keyspace5", "table5", "primarykey4", new PreparedQueryObject());
+ assertEquals(rs, result);
+ }
+
+ @Test
+ public void testGetLockQueue() throws MusicServiceException, MusicQueryException, MusicLockingException {
+ List<String> result = Mockito.mock(List.class);
+ List<String> rst = null;
+ Mockito.when(musicCore.getLockQueue(Mockito.any())).thenReturn(result);
+ rst = MusicCore.getLockQueue("key5");
+ assertEquals(result, rst);
+ }
+
+ @Test
+ public void testGetLockQueueSize() throws MusicServiceException, MusicQueryException, MusicLockingException {
+ long result = 0L;
+ Mockito.when(musicCore.getLockQueueSize(Mockito.any())).thenReturn(100L);
+ result = MusicCore.getLockQueueSize("key6");
+ assertEquals(100L, result);
+ }
+
+ @Test
+ public void testatomicPutWithDeleteLock() throws MusicLockingException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ Mockito.when(musicCore.atomicPutWithDeleteLock(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(),
+ Mockito.any())).thenReturn(returnType);
+ result = MusicCore.atomicPutWithDeleteLock("keyspace5", "table5", "primarykey4", new PreparedQueryObject(),
+ new Condition(new HashMap(), new PreparedQueryObject()));
+ assertEquals(returnType, result);
+ }
+
+ @Test
+ public void testAtomicGetWithDeleteLock() throws MusicServiceException, MusicLockingException {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ ResultSet result = null;
+ Mockito.when(musicCore.atomicGetWithDeleteLock(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))
+ .thenReturn(rs);
+ result = MusicCore.atomicGetWithDeleteLock("keyspace5", "table5", "primarykey4", new PreparedQueryObject());
+ assertEquals(rs, result);
+ }
+
+ @Test
+ public void testValidateLock() {
+ Map<String, Object> map = Mockito.mock(Map.class);
+ Mockito.when(musicCore.validateLock(Mockito.any())).thenReturn(map);
+ assertEquals(map, MusicCore.validateLock("lockname"));
+ }
+
+ @Test
+ public void testReleaseLock() throws MusicLockingException {
+ MusicLockState musicLockState = Mockito.mock(MusicLockState.class);
+ MusicLockState result = null;
+ Mockito.when(musicCore.releaseLock(Mockito.anyString(), Mockito.anyBoolean())).thenReturn(musicLockState);
+ result = MusicCore.releaseLock("lockid", true);
+ assertEquals(musicLockState, result);
+ }
+
+ @Test
+ public void testReleaseAllLocksForOwner() throws MusicLockingException, MusicServiceException, MusicQueryException {
+ List<String> result = Mockito.mock(List.class);
+ List<String> rst = null;
+ Mockito.when(musicCore.releaseAllLocksForOwner(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(result);
+ rst = MusicCore.releaseAllLocksForOwner("owner2", "keyspace6", "table6");
+ assertEquals(result, rst);
+ }
+
+ @Test
+ public void testCreateKeyspace() throws MusicServiceException, MusicQueryException {
+ ResultType resultType = Mockito.mock(ResultType.class);
+ ResultType result = null;
+ Mockito.when(musicCore.createKeyspace(Mockito.any(), Mockito.any())).thenReturn(resultType);
+ result = MusicCore.createKeyspace(new JsonKeySpace(), "consistency3");
+ assertEquals(resultType, result);
+ }
+
+ @Test
+ public void testDropKeyspace() throws MusicServiceException, MusicQueryException {
+ ResultType resultType = Mockito.mock(ResultType.class);
+ ResultType result = null;
+ Mockito.when(musicCore.dropKeyspace(Mockito.any(), Mockito.any())).thenReturn(resultType);
+ result = MusicCore.dropKeyspace(new JsonKeySpace(), "consistency4");
+ assertEquals(resultType, result);
+ }
+
+ @Test
+ public void testCreateTable2() throws MusicServiceException, MusicQueryException {
+ ResultType resultType = Mockito.mock(ResultType.class);
+ ResultType result = null;
+ Mockito.when(musicCore.createTable(Mockito.any(), Mockito.any())).thenReturn(resultType);
+ result = MusicCore.createTable(new JsonTable(), "consistency5");
+ assertEquals(resultType, result);
+ }
+
+ @Test
+ public void testDropTable() throws MusicServiceException, MusicQueryException {
+ ResultType resultType = Mockito.mock(ResultType.class);
+ ResultType result = null;
+ Mockito.when(musicCore.dropTable(Mockito.any(), Mockito.any())).thenReturn(resultType);
+ result = MusicCore.dropTable(new JsonTable(), "consistency5");
+ assertEquals(resultType, result);
+ }
+
+ @Test
+ public void testCreateIndex() throws MusicServiceException, MusicQueryException {
+ ResultType resultType = Mockito.mock(ResultType.class);
+ ResultType result = null;
+ Mockito.when(musicCore.createIndex(Mockito.any(), Mockito.any())).thenReturn(resultType);
+ result = MusicCore.createIndex(new JsonIndex("indexName", "keyspace7", "table7", "field"), "consistency6");
+ assertEquals(resultType, result);
+ }
+
+ @Test
+ public void testSelect() throws MusicServiceException, MusicQueryException {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ ResultSet result = null;
+ Mockito.when(musicCore.select(Mockito.any(), Mockito.any())).thenReturn(rs);
+ MultivaluedMap<String, String> map = Mockito.mock(MultivaluedMap.class);
+ result = MusicCore.select(new JsonSelect(), map);
+ assertEquals(rs, result);
+ }
+
+ @Test
+ public void testSelectCritical() throws MusicLockingException, MusicQueryException, MusicServiceException {
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ ResultSet result = null;
+ Mockito.when(musicCore.selectCritical(Mockito.any(), Mockito.any())).thenReturn(rs);
+ MultivaluedMap<String, String> map = Mockito.mock(MultivaluedMap.class);
+ result = MusicCore.selectCritical(new JsonInsert(), map);
+ assertEquals(rs, result);
+ }
+
+ @Test
+ public void testInsertIntoTable() throws MusicLockingException, MusicQueryException, MusicServiceException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ Mockito.when(musicCore.insertIntoTable(Mockito.any())).thenReturn(returnType);
+ result = MusicCore.insertIntoTable(new JsonInsert());
+ assertEquals(returnType, result);
+ }
+
+ @Test
+ public void testUpdateTable() throws MusicLockingException, MusicQueryException, MusicServiceException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ Mockito.when(musicCore.updateTable(Mockito.any(), Mockito.any())).thenReturn(returnType);
+ MultivaluedMap<String, String> map = Mockito.mock(MultivaluedMap.class);
+ result = MusicCore.updateTable(new JsonUpdate(), map);
+ assertEquals(returnType, result);
+ }
+
+ @Test
+ public void testDeleteFromTable() throws MusicLockingException, MusicQueryException, MusicServiceException {
+ ReturnType returnType = Mockito.mock(ReturnType.class);
+ ReturnType result = null;
+ MultivaluedMap<String, String> map = Mockito.mock(MultivaluedMap.class);
+ Mockito.when(musicCore.deleteFromTable(Mockito.any(), Mockito.any())).thenReturn(returnType);
+ result = MusicCore.deleteFromTable(new JsonDelete(), map);
+ assertEquals(returnType, result);
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/main/ResultTypeTest.java b/music-core/src/test/java/org/onap/music/main/ResultTypeTest.java
new file mode 100644
index 00000000..d6ccc1f1
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/main/ResultTypeTest.java
@@ -0,0 +1,42 @@
+/*
+ * ============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.main;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class ResultTypeTest {
+
+ @Test
+ public void testResultType() {
+ assertEquals("SUCCESS",ResultType.SUCCESS.name());
+ assertEquals("FAILURE",ResultType.FAILURE.name());
+ }
+
+ @Test
+ public void testGetResult() {
+ assertEquals("Success",ResultType.SUCCESS.getResult());
+ assertEquals("Failure",ResultType.FAILURE.getResult());
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/main/ReturnTypeTest.java b/music-core/src/test/java/org/onap/music/main/ReturnTypeTest.java
new file mode 100644
index 00000000..fbb5f84d
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/main/ReturnTypeTest.java
@@ -0,0 +1,82 @@
+/*
+ * ============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.main;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.junit.Test;
+
+public class ReturnTypeTest {
+
+ @Test
+ public void testReturnType() {
+ ReturnType result = new ReturnType(ResultType.SUCCESS,"message");
+ assertEquals(result.getMessage(),"message");
+ assertEquals(result.getResult(),ResultType.SUCCESS);
+ }
+
+ @Test
+ public void testTimingInfo() {
+ ReturnType result = new ReturnType(ResultType.SUCCESS,"message");
+ result.setTimingInfo("123");
+ assertEquals(result.getTimingInfo(),"123");
+ }
+
+ @Test
+ public void testGetResult() {
+ ReturnType result = new ReturnType(ResultType.FAILURE,"message");
+ assertEquals(result.getResult(),ResultType.FAILURE);
+ }
+
+ @Test
+ public void testGetMessage() {
+ ReturnType result = new ReturnType(ResultType.SUCCESS,"message");
+ result.setMessage("NewMessage");
+ assertEquals(result.getMessage(),"NewMessage");
+ }
+
+ @Test
+ public void testToJson() {
+ ReturnType result = new ReturnType(ResultType.SUCCESS,"message");
+ String myJson = result.toJson();
+ assertTrue(myJson.contains("message"));
+ }
+
+ @Test
+ public void testToString() {
+ ReturnType result = new ReturnType(ResultType.SUCCESS,"message");
+ String test = result.toString();
+ assertTrue(test.contains("message"));
+ }
+
+ @Test
+ public void testToMap() {
+ ReturnType result = new ReturnType(ResultType.SUCCESS,"message");
+ Map<String, Object> myMap = result.toMap();
+ assertTrue(myMap.containsKey("message"));
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/service/impl/MusicCassaCoreTest.java b/music-core/src/test/java/org/onap/music/service/impl/MusicCassaCoreTest.java
new file mode 100644
index 00000000..33debfaa
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/service/impl/MusicCassaCoreTest.java
@@ -0,0 +1,485 @@
+/*******************************************************************************
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2018 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.service.impl;
+
+import static org.junit.Assert.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.music.datastore.MusicDataStore;
+import org.onap.music.datastore.MusicDataStoreHandle;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonKeySpace;
+import org.onap.music.datastore.jsonobjects.JsonTable;
+import org.onap.music.exceptions.MusicLockingException;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.lockingservice.cassandra.CassaLockStore;
+import org.onap.music.lockingservice.cassandra.CassaLockStore.LockObject;
+import org.onap.music.lockingservice.cassandra.LockType;
+import org.onap.music.main.MusicUtil;
+import org.onap.music.main.ResultType;
+import org.onap.music.main.ReturnType;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MusicCassaCoreTest {
+
+ @Mock
+ private CassaLockStore mLockHandle;
+
+ @Mock
+ private MusicDataStore dsHandle;
+
+ @Mock
+ private Session session;
+
+ MusicCassaCore core;
+
+ @Before
+ public void before() {
+ core = MusicCassaCore.getInstance();
+ MusicCassaCore.setmLockHandle(mLockHandle);
+ MusicDataStoreHandle.setMDstoreHandle(dsHandle);
+ Mockito.when(dsHandle.getSession()).thenReturn(session);
+ }
+
+ @Test
+ public void testGetmLockHandle() {
+ assertEquals(mLockHandle, MusicCassaCore.getmLockHandle());
+ }
+
+ @Test
+ public void testSetmLockHandle() {
+ CassaLockStore m2 = Mockito.mock(CassaLockStore.class);
+ MusicCassaCore.setmLockHandle(m2);
+ assertEquals(m2, MusicCassaCore.getmLockHandle());
+ //revert back to original handle
+ MusicCassaCore.setmLockHandle(mLockHandle);
+ }
+
+ @Test
+ public void testGetInstance() {
+ assertEquals(core, MusicCassaCore.getInstance());
+ }
+
+ @Test
+ public void testGetLockingServiceHandle() {
+ assertEquals(mLockHandle, MusicCassaCore.getmLockHandle());
+ }
+
+ @Test
+ public void testCreateLockReferenceAtomicString() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ Mockito.when(mLockHandle.genLockRefandEnQueue("keyspace", "table", "lockName", LockType.WRITE, null))
+ .thenReturn("lockReturned");
+
+ String lockRef = core.createLockReferenceAtomic(fullyQualifiedKey);
+
+ Mockito.verify(mLockHandle).genLockRefandEnQueue("keyspace", "table", "lockName", LockType.WRITE, null);
+ assertEquals("lockReturned", lockRef);
+ }
+
+ @Test
+ public void testCreateLockReferenceStringString() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ String owner = "owner1";
+ Mockito.when(mLockHandle.genLockRefandEnQueue("keyspace", "table", "lockName", LockType.WRITE, owner))
+ .thenReturn("lockReturned");
+
+ String lockRef = core.createLockReference(fullyQualifiedKey, owner);
+
+ Mockito.verify(mLockHandle).genLockRefandEnQueue("keyspace", "table", "lockName", LockType.WRITE, owner);
+ assertEquals("lockReturned", lockRef);
+ }
+
+ @Test
+ public void testCreateLockReferenceAtomicStringLockType() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ Mockito.when(mLockHandle.genLockRefandEnQueue("keyspace", "table", "lockName", LockType.READ, null))
+ .thenReturn("lockReturned");
+
+ String lockRef = core.createLockReferenceAtomic(fullyQualifiedKey, LockType.READ);
+
+ Mockito.verify(mLockHandle).genLockRefandEnQueue("keyspace", "table", "lockName", LockType.READ, null);
+ assertEquals("lockReturned", lockRef);
+ }
+
+ @Test
+ public void testCreateLockReferenceStringLockTypeString() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ String owner = "owner1";
+ Mockito.when(mLockHandle.genLockRefandEnQueue("keyspace", "table", "lockName", LockType.READ, owner))
+ .thenReturn("lockReturned");
+
+ String lockRef = core.createLockReference(fullyQualifiedKey, LockType.READ, owner);
+
+ Mockito.verify(mLockHandle).genLockRefandEnQueue("keyspace", "table", "lockName", LockType.READ, owner);
+ assertEquals("lockReturned", lockRef);
+ }
+
+ @Test
+ public void testPromoteLock() throws Exception {
+ String lockId = "$keyspace.table.lockName$1";
+ Mockito.when(mLockHandle.promoteLock("keyspace", "table", "lockName", "1"))
+ .thenReturn(new ReturnType(ResultType.SUCCESS, "Lock Promoted"));
+
+ ReturnType rt = core.promoteLock(lockId);
+ assertEquals(ResultType.SUCCESS, rt.getResult());
+ assertEquals("Lock Promoted", rt.getMessage());
+ }
+
+ @Test
+ public void testAcquireLockWithLease() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ String lockId = "$keyspace.table.lockName$1";
+ long leasePeriod = 1000;
+ String currTime = String.valueOf(System.currentTimeMillis());
+ Mockito.when(mLockHandle.peekLockQueue("keyspace", "table", "lockName"))
+ .thenReturn(mLockHandle.new LockObject(true, lockId, currTime, currTime, LockType.WRITE, null));
+ Mockito.when(mLockHandle.getLockInfo("keyspace", "table", "lockName", "1"))
+ .thenReturn(mLockHandle.new LockObject(false, lockId, null, null, LockType.WRITE, null));
+
+ ReturnType rt = core.acquireLockWithLease(fullyQualifiedKey, lockId, leasePeriod);
+ assertEquals(ResultType.FAILURE, rt.getResult());
+ }
+
+ @Test
+ public void testAcquireLock() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ String lockId = "$keyspace.table.lockName$1";
+ Mockito.when(mLockHandle.getLockInfo("keyspace", "table", "lockName", "1"))
+ .thenReturn(mLockHandle.new LockObject(false, lockId, null, null, LockType.WRITE, null));
+
+ ReturnType rt = core.acquireLock(fullyQualifiedKey, lockId);
+
+ assertEquals(ResultType.FAILURE, rt.getResult());
+ Mockito.verify(mLockHandle).getLockInfo("keyspace", "table", "lockName", "1");
+ /*TODO: if we successfully acquire the lock we hit an error by trying to read MusicDatastoreHandle */
+ }
+
+ @Test
+ public void testWhoseTurnIsIt() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ Mockito.when(mLockHandle.peekLockQueue("keyspace", "table", "lockName"))
+ .thenReturn(mLockHandle.new LockObject(true, "1", "", "", LockType.WRITE, null));
+
+ String topOfQ = core.whoseTurnIsIt(fullyQualifiedKey);
+ System.out.println(topOfQ);
+
+ assertEquals("$"+fullyQualifiedKey+"$1", topOfQ);
+ }
+
+ @Test
+ public void testGetCurrentLockHolders() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ List<String> currentHolders = new ArrayList<>();
+ currentHolders.add("$"+fullyQualifiedKey+"$1");
+ currentHolders.add("$"+fullyQualifiedKey+"$2");
+ Mockito.when(mLockHandle.getCurrentLockHolders("keyspace", "table", "lockName"))
+ .thenReturn(currentHolders);
+
+ List<String> holders = core.getCurrentLockHolders(fullyQualifiedKey);
+
+ assertTrue(currentHolders.containsAll(holders) && holders.containsAll(currentHolders));
+ }
+
+ @Test
+ public void testGetLockNameFromId() {
+ String lockId = "$keyspace.table.lockName$1";
+ assertEquals("keyspace.table.lockName", core.getLockNameFromId(lockId));
+ }
+
+ @Test
+ public void testDestroyLockRefString() throws Exception {
+ String lockId = "$keyspace.table.lockName$1";
+
+ core.destroyLockRef(lockId);
+ Mockito.verify(mLockHandle).deQueueLockRef("keyspace", "table", "lockName", "1", MusicUtil.getRetryCount());
+ }
+
+ @Test
+ public void testDestroyLockRefStringString() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ String lockReference = "1";
+
+ core.destroyLockRef(fullyQualifiedKey, lockReference);
+ Mockito.verify(mLockHandle).deQueueLockRef("keyspace", "table", "lockName", "1", MusicUtil.getRetryCount());
+ }
+
+ @Test
+ public void testReleaseLock() throws Exception {
+ String lockId = "$keyspace.table.lockName$1";
+
+ core.releaseLock(lockId, true);
+
+ Mockito.verify(mLockHandle).deQueueLockRef("keyspace", "table", "lockName", "1", MusicUtil.getRetryCount());
+ }
+
+ @Test
+ public void testVoluntaryReleaseLock() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ String lockReference = "1";
+
+ core.voluntaryReleaseLock(fullyQualifiedKey, lockReference);
+
+ Mockito.verify(mLockHandle).deQueueLockRef("keyspace", "table", "lockName", "1", MusicUtil.getRetryCount());
+ }
+
+ @Test
+ public void testReleaseAllLocksForOwner() throws Exception {
+ List<String> ownersLocks = new ArrayList<>();
+ ownersLocks.add("lockName$1");
+ ownersLocks.add("lockName$2");
+ Mockito.when(mLockHandle.getAllLocksForOwner("ownerId", "keyspace", "table"))
+ .thenReturn(ownersLocks);
+
+ List<String> locksReleased = core.releaseAllLocksForOwner("ownerId", "keyspace", "table");
+
+ Mockito.verify(mLockHandle).deQueueLockRef("keyspace", "table", "lockName", "1", MusicUtil.getRetryCount());
+ Mockito.verify(mLockHandle).deQueueLockRef("keyspace", "table", "lockName", "2", MusicUtil.getRetryCount());
+ assertTrue(ownersLocks.containsAll(locksReleased) && locksReleased.containsAll(ownersLocks));
+ }
+
+
+ @Test
+ public void testValidateLock() {
+ String lockId = "$keyspace.table.lockName$1";
+
+ assertFalse(core.validateLock(lockId).containsKey("Error"));
+ }
+
+ @Test
+ public void testGetLockQueue() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ List<String> myList = new ArrayList<>();
+ Mockito.when(mLockHandle.getLockQueue("keyspace", "table", "lockName"))
+ .thenReturn(myList);
+ List<String> theirList = core.getLockQueue(fullyQualifiedKey);
+
+ assertEquals(myList, theirList);
+ }
+
+ @Test
+ public void testGetLockQueueSize() throws Exception {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ Mockito.when(mLockHandle.getLockQueueSize("keyspace", "table", "lockName"))
+ .thenReturn((long) 23);
+ long theirSize = core.getLockQueueSize(fullyQualifiedKey);
+
+ assertEquals(23, theirSize);
+ }
+
+ @Test
+ public void testCreateTable() throws MusicServiceException, MusicQueryException {
+ String keyspaceName = "keyspace";
+ String tableName = "table";
+ JsonTable table = new JsonTable();
+ table.setTableName(tableName);
+ table.setKeyspaceName(keyspaceName);
+ Map<String, String> fields = new HashMap<>();
+ fields.put("employee", "text");
+ fields.put("salary", "int");
+ table.setFields(fields);
+ table.setPrimaryKey("employee");
+
+ Mockito.when(mLockHandle.createLockQueue(Mockito.matches(keyspaceName), Mockito.matches(tableName)))
+ .thenReturn(true);
+ Mockito.when(dsHandle.executePut(Mockito.any(PreparedQueryObject.class), Mockito.matches("eventual"))).thenReturn(true);
+ ResultType rs = core.createTable(table , "eventual");
+
+ assertEquals(ResultType.SUCCESS, rs);
+ }
+
+ @Test
+ public void testDropTable() throws MusicServiceException, MusicQueryException {
+ String keyspaceName = "keyspace";
+ String tableName = "table";
+ JsonTable table = new JsonTable();
+ table.setTableName(tableName);
+ table.setKeyspaceName(keyspaceName);
+
+ ArgumentCaptor<PreparedQueryObject> queryCaptor = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ Mockito.when(dsHandle.executePut(queryCaptor.capture(), Mockito.matches("eventual"))).thenReturn(true);
+
+ ResultType rs = core.dropTable(table, "eventual");
+ assertEquals(ResultType.SUCCESS, rs);
+ assertEquals("DROP TABLE keyspace.table;", queryCaptor.getValue().getQuery());
+ }
+
+ @Test
+ public void testQuorumGet() throws MusicServiceException, MusicQueryException {
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM EMPLOYEES;");
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Mockito.when(dsHandle.executeQuorumConsistencyGet(Mockito.same(query))).thenReturn(rs);
+ ResultSet returnedRs = core.quorumGet(query);
+
+ assertEquals(rs, returnedRs);
+ }
+
+ @Test
+ public void testForciblyReleaseLock() throws MusicServiceException, MusicQueryException, MusicLockingException {
+ String fullyQualifiedKey = "keyspace.table.lockName";
+ ArgumentCaptor<PreparedQueryObject> unsyncedQuery = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ Mockito.doReturn(true).when(dsHandle).executePut(unsyncedQuery.capture(), Mockito.matches("critical"));
+ core.forciblyReleaseLock(fullyQualifiedKey, "123");
+
+ assertEquals("insert into keyspace.unsyncedKeys_table (key) values (?);",unsyncedQuery.getValue().getQuery());
+ }
+
+ @Test
+ public void testEventualPut() throws MusicServiceException, MusicQueryException {
+ PreparedQueryObject query = new PreparedQueryObject("INSERT INTO EMPLOYEES VALUES ('John', 1);");
+ Mockito.when(dsHandle.executePut(Mockito.same(query), Mockito.matches("eventual"))).thenReturn(true);
+
+ assertEquals(ResultType.SUCCESS, core.eventualPut(query).getResult());
+ }
+
+ @Test
+ public void testEventualPutNB() throws MusicServiceException, MusicQueryException {
+ String keyspace = "keyspace";
+ String table = "EMPLOYEES";
+ String primaryKey = "NAME";
+ PreparedQueryObject query = new PreparedQueryObject("INSERT INTO EMPLOYEES VALUES ('John', 1);");
+
+ ArgumentCaptor<PreparedQueryObject> queryCapture = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Row row = Mockito.mock(Row.class);
+ Mockito.when(dsHandle.executeQuorumConsistencyGet(queryCapture.capture())).thenReturn(rs);
+ Mockito.when(rs.one()).thenReturn(row);
+
+ Mockito.when(dsHandle.executePut(queryCapture.capture(), Mockito.matches("eventual"))).thenReturn(true);
+
+ ReturnType rt = core.eventualPut_nb(query, keyspace, table, primaryKey);
+
+ assertEquals("SELECT guard FROM keyspace.lockq_EMPLOYEES WHERE key = ? ;",
+ queryCapture.getAllValues().get(0).getQuery());
+ assertEquals("INSERT INTO EMPLOYEES VALUES ('John', 1);", queryCapture.getAllValues().get(1).getQuery());
+
+ assertEquals(ResultType.SUCCESS, rt.getResult());
+ }
+
+ @Test
+ public void testCriticalPut() throws MusicServiceException, MusicQueryException {
+ String keyspace = "keyspace";
+ String table = "table";
+ String primaryKey = "lockName";
+ PreparedQueryObject query = new PreparedQueryObject("INSERT INTO TABLE VALUES ('John', 1);");
+ String lockId = "$keyspace.table.lockName$1";
+
+ Mockito.when(mLockHandle.getLockInfo("keyspace", "table", "lockName", "1"))
+ .thenReturn(mLockHandle.new LockObject(true, lockId, null, null, LockType.WRITE, null));
+
+ ArgumentCaptor<PreparedQueryObject> queryCapture = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ Mockito.when(dsHandle.executePut(queryCapture.capture(), Mockito.matches("critical"))).thenReturn(true);
+ ReturnType rt = core.criticalPut(keyspace, table, primaryKey, query, lockId, null);
+
+ assertEquals(true, queryCapture.getValue().getQuery()
+ .startsWith("INSERT INTO TABLE VALUES ('John', 1) USING TIMESTAMP"));
+ assertEquals(ResultType.SUCCESS, rt.getResult());
+ }
+
+ @Test
+ public void testNonKeyRelatedPut() throws MusicServiceException, MusicQueryException {
+ PreparedQueryObject query = new PreparedQueryObject("INSERT INTO TABLE VALUES ('John', 1);");
+ String consistency = "eventual";
+ ArgumentCaptor<PreparedQueryObject> queryCapture = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ Mockito.when(dsHandle.executePut(queryCapture.capture(), Mockito.matches(consistency))).thenReturn(true);
+
+ core.nonKeyRelatedPut(query, consistency);
+
+ assertEquals(query.getQuery(), queryCapture.getValue().getQuery());
+ }
+
+ @Test
+ public void testGet() throws MusicServiceException, MusicQueryException {
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM EMPLOYEES;");
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Mockito.when(dsHandle.executeOneConsistencyGet(Mockito.same(query))).thenReturn(rs);
+ assertEquals(rs, core.get(query));
+ }
+
+ @Test
+ public void testCriticalGet() throws MusicServiceException, MusicQueryException {
+ String keyspace = "keyspace";
+ String table = "table";
+ String primaryKey = "lockName";
+ PreparedQueryObject query = new PreparedQueryObject("SELECT * FROM EMPLOYEES WHERE LOCKNAME='lockName';");
+ String lockId = "$keyspace.table.lockName$1";
+
+ Mockito.when(mLockHandle.getLockInfo("keyspace", "table", "lockName", "1"))
+ .thenReturn(mLockHandle.new LockObject(true, lockId, null, null, LockType.WRITE, null));
+
+ ArgumentCaptor<PreparedQueryObject> queryCapture = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ ResultSet rs = Mockito.mock(ResultSet.class);
+ Mockito.when(dsHandle.executeQuorumConsistencyGet(queryCapture.capture())).thenReturn(rs);
+ assertEquals(rs, core.criticalGet(keyspace, table, primaryKey, query, lockId));
+ }
+
+ @Test
+ public void testCreateKeyspace() throws MusicServiceException, MusicQueryException {
+ String keyspace = "cycling";
+ JsonKeySpace ks = new JsonKeySpace();
+ ks.setKeyspaceName(keyspace);
+ ks.setDurabilityOfWrites("true");
+
+ Map<String, Object> replicationInfo = new HashMap<>();
+ replicationInfo.put("class", "SimpleStrategy");
+ replicationInfo.put("replication_factor", 1);
+ ks.setReplicationInfo(replicationInfo);
+ Map<String, String> consistencyInfo = new HashMap<>();
+ consistencyInfo.put("consistency", "quorum");
+ ks.setConsistencyInfo(consistencyInfo);
+
+ ArgumentCaptor<PreparedQueryObject> queryCapture = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ Mockito.when(dsHandle.executePut(queryCapture.capture(), Mockito.matches("eventual"))).thenReturn(true);
+
+ core.createKeyspace(ks , "eventual");
+
+ assertEquals("CREATE KEYSPACE cycling WITH replication = {'replication_factor':1,'class':'SimpleStrategy'} AND durable_writes = true;",
+ queryCapture.getValue().getQuery());
+ }
+
+ @Test
+ public void testDropKeyspace() throws MusicServiceException, MusicQueryException {
+ String keyspace = "cycling";
+ JsonKeySpace ks = new JsonKeySpace();
+ ks.setKeyspaceName(keyspace);
+
+ ArgumentCaptor<PreparedQueryObject> queryCapture = ArgumentCaptor.forClass(PreparedQueryObject.class);
+ Mockito.when(dsHandle.executePut(queryCapture.capture(), Mockito.matches("eventual"))).thenReturn(true);
+
+ core.dropKeyspace(ks , "eventual");
+
+ assertEquals("DROP KEYSPACE cycling;", queryCapture.getValue().getQuery());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/unittests/jsonobjects/JSONObjectTest.java b/music-core/src/test/java/org/onap/music/unittests/jsonobjects/JSONObjectTest.java
new file mode 100644
index 00000000..7f6af4c5
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/unittests/jsonobjects/JSONObjectTest.java
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 IBM.
+ * ===================================================================
+ * 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.unittests.jsonobjects;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.onap.music.datastore.jsonobjects.JSONObject;
+
+public class JSONObjectTest {
+ private JSONObject jsonObject;
+
+ @Before
+ public void setUp() {
+ jsonObject = new JSONObject();
+ }
+
+ @Test
+ public void testGetSetData() {
+ jsonObject.setData("data");
+ Assert.assertEquals("data", jsonObject.getData());
+ }
+}
diff --git a/music-core/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java b/music-core/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java
new file mode 100644
index 00000000..b7dfa075
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/unittests/jsonobjects/JsonLeasedLockTest.java
@@ -0,0 +1,47 @@
+/*
+ * ============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.unittests.jsonobjects;
+
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.music.datastore.jsonobjects.JsonLeasedLock;
+
+public class JsonLeasedLockTest {
+
+ JsonLeasedLock jl = null;
+
+ @Before
+ public void init() {
+ jl = new JsonLeasedLock();
+ }
+
+
+ @Test
+ public void testGetLeasePeriod() {
+ long lease = 20000;
+ jl.setLeasePeriod(lease);
+ assertEquals(lease,jl.getLeasePeriod());
+ }
+
+}
diff --git a/music-core/src/test/java/org/onap/music/unittests/jsonobjects/MusicHealthCheckTest.java b/music-core/src/test/java/org/onap/music/unittests/jsonobjects/MusicHealthCheckTest.java
new file mode 100644
index 00000000..ceda3f3a
--- /dev/null
+++ b/music-core/src/test/java/org/onap/music/unittests/jsonobjects/MusicHealthCheckTest.java
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * 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.
+ * 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.unittests.jsonobjects;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.music.eelf.healthcheck.MusicHealthCheck;
+
+public class MusicHealthCheckTest {
+
+ private MusicHealthCheck musicHealthCheck;
+
+ @Before
+ public void setUp()
+ {
+ musicHealthCheck= new MusicHealthCheck();
+ }
+
+ @Test
+ public void testCassandraHost()
+ {
+ musicHealthCheck.setCassandrHost("9042");
+ assertEquals("9042", musicHealthCheck.getCassandrHost());
+ }
+
+}
diff --git a/music-core/src/test/resources/LICENSE.txt b/music-core/src/test/resources/LICENSE.txt
new file mode 100644
index 00000000..cc6cdea5
--- /dev/null
+++ b/music-core/src/test/resources/LICENSE.txt
@@ -0,0 +1,24 @@
+
+The following license applies to all files in this and sub-directories. Licenses
+are included in individual source files where appropriate, and if it differs
+from this text, it supersedes this. Any file that does not have license text
+defaults to being covered by this text; not all files support the addition of
+licenses.
+#
+# -------------------------------------------------------------------------
+# 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.
+#
+# -------------------------------------------------------------------------
+# \ No newline at end of file
diff --git a/music-core/src/test/resources/Resources.properties b/music-core/src/test/resources/Resources.properties
new file mode 100644
index 00000000..72269cb8
--- /dev/null
+++ b/music-core/src/test/resources/Resources.properties
@@ -0,0 +1,50 @@
+#============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=============================================
+#====================================================================
+#Resource key=Error Code|Message text|Resolution text |Description text
+LOADING_DEFAULT_LOG_CONFIGURATION=\
+ EELF0001I|\
+ Loading default logging configuration from system resource file "{0}"|\
+ No external logging configurations were defined or found, So verify the default logging configuration from system resource file (../logback.xml). |\
+ Loading default logging configuration from system resource file
+LOADING_LOG_CONFIGURATION=EELF0002I|\
+ Loading logging configuration from file "{0}"|\
+ Verify the correct logging configuration file is loaded. |\
+ Loading logging configuration for specific file
+LOGGING_ALREADY_INITIALIZED=\
+ EELF0003W|\
+ Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.|\
+ Verify the container logging definitions to ensure they represent your desired logging configuration. |\
+ Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.
+NO_LOG_CONFIGURATION=\
+ EELF0004E|\
+ No log configuration could be found or defaulted!|\
+ No external and default logging configuration file. |\
+ No log configuration could be found or defaulted!
+SEARCHING_LOG_CONFIGURATION=\
+ EELF0005I|\
+ Searching path "{0}" for log configuration file "{1}"|\
+ Verify the correct Path({user.home};etc;../etc) and filename (eelf.logging.file).|\
+ Searching path for specific log configuration file.
+UNSUPPORTED_LOGGING_FRAMEWORK=\
+ EELF0006E|\
+ An unsupported logging framework is bound to SLF4J. |\
+ Verify your logging frameworks.|\
+ An unsupported logging framework is bound to SLF4J.
+
diff --git a/music-core/src/test/resources/application.properties b/music-core/src/test/resources/application.properties
new file mode 100644
index 00000000..02e9c1a9
--- /dev/null
+++ b/music-core/src/test/resources/application.properties
@@ -0,0 +1,2 @@
+server.port=8080
+server.servlet.context-path=/MUSIC/rest \ No newline at end of file
diff --git a/music-core/src/test/resources/cache.ccf b/music-core/src/test/resources/cache.ccf
new file mode 100644
index 00000000..e152ee8b
--- /dev/null
+++ b/music-core/src/test/resources/cache.ccf
@@ -0,0 +1,62 @@
+# DEFAULT CACHE REGION
+jcs.default=DC
+jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.default.cacheattributes.MaxObjects=1000
+jcs.default.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.default.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.default.elementattributes.IsEternal=true
+jcs.default.elementattributes.IsSpool=true
+
+# PRE-DEFINED CACHE REGIONS
+jcs.region.musicCache=
+jcs.region.musicCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.region.musicCache.cacheattributes.MaxObjects=1000
+jcs.region.musicCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.musicCache.cacheattributes.UseMemoryShrinker=false
+jcs.region.musicCache.cacheattributes.MaxMemoryIdleTime=3600
+jcs.region.musicCache.cacheattributes.ShrinkerInterval=60
+jcs.region.musicCache.cacheattributes.MaxSpoolPerRun=500
+jcs.region.musicCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.region.musicCache.elementattributes.IsEternal=false
+
+
+# PRE-DEFINED CACHE REGIONS
+jcs.region.aafCache=
+jcs.region.aafCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.region.aafCache.cacheattributes.MaxObjects=1000
+jcs.region.aafCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.aafCache.cacheattributes.UseMemoryShrinker=false
+jcs.region.aafCache.cacheattributes.MaxMemoryIdleTime=3600
+jcs.region.aafCache.cacheattributes.ShrinkerInterval=60
+jcs.region.aafCache.cacheattributes.MaxSpoolPerRun=500
+jcs.region.aafCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.region.aafCache.elementattributes.IsEternal=false
+
+# PRE-DEFINED CACHE REGIONS
+jcs.region.appNameCache=
+jcs.region.appNameCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.region.appNameCache.cacheattributes.MaxObjects=1000
+jcs.region.appNameCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.appNameCache.cacheattributes.UseMemoryShrinker=false
+jcs.region.appNameCache.cacheattributes.MaxMemoryIdleTime=3600
+jcs.region.appNameCache.cacheattributes.ShrinkerInterval=60
+jcs.region.appNameCache.cacheattributes.MaxSpoolPerRun=500
+jcs.region.appNameCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.region.appNameCache.elementattributes.IsEternal=false
+
+jcs.default=DC
+jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.default.cacheattributes.MaxObjects=1000
+jcs.default.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.default.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.default.elementattributes.IsEternal=true
+jcs.default.elementattributes.IsSpool=true
+
+jcs.region.eternalCache=DC
+jcs.region.eternalCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.region.eternalCache.cacheattributes.MaxObjects=1000
+jcs.region.eternalCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.eternalCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.region.eternalCache.elementattributes.IsEternal=true
+jcs.region.eternalCache.elementattributes.IsSpool=true
+
diff --git a/music-core/src/test/resources/logback.xml b/music-core/src/test/resources/logback.xml
new file mode 100644
index 00000000..6bc5fd5e
--- /dev/null
+++ b/music-core/src/test/resources/logback.xml
@@ -0,0 +1,302 @@
+<!--
+ ============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">
+ <!-- <encoder>
+ <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">
+ <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">
+ <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">
+ <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
+ 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
+ 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>
+
+
+ <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">
+ <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"/>
+
+</configuration>
diff --git a/music-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/music-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 00000000..1f0955d4
--- /dev/null
+++ b/music-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline
diff --git a/music-core/src/test/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider b/music-core/src/test/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider
new file mode 100644
index 00000000..bc2f0992
--- /dev/null
+++ b/music-core/src/test/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider
@@ -0,0 +1 @@
+org.mockito.internal.exceptions.stacktrace.DefaultStackTraceCleanerProvider
diff --git a/music-core/src/test/resources/project.properties b/music-core/src/test/resources/project.properties
new file mode 100644
index 00000000..199afa33
--- /dev/null
+++ b/music-core/src/test/resources/project.properties
@@ -0,0 +1,4 @@
+version=${project.version}
+artifactId=${project.artifactId}
+music.properties=/opt/app/music/etc/music.properties
+