aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdbc-benchmark/pom.xml406
-rw-r--r--mdbc-benchmark/src/main/java/org/onap/music/mdbc/BenchmarkUtils.java245
-rw-r--r--mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricBenchmark.java217
-rw-r--r--mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java141
-rw-r--r--mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricStatementBenchmark.java144
-rwxr-xr-xmdbc-benchmark/src/main/resources/logback.xml2
-rw-r--r--mdbc-internal-benchmark/pom.xml193
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricAddTxDigestBenchmark.java143
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java137
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricIsolatedMixinCommBenchmark.java151
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricOwnBenchmark.java142
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricPeekLockBenchmark.java151
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricRedoLogBenchmark.java130
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricThreadJoinBenchmark.java197
-rw-r--r--mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/OwnUtils.java383
-rwxr-xr-xmdbc-internal-benchmark/src/main/resources/logback.xml369
-rwxr-xr-xmdbc-internal-benchmark/src/main/resources/mdbc.properties13
-rwxr-xr-xmdbc-internal-benchmark/src/main/resources/music.properties8
-rwxr-xr-xmdbc-server/pom.xml93
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java25
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/MdbcServer.java2
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/MdbcServerLogic.java1
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/Range.java6
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/StateManager.java33
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/configurations/ClusterConfiguration.java88
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/configurations/NodeConfiguration.java3
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/configurations/TablesConfiguration.java69
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/examples/MdbcTestClient.java7
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/mixins/DBInterface.java3
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicInterface.java41
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicMixin.java513
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java38
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpoint.java33
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigest.java176
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestDaemon.java144
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestId.java12
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java12
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java120
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/tools/ClusterSetup.java80
-rwxr-xr-xmdbc-server/src/main/resources/music.properties2
-rw-r--r--mdbc-server/src/test/java/org/onap/music/mdbc/MusicTxDigestTest.java2
-rwxr-xr-xmdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java63
-rw-r--r--mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java15
-rw-r--r--mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java10
-rw-r--r--mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java2
-rwxr-xr-xpom.xml6
46 files changed, 3698 insertions, 1073 deletions
diff --git a/mdbc-benchmark/pom.xml b/mdbc-benchmark/pom.xml
index 84b7e56..a12e4a2 100644
--- a/mdbc-benchmark/pom.xml
+++ b/mdbc-benchmark/pom.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2014, Oracle America, Inc.
All rights reserved.
@@ -30,72 +29,171 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>mdbc</artifactId>
- <groupId>org.onap.music.mdbc</groupId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>mdbc</artifactId>
+ <groupId>org.onap.music.mdbc</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
- <artifactId>benchmark</artifactId>
- <packaging>jar</packaging>
+ <artifactId>mdbc-benchmark</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <name>mdbc-benchmark</name>
+ <description>MDBC Benchmark</description>
+ <packaging>jar</packaging>
- <name>JMH benchmark sample: Java</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20160810</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-core</artifactId>
+ <version>${jmh.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-generator-annprocess</artifactId>
+ <version>${jmh.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica-server</artifactId>
+ <version>1.12.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.8.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ <version>1.1.7</version>
+ </dependency>
+ <dependency>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ <version>9.1-901-1.jdbc4</version>
+ </dependency>
+ <dependency>
+ <groupId>com.datastax.cassandra</groupId>
+ <artifactId>cassandra-driver-core</artifactId>
+ <version>3.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>19.0</version>
+ </dependency>
+ <dependency>
+ <!-- The oparent dependency managed version 9.4.12.v20180830 will not work -->
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ <version>9.2.19.v20160908</version>
+ </dependency>
+ <dependency>
+ <!-- The oparent dependency managed version 9.4.12.v20180830 will not work -->
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>9.2.19.v20160908</version>
+ </dependency>
+ <dependency>
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ <version>9.2.19.v20160908</version>
+ </dependency>
+ <dependency>
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ <version>9.2.19.v20160908</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.7</version>
+ </dependency>
+ <!-- These two dependencies pull in optional libraries for Cassandra -->
+ <dependency>
+ <groupId>net.jpountz.lz4</groupId>
+ <artifactId>lz4</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.xerial.snappy</groupId>
+ <artifactId>snappy-java</artifactId>
+ <version>1.1.2.6</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.jsqlparser</groupId>
+ <artifactId>jsqlparser</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <version>1.2.3</version>
+ </dependency>
- <!--
- This is the demo/sample template build script for building Java benchmarks with JMH.
- Edit as needed.
- -->
+ <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- https://mvnrepository.com/artifact/org.apache.calcite.avatica/avatica-server -->
+ <dependency>
+ <groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica-server</artifactId>
+ <version>1.12.0</version>
+ </dependency>
+ <!-- https://mvnrepository.com/artifact/org.apache.calcite/calcite-plus -->
+ <dependency>
+ <groupId>org.apache.calcite</groupId>
+ <artifactId>calcite-plus</artifactId>
+ <version>1.12.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.beust</groupId>
+ <artifactId>jcommander</artifactId>
+ <version>1.72</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.8.5</version>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-handler</artifactId>
+ <version>4.1.30.Final</version>
+ </dependency>
+ <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>3.6.1</version>
+ </dependency>
+ </dependencies>
- <dependencies>
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <version>20160810</version>
- </dependency>
- <dependency>
- <groupId>org.openjdk.jmh</groupId>
- <artifactId>jmh-core</artifactId>
- <version>${jmh.version}</version>
- </dependency>
- <dependency>
- <groupId>org.openjdk.jmh</groupId>
- <artifactId>jmh-generator-annprocess</artifactId>
- <version>${jmh.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.att.eelf</groupId>
- <artifactId>eelf-core</artifactId>
- <version>1.0.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.calcite.avatica</groupId>
- <artifactId>avatica-server</artifactId>
- <version>1.12.0</version>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>2.8.5</version>
- </dependency>
- <dependency>
- <groupId>org.mariadb.jdbc</groupId>
- <artifactId>mariadb-java-client</artifactId>
- <version>1.1.7</version>
- </dependency>
- <dependency>
- <groupId>postgresql</groupId>
- <artifactId>postgresql</artifactId>
- <version>9.1-901-1.jdbc4</version>
- </dependency>
- </dependencies>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
- <!--
+ <!--
JMH version to use with this project.
-->
<jmh.version>1.21</jmh.version>
@@ -108,98 +206,100 @@ THE POSSIBILITY OF SUCH DAMAGE.
<!--
Name of the benchmark Uber-JAR to generate.
-->
- <uberjar.name>benchmarks</uberjar.name>
+ <!--
+ Name of the benchmark Uber-JAR to generate.
+ -->
+ <uberjar.name>benchmarks</uberjar.name>
</properties>
<build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.1</version>
- <configuration>
- <compilerVersion>${javac.target}</compilerVersion>
- <source>${javac.target}</source>
- <target>${javac.target}</target>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.2</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <finalName>${uberjar.name}</finalName>
- <transformers>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.openjdk.jmh.Main</mainClass>
- </transformer>
- </transformers>
- <filters>
- <filter>
- <!--
- Shading signed JARs will fail without this.
- http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
- -->
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- </excludes>
- </filter>
- </filters>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- <pluginManagement>
- <plugins>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <version>2.5</version>
- </plugin>
- <plugin>
- <artifactId>maven-deploy-plugin</artifactId>
- <version>2.8.1</version>
- </plugin>
- <plugin>
- <artifactId>maven-install-plugin</artifactId>
- <version>2.5.1</version>
- </plugin>
- <plugin>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.4</version>
- </plugin>
- <plugin>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.9.1</version>
- </plugin>
- <plugin>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.6</version>
- </plugin>
- <plugin>
- <artifactId>maven-site-plugin</artifactId>
- <version>3.3</version>
- </plugin>
- <plugin>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.2.1</version>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.17</version>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <compilerVersion>${javac.target}</compilerVersion>
+ <source>${javac.target}</source>
+ <target>${javac.target}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <finalName>${uberjar.name}</finalName>
+ <transformers>
+ <transformer
+ implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.openjdk.jmh.Main</mainClass>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <!--
+ Shading signed JARs will fail without this.
+ http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
+ -->
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.5</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.17</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+</build>
</project>
diff --git a/mdbc-benchmark/src/main/java/org/onap/music/mdbc/BenchmarkUtils.java b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/BenchmarkUtils.java
new file mode 100644
index 0000000..06f2a95
--- /dev/null
+++ b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/BenchmarkUtils.java
@@ -0,0 +1,245 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+public class BenchmarkUtils {
+ public static final String driver = "org.apache.calcite.avatica.remote.Driver";
+ public static final String mariaDriver = "org.mariadb.jdbc.Driver";
+ public static final String postgresDriver = "org.postgresql.Driver";
+ public static String TABLE;
+ public static String updateBuilder;
+
+ public enum ExecutionType {
+ MARIA_DB, COCKROACH_DB, METRIC,POSTGRES
+ }
+
+ public static void SetupTable(String table){
+ TABLE=table;
+ updateBuilder = new StringBuilder()
+ .append("UPDATE ")
+ .append(table)
+ .append(" SET Counter = Counter + 1,")
+ .append("City = 'Sandy Springs'")
+ .append(";").toString();
+ }
+
+ public static void setupCreateTables(Connection connection){
+ createTable(connection);
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static void setupCreateRows(Connection testConnection, int rows){
+ //Empty database
+ boolean cleanResult = BenchmarkUtils.cleanTable(testConnection);
+ //Add new lines
+ BenchmarkUtils.addRowsToTable(Integer.valueOf(rows),testConnection);
+
+ //Commit
+ try {
+ testConnection.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static Connection getConnection(String ip, ExecutionType type, String user, String password) {
+ final String connectionUrl = "jdbc:avatica:remote:url=http://" + ip + ":30000;serialization=protobuf";
+ final String mariaConnectionUrl = "jdbc:mariadb://" + ip + ":3306/test";
+ final String cockroachUrl = "jdbc:postgresql://" + ip + ":26257/test";
+ final String postgresUrl = "jdbc:postgresql://" + ip + ":5432/test";
+
+ try {
+ switch (type) {
+ case MARIA_DB:
+ Class.forName(mariaDriver);
+ break;
+ case METRIC:
+ Class.forName(driver);
+ break;
+ case COCKROACH_DB:
+ case POSTGRES:
+ Class.forName(postgresDriver);
+ break;
+ }
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ Connection connection = null;
+ try {
+ if (type == ExecutionType.METRIC) {
+ connection = DriverManager.getConnection(connectionUrl);
+ } else {
+ Properties connectionProps = new Properties();
+ connectionProps.put("user", user);
+ if (type == ExecutionType.COCKROACH_DB) {
+ connectionProps.setProperty("sslmode", "disable");
+ } else {
+ connectionProps.put("password", password);
+ }
+ final String url = (type == ExecutionType.MARIA_DB) ? mariaConnectionUrl :
+ (type == ExecutionType.COCKROACH_DB)?cockroachUrl:postgresUrl;
+ connection = DriverManager.getConnection(url, connectionProps);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ connection.setAutoCommit(false);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return connection;
+ }
+
+ public static void createTable(Connection connection) {
+ final String sql = "CREATE TABLE IF NOT EXISTS "+TABLE+" (\n" +
+ " PersonID int,\n" +
+ " Counter int,\n" +
+ " LastName varchar(255),\n" +
+ " FirstName varchar(255),\n" +
+ " Address varchar(255),\n" +
+ " City varchar(255),\n" +
+ " PRIMARY KEY(PersonID)"+
+ ");";
+
+ Statement stmt = null;
+ try {
+ stmt = connection.createStatement();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ Boolean execute = null;
+ try {
+ execute = stmt.execute(sql);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ try {
+ connection.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static boolean cleanTable(Connection testConnection) {
+ String cleanCmd = "DELETE FROM "+TABLE+";";
+ Statement stmt = null;
+ try {
+ stmt = testConnection.createStatement();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ Boolean execute = null;
+ try {
+ execute = stmt.execute(cleanCmd);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ testConnection.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return execute;
+ }
+
+ public static void addRowsToTable(int totalNumberOfRows, Connection testConnection) {
+ for (int i = 0; i < totalNumberOfRows; i++) {
+ final StringBuilder insertSQLBuilder = new StringBuilder()
+ .append("INSERT INTO "+TABLE+" VALUES (")
+ .append(i)
+ .append(", ")
+ .append(0)
+ .append(", '")
+ .append("Last-")
+ .append(i)
+ .append("', '")
+ .append("First-")
+ .append(i)
+ .append("', 'KACB', 'ATLANTA');");
+ Statement stmt = null;
+ try {
+ stmt = testConnection.createStatement();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ Boolean execute = null;
+ try {
+ execute = stmt.execute(insertSQLBuilder.toString());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ try {
+ testConnection.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+
+}
diff --git a/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricBenchmark.java b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricBenchmark.java
index 1fb584c..19db6f4 100644
--- a/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricBenchmark.java
+++ b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricBenchmark.java
@@ -2,7 +2,7 @@
* ============LICENSE_START====================================================
* org.onap.music.mdbc
* =============================================================================
- * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
* =============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,40 +19,39 @@
*/
package org.onap.music.mdbc;
+import static org.onap.music.mdbc.BenchmarkUtils.setupCreateRows;
+import static org.onap.music.mdbc.BenchmarkUtils.setupCreateTables;
+
+import org.onap.music.mdbc.BenchmarkUtils.ExecutionType;
import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
-import java.util.Properties;
import java.util.concurrent.TimeUnit;
@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
public class MetricBenchmark {
- public StringBuilder updateBuilder = new StringBuilder()
- .append("UPDATE PERSONS ")
- .append("SET Counter = Counter + 1,")
- .append("City = 'Sandy Springs'")
- .append(";");
- public String update = updateBuilder.toString();
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(MetricBenchmark.class.getSimpleName())
.param("type", ExecutionType.METRIC.name())
+ .forks(0)
+ .threads(1)
.build();
new Runner(opt).run();
}
@Benchmark
- public boolean testMethod(MyState state) {
+ public boolean testMethod(MyState state, Blackhole blackhole) {
Statement stmt = null;
try {
stmt = state.testConnection.createStatement();
@@ -63,7 +62,7 @@ public class MetricBenchmark {
Boolean execute = null;
try {
- execute = stmt.execute(update);
+ execute = stmt.execute(state.update);
} catch (SQLException e) {
e.printStackTrace();
System.exit(1);
@@ -81,15 +80,14 @@ public class MetricBenchmark {
e.printStackTrace();
System.exit(1);
}
+ blackhole.consume(execute);
return execute;
}
- public static enum ExecutionType {
- MARIA_DB, COCKROACH_DB, METRIC
- }
@State(Scope.Benchmark)
public static class MyState {
+ public String update;
public final String driver = "org.apache.calcite.avatica.remote.Driver";
public final String mariaDriver = "org.mariadb.jdbc.Driver";
public final String cockroachDriver = "org.postgresql.Driver";
@@ -97,205 +95,34 @@ public class MetricBenchmark {
final String password = "metriccluster";
@Param({"104.209.240.219"})
public String ip;
+ @Param({"PERSONS"})
+ public String table;
@Param({"1", "10", "50", "80", "100", "200", "300", "400"})
public int rows;
- @Param({"MARIA_DB", "COCKROACH_DB", "METRIC"})
+ @Param({"MARIA_DB", "COCKROACH_DB", "METRIC", "POSTGRES"})
public ExecutionType type;
public Connection testConnection;
private Connection createConnection() {
- final String connectionUrl = "jdbc:avatica:remote:url=http://" + ip + ":30000;serialization=protobuf";
- final String mariaConnectionUrl = "jdbc:mariadb://" + ip + ":3306/test";
- final String cockroachUrl = "jdbc:postgresql://" + ip + ":26257/test";
-
- try {
- switch (type) {
- case MARIA_DB:
- Class.forName(this.mariaDriver);
- break;
- case METRIC:
- Class.forName(this.driver);
- break;
- case COCKROACH_DB:
- Class.forName(this.cockroachDriver);
- break;
- }
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- System.exit(1);
- }
- Connection connection = null;
- try {
- if (type == ExecutionType.METRIC) {
- connection = DriverManager.getConnection(connectionUrl);
- } else {
- Properties connectionProps = new Properties();
- connectionProps.put("user", user);
- if(type == ExecutionType.COCKROACH_DB){
- connectionProps.setProperty("sslmode", "disable");
- }
- else{
- connectionProps.put("password", password);
- }
- final String url = (type == ExecutionType.MARIA_DB) ? mariaConnectionUrl : cockroachUrl;
- connection = DriverManager.getConnection(url, connectionProps);
- }
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- try {
- connection.setAutoCommit(false);
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- return connection;
+ return BenchmarkUtils.getConnection(ip,type,user,password);
}
- private void createTable(Connection connection) {
- final String sql = "CREATE TABLE IF NOT EXISTS PERSONS (\n" +
- " PersonID int,\n" +
- " Counter int,\n" +
- " LastName varchar(255),\n" +
- " FirstName varchar(255),\n" +
- " Address varchar(255),\n" +
- " City varchar(255)\n" +
- ");";
-
- Statement stmt = null;
- try {
- stmt = connection.createStatement();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
-
- Boolean execute = null;
- try {
- execute = stmt.execute(sql);
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
-
- try {
- connection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
-
- try {
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- private boolean cleanTable() {
- String cleanCmd = "DELETE FROM PERSONS;";
- Statement stmt = null;
- try {
- stmt = testConnection.createStatement();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
-
- Boolean execute = null;
- try {
- execute = stmt.execute(cleanCmd);
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- try {
- testConnection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- try {
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- return execute;
- }
-
- private void addRowsToTable(int totalNumberOfRows) {
- for (int i = 0; i < totalNumberOfRows; i++) {
- final StringBuilder insertSQLBuilder = new StringBuilder()
- .append("INSERT INTO PERSONS VALUES (")
- .append(i)
- .append(", ")
- .append(0)
- .append(", '")
- .append("Last-")
- .append(i)
- .append("', '")
- .append("First-")
- .append(i)
- .append("', 'KACB', 'ATLANTA');");
- Statement stmt = null;
- try {
- stmt = testConnection.createStatement();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
-
- Boolean execute = null;
- try {
- execute = stmt.execute(insertSQLBuilder.toString());
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- try {
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
- try {
- testConnection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ BenchmarkUtils.SetupTable(table);
+ update = BenchmarkUtils.updateBuilder;
}
@Setup(Level.Iteration)
public void doSetup() {
Connection connection = createConnection();
- createTable(connection);
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
+ setupCreateTables(connection);
//Setup connection
testConnection = createConnection();
- //Empty database
- boolean cleanResult = cleanTable();
- //Add new lines
- addRowsToTable(Integer.valueOf(rows));
+ setupCreateRows(testConnection,rows);
- //Commit
- try {
- testConnection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- System.exit(1);
- }
}
@TearDown(Level.Iteration)
diff --git a/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java
new file mode 100644
index 0000000..803a162
--- /dev/null
+++ b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java
@@ -0,0 +1,141 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import static org.onap.music.mdbc.BenchmarkUtils.setupCreateRows;
+import static org.onap.music.mdbc.BenchmarkUtils.setupCreateTables;
+
+import org.onap.music.mdbc.BenchmarkUtils.ExecutionType;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricCommitBenchmark {
+
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricBenchmark.class.getSimpleName())
+ .param("type", ExecutionType.METRIC.name())
+ .forks(1)
+ .threads(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public void testMethod(MyState state) {
+ try {
+ state.testConnection.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+
+ String update;
+ final String user = "root";
+ final String password = "metriccluster";
+ @Param({"104.209.240.219"})
+ public String ip;
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ @Param({"MARIA_DB", "COCKROACH_DB", "METRIC","POSTGRES"})
+ public ExecutionType type;
+ @Param({"PERSONS"})
+ public String table;
+
+ public Connection testConnection;
+
+ public Statement stmt;
+
+ private Connection createConnection() {
+ return BenchmarkUtils.getConnection(ip,type,user,password);
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ BenchmarkUtils.SetupTable(table);
+ update=BenchmarkUtils.updateBuilder;
+ }
+
+ @Setup(Level.Invocation)
+ public void doInvocationSetup(){
+ try {
+ stmt = testConnection.createStatement();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ Boolean execute = null;
+ try {
+ execute = stmt.execute(update);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @TearDown(Level.Invocation)
+ public void doInvocationTearDown(){
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @Setup(Level.Iteration)
+ public void doSetup() {
+ Connection connection = createConnection();
+ setupCreateTables(connection);
+ //Setup connection
+ testConnection = createConnection();
+ setupCreateRows(testConnection,rows);
+ }
+
+ @TearDown(Level.Iteration)
+ public void doTearDown() {
+ System.out.println("Do TearDown");
+ try {
+ testConnection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+}
diff --git a/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricStatementBenchmark.java b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricStatementBenchmark.java
new file mode 100644
index 0000000..7dc950a
--- /dev/null
+++ b/mdbc-benchmark/src/main/java/org/onap/music/mdbc/MetricStatementBenchmark.java
@@ -0,0 +1,144 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import static org.onap.music.mdbc.BenchmarkUtils.setupCreateRows;
+import static org.onap.music.mdbc.BenchmarkUtils.setupCreateTables;
+
+import org.onap.music.mdbc.BenchmarkUtils.ExecutionType;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricStatementBenchmark {
+
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricBenchmark.class.getSimpleName())
+ .param("type", ExecutionType.METRIC.name())
+ .forks(1)
+ .threads(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public boolean testMethod(MyState state, Blackhole blackhole) {
+ Boolean execute = null;
+ try {
+ execute = state.stmt.execute(state.update);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ blackhole.consume(execute);
+ return execute;
+ }
+
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+
+ public String update;
+ final String user = "root";
+ final String password = "metriccluster";
+ @Param({"104.209.240.219"})
+ public String ip;
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ @Param({"MARIA_DB", "COCKROACH_DB", "METRIC","POSTGRES"})
+ public ExecutionType type;
+ @Param({"PERSONS"})
+ public String table;
+
+ public Connection testConnection;
+
+ public Statement stmt;
+
+ private Connection createConnection() {
+ return BenchmarkUtils.getConnection(ip,type,user,password);
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ BenchmarkUtils.SetupTable(table);
+ update=BenchmarkUtils.updateBuilder;
+ }
+
+ @Setup(Level.Invocation)
+ public void doInvocationSetup(){
+ try {
+ stmt = testConnection.createStatement();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @TearDown(Level.Invocation)
+ public void doInvocationTearDown(){
+ try {
+ //TODO: check if state need to be consumed by blackhole to guarantee execution
+ testConnection.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @Setup(Level.Iteration)
+ public void doSetup() {
+ Connection connection = createConnection();
+ setupCreateTables(connection);
+ //Setup connection
+ testConnection = createConnection();
+ setupCreateRows(testConnection,rows);
+ }
+
+ @TearDown(Level.Iteration)
+ public void doTearDown() {
+ System.out.println("Do TearDown");
+ try {
+ testConnection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+}
diff --git a/mdbc-benchmark/src/main/resources/logback.xml b/mdbc-benchmark/src/main/resources/logback.xml
index e4d0030..4215681 100755
--- a/mdbc-benchmark/src/main/resources/logback.xml
+++ b/mdbc-benchmark/src/main/resources/logback.xml
@@ -37,7 +37,7 @@
-->
-<configuration scan="true" scanPeriod="3 seconds" debug="true">
+<configuration scan="false" scanPeriod="3 seconds" debug="true">
<!--
Logback files for the mdbc Driver "mdbc"
are created in directory ${catalina.base}/logs/mdbc;
diff --git a/mdbc-internal-benchmark/pom.xml b/mdbc-internal-benchmark/pom.xml
new file mode 100644
index 0000000..b356638
--- /dev/null
+++ b/mdbc-internal-benchmark/pom.xml
@@ -0,0 +1,193 @@
+<!--
+Copyright (c) 2014, Oracle America, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of Oracle nor the names of its contributors may be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<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">
+ <parent>
+ <artifactId>mdbc</artifactId>
+ <groupId>org.onap.music.mdbc</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>mdbc-own-benchmark</artifactId>
+ <packaging>jar</packaging>
+
+ <name>JMH benchmark sample: Java</name>
+
+ <!--
+ This is the demo/sample template build script for building Java benchmarks with JMH.
+ Edit as needed.
+ -->
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-core</artifactId>
+ <version>${jmh.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-generator-annprocess</artifactId>
+ <version>${jmh.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ <version>1.1.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.music.mdbc</groupId>
+ <artifactId>mdbc-server</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.music</groupId>
+ <artifactId>dev-MUSIC-cassandra</artifactId>
+ <version>3.2.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.datastax.cassandra</groupId>
+ <artifactId>cassandra-driver-core</artifactId>
+ <version>3.3.0</version>
+ </dependency>
+ </dependencies>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <jmh.version>1.9.3</jmh.version>
+ <javac.target>1.6</javac.target>
+ <uberjar.name>benchmarks</uberjar.name>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <compilerVersion>${javac.target}</compilerVersion>
+ <source>7</source>
+ <target>7</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <finalName>${uberjar.name}</finalName>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.openjdk.jmh.Main</mainClass>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <!--
+ Shading signed JARs will fail without this.
+ http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
+ -->
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.5</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.17</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricAddTxDigestBenchmark.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricAddTxDigestBenchmark.java
new file mode 100644
index 0000000..d15c3e6
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricAddTxDigestBenchmark.java
@@ -0,0 +1,143 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.onap.music.mdbc.tables.MusicTxDigestId;
+import org.onap.music.mdbc.tables.StagingTable;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricAddTxDigestBenchmark {
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricAddTxDigestBenchmark.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public void testMethod(MyState state, Blackhole blackhole) {
+ OwnUtils.addTransactionDigest(state.copy, state.copyTxDigestId,
+ (MusicMixin) state.getManager().getMusicInterface());
+ }
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+ public MusicTxDigestId musicTxDigestId,copyTxDigestId;
+ public StagingTable copy,current;
+ final String user = OwnUtils.SQL_USER;
+ final String password = OwnUtils.SQL_PASSWORD;
+ public final Range range = new Range(OwnUtils.TABLE);
+ @Param({"127.0.0.1"})
+ public String ip;
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ private MusicInterface musicMixin = null;
+ private MdbcConnection conn;
+ private DBInterface dbMixin;
+ private MdbcServerLogic meta;
+ private String id;
+
+ private void setupServer(){
+ meta = OwnUtils.setupServer(user, password);
+ }
+
+ private StateManager getManager(){
+ return meta.getStateManager();
+ }
+
+ private void assignManager() {
+ StateManager manager = getManager();
+ musicMixin=manager.getMusicInterface();
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ OwnUtils.dropAll(ip);
+ setupServer();
+ assignManager();
+ OwnUtils.initMri((MusicMixin) musicMixin,range,meta, rows,1,1);
+ id = UUID.randomUUID().toString();
+ conn = (MdbcConnection) getManager().getConnection(id);
+ try {
+ Statement stmt = conn.createStatement();
+ stmt.execute(OwnUtils.UPDATE);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ musicTxDigestId = OwnUtils.setupCommit(conn.getPartition(), conn.getTransactionDigest());
+ final DatabasePartition partition = conn.getPartition();
+ OwnUtils.appendToRedo((MusicMixin)getManager().getMusicInterface(),partition.getMRIIndex(),partition.getLockId(),
+ musicTxDigestId);
+ current=conn.getTransactionDigest();
+ }
+
+ @TearDown(Level.Trial)
+ public void doTrialTearDown(){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ meta=null;
+ }
+
+ @Setup(Level.Invocation)
+ public void doInvocationSetup(){
+ try {
+ copy = new StagingTable(current);
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ copyTxDigestId = new MusicTxDigestId(MDBCUtils.generateUniqueKey(), -1);
+ }
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java
new file mode 100644
index 0000000..7461457
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricCommitBenchmark.java
@@ -0,0 +1,137 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricCommitBenchmark {
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricCommitBenchmark.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public void testMethod(MyState state, Blackhole blackhole) {
+ try {
+ state.conn.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+ final String user = OwnUtils.SQL_USER;
+ final String password = OwnUtils.SQL_PASSWORD;
+ public final Range range = new Range(OwnUtils.TABLE);
+ @Param({"104.209.240.219"})
+ public String ip;
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ private MusicInterface musicMixin = null;
+ private MdbcConnection conn;
+ private DBInterface dbMixin;
+ private MdbcServerLogic meta;
+ private String id;
+
+ private void setupServer(){
+ meta = OwnUtils.setupServer(user, password);
+ }
+
+ private StateManager getManager(){
+ return meta.getStateManager();
+ }
+
+ private void assignManager() {
+ StateManager manager = getManager();
+ musicMixin=manager.getMusicInterface();
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ OwnUtils.dropAll(ip);
+ setupServer();
+ assignManager();
+ OwnUtils.initMri((MusicMixin) musicMixin,range,meta, rows,1,1);
+ id = UUID.randomUUID().toString();
+ conn = (MdbcConnection) getManager().getConnection(id);
+
+ }
+
+ @TearDown(Level.Trial)
+ public void doTrialTearDown(){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ meta=null;
+ }
+
+ @Setup(Level.Invocation)
+ public void doInvocationSetup(){
+ Statement stmt = null;
+ try {
+ stmt = conn.createStatement();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ stmt.execute(OwnUtils.UPDATE);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricIsolatedMixinCommBenchmark.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricIsolatedMixinCommBenchmark.java
new file mode 100644
index 0000000..c789ca7
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricIsolatedMixinCommBenchmark.java
@@ -0,0 +1,151 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.onap.music.exceptions.MDBCServiceException;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.onap.music.mdbc.tables.MusicTxDigestId;
+import org.onap.music.mdbc.tables.StagingTable;
+import org.onap.music.mdbc.tables.TxCommitProgress;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricIsolatedMixinCommBenchmark {
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricIsolatedMixinCommBenchmark.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public void testMethod(MyState state, Blackhole blackhole) {
+ try {
+ state.musicMixin.commitLog(state.conn.getPartition(),null,state.copy,
+ state.copyTxDigestId.transactionId.toString(),state.progressKeeper);
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+ public TxCommitProgress progressKeeper;
+ public MusicTxDigestId musicTxDigestId,copyTxDigestId;
+ final String user = OwnUtils.SQL_USER;
+ final String password = OwnUtils.SQL_PASSWORD;
+ public final Range range = new Range(OwnUtils.TABLE);
+ @Param({"104.209.240.219"})
+ public String ip;
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ private MusicInterface musicMixin = null;
+ private MdbcConnection conn;
+ private DBInterface dbMixin;
+ private MdbcServerLogic meta;
+ private String id;
+ public StagingTable copy,current;
+
+ private void setupServer(){
+ meta = OwnUtils.setupServer(user, password);
+ }
+
+ private StateManager getManager(){
+ return meta.getStateManager();
+ }
+
+ private void assignManager() {
+ StateManager manager = getManager();
+ musicMixin=manager.getMusicInterface();
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ OwnUtils.dropAll(ip);
+ setupServer();
+ assignManager();
+ OwnUtils.initMri((MusicMixin) musicMixin,range,meta, rows,1,1);
+ id = UUID.randomUUID().toString();
+ conn = (MdbcConnection) getManager().getConnection(id);
+ Statement stmt = null;
+ try {
+ stmt = conn.createStatement();
+ stmt.execute(OwnUtils.UPDATE);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ musicTxDigestId = OwnUtils.setupCommit(conn.getPartition(), conn.getTransactionDigest());
+ current=conn.getTransactionDigest();
+ progressKeeper = new TxCommitProgress();
+ }
+
+ @TearDown(Level.Trial)
+ public void doTrialTearDown(){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ meta=null;
+ }
+
+ @Setup(Level.Invocation)
+ public void doInvocationSetup(){
+ try {
+ copy = new StagingTable(current);
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ copyTxDigestId = new MusicTxDigestId(MDBCUtils.generateUniqueKey(), -1);
+ progressKeeper.createNewTransactionTracker(copyTxDigestId.transactionId.toString(),conn);
+ }
+
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricOwnBenchmark.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricOwnBenchmark.java
new file mode 100644
index 0000000..42665b1
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricOwnBenchmark.java
@@ -0,0 +1,142 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import java.sql.SQLException;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.onap.music.exceptions.MDBCServiceException;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricOwnBenchmark{
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricOwnBenchmark.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public void testMethod(MyState state, Blackhole blackhole) {
+ try {
+ state.conn.preStatementHook(state.update);
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+ public String update="SELECT * FROM PERSONS;";
+ final String user = OwnUtils.SQL_USER;
+ final String password = OwnUtils.SQL_PASSWORD;
+ public final Range range = new Range(OwnUtils.TABLE);
+ @Param({"104.209.240.219"})
+ public String ip;
+ //Rows per transaction (e.g. size of each tx digest)
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ //Transaction before each ownership transition (e.g. size of redo log)
+ @Param({"1","10","100"})
+ public int updates;
+ //Number of ownership transitions before measurement (e.g. number of mri rows"
+ @Param({"1","10","100"})
+ public int transitions;
+ private MusicInterface musicMixin = null;
+ private MdbcConnection conn;
+ private DBInterface dbMixin;
+ private MdbcServerLogic meta;
+ private String id;
+
+ private void setupServer(){
+ meta = OwnUtils.setupServer(user, password);
+ }
+
+ private StateManager getManager(){
+ return meta.getStateManager();
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ OwnUtils.dropAll(ip);
+ setupServer();
+ StateManager manager = getManager();
+ musicMixin=manager.getMusicInterface();
+ OwnUtils.initMri((MusicMixin) musicMixin,range,meta, rows, updates, transitions);
+ meta=null;
+ }
+
+ @TearDown(Level.Trial)
+ public void doTrialTearDown(){
+ meta=null;
+ }
+
+ @Setup(Level.Invocation)
+ public void doInvocationSetup(){
+ setupServer();
+ id = UUID.randomUUID().toString();
+ conn = (MdbcConnection) getManager().getConnection(id);
+ try {
+ OwnUtils.dropAndCreateTable(conn.getDBInterface());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @TearDown(Level.Invocation)
+ public void doInvocationTearDown(){
+ OwnUtils.deleteLastMriRow((MusicMixin) musicMixin);
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ getManager().closeConnection(id);
+ }
+
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricPeekLockBenchmark.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricPeekLockBenchmark.java
new file mode 100644
index 0000000..1b56c6b
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricPeekLockBenchmark.java
@@ -0,0 +1,151 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.ExecutionInfo;
+import com.datastax.driver.core.QueryTrace;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.SimpleStatement;
+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 org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.onap.music.mdbc.tables.MusicRangeInformationRow;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricPeekLockBenchmark {
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricPeekLockBenchmark.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public void testMethod(MyState state, Blackhole blackhole) {
+ String table = state.table_prepend_name+OwnUtils.MRI_TABLE_NAME;
+ String selectQuery = "select * from "+OwnUtils.KEYSPACE+"."+table+" where key='"+state.key+"' LIMIT 1;";
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(selectQuery);
+ ResultSet results=null;
+ SimpleStatement statement = new SimpleStatement(queryObject.getQuery(), queryObject.getValues().toArray());
+ statement.setConsistencyLevel(ConsistencyLevel.ONE);
+ statement.enableTracing();
+ results = state.dsHandle.getSession().execute(statement);
+ blackhole.consume(results);
+ }
+
+ public void printInfo(ResultSet results){
+ ExecutionInfo executionInfo = results.getExecutionInfo();
+ System.out.println(executionInfo.getQueriedHost().getAddress());
+ System.out.println(executionInfo.getQueriedHost().getDatacenter());
+ System.out.println(executionInfo.getQueriedHost().getRack());
+ final QueryTrace trace = executionInfo.getQueryTrace();
+ System.out.printf(
+ "'%s' to %s took %dμs%n",
+ trace.getRequestType(), trace.getCoordinator(), trace.getDurationMicros());
+ for (QueryTrace.Event event : trace.getEvents()) {
+ System.out.printf(
+ " %d - %s - %s%n",
+ event.getSourceElapsedMicros(), event.getSource(), event.getDescription());
+ }
+ }
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+ public MusicDataStore dsHandle;
+ public String key;
+ private String table_prepend_name = "lockQ_";
+ final String user = OwnUtils.SQL_USER;
+ final String password = OwnUtils.SQL_PASSWORD;
+ public final Range range = new Range(OwnUtils.TABLE);
+ @Param({"104.209.240.219"})
+ public String ip;
+ private MusicInterface musicMixin = null;
+ private MdbcConnection conn;
+ private DBInterface dbMixin;
+ private MdbcServerLogic meta;
+ private String id;
+ public MusicRangeInformationRow lastRow;
+
+ private void setupServer(){
+ meta = OwnUtils.setupServer(user, password);
+ }
+
+ private StateManager getManager(){
+ return meta.getStateManager();
+ }
+
+ private void assignManager() {
+ StateManager manager = getManager();
+ musicMixin=manager.getMusicInterface();
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ OwnUtils.dropAll(ip);
+ setupServer();
+ try {
+ dsHandle=MusicDataStoreHandle.getDSHandle();
+ } catch (MusicServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ assignManager();
+ OwnUtils.initMri((MusicMixin) musicMixin,range,meta, 1,1,1);
+ id = UUID.randomUUID().toString();
+ conn = (MdbcConnection) getManager().getConnection(id);
+ lastRow = OwnUtils.getLastRow((MusicMixin) musicMixin);
+ key = lastRow.getPartitionIndex().toString();
+ }
+
+ @TearDown(Level.Trial)
+ public void doTrialTearDown(){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ System.exit(1);
+ }
+ meta=null;
+ }
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricRedoLogBenchmark.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricRedoLogBenchmark.java
new file mode 100644
index 0000000..7e227fd
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricRedoLogBenchmark.java
@@ -0,0 +1,130 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.onap.music.mdbc.tables.MusicTxDigestId;
+import org.onap.music.mdbc.tables.StagingTable;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricRedoLogBenchmark {
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricRedoLogBenchmark.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public void testMethod(MyState state, Blackhole blackhole) {
+ final DatabasePartition partition = state.conn.getPartition();
+ OwnUtils.appendToRedo((MusicMixin)state.getManager().getMusicInterface(),partition.getMRIIndex(),
+ partition.getLockId(),state.musicTxDigestId);
+ }
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+ public MusicTxDigestId musicTxDigestId;
+ final String user = OwnUtils.SQL_USER;
+ final String password = OwnUtils.SQL_PASSWORD;
+ public final Range range = new Range(OwnUtils.TABLE);
+ @Param({"104.209.240.219"})
+ public String ip;
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ private MusicInterface musicMixin = null;
+ private MdbcConnection conn;
+ private DBInterface dbMixin;
+ private MdbcServerLogic meta;
+ private String id;
+
+ private void setupServer(){
+ meta = OwnUtils.setupServer(user, password);
+ }
+
+ private StateManager getManager(){
+ return meta.getStateManager();
+ }
+
+ private void assignManager() {
+ StateManager manager = getManager();
+ musicMixin=manager.getMusicInterface();
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ OwnUtils.dropAll(ip);
+ setupServer();
+ assignManager();
+ OwnUtils.initMri((MusicMixin) musicMixin,range,meta, rows,1,1);
+ id = UUID.randomUUID().toString();
+ conn = (MdbcConnection) getManager().getConnection(id);
+ Statement stmt = null;
+ try {
+ stmt = conn.createStatement();
+ stmt.execute(OwnUtils.UPDATE);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ musicTxDigestId = OwnUtils.setupCommit(conn.getPartition(), conn.getTransactionDigest());
+ }
+
+ @TearDown(Level.Trial)
+ public void doTrialTearDown(){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ meta=null;
+ }
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricThreadJoinBenchmark.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricThreadJoinBenchmark.java
new file mode 100644
index 0000000..70ba10a
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/MetricThreadJoinBenchmark.java
@@ -0,0 +1,197 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.onap.music.exceptions.MDBCServiceException;
+import org.onap.music.exceptions.MusicLockingException;
+import org.onap.music.logging.EELFLoggerDelegate;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.onap.music.mdbc.tables.MusicTxDigestId;
+import org.onap.music.mdbc.tables.StagingTable;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+@BenchmarkMode({Mode.AverageTime, Mode.SampleTime})
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Benchmark)
+public class MetricThreadJoinBenchmark {
+
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(MetricThreadJoinBenchmark.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+
+ public void testMethod1(final MyState state) {
+ final String lockId = state.conn.getPartition().getLockId();
+ final UUID MRIIndex = state.conn.getPartition().getMRIIndex();
+ Thread t1=null;
+ Thread t2=null;
+ if(state.runTxDigest) {
+ final Runnable insertDigestCallable = new Runnable() {
+ @Override
+ public void run() {
+ OwnUtils.hardcodedAddtransaction(110);
+ }
+ };
+ t1 = new Thread(insertDigestCallable);
+ t1.start();
+ }
+ if(state.runRedo) {
+ final Runnable appendCallable = new Runnable() {
+ @Override
+ public void run() {
+ OwnUtils.hardcodedAppendToRedo(MRIIndex,lockId);
+ }
+ };
+ t2 = new Thread(appendCallable);
+ t2.start();
+ }
+
+ try {
+ if(state.runTxDigest) {
+ t1.join();
+ }
+ if(state.runRedo) {
+ t2.join();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ @Benchmark
+ public void testMethod2(final MyState state) {
+ final String lockId = state.conn.getPartition().getLockId();
+ final UUID MRIIndex = state.conn.getPartition().getMRIIndex();
+ OwnUtils.hardcodedAddtransaction(110);
+ OwnUtils.hardcodedAppendToRedo(MRIIndex,lockId);
+ }
+
+ @State(Scope.Benchmark)
+ public static class MyState {
+ public MusicTxDigestId musicTxDigestId,copyTxDigestId;
+ public StagingTable copy,current;
+ final String user = OwnUtils.SQL_USER;
+ final String password = OwnUtils.SQL_PASSWORD;
+ public final Range range = new Range(OwnUtils.TABLE);
+ @Param({"127.0.0.1"})
+ public String ip;
+ @Param({"1", "10", "50", "80", "100", "200", "300", "400"})
+ public int rows;
+ @Param({"true","false"})
+ public boolean runRedo;
+ @Param({"true","false"})
+ public boolean runTxDigest;
+ private MusicInterface musicMixin = null;
+ private MdbcConnection conn;
+ private DBInterface dbMixin;
+ private MdbcServerLogic meta;
+ private String id;
+ public ExecutorService commitExecutorThreads;
+
+ private void setupServer(){
+ meta = OwnUtils.setupServer(user, password);
+ }
+
+ private StateManager getManager(){
+ return meta.getStateManager();
+ }
+
+ private void assignManager() {
+ StateManager manager = getManager();
+ musicMixin=manager.getMusicInterface();
+ }
+
+ @Setup(Level.Trial)
+ public void doTrialSetup(){
+ commitExecutorThreads = Executors.newFixedThreadPool(4);
+ OwnUtils.dropAll(ip);
+ setupServer();
+ assignManager();
+ OwnUtils.initMri((MusicMixin) musicMixin,range,meta, rows,0,0);
+ id = UUID.randomUUID().toString();
+ conn = (MdbcConnection) getManager().getConnection(id);
+ try {
+ Statement stmt = conn.createStatement();
+ stmt.execute(OwnUtils.UPDATE);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ musicTxDigestId = OwnUtils.setupCommit(conn.getPartition(), conn.getTransactionDigest());
+ current=conn.getTransactionDigest();
+ }
+
+ @TearDown(Level.Trial)
+ public void doTrialTearDown(){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ meta=null;
+ commitExecutorThreads.shutdown();
+ }
+
+ @Setup(Level.Invocation)
+ public void doInvocationSetup(){
+ try {
+ copy = new StagingTable(current);
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ copyTxDigestId = new MusicTxDigestId(MDBCUtils.generateUniqueKey(), -1);
+ }
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/OwnUtils.java b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/OwnUtils.java
new file mode 100644
index 0000000..980408b
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/java/org/onap/music/mdbc/OwnUtils.java
@@ -0,0 +1,383 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Cluster.Builder;
+import com.datastax.driver.core.Session;
+
+import java.nio.ByteBuffer;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.datastax.driver.core.SocketOptions;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.exceptions.MDBCServiceException;
+import org.onap.music.exceptions.MusicLockingException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.lockingservice.cassandra.MusicLockState;
+import org.onap.music.main.MusicCore;
+import org.onap.music.main.ResultType;
+import org.onap.music.main.ReturnType;
+import org.onap.music.mdbc.configurations.NodeConfiguration;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+import org.onap.music.mdbc.mixins.MusicMixin;
+import org.onap.music.mdbc.tables.MriRowComparator;
+import org.onap.music.mdbc.tables.MusicRangeInformationRow;
+import org.onap.music.mdbc.tables.MusicTxDigestId;
+import org.onap.music.mdbc.tables.StagingTable;
+
+public class OwnUtils {
+
+ public static final int SQL_PORT= 3306;
+
+ public static final String SQL_USER = "root";
+ public static final String SQL_PASSWORD = "metriccluster";
+ public static final String CASSANDRA_USER = "metric";
+ public static final String CASSANDRA_PASSWORD = "metriccluster";
+ public static final String KEYSPACE ="namespace";
+ public static final String MRI_TABLE_NAME = "musicrangeinformation";
+ public static final String MTD_TABLE_NAME = "musictxdigest";
+ public static final String MDBC_SERVER_NAME = "name";
+ public static final String DATABASE = "test";
+ public static final String TABLE= "PERSONS";
+ public static final int REPLICATION_FACTOR = 3;
+ public static final String SQL_URL="jdbc:mariadb://localhost:"+OwnUtils.SQL_PORT;
+ final static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "+TABLE+" (\n" +
+ " PersonID int,\n" +
+ " Counter int,\n" +
+ " LastName varchar(255),\n" +
+ " FirstName varchar(255),\n" +
+ " Address varchar(255),\n" +
+ " City varchar(255),\n" +
+ " PRIMARY KEY(PersonID)"+
+ ");";
+
+ public static final String UPDATE = new StringBuilder()
+ .append("UPDATE PERSONS ")
+ .append("SET Counter = Counter + 1,")
+ .append("City = 'Sandy Springs'")
+ .append(";").toString();
+ public static final String PURGE = "PURGE BINARY LOGS BEFORE '";
+ public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE + ";";
+ private static Lock sessionLock = new ReentrantLock();
+ private static Boolean sessionReady= false;
+ private static Cluster cluster;
+ private static Session session;
+
+ private static String getPurgeCommand(){
+ String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+ return PURGE+timeStamp+"';";
+ }
+
+ public static Session getSession(String CASSANDRA_HOST){
+ sessionLock.lock();
+ try {
+ if(!sessionReady){
+ SocketOptions options = new SocketOptions();
+ options.setConnectTimeoutMillis(30000);
+ options.setReadTimeoutMillis(300000);
+ options.setTcpNoDelay(true);
+ final Builder builder = Cluster.builder();
+ builder.addContactPoint(CASSANDRA_HOST);
+ builder.withCredentials(CASSANDRA_USER, CASSANDRA_PASSWORD);
+ builder.withSocketOptions(options);
+ cluster = builder.build();
+ session=cluster.newSession();
+ }
+ return session;
+ // access the resource protected by this lock
+ } finally {
+ sessionLock.unlock();
+ }
+ }
+
+ public static Connection getConnection() throws ClassNotFoundException, SQLException {
+ Class.forName("org.mariadb.jdbc.Driver");
+ Properties connectionProps = new Properties();
+ connectionProps.put("user", SQL_USER);
+ connectionProps.put("password", SQL_PASSWORD);
+ Connection connection = DriverManager.getConnection(SQL_URL+"/"+DATABASE, connectionProps);
+ connection.setAutoCommit(false);
+ return connection;
+ }
+
+ public static void purgeBinLogs(Connection conn) throws SQLException{
+ final Statement dropStatement = conn.createStatement();
+ dropStatement.execute(getPurgeCommand());
+ dropStatement.close();
+ }
+
+ public static void dropTable(Connection conn) throws SQLException {
+ final Statement dropStatement = conn.createStatement();
+ dropStatement.execute(DROP_TABLE);
+ dropStatement.close();
+ }
+
+ private static void createTable(Connection conn) throws SQLException {
+ final Statement createStatement = conn.createStatement();
+ createStatement.execute(CREATE_TABLE);
+ createStatement.close();
+ }
+
+ public static void dropAndCreateTable(DBInterface dbMixin) throws SQLException {
+ dbMixin.dropSQLTriggers(TABLE);
+ dropTable(dbMixin.getSQLConnection());
+ createTable(dbMixin.getSQLConnection());
+ dbMixin.createSQLTriggers(TABLE);
+ }
+
+ public static void unlockRow(String keyspace, String mriTableName, DatabasePartition partition)
+ throws MusicLockingException {
+ String fullyQualifiedMriKey = keyspace+"."+ mriTableName+"."+partition.getMRIIndex().toString();
+ MusicLockState musicLockState = MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey, partition.getLockId());
+ }
+
+ public static DatabasePartition createBasicRow(Range range, MusicInterface mixin, String mdbcServerName)
+ throws MDBCServiceException {
+ List<Range> ranges = new ArrayList<>();
+ ranges.add(range);
+ final UUID uuid = MDBCUtils.generateTimebasedUniqueKey();
+ DatabasePartition dbPartition = new DatabasePartition(ranges,uuid,null);
+ MusicRangeInformationRow newRow = new MusicRangeInformationRow(uuid,dbPartition, new ArrayList<MusicTxDigestId>(), "",
+ mdbcServerName, true);
+ DatabasePartition partition=mixin.createMusicRangeInformation(newRow);
+ return partition;
+ }
+
+ public static void initMriTable(MusicMixin musicMixin, Range range)
+ throws MDBCServiceException, SQLException, MusicLockingException {
+ final DatabasePartition partition = createBasicRow(range, musicMixin, MDBC_SERVER_NAME);
+ unlockRow(KEYSPACE,MRI_TABLE_NAME,partition);
+ }
+
+ public static MusicRangeInformationRow getLastRow(MusicMixin musicMixin){
+ List<MusicRangeInformationRow> allMriRows;
+ try {
+ allMriRows = musicMixin.getAllMriRows();
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ allMriRows=null;//Just to avoid IDE annoyance
+ }
+ Collections.sort(allMriRows, new MriRowComparator());
+ MusicRangeInformationRow musicRangeInformationRow = allMriRows.get(allMriRows.size() - 1);
+ return musicRangeInformationRow;
+ }
+
+ public static void deleteLastMriRow(MusicMixin musicMixin){
+ MusicRangeInformationRow musicRangeInformationRow = getLastRow(musicMixin);
+ try {
+ musicMixin.deleteMriRow(musicRangeInformationRow);
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void changeRows(Connection conn) throws SQLException {
+ Statement stmt = conn.createStatement();
+ Boolean execute = stmt.execute(UPDATE);
+ conn.commit();
+ stmt.close();
+ }
+
+ private static void addRowsToTable(int totalNumberOfRows, Connection testConnection) throws SQLException {
+ for (int i = 0; i < totalNumberOfRows; i++) {
+ final StringBuilder insertSQLBuilder = new StringBuilder()
+ .append("INSERT INTO PERSONS VALUES (")
+ .append(i)
+ .append(", ")
+ .append(0)
+ .append(", '")
+ .append("Last-")
+ .append(i)
+ .append("', '")
+ .append("First-")
+ .append(i)
+ .append("', 'KACB', 'ATLANTA');");
+ Statement stmt = testConnection.createStatement();
+ Boolean execute = stmt.execute(insertSQLBuilder.toString());
+ stmt.close();
+ }
+ testConnection.commit();
+ }
+
+ public static void createHistory(MdbcServerLogic meta,int rows, int updates,int transitions)
+ throws SQLException {
+ final StateManager stateManager = meta.getStateManager();
+ String id = UUID.randomUUID().toString();
+ Connection connection = stateManager.getConnection(id);
+ createTable(connection);
+ addRowsToTable(rows, connection);
+ connection.close();
+ stateManager.closeConnection(id);
+ for(int mriRow=0;mriRow<transitions;mriRow++) {
+ final String finalId = UUID.randomUUID().toString();
+ connection = stateManager.getConnection(finalId);
+ for(int depth=0;depth<updates;depth++){
+ changeRows(connection);
+ }
+ connection.close();
+ stateManager.closeConnection(finalId);
+ }
+ }
+
+ public static MdbcServerLogic setupServer(String user, String password){
+ MdbcServerLogic meta;
+ NodeConfiguration config = new NodeConfiguration("","",null,OwnUtils.DATABASE,
+ OwnUtils.MDBC_SERVER_NAME);
+ //\TODO Add configuration file with Server Info
+ Properties connectionProps = new Properties();
+ connectionProps.setProperty("user", user);
+ connectionProps.setProperty("password", password);
+ connectionProps.setProperty(MusicMixin.KEY_MUSIC_RFACTOR,Integer.toString(OwnUtils.REPLICATION_FACTOR));
+ connectionProps.setProperty(MusicMixin.KEY_MUSIC_NAMESPACE,OwnUtils.KEYSPACE);
+ try {
+ meta = new MdbcServerLogic(OwnUtils.SQL_URL,connectionProps,config);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ meta=null;
+ System.exit(1);
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ meta=null;
+ System.exit(1);
+ }
+ return meta;
+ }
+
+ public static void dropAll(String ip){
+ Session session=OwnUtils.getSession(ip);
+ session.execute("DROP KEYSPACE IF EXISTS "+OwnUtils.KEYSPACE+";");
+ try {
+ Connection connection = OwnUtils.getConnection();
+ OwnUtils.dropTable(connection);
+ connection.close();
+ } catch (SQLException|ClassNotFoundException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static void initMri(MusicMixin musicMixin,Range range,MdbcServerLogic meta, int rows, int updates, int transitions){
+ try {
+ OwnUtils.initMriTable(musicMixin,range);
+ } catch (MusicLockingException|SQLException|MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ try {
+ OwnUtils.createHistory(meta, rows, updates, transitions);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static void hardcodedAddtransaction(int size){
+ final UUID uuid = MDBCUtils.generateTimebasedUniqueKey();
+ ByteBuffer serializedTransactionDigest = ByteBuffer.allocate(size);
+ for(int i=0;i<size;i++){
+ serializedTransactionDigest.put((byte)i);
+ }
+ PreparedQueryObject query = new PreparedQueryObject();
+ String cql = String.format("INSERT INTO %s.%s (txid,transactiondigest,compressed ) VALUES (?,?,?);",KEYSPACE,
+ MTD_TABLE_NAME);
+ query.appendQueryString(cql);
+ query.addValue(uuid);
+ query.addValue(serializedTransactionDigest);
+ query.addValue(false);
+ //\TODO check if I am not shooting on my own foot
+ try {
+ MusicCore.nonKeyRelatedPut(query,"critical");
+ } catch (MusicServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static void hardcodedAppendToRedo(UUID mriId, String lockId){
+ final UUID uuid = MDBCUtils.generateTimebasedUniqueKey();
+ PreparedQueryObject query = new PreparedQueryObject();
+ StringBuilder appendBuilder = new StringBuilder();
+ appendBuilder.append("UPDATE ")
+ .append(KEYSPACE)
+ .append(".")
+ .append(MRI_TABLE_NAME)
+ .append(" SET txredolog = txredolog +[('")
+ .append(MTD_TABLE_NAME)
+ .append("',")
+ .append(uuid)
+ .append(")] WHERE rangeid = ")
+ .append(mriId)
+ .append(";");
+ query.appendQueryString(appendBuilder.toString());
+ ReturnType returnType = MusicCore.criticalPut(KEYSPACE, MRI_TABLE_NAME, mriId.toString(),
+ query, lockId, null);
+ //returnType.getExecutionInfo()
+ if (returnType.getResult().compareTo(ResultType.SUCCESS) != 0) {
+ System.exit(1);
+ }
+ }
+
+ public static void addTransactionDigest(StagingTable transactionDigest, MusicTxDigestId digestId, MusicMixin music){
+ try {
+ music.createAndAddTxDigest(transactionDigest, digestId.transactionId);
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static void appendToRedo(MusicMixin music, UUID MRIIndex, String lockId, MusicTxDigestId digestId){
+ try {
+ music.appendToRedoLog(KEYSPACE,MRIIndex,digestId.transactionId,lockId,OwnUtils.MTD_TABLE_NAME,
+ OwnUtils.MRI_TABLE_NAME);
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static MusicTxDigestId setupCommit(DatabasePartition partition, StagingTable transactionDigest){
+ UUID mriIndex = partition.getMRIIndex();
+
+ if(transactionDigest == null || transactionDigest.isEmpty()) {
+ System.err.println("Transaction digest is empty");
+ System.exit(1);
+ }
+
+ MusicTxDigestId digestId = new MusicTxDigestId(MDBCUtils.generateUniqueKey(), -1);
+ return digestId;
+ }
+}
diff --git a/mdbc-internal-benchmark/src/main/resources/logback.xml b/mdbc-internal-benchmark/src/main/resources/logback.xml
new file mode 100755
index 0000000..4215681
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/resources/logback.xml
@@ -0,0 +1,369 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START==========================================
+ mdbc
+ ===================================================================
+ Copyright © 2017 AT&T 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============================================
+
+
+ -->
+
+<configuration scan="false" scanPeriod="3 seconds" debug="true">
+ <!--
+ Logback files for the mdbc Driver "mdbc"
+ are created in directory ${catalina.base}/logs/mdbc;
+ e.g., apache-tomcat-8.0.35/logs/mdbc/application.log
+ -->
+ <!--<jmxConfigurator /> -->
+
+ <!-- specify the component name -->
+ <property name="catalina.home" value="/var/log/metric/"/>
+ <property name="componentName" value="mdbc"></property>
+
+ <!-- specify the base path of the log directory -->
+ <property name="logDirPrefix" value="${catalina.base}/logs"></property>
+
+ <!-- The directories where logs are written -->
+ <property name="logDirectory" value="${logDirPrefix}/${componentName}"/>
+ <!-- Can easily relocate debug logs by modifying this path. -->
+ <property name="debugLogDirectory" value="${logDirPrefix}/${componentName}"/>
+
+ <!-- log file names -->
+ <property name="generalLogName" value="application"/>
+ <property name="errorLogName" value="error"/>
+ <property name="metricsLogName" value="metrics"/>
+ <property name="auditLogName" value="audit"/>
+ <property name="debugLogName" value="debug"/>
+ <!--
+ These loggers are not used in code (yet).
+ <property name="securityLogName" value="security" />
+ <property name="policyLogName" value="policy" />
+ <property name="performanceLogName" value="performance" />
+ <property name="serverLogName" value="server" />
+ -->
+
+ <!-- 1610 Logging Fields Format Revisions -->
+ <property name="auditLoggerPattern"
+ value="%X{AuditLogBeginTimestamp}|%X{AuditLogEndTimestamp}|%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{Timer}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n"/>
+
+ <property name="metricsLoggerPattern"
+ value="%X{MetricsLogBeginTimestamp}|%X{MetricsLogEndTimestamp}|%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{Timer}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{TargetVisualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n"/>
+
+ <property name="errorLoggerPattern"
+ value="%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestId}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ClassName}|%X{AlertSeverity}|%X{ErrorCode}|%X{ErrorDescription}| %msg%n"/>
+
+ <property name="defaultLoggerPattern"
+ value="%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestId}|%thread|%X{ClassName}| %msg%n"/>
+
+ <!-- use %class so library logging calls yield their class name -->
+ <property name="applicationLoggerPattern"
+ value="%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestId}|%thread|%class{36}| %msg%n"/>
+
+ <!-- Example evaluator filter applied against console appender -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>${defaultLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <!-- ============================================================================ -->
+ <!-- EELF Appenders -->
+ <!-- ============================================================================ -->
+
+ <!-- The EELFAppender is used to record events to the general application
+ log -->
+
+
+ <appender name="EELF"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${generalLogName}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <!-- daily rollover -->
+ <fileNamePattern>${logDirectory}/${generalLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+
+ <!-- keep 30 days' worth of history capped at 3GB total size -->
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>3GB</totalSizeCap>
+
+ </rollingPolicy>
+ <encoder>
+ <pattern>${applicationLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="asyncEELF" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <!-- Class name is part of caller data -->
+ <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>${defaultPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="asyncEELFSecurity" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <discardingThreshold>0</discardingThreshold>
+ <appender-ref ref="EELFSecurity" />
+ </appender>
+ -->
+
+ <!-- EELF Performance Appender. This appender is used to record performance
+ records. -->
+ <!--
+ <appender name="EELFPerformance"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${performanceLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${performanceLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <outputPatternAsHeader>true</outputPatternAsHeader>
+ <pattern>${defaultPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFPerformance" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFPerformance" />
+ </appender>
+ -->
+
+ <!-- EELF Server Appender. This appender is used to record Server related
+ logging events. The Server logger and appender are specializations of the
+ EELF application root logger and appender. This can be used to segregate Server
+ events from other components, or it can be eliminated to record these events
+ as part of the application root log. -->
+ <!--
+ <appender name="EELFServer"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${serverLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${serverLogName}.%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>${defaultPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFServer" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFServer" />
+ </appender>
+ -->
+
+ <!-- EELF Policy Appender. This appender is used to record Policy engine
+ related logging events. The Policy 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="EELFPolicy"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${policyLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${policyLogName}.%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>${defaultPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFPolicy" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFPolicy" />
+ </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.TimeBasedRollingPolicy">
+ <!-- daily rollover -->
+ <fileNamePattern>${logDirectory}/${auditLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+
+ <!-- keep 30 days' worth of history capped at 3GB total size -->
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>3GB</totalSizeCap>
+
+ </rollingPolicy>
+ <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.TimeBasedRollingPolicy">
+ <!-- daily rollover -->
+ <fileNamePattern>${logDirectory}/${metricsLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+
+ <!-- keep 30 days' worth of history capped at 3GB total size -->
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>3GB</totalSizeCap>
+
+ </rollingPolicy>
+ <encoder>
+ <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.TimeBasedRollingPolicy">
+ <!-- daily rollover -->
+ <fileNamePattern>${logDirectory}/${errorLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+
+ <!-- keep 30 days' worth of history capped at 3GB total size -->
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>3GB</totalSizeCap>
+
+ </rollingPolicy>
+ <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.TimeBasedRollingPolicy">
+ <!-- daily rollover -->
+ <fileNamePattern>${logDirectory}/${debugLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+
+ <!-- keep 30 days' worth of history capped at 3GB total size -->
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>3GB</totalSizeCap>
+
+ </rollingPolicy>
+ <encoder>
+ <pattern>${defaultLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFDebug"/>
+ </appender>
+
+
+ <logger name="com.att.eelf" level="error" additivity="false">
+ <appender-ref ref="asyncEELF"/>
+ </logger>
+
+ <logger name="com.att.eelf" level="error" additivity="false">
+ <appender-ref ref="asyncEELFAudit"/>
+ </logger>
+
+ <logger name="com.att.eelf" level="error" additivity="false">
+ <appender-ref ref="asyncEELFDebug"/>
+ </logger>
+
+ <logger name="com.att.eelf.error" level="error" additivity="false">
+ <appender-ref ref="asyncEELFError"/>
+ </logger>
+
+ <logger name="com.att.eelf.metrics" level="error" additivity="false">
+ <appender-ref ref="asyncEELFMetrics"/>
+ </logger>
+
+ <root level="ERROR">
+ <appender-ref ref="asyncEELF"/>
+ </root>
+
+</configuration>
diff --git a/mdbc-internal-benchmark/src/main/resources/mdbc.properties b/mdbc-internal-benchmark/src/main/resources/mdbc.properties
new file mode 100755
index 0000000..73e8f77
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/resources/mdbc.properties
@@ -0,0 +1,13 @@
+#
+# A list of all Mixins that should be checked by MDBC
+#
+MIXINS= \
+ org.onap.music.mdbc.mixins.MySQLMixin \
+ org.onap.music.mdbc.mixins.MusicMixin \
+ org.onap.music.mdbc.mixins.Music2Mixin
+
+DEFAULT_DRIVERS=\
+ org.h2.Driver \
+ com.mysql.jdbc.Driver
+
+txdaemonsleeps=15 \ No newline at end of file
diff --git a/mdbc-internal-benchmark/src/main/resources/music.properties b/mdbc-internal-benchmark/src/main/resources/music.properties
new file mode 100755
index 0000000..ccacd38
--- /dev/null
+++ b/mdbc-internal-benchmark/src/main/resources/music.properties
@@ -0,0 +1,8 @@
+cassandra.host =\
+ 10.0.0.5
+cassandra.user =\
+ metric
+cassandra.password =\
+ metriccluster
+zookeeper.host =\
+ localhost
diff --git a/mdbc-server/pom.xml b/mdbc-server/pom.xml
index f69cf2f..cdf7cff 100755
--- a/mdbc-server/pom.xml
+++ b/mdbc-server/pom.xml
@@ -34,49 +34,49 @@
</parent>
<dependencies>
- <dependency>
- <groupId>org.apache.calcite</groupId>
- <artifactId>calcite</artifactId>
- <version>1.11.0</version>
- <type>pom</type>
- </dependency>
+ <dependency>
+ <groupId>org.apache.calcite</groupId>
+ <artifactId>calcite</artifactId>
+ <version>1.11.0</version>
+ <type>pom</type>
+ </dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
- <!-- The oparent dependency managed version 26.0-jre will not work -->
- <!-- 19.0 is needed by cassandra-driver-core 3.3.0 -->
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>19.0</version>
+ <!-- The oparent dependency managed version 26.0-jre will not work -->
+ <!-- 19.0 is needed by cassandra-driver-core 3.3.0 -->
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>19.0</version>
</dependency>
<dependency>
- <!-- The oparent dependency managed version 9.4.12.v20180830 will not work -->
- <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-http</artifactId>
- <version>9.2.19.v20160908</version>
+ <!-- The oparent dependency managed version 9.4.12.v20180830 will not work -->
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ <version>9.2.19.v20160908</version>
</dependency>
<dependency>
- <!-- The oparent dependency managed version 9.4.12.v20180830 will not work -->
- <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>9.2.19.v20160908</version>
+ <!-- The oparent dependency managed version 9.4.12.v20180830 will not work -->
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>9.2.19.v20160908</version>
</dependency>
<dependency>
- <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-security</artifactId>
- <version>9.2.19.v20160908</version>
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ <version>9.2.19.v20160908</version>
</dependency>
<dependency>
- <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
- <version>9.2.19.v20160908</version>
+ <!-- 9.2.19.v20160908 is needed by avatica-server 1.12.0 -->
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ <version>9.2.19.v20160908</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
@@ -89,9 +89,9 @@
<version>20160810</version>
</dependency>
<dependency>
- <groupId>org.mariadb.jdbc</groupId>
- <artifactId>mariadb-java-client</artifactId>
- <version>2.3.0</version>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ <version>2.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
@@ -214,11 +214,11 @@
</configuration>
<executions>
<execution>
- <id>make-assembly</id> <!-- this is used for inheritance merges -->
- <phase>package</phase> <!-- bind to the packaging phase -->
- <goals>
- <goal>single</goal>
- </goals>
+ <id>make-assembly</id> <!-- this is used for inheritance merges -->
+ <phase>package</phase> <!-- bind to the packaging phase -->
+ <goals>
+ <goal>single</goal>
+ </goals>
</execution>
<execution>
<id>node-configuration</id>
@@ -240,6 +240,25 @@
</configuration>
</execution>
<execution>
+ <id>cluster-setup</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>org.onap.music.mdbc.tools.ClusterSetup</mainClass>
+ </manifest>
+ </archive>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <finalName>cluster-setup</finalName>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ </execution>
+ <execution>
<id>mdbc-server</id>
<phase>package</phase>
<goals>
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java
index 7377c4f..72b8899 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java
@@ -53,7 +53,7 @@ import org.onap.music.mdbc.ownership.Dag;
import org.onap.music.mdbc.ownership.DagNode;
import org.onap.music.mdbc.ownership.OwnershipAndCheckpoint;
import org.onap.music.mdbc.query.QueryProcessor;
-import org.onap.music.mdbc.tables.MusicTxDigest;
+import org.onap.music.mdbc.tables.MusicTxDigestDaemon;
import org.onap.music.mdbc.tables.MusicRangeInformationRow;
import org.onap.music.mdbc.tables.StagingTable;
import org.onap.music.mdbc.tables.TxCommitProgress;
@@ -115,6 +115,10 @@ public class MdbcConnection implements Connection {
logger.debug("Mdbc connection created with id: "+id);
}
+ public DBInterface getDatabaseInterface(){
+ return this.dbi;
+ }
+
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
logger.error(EELFLoggerDelegate.errorLogger, "proxyconn unwrap: " + iface.getName());
@@ -263,6 +267,11 @@ public class MdbcConnection implements Connection {
jdbcConn.close();
logger.debug("Connection was closed for id:" + id);
}
+ try {
+ mi.relinquish(partition.getLockId(),partition.getMRIIndex().toString());
+ } catch (MDBCServiceException e) {
+ throw new SQLException("Failure during relinquish of partition",e);
+ }
}
@Override
@@ -509,7 +518,7 @@ public class MdbcConnection implements Connection {
this.partition.updateDatabasePartition(tempPartition);
statemanager.getOwnAndCheck().reloadAlreadyApplied(this.partition);
}
- dbi.preStatementHook(sql);
+ dbi.preStatementHook(sql);
}
@@ -603,4 +612,16 @@ public class MdbcConnection implements Connection {
mi.relinquishIfRequired(partition);
}
+ public Connection getConnection(){
+ return jdbcConn;
+ }
+
+ public DatabasePartition getPartition() {
+ return partition;
+ }
+
+ public StagingTable getTransactionDigest(){
+ return transactionDigest;
+ }
+
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServer.java b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServer.java
index 1712c30..42b9710 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServer.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServer.java
@@ -20,7 +20,7 @@
package org.onap.music.mdbc;
import org.onap.music.mdbc.configurations.NodeConfiguration;
-import org.onap.music.mdbc.tables.MusicTxDigest;
+import org.onap.music.mdbc.tables.MusicTxDigestDaemon;
import org.apache.calcite.avatica.remote.Driver.Serialization;
import org.apache.calcite.avatica.remote.LocalService;
import org.apache.calcite.avatica.server.HttpServer;
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServerLogic.java b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServerLogic.java
index 9fb36ae..8f79840 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServerLogic.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcServerLogic.java
@@ -29,7 +29,6 @@ import java.util.concurrent.TimeUnit;
import org.onap.music.exceptions.MDBCServiceException;
import org.onap.music.mdbc.configurations.NodeConfiguration;
-import org.onap.music.mdbc.tables.MusicTxDigest;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/Range.java b/mdbc-server/src/main/java/org/onap/music/mdbc/Range.java
index c498952..16e7170 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/Range.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/Range.java
@@ -30,9 +30,7 @@ import java.util.Objects;
* In the future we may decide to partition ranges differently
* @author Enrique Saurez
*/
-public class Range implements Serializable, Cloneable{
-
- private static final long serialVersionUID = 1610744496930800088L;
+public class Range implements Cloneable{
private String table;
@@ -61,7 +59,7 @@ public class Range implements Serializable, Cloneable{
}
@Override
- protected Range clone() {
+ public Range clone() {
Range newRange = null;
try{
newRange = (Range) super.clone();
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/StateManager.java b/mdbc-server/src/main/java/org/onap/music/mdbc/StateManager.java
index f0d9832..1105bda 100644
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/StateManager.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/StateManager.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.tuple.Pair;
import org.onap.music.exceptions.MDBCServiceException;
import org.onap.music.logging.EELFLoggerDelegate;
@@ -36,7 +35,7 @@ import org.onap.music.mdbc.mixins.MusicInterface;
import org.onap.music.mdbc.mixins.MusicInterface.OwnershipReturn;
import org.onap.music.mdbc.ownership.OwnershipAndCheckpoint;
import org.onap.music.mdbc.tables.MriReference;
-import org.onap.music.mdbc.tables.MusicTxDigest;
+import org.onap.music.mdbc.tables.MusicTxDigestDaemon;
import org.onap.music.mdbc.tables.TxCommitProgress;
import java.io.IOException;
@@ -48,7 +47,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
-import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -95,6 +93,7 @@ public class StateManager {
/** map of transactions that have already been applied/updated in this sites SQL db */
private Map<Range, Pair<MriReference, Integer>> alreadyApplied;
private OwnershipAndCheckpoint ownAndCheck;
+ private Thread txDaemon ;
/**
* For testing purposes only
@@ -122,19 +121,22 @@ public class StateManager {
musicmixin = info.getProperty(Configuration.KEY_MUSIC_MIXIN_NAME, Configuration.MUSIC_MIXIN_DEFAULT);
initMusic();
- initSqlDatabase();
-
+ initSqlDatabase();
+ initTxDaemonThread();
String t = info.getProperty(Configuration.KEY_OWNERSHIP_TIMEOUT);
- long timeoutMs = (t == null) ? Configuration.DEFAULT_OWNERSHIP_TIMEOUT : Integer.parseInt(t);
+ long timeout = (t == null) ? Configuration.DEFAULT_OWNERSHIP_TIMEOUT : Integer.parseInt(t);
alreadyApplied = new ConcurrentHashMap<>();
- ownAndCheck = new OwnershipAndCheckpoint(alreadyApplied, timeoutMs);
-
- rangesToWarmup = initWarmupRanges();
- logger.info("Warmup ranges for this site is " + rangesToWarmup);
+ ownAndCheck = new OwnershipAndCheckpoint(alreadyApplied, timeout);
+ }
- MusicTxDigest txDaemon = new MusicTxDigest(this);
- txDaemon.startBackgroundDaemon(Integer.parseInt(
- info.getProperty(Configuration.TX_DAEMON_SLEEPTIME_S, Configuration.TX_DAEMON_SLEEPTIME_S_DEFAULT)));
+ protected void initTxDaemonThread(){
+ txDaemon = new Thread(
+ new MusicTxDigestDaemon(Integer.parseInt(
+ info.getProperty(Configuration.TX_DAEMON_SLEEPTIME_S, Configuration.TX_DAEMON_SLEEPTIME_S_DEFAULT)),
+ this));
+ txDaemon.setName("TxDaemon");
+ txDaemon.setDaemon(true);
+ txDaemon.start();
}
/**
@@ -163,6 +165,7 @@ public class StateManager {
.append(";");
Statement stmt = sqlConnection.createStatement();
stmt.execute(sql.toString());
+ sqlConnection.close();
} catch (SQLException e) {
logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.CRITICAL,
ErrorTypes.GENERALSERVICEERROR);
@@ -243,7 +246,7 @@ public class StateManager {
returnArray = new ArrayList<>(eventualRanges);
}
else{
- returnArray= null;
+ returnArray= new ArrayList<>();
}
}
finally{
@@ -291,7 +294,7 @@ public class StateManager {
}
if(connectionRanges.containsKey(connectionId)){
//We relinquish all locks obtained by a given
- relinquish(connectionRanges.get(connectionId));
+ //relinquish(connectionRanges.get(connectionId));
connectionRanges.remove(connectionId);
}
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/ClusterConfiguration.java b/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/ClusterConfiguration.java
new file mode 100644
index 0000000..943fd46
--- /dev/null
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/ClusterConfiguration.java
@@ -0,0 +1,88 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc.configurations;
+
+import com.google.gson.Gson;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.exceptions.MDBCServiceException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.logging.EELFLoggerDelegate;
+import org.onap.music.main.MusicCore;
+import org.onap.music.mdbc.mixins.MusicMixin;
+
+public class ClusterConfiguration {
+ private String internalNamespace;
+ private int internalReplicationFactor;
+ private String musicNamespace;
+ private int musicReplicationFactor;
+ private String mriTableName;
+ private String mtxdTableName;
+ private String eventualMtxdTableName;
+ private String nodeInfoTableName;
+ private String rangeDependencyTableName;
+
+ private transient static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ClusterConfiguration.class);
+
+ public void initNamespaces() throws MDBCServiceException{
+ MusicMixin.createKeyspace(internalNamespace,internalReplicationFactor);
+ MusicMixin.createKeyspace(musicNamespace,musicReplicationFactor);
+ }
+
+ public void initTables() throws MDBCServiceException{
+ MusicMixin.createMusicRangeInformationTable(musicNamespace, mriTableName);
+ MusicMixin.createMusicTxDigest(mtxdTableName,musicNamespace, -1);
+ MusicMixin.createMusicEventualTxDigest(eventualMtxdTableName,musicNamespace, -1);
+ MusicMixin.createMusicNodeInfoTable(nodeInfoTableName,musicNamespace,-1);
+ MusicMixin.createMusicRangeDependencyTable(musicNamespace,rangeDependencyTableName);
+ }
+
+ private void initInternalTable() throws MDBCServiceException {
+ StringBuilder createKeysTableCql = new StringBuilder("CREATE TABLE IF NOT EXISTS ")
+ .append(internalNamespace)
+ .append(".unsynced_keys (key text PRIMARY KEY);");
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(createKeysTableCql.toString());
+ try {
+ MusicCore.createTable(internalNamespace,"unsynced_keys", queryObject,"critical");
+ } catch (MusicServiceException e) {
+ logger.error("Error creating unsynced keys table" );
+ throw new MDBCServiceException("Error creating unsynced keys table", e);
+ }
+ }
+
+ public static ClusterConfiguration readJsonFromFile(String filepath) throws FileNotFoundException {
+ BufferedReader br;
+ try {
+ br = new BufferedReader(
+ new FileReader(filepath));
+ } catch (FileNotFoundException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,"File was not found when reading json"+e);
+ throw e;
+ }
+ Gson gson = new Gson();
+ ClusterConfiguration config = gson.fromJson(br, ClusterConfiguration.class);
+ return config;
+ }
+
+
+}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/NodeConfiguration.java b/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/NodeConfiguration.java
index 5349219..38309d5 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/NodeConfiguration.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/NodeConfiguration.java
@@ -50,6 +50,9 @@ public class NodeConfiguration {
}
protected List<Range> toRanges(String tables){
+ if(tables.isEmpty()){
+ return new ArrayList<>();
+ }
List<Range> newRange = new ArrayList<>();
String[] tablesArray=tables.split(",");
for(String table: tablesArray) {
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/TablesConfiguration.java b/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/TablesConfiguration.java
index a9d179f..343a8b8 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/TablesConfiguration.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/configurations/TablesConfiguration.java
@@ -20,14 +20,12 @@
package org.onap.music.mdbc.configurations;
import com.datastax.driver.core.ResultSet;
-import java.util.stream.Collectors;
import org.onap.music.exceptions.MDBCServiceException;
import org.onap.music.logging.EELFLoggerDelegate;
import org.onap.music.mdbc.MDBCUtils;
import org.onap.music.mdbc.Range;
-import org.onap.music.mdbc.RedoRow;
import org.onap.music.mdbc.mixins.MusicMixin;
-import org.onap.music.mdbc.tables.MusicTxDigest;
+import org.onap.music.mdbc.tables.MusicRangeInformationRow;
import com.google.gson.Gson;
import org.onap.music.datastore.PreparedQueryObject;
@@ -48,11 +46,8 @@ public class TablesConfiguration {
private transient static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(TablesConfiguration.class);
private List<PartitionInformation> partitions;
- private String internalNamespace;
- private int internalReplicationFactor;
+ String tableToPartitionName;
private String musicNamespace;
- private int musicReplicationFactor;
- private String tableToPartitionName;
private String partitionInformationTableName;
private String redoHistoryTableName;
private String sqlDatabaseName;
@@ -67,8 +62,6 @@ public class TablesConfiguration {
*/
public List<NodeConfiguration> initializeAndCreateNodeConfigurations() throws MDBCServiceException {
logger.info("initializing the required spaces");
- createKeyspaces();
- initInternalNamespace();
List<NodeConfiguration> nodeConfigs = new ArrayList<>();
if(partitions == null){
@@ -77,10 +70,7 @@ public class TablesConfiguration {
}
for(PartitionInformation partitionInfo : partitions){
String mriTableName = partitionInfo.mriTableName;
- checkIfMriIsEmpty(mriTableName);
- //0) Create the corresponding Music Range Information table
- MusicMixin.createMusicRangeInformationTable(musicNamespace,mriTableName);
-
+ checkIfMriDoesNotExists(mriTableName,partitionInfo);
String partitionId;
if(partitionInfo.partitionId==null || partitionInfo.partitionId.isEmpty()){
//1) Create a row in the partition info table
@@ -108,24 +98,7 @@ public class TablesConfiguration {
return nodeConfigs;
}
- private void createKeyspaces() throws MDBCServiceException {
- MusicMixin.createKeyspace(internalNamespace,internalReplicationFactor);
- MusicMixin.createKeyspace(musicNamespace,musicReplicationFactor);
-
- }
-
- private void checkIfMriIsEmpty(String mriTableName) throws MDBCServiceException {
- //First check if table exists
- StringBuilder checkTableExistsString = new StringBuilder("SELECT table_name FROM system_schema.tables WHERE keyspace_name='")
- .append(musicNamespace)
- .append("';");
- PreparedQueryObject checkTableExists = new PreparedQueryObject();
- checkTableExists.appendQueryString(checkTableExistsString.toString());
- final ResultSet resultSet = MusicCore.quorumGet(checkTableExists);
- if(resultSet.isExhausted()){
- //Table doesn't exist
- return;
- }
+ private void checkIfMriDoesNotExists(String mriTableName, PartitionInformation partition) throws MDBCServiceException {
//If exists, check if empty
StringBuilder checkRowsInTableString = new StringBuilder("SELECT * FROM ")
.append(musicNamespace)
@@ -134,27 +107,19 @@ public class TablesConfiguration {
.append("';");
PreparedQueryObject checkRowsInTable = new PreparedQueryObject();
checkRowsInTable.appendQueryString(checkRowsInTableString.toString());
- final ResultSet resultSet2 = MusicCore.quorumGet(checkTableExists);
- if(!resultSet2.isExhausted()) {
- throw new MDBCServiceException("When initializing the configuration of the system, the MRI should not exits "
- + "be empty");
+ final ResultSet resultSet = MusicCore.quorumGet(checkRowsInTable);
+ while(resultSet!=null && !resultSet.isExhausted()){
+ final MusicRangeInformationRow mriRowFromCassandraRow = MusicMixin.getMRIRowFromCassandraRow(resultSet.one());
+ List<Range> ranges = mriRowFromCassandraRow.getDBPartition().getSnapshot();
+ for(Range range: partition.getTables()) {
+ if (Range.overlaps(ranges,range.getTable())){
+ throw new MDBCServiceException("MRI row already exists");
+ }
+ }
}
}
- private void initInternalNamespace() throws MDBCServiceException {
- StringBuilder createKeysTableCql = new StringBuilder("CREATE TABLE IF NOT EXISTS ")
- .append(internalNamespace)
- .append(".unsynced_keys (key text PRIMARY KEY);");
- PreparedQueryObject queryObject = new PreparedQueryObject();
- queryObject.appendQueryString(createKeysTableCql.toString());
- try {
- MusicCore.createTable(internalNamespace,"unsynced_keys", queryObject,"critical");
- } catch (MusicServiceException e) {
- logger.error("Error creating unsynced keys table" );
- throw new MDBCServiceException("Error creating unsynced keys table", e);
- }
- }
public static TablesConfiguration readJsonFromFile(String filepath) throws FileNotFoundException {
BufferedReader br;
@@ -174,7 +139,6 @@ public class TablesConfiguration {
private List<Range> tables;
private String owner;
private String mriTableName;
- private String mtxdTableName;
private String partitionId;
public List<Range> getTables() {
@@ -209,12 +173,5 @@ public class TablesConfiguration {
this.partitionId = partitionId;
}
- public String getMtxdTableName(){
- return mtxdTableName;
- }
-
- public void setMtxdTableName(String mtxdTableName) {
- this.mtxdTableName = mtxdTableName;
- }
}
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/examples/MdbcTestClient.java b/mdbc-server/src/main/java/org/onap/music/mdbc/examples/MdbcTestClient.java
index 8ca8517..60c97d1 100644
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/examples/MdbcTestClient.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/examples/MdbcTestClient.java
@@ -51,8 +51,8 @@ public class MdbcTestClient {
}
Connection connection;
try {
- String metricURL = "http://localhost:300000/test";
- if(args[0] != null) {
+ String metricURL = "http://localhost:30000/test";
+ if (args.length>0 && args[0] != null) {
metricURL = args[0];
}
connection = DriverManager.getConnection("jdbc:avatica:remote:url=" + metricURL+ ";serialization=protobuf");
@@ -60,7 +60,6 @@ public class MdbcTestClient {
e.printStackTrace();
return;
}
-
try {
connection.setAutoCommit(false);
} catch (SQLException e) {
@@ -68,7 +67,6 @@ public class MdbcTestClient {
return;
}
-
final String sql = "CREATE TABLE IF NOT EXISTS Persons (\n" +
" PersonID int,\n" +
" LastName varchar(255),\n" +
@@ -84,7 +82,6 @@ public class MdbcTestClient {
e.printStackTrace();
return;
}
-
boolean execute = true;
// try {
// execute = stmt.execute(sql);
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/DBInterface.java b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/DBInterface.java
index a514dc6..a594918 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/DBInterface.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/DBInterface.java
@@ -19,6 +19,7 @@
*/
package org.onap.music.mdbc.mixins;
+import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
@@ -130,4 +131,6 @@ public interface DBInterface {
void enableForeignKeyChecks() throws SQLException;
void applyTxDigest(StagingTable txDigest, List<Range> ranges) throws SQLException, MDBCServiceException;
+
+ Connection getSQLConnection();
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicInterface.java b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicInterface.java
index 00f6d00..8b91b28 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicInterface.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicInterface.java
@@ -21,11 +21,8 @@ package org.onap.music.mdbc.mixins;
import com.datastax.driver.core.ResultSet;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
+
import org.json.JSONObject;
import org.onap.music.exceptions.MDBCServiceException;
import org.onap.music.exceptions.MusicLockingException;
@@ -230,12 +227,12 @@ public interface MusicInterface {
/**
* This function is used to append an index to the redo log in a MRI row
- * @param partition information related to ownership of partitions, used to verify ownership
+ * @param MRIIndex index of the row to which the record is going to be added (obtained from the Partition)
+ * @param lockId reference to lock associated to the row in the MRI table MRIIndex.
* @param newRecord index of the new record to be appended to the redo log
* @throws MDBCServiceException
*/
- void appendToRedoLog( DatabasePartition partition, MusicTxDigestId newRecord) throws MDBCServiceException;
-
+ void appendToRedoLog(UUID MRIIndex, String lockId, MusicTxDigestId newRecord)throws MDBCServiceException;
/**
* This functions adds the tx digest to
* @param newId id used as index in the MTD table
@@ -261,7 +258,7 @@ public interface MusicInterface {
* @throws MDBCServiceException
*/
- public LinkedHashMap<UUID, StagingTable> getEveTxDigest(String nodeName) throws MDBCServiceException;
+ LinkedHashMap<UUID, StagingTable> getEveTxDigest(String nodeName) throws MDBCServiceException;
/**
* Function used to retrieve a given transaction digest and deserialize it
* @param id of the transaction digest to be retrieved
@@ -277,17 +274,6 @@ public interface MusicInterface {
*/
void relinquishIfRequired(DatabasePartition partition) throws MDBCServiceException;
- /**
- * This function is in charge of owning all the ranges requested and creating a new row that show the ownership of all
- * those ranges.
- * @param rangeId new id to be used in the new row
- * @param ranges ranges to be owned by the end of the function called
- * @param partition current ownership status
- * @return
- * @throws MDBCServiceException
- */
- //OwnershipReturn appendRange(String rangeId, List<Range> ranges, DatabasePartition partition) throws MDBCServiceException;
-
/**
* This functions relinquishes a range
* @param ownerId id of the current ownerh
@@ -318,10 +304,17 @@ public interface MusicInterface {
List<MusicRangeInformationRow> getAllMriRows() throws MDBCServiceException;
- public void updateNodeInfoTableWithTxTimeIDKey(UUID txTimeID, String nodeName) throws MDBCServiceException;
- public LockResult requestLock(LockRequest request) throws MDBCServiceException;
- public void releaseLocks(Map<UUID, LockResult> newLocks) throws MDBCServiceException;
- public OwnershipReturn mergeLatestRows(Dag extendedDag, List<MusicRangeInformationRow> latestRows, List<Range> ranges,
+
+ void deleteMriRow(MusicRangeInformationRow row) throws MDBCServiceException;
+
+ void updateNodeInfoTableWithTxTimeIDKey(UUID txTimeID, String nodeName) throws MDBCServiceException;
+
+ LockResult requestLock(LockRequest request) throws MDBCServiceException;
+
+ void releaseLocks(Map<UUID, LockResult> newLocks) throws MDBCServiceException;
+
+ OwnershipReturn mergeLatestRows(Dag extendedDag, List<MusicRangeInformationRow> latestRows, List<Range> ranges,
Map<UUID, LockResult> locks, UUID ownershipId) throws MDBCServiceException;
+
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicMixin.java b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicMixin.java
index c6cc512..e548f1a 100644
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicMixin.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicMixin.java
@@ -37,8 +37,9 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiFunction;
+import java.util.concurrent.*;
+
+import com.datastax.driver.core.*;
import org.apache.commons.lang3.tuple.Pair;
import org.json.JSONObject;
import org.onap.music.datastore.Condition;
@@ -67,14 +68,6 @@ import org.onap.music.mdbc.tables.MusicTxDigestId;
import org.onap.music.mdbc.tables.RangeDependency;
import org.onap.music.mdbc.tables.StagingTable;
import org.onap.music.mdbc.tables.TxCommitProgress;
-import com.datastax.driver.core.BoundStatement;
-import com.datastax.driver.core.ColumnDefinitions;
-import com.datastax.driver.core.DataType;
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Row;
-import com.datastax.driver.core.Session;
-import com.datastax.driver.core.TupleValue;
/**
* This class provides the methods that MDBC needs to access Cassandra directly in order to provide persistence
@@ -106,16 +99,19 @@ public class MusicMixin implements MusicInterface {
public static final String KEY_MUSIC_RFACTOR = "music_rfactor";
/** The property name to use to provide the replication factor for Cassandra. */
public static final String KEY_MUSIC_NAMESPACE = "music_namespace";
+ /** The property name to use to provide a flag indicating if compression is required */
+ public static final String KEY_COMPRESSION = "mdbc_compression";
/** Namespace for the tables in MUSIC (Cassandra) */
public static final String DEFAULT_MUSIC_NAMESPACE = "namespace";
/** The default property value to use for the Cassandra IP address. */
public static final String DEFAULT_MUSIC_ADDRESS = "localhost";
/** The default property value to use for the Cassandra replication factor. */
- public static final int DEFAULT_MUSIC_RFACTOR = 1;
+ public static final int DEFAULT_MUSIC_RFACTOR = 3;
/** The default primary string column, if none is provided. */
public static final String MDBC_PRIMARYKEY_NAME = "mdbc_cuid";
/** Type of the primary key, if none is defined by the user */
public static final String MDBC_PRIMARYKEY_TYPE = "uuid";
+ public static final boolean DEFAULT_COMPRESSION = true;
//\TODO Add logic to change the names when required and create the tables when necessary
@@ -178,9 +174,12 @@ public class MusicMixin implements MusicInterface {
//typemap.put(Types.DATE, "TIMESTAMP");
}
+
protected final String music_ns;
protected final String myId;
protected final String[] allReplicaIds;
+ protected ExecutorService commitExecutorThreads;
+
private final String musicAddress;
private final int music_rfactor;
private MusicConnector mCon = null;
@@ -189,7 +188,7 @@ public class MusicMixin implements MusicInterface {
private Map<String, PreparedStatement> ps_cache = new HashMap<>();
private Set<String> in_progress = Collections.synchronizedSet(new HashSet<String>());
private StateManager stateManager;
-
+ private boolean useCompression;
public MusicMixin() {
@@ -206,14 +205,16 @@ public class MusicMixin implements MusicInterface {
// Default to using the host_ids of the various peers as the replica IDs (this is probably preferred)
this.musicAddress = info.getProperty(KEY_MUSIC_ADDRESS, DEFAULT_MUSIC_ADDRESS);
logger.info(EELFLoggerDelegate.applicationLogger,"MusicSqlManager: musicAddress="+musicAddress);
-
- String s = info.getProperty(KEY_MUSIC_RFACTOR);
- this.music_rfactor = (s == null) ? DEFAULT_MUSIC_RFACTOR : Integer.parseInt(s);
+ MusicDataStore dsHandle = null;
+ try {
+ dsHandle = MusicDataStoreHandle.getDSHandle();
+ } catch (MusicServiceException e) {
+ e.printStackTrace();
+ }
this.myId = info.getProperty(KEY_MY_ID, getMyHostId());
logger.info(EELFLoggerDelegate.applicationLogger,"MusicSqlManager: myId="+myId);
-
this.allReplicaIds = info.getProperty(KEY_REPLICAS, getAllHostIds()).split(",");
logger.info(EELFLoggerDelegate.applicationLogger,"MusicSqlManager: allReplicaIds="+info.getProperty(KEY_REPLICAS, this.myId));
@@ -222,7 +223,14 @@ public class MusicMixin implements MusicInterface {
this.stateManager = stateManager;
+ String c = info.getProperty(KEY_COMPRESSION);
+ this.useCompression = (c == null) ? DEFAULT_COMPRESSION: Boolean.parseBoolean(c);
+
+ String s = info.getProperty(KEY_MUSIC_RFACTOR);
+ this.music_rfactor = (s == null) ? DEFAULT_MUSIC_RFACTOR : Integer.parseInt(s);
+
initializeMetricTables();
+ commitExecutorThreads = Executors.newFixedThreadPool(4);
}
public String getMusicTxDigestTableName(){
@@ -244,8 +252,16 @@ public class MusicMixin implements MusicInterface {
public static void createKeyspace(String keyspace, int replicationFactor) throws MDBCServiceException {
Map<String,Object> replicationInfo = new HashMap<>();
- replicationInfo.put("'class'", "'SimpleStrategy'");
- replicationInfo.put("'replication_factor'", replicationFactor);
+ replicationInfo.put("'class'", "'NetworkTopologyStrategy'");
+ if(replicationFactor==3){
+ replicationInfo.put("'dc1'", 1);
+ replicationInfo.put("'dc2'", 1);
+ replicationInfo.put("'dc3'", 1);
+ }
+ else {
+ replicationInfo.put("'class'", "'SimpleStrategy'");
+ replicationInfo.put("'replication_factor'", replicationFactor);
+ }
PreparedQueryObject queryObject = new PreparedQueryObject();
queryObject.appendQueryString(
@@ -317,7 +333,7 @@ public class MusicMixin implements MusicInterface {
createMusicEventualTxDigest();
createMusicNodeInfoTable();
createMusicRangeInformationTable(this.music_ns,this.musicRangeInformationTableName);
- createMusicRangeDependencyTable();
+ createMusicRangeDependencyTable(this.music_ns,this.musicRangeDependencyTableName);
}
catch(MDBCServiceException e){
logger.error(EELFLoggerDelegate.errorLogger,"Error creating tables in MUSIC");
@@ -1207,67 +1223,6 @@ public class MusicMixin implements MusicInterface {
return previous.keySet().equals(current.keySet());
}
- protected List<Range> waitForLock(LockRequest request, DatabasePartition partition,
- Map<UUID, LockResult> rowLock) throws MDBCServiceException {
- List<Range> newRanges = new ArrayList<>();
- if(partition.getMRIIndex()!=request.getId()){
- throw new MDBCServiceException("Invalid argument for wait for lock, range id in request and partition should match");
- }
- String fullyQualifiedKey= music_ns+"."+ request.getTable()+"."+request.getId();
- String lockId = MusicCore.createLockReference(fullyQualifiedKey);
- ReturnType lockReturn = acquireLock(fullyQualifiedKey,lockId);
- if(lockReturn.getResult().compareTo(ResultType.SUCCESS) != 0 ) {
- //\TODO Improve the exponential backoff
- List<Range> pendingToLock = request.getToLockRanges();
- Map<UUID, String> currentLockRef = new HashMap<>();
- int n = 1;
- int low = 1;
- int high = 1000;
- Random r = new Random();
- Map<Range, RangeMriRow> rangeRows = findRangeRows(pendingToLock);
- NavigableMap<UUID, List<Range>> rowsToLock = getPendingRows(rangeRows);
- NavigableMap<UUID, List<Range>> prevRows = new TreeMap<>();
- while (!pendingToLock.isEmpty() && isDifferent(prevRows,rowsToLock) ) {
- pendingToLock.clear();
- try {
- Thread.sleep(((int) Math.round(Math.pow(2, n)) * 1000)
- + (r.nextInt(high - low) + low));
- } catch (InterruptedException e) {
- continue;
- }
- n++;
- if (n == 20) {
- throw new MDBCServiceException("Lock was impossible to obtain, waited for 20 exponential backoffs!");
- }
- //\TODO do this in parallel
- //\TODO there is a race condition here, from the time we get the find range rows, to the time we lock the row,
- //\TODO this race condition can only be solved if require to obtain lock to all related rows in MRI
- //\TODO before fully owning the range
- //\TODO The rows need to be lock in increasing order of timestamp
- //there could be a new row created
- // Note: This loop needs to be perfomed in sorted order of timebased UUID
- for (Map.Entry<UUID, List<Range>> pending : rowsToLock.entrySet()) {
- List<Range> rs = lockRow(request, pending, currentLockRef, fullyQualifiedKey, lockId, pendingToLock, rowLock);
- newRanges.addAll(rs);
- }
- if (n++ == 20) {
- throw new MDBCServiceException(
- "Lock was impossible to obtain, waited for 20 exponential backoffs!");
- }
- rangeRows = findRangeRows(pendingToLock);
- prevRows = rowsToLock;
- rowsToLock = getPendingRows(rangeRows);
- }
- }
- else {
- partition.setLockId(lockId);
- rowLock.put(partition.getMRIIndex(),new LockResult(partition.getMRIIndex(), lockId, true, partition.getSnapshot()));
- }
- return newRanges;
- }
-
-
-
protected String createAndAssignLock(String fullyQualifiedKey, DatabasePartition partition) throws MDBCServiceException {
UUID mriIndex = partition.getMRIIndex();
String lockId;
@@ -1315,13 +1270,14 @@ public class MusicMixin implements MusicInterface {
}
}
- protected void appendIndexToMri(String lockId, UUID commitId, UUID MriIndex) throws MDBCServiceException{
- PreparedQueryObject appendQuery = createAppendMtxdIndexToMriQuery(musicRangeInformationTableName, MriIndex, musicTxDigestTableName, commitId);
- ReturnType returnType = MusicCore.criticalPut(music_ns, musicRangeInformationTableName, MriIndex.toString(), appendQuery, lockId, null);
- if(returnType.getResult().compareTo(ResultType.SUCCESS) != 0 ){
- logger.error(EELFLoggerDelegate.errorLogger, "Error when executing append operation with return type: "+returnType.getMessage());
- throw new MDBCServiceException("Error when executing append operation with return type: "+returnType.getMessage());
+ public void createAndAddTxDigest(final StagingTable transactionDigest, UUID digestId)
+ throws MDBCServiceException {
+ ByteBuffer serializedTransactionDigest;
+ serializedTransactionDigest = transactionDigest.getSerializedStagingAndClean();
+ if(useCompression){
+ serializedTransactionDigest = StagingTable.Compress(serializedTransactionDigest);
}
+ addTxDigest(digestId, serializedTransactionDigest);
}
/**
@@ -1331,9 +1287,7 @@ public class MusicMixin implements MusicInterface {
@Override
public void commitLog(DatabasePartition partition,List<Range> eventualRanges, StagingTable transactionDigest,
String txId ,TxCommitProgress progressKeeper) throws MDBCServiceException {
- // first deal with commit for eventually consistent tables
- filterAndAddEventualTxDigest(eventualRanges, transactionDigest, txId, progressKeeper);
-
+
if(partition==null){
logger.warn("Trying tcommit log with null partition");
return;
@@ -1343,7 +1297,9 @@ public class MusicMixin implements MusicInterface {
logger.warn("Trying to commit log with empty ranges");
return;
}
-
+
+ // first deal with commit for eventually consistent tables
+ filterAndAddEventualTxDigest(eventualRanges, transactionDigest, txId, progressKeeper);
UUID mriIndex = partition.getMRIIndex();
String fullyQualifiedMriKey = music_ns+"."+ this.musicRangeInformationTableName+"."+mriIndex;
@@ -1353,54 +1309,70 @@ public class MusicMixin implements MusicInterface {
throw new MDBCServiceException("Not able to commit, as you are no longer the lock-holder for this partition");
}
- UUID commitId;
- //Generate a local commit id
- if(progressKeeper.containsTx(txId)) {
- commitId = progressKeeper.getCommitId(txId);
- }
- else{
- logger.error(EELFLoggerDelegate.errorLogger, "Tx with id "+txId+" was not created in the TxCommitProgress ");
- throw new MDBCServiceException("Tx with id "+txId+" was not created in the TxCommitProgress ");
- }
//Add creation type of transaction digest
-
- //1. Push new row to RRT and obtain its index
if(transactionDigest == null || transactionDigest.isEmpty()) {
return;
}
-
- ByteBuffer serializedTransactionDigest;
- if(!transactionDigest.isEmpty()) {
- serializedTransactionDigest = transactionDigest.getSerializedStagingAndClean();
- MusicTxDigestId digestId = new MusicTxDigestId(mriIndex, -1);
- addTxDigest(digestId, serializedTransactionDigest);
- //2. Save RRT index to RQ
- if (progressKeeper != null) {
- progressKeeper.setRecordId(txId, digestId);
+
+ final MusicTxDigestId digestId = new MusicTxDigestId(MDBCUtils.generateUniqueKey(), -1);
+ Callable<Boolean> insertDigestCallable =()-> {
+ try {
+ createAndAddTxDigest(transactionDigest,digestId.transactionId);
+ return true;
+ } catch (MDBCServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Error creating and pushing tx digest to music",e);
+ return false;
}
- //3. Append RRT index into the corresponding TIT row array
- appendToRedoLog(partition, digestId);
- List<Range> ranges = partition.getSnapshot();
- for(Range r : ranges) {
- Map<Range, Pair<MriReference, Integer>> alreadyApplied = stateManager.getOwnAndCheck().getAlreadyApplied();
- if(!alreadyApplied.containsKey(r)){
- throw new MDBCServiceException("already applied data structure was not updated correctly and range "
+ };
+ Callable<Boolean> appendCallable=()-> {
+ try {
+ appendToRedoLog(music_ns, mriIndex, digestId.transactionId, lockId, musicTxDigestTableName,
+ musicRangeInformationTableName);
+ return true;
+ } catch (MDBCServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Error creating and pushing tx digest to music",e);
+ return false;
+ }
+ };
+
+ Future<Boolean> appendResultFuture = commitExecutorThreads.submit(appendCallable);
+ Future<Boolean> digestFuture = commitExecutorThreads.submit(insertDigestCallable);
+ try {
+ //Boolean appendResult = appendResultFuture.get();
+ Boolean digestResult = digestFuture.get();
+ if(/*!appendResult ||*/ !digestResult){
+ logger.error(EELFLoggerDelegate.errorLogger, "Error appending to log or adding tx digest");
+ throw new MDBCServiceException("Error appending to log or adding tx digest");
+ }
+ } catch (InterruptedException|ExecutionException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Error executing futures for creating and pushing tx " +
+ "digest to music",e);
+ throw new MDBCServiceException("Failure when retrieving futures for execution of digestion creation and append", e);
+ }
+
+ if (progressKeeper != null) {
+ progressKeeper.setRecordId(txId, digestId);
+ }
+ List<Range> ranges = partition.getSnapshot();
+ for(Range r : ranges) {
+ Map<Range, Pair<MriReference, Integer>> alreadyApplied = stateManager.getOwnAndCheck().getAlreadyApplied();
+ if(!alreadyApplied.containsKey(r)){
+ throw new MDBCServiceException("already applied data structure was not updated correctly and range "
+r+" is not contained");
- }
- Pair<MriReference, Integer> rowAndIndex = alreadyApplied.get(r);
- MriReference key = rowAndIndex.getKey();
- if(!mriIndex.equals(key.index)){
- throw new MDBCServiceException("already applied data structure was not updated correctly and range "+
- r+" is not pointing to row: "+mriIndex.toString());
- }
- alreadyApplied.put(r, Pair.of(new MriReference(mriIndex), rowAndIndex.getValue()+1));
}
+ Pair<MriReference, Integer> rowAndIndex = alreadyApplied.get(r);
+ MriReference key = rowAndIndex.getKey();
+ if(!mriIndex.equals(key.index)){
+ throw new MDBCServiceException("already applied data structure was not updated correctly and range "+
+ r+" is not pointing to row: "+mriIndex.toString());
+ }
+ alreadyApplied.put(r, Pair.of(new MriReference(mriIndex), rowAndIndex.getValue()+1));
}
}
private void filterAndAddEventualTxDigest(List<Range> eventualRanges,
- StagingTable transactionDigest, String txId,
- TxCommitProgress progressKeeper) throws MDBCServiceException {
+ StagingTable transactionDigest, String txId,
+ TxCommitProgress progressKeeper) throws MDBCServiceException {
if(eventualRanges == null || eventualRanges.isEmpty()) {
return;
@@ -1410,30 +1382,19 @@ public class MusicMixin implements MusicInterface {
throw new MDBCServiceException();
}
- UUID commitId = getCommitId(txId, progressKeeper);
+ if(!transactionDigest.isEmpty()) {
+ ByteBuffer serialized = transactionDigest.getSerializedEventuallyStagingAndClean();
- ByteBuffer serialized = transactionDigest.getSerializedEventuallyStagingAndClean();
+ if (serialized!=null && useCompression) {
+ serialized = StagingTable.Compress(serialized);
+ }
- if(serialized != null ) {
- MusicTxDigestId digestId = new MusicTxDigestId(commitId,-1);
- addEventualTxDigest(digestId, serialized);
+ if (serialized != null) {
+ MusicTxDigestId digestId = new MusicTxDigestId(MDBCUtils.generateUniqueKey(), -1);
+ addEventualTxDigest(digestId, serialized);
+ }
}
-
- }
-
- private UUID getCommitId(String txId, TxCommitProgress progressKeeper)
- throws MDBCServiceException {
- UUID commitId;
- //Generate a local commit id
- if(progressKeeper.containsTx(txId)) {
- commitId = progressKeeper.getCommitId(txId);
- }
- else{
- logger.error(EELFLoggerDelegate.errorLogger, "Tx with id "+txId+" was not created in the TxCommitProgress ");
- throw new MDBCServiceException("Tx with id "+txId+" was not created in the TxCommitProgress ");
- }
- return commitId;
}
/**
@@ -1503,7 +1464,7 @@ public class MusicMixin implements MusicInterface {
return partitions;
}
- public MusicRangeInformationRow getMRIRowFromCassandraRow(Row newRow){
+ static public MusicRangeInformationRow getMRIRowFromCassandraRow(Row newRow){
UUID partitionIndex = newRow.getUUID("rangeid");
List<TupleValue> log = newRow.getList("txredolog",TupleValue.class);
List<MusicTxDigestId> digestIds = new ArrayList<>();
@@ -1608,9 +1569,13 @@ public class MusicMixin implements MusicInterface {
DatabasePartition newPartition = info.getDBPartition();
String fullyQualifiedMriKey = music_ns+"."+ musicRangeInformationTableName+"."+newPartition.getMRIIndex().toString();
- String lockId = createAndAssignLock(fullyQualifiedMriKey, newPartition);
+ String lockId;
+ int counter=0;
+ do {
+ lockId = createAndAssignLock(fullyQualifiedMriKey, newPartition);
//TODO: fix this retry logic
- if(lockId == null || lockId.isEmpty()){
+ } while ((lockId ==null||lockId.isEmpty())&&(counter++<3));
+ if (lockId == null || lockId.isEmpty()) {
throw new MDBCServiceException("Error initializing music range information, error creating a lock for a new row" +
"for key "+fullyQualifiedMriKey) ;
}
@@ -1632,7 +1597,7 @@ public class MusicMixin implements MusicInterface {
.append(rangeAndDependencies.getRange().getTable())
.append(",{");
boolean first=true;
- for(Range r: rangeAndDependencies.dependentRanges()){
+ for (Range r: rangeAndDependencies.dependentRanges()) {
if(first){ first=false; }
else {
insert.append(',');
@@ -1658,7 +1623,7 @@ public class MusicMixin implements MusicInterface {
.append(id)
.append(",{");
boolean first=true;
- for(Range r: rangesCopy){
+ for (Range r: rangesCopy) {
if(first){ first=false; }
else {
insert.append(',');
@@ -1706,7 +1671,7 @@ public class MusicMixin implements MusicInterface {
.append(id)
.append(",{");
boolean first=true;
- for(Range r: ranges){
+ for (Range r: ranges) {
if(first){ first=false; }
else {
insert.append(',');
@@ -1731,24 +1696,32 @@ public class MusicMixin implements MusicInterface {
}
@Override
- public void appendToRedoLog(DatabasePartition partition, MusicTxDigestId newRecord) throws MDBCServiceException {
- logger.info("Appending to redo log for partition " + partition.getMRIIndex() + " txId=" + newRecord.txId);
- PreparedQueryObject appendQuery = createAppendMtxdIndexToMriQuery(musicRangeInformationTableName, partition.getMRIIndex(),
- musicTxDigestTableName, newRecord.txId);
- ReturnType returnType = MusicCore.criticalPut(music_ns, musicRangeInformationTableName, partition.getMRIIndex().toString(),
- appendQuery, partition.getLockId(), null);
- if(returnType.getResult().compareTo(ResultType.SUCCESS) != 0 ){
+ public void appendToRedoLog(UUID MRIIndex, String lockId, MusicTxDigestId newRecord) throws MDBCServiceException {
+ logger.debug("Appending to redo log for partition " + MRIIndex + " txId=" + newRecord.transactionId);
+ appendToRedoLog(music_ns,MRIIndex,newRecord.transactionId,lockId,musicTxDigestTableName,
+ musicRangeInformationTableName);
+ }
+
+ public void appendToRedoLog(String musicNamespace, UUID MRIIndex, UUID transactionId, String lockId,
+ String musicTxDigestTableName, String musicRangeInformationTableName)
+ throws MDBCServiceException{
+ PreparedQueryObject appendQuery = createAppendMtxdIndexToMriQuery(musicRangeInformationTableName, MRIIndex,
+ musicTxDigestTableName, transactionId);
+ ReturnType returnType = MusicCore.criticalPut(musicNamespace, musicRangeInformationTableName, MRIIndex.toString(),
+ appendQuery, lockId, null);
+ //returnType.getExecutionInfo()
+ if (returnType.getResult().compareTo(ResultType.SUCCESS) != 0) {
logger.error(EELFLoggerDelegate.errorLogger, "Error when executing append operation with return type: "+returnType.getMessage());
throw new MDBCServiceException("Error when executing append operation with return type: "+returnType.getMessage());
}
}
public void createMusicTxDigest() throws MDBCServiceException {
- createMusicTxDigest(-1);
+ createMusicTxDigest(this.musicTxDigestTableName,this.music_ns,-1);
}
public void createMusicEventualTxDigest() throws MDBCServiceException {
- createMusicEventualTxDigest(-1);
+ createMusicEventualTxDigest(musicEventualTxDigestTableName,music_ns,-1);
}
@@ -1758,9 +1731,9 @@ public class MusicMixin implements MusicInterface {
* * LeaseCounter: transaction number under this lease, bigint \TODO this may need to be a varint later
* * TransactionDigest: text that contains all the changes in the transaction
*/
- private void createMusicEventualTxDigest(int musicTxDigestTableNumber) throws MDBCServiceException {
- String tableName = this.musicEventualTxDigestTableName;
- if(musicTxDigestTableNumber >= 0) {
+ public static void createMusicEventualTxDigest(String musicEventualTxDigestTableName, String musicNamespace, int musicTxDigestTableNumber) throws MDBCServiceException {
+ String tableName = musicEventualTxDigestTableName;
+ if (musicTxDigestTableNumber >= 0) {
tableName = tableName +
"-" +
Integer.toString(musicTxDigestTableNumber);
@@ -1769,12 +1742,13 @@ public class MusicMixin implements MusicInterface {
StringBuilder fields = new StringBuilder();
fields.append("txid uuid, ");
fields.append("transactiondigest blob, ");
+ fields.append("compressed boolean, ");
fields.append("txTimeId TIMEUUID ");//notice lack of ','
- String cql = String.format("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));", this.music_ns, tableName, fields, priKey);
+ String cql = String.format("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));", musicNamespace, tableName, fields, priKey);
try {
- executeMusicWriteQuery(this.music_ns,tableName,cql);
+ executeMusicWriteQuery(musicNamespace,tableName,cql);
} catch (MDBCServiceException e) {
- logger.error("Initialization error: Failure to create redo records table");
+ logger.error("Initialization error: Failure to create eventual tx digest table");
throw(e);
}
}
@@ -1786,9 +1760,9 @@ public class MusicMixin implements MusicInterface {
* * LeaseCounter: transaction number under this lease, bigint \TODO this may need to be a varint later
* * TransactionDigest: text that contains all the changes in the transaction
*/
- private void createMusicTxDigest(int musicTxDigestTableNumber) throws MDBCServiceException {
- String tableName = this.musicTxDigestTableName;
- if(musicTxDigestTableNumber >= 0) {
+ public static void createMusicTxDigest(String musicTxDigestTableName, String musicNamespace, int musicTxDigestTableNumber) throws MDBCServiceException {
+ String tableName = musicTxDigestTableName;
+ if (musicTxDigestTableNumber >= 0) {
tableName = tableName +
"-" +
Integer.toString(musicTxDigestTableNumber);
@@ -1796,26 +1770,29 @@ public class MusicMixin implements MusicInterface {
String priKey = "txid";
StringBuilder fields = new StringBuilder();
fields.append("txid uuid, ");
+ fields.append("compressed boolean, ");
fields.append("transactiondigest blob ");//notice lack of ','
- String cql = String.format("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));", this.music_ns, tableName, fields, priKey);
+ String cql = String.format("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));", musicNamespace,
+ tableName, fields, priKey);
try {
- executeMusicWriteQuery(this.music_ns,tableName,cql);
+ executeMusicWriteQuery(musicNamespace,tableName,cql);
} catch (MDBCServiceException e) {
logger.error("Initialization error: Failure to create redo records table");
throw(e);
}
}
- private void createMusicRangeDependencyTable() throws MDBCServiceException {
- String tableName = this.musicRangeDependencyTableName;
+ public static void createMusicRangeDependencyTable(String musicNamespace,String musicRangeDependencyTableName)
+ throws MDBCServiceException {
+ String tableName = musicRangeDependencyTableName;
String priKey = "range";
StringBuilder fields = new StringBuilder();
fields.append("range text, ");
fields.append("dependencies set<text> ");//notice lack of ','
- String cql = String.format("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));", this.music_ns, tableName,
+ String cql = String.format("CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));", musicNamespace, tableName,
fields, priKey);
try {
- executeMusicWriteQuery(this.music_ns,tableName,cql);
+ executeMusicWriteQuery(musicNamespace,tableName,cql);
} catch (MDBCServiceException e) {
logger.error("Initialization error: Failure to create redo records table");
throw(e);
@@ -1828,18 +1805,23 @@ public class MusicMixin implements MusicInterface {
@Override
public void addTxDigest(MusicTxDigestId newId, ByteBuffer transactionDigest) throws MDBCServiceException {
//\TODO: Save Prepared query to history
+ addTxDigest(newId.transactionId,transactionDigest);
+ }
+
+ private void addTxDigest(UUID digestId, ByteBuffer transactionDigest) throws MDBCServiceException{
PreparedQueryObject query = new PreparedQueryObject();
- String cql = String.format("INSERT INTO %s.%s (txid,transactiondigest) VALUES (?,?);",this.music_ns,
+ String cql = String.format("INSERT INTO %s.%s (txid,transactiondigest,compressed ) VALUES (?,?,?);",this.music_ns,
this.musicTxDigestTableName);
query.appendQueryString(cql);
- query.addValue(newId.txId);
+ query.addValue(digestId);
query.addValue(transactionDigest);
+ query.addValue(useCompression);
//\TODO check if I am not shooting on my own foot
try {
MusicCore.nonKeyRelatedPut(query,"critical");
} catch (MusicServiceException e) {
- logger.error(EELFLoggerDelegate.errorLogger, "Transaction Digest serialization was invalid for commit "+newId.txId.toString()+ "with error "+e.getErrorMessage());
- throw new MDBCServiceException("Transaction Digest serialization for commit "+newId.txId.toString(), e);
+ logger.error(EELFLoggerDelegate.errorLogger, "Transaction Digest serialization was invalid for digest id "+digestId.toString()+ "with error "+e.getErrorMessage());
+ throw new MDBCServiceException("Transaction Digest serialization for digest id "+digestId.toString(), e);
}
}
@@ -1854,11 +1836,11 @@ public class MusicMixin implements MusicInterface {
this.music_ns +
'.' +
this.musicEventualTxDigestTableName +
- " (txid,transactiondigest,txTimeId) " +
+ " (txid,transactiondigest,compressed,txTimeId) " +
"VALUES (" +
- newId.txId + ",'" +
- transactionDigest +
- "'," +
+ newId.transactionId+ ",'" +
+ transactionDigest + "'," +
+ useCompression + ","+
// "toTimestamp(now())" +
"now()" +
");";
@@ -1867,8 +1849,8 @@ public class MusicMixin implements MusicInterface {
try {
MusicCore.nonKeyRelatedPut(query,"critical");
} catch (MusicServiceException e) {
- logger.error(EELFLoggerDelegate.errorLogger, "Transaction Digest serialization was invalid for commit "+newId.txId.toString()+ "with error "+e.getErrorMessage());
- throw new MDBCServiceException("Transaction Digest serialization for commit "+newId.txId.toString(), e);
+ logger.error(EELFLoggerDelegate.errorLogger, "Transaction Digest serialization was invalid for commit "+newId.transactionId.toString()+ "with error "+e.getErrorMessage());
+ throw new MDBCServiceException("Transaction Digest serialization for commit "+newId.transactionId.toString(), e);
}
}
@@ -1877,17 +1859,21 @@ public class MusicMixin implements MusicInterface {
String cql = String.format("SELECT * FROM %s.%s WHERE txid = ?;", music_ns, musicTxDigestTableName);
PreparedQueryObject pQueryObject = new PreparedQueryObject();
pQueryObject.appendQueryString(cql);
- pQueryObject.addValue(id.txId);
+ pQueryObject.addValue(id.transactionId);
Row newRow;
try {
newRow = executeMusicUnlockedQuorumGet(pQueryObject);
} catch (MDBCServiceException e) {
- logger.error("Get operation error: Failure to get row from txdigesttable with id:"+id.txId);
+ logger.error("Get operation error: Failure to get row from txdigesttable with id:"+id.transactionId);
throw new MDBCServiceException("Initialization error:Failure to add new row to transaction information", e);
}
ByteBuffer digest = newRow.getBytes("transactiondigest");
+ Boolean compressed = newRow.getBool("compressed");
StagingTable changes;
try {
+ if(compressed){
+ digest = StagingTable.Decompress(digest);
+ }
changes = new StagingTable(digest);
} catch (MDBCServiceException e) {
logger.error("Deserializng digest failed with an exception:"+e.getErrorMessage());
@@ -1921,10 +1907,14 @@ public class MusicMixin implements MusicInterface {
while (!rs.isExhausted()) {
Row row = rs.one();
ByteBuffer digest = row.getBytes("transactiondigest");
+ Boolean compressed = row.getBool("compressed");
//String txTimeId = row.getString("txtimeid"); //???
UUID txTimeId = row.getUUID("txtimeid");
try {
+ if(compressed){
+ digest=StagingTable.Decompress(digest);
+ }
changes = new StagingTable(digest);
} catch (MDBCServiceException e) {
logger.error("Deserializng digest failed: "+e.getErrorMessage());
@@ -1935,9 +1925,6 @@ public class MusicMixin implements MusicInterface {
return ecDigestInformation;
}
-
-
-
ResultSet getAllMriCassandraRows() throws MDBCServiceException {
StringBuilder cqlOperation = new StringBuilder();
cqlOperation.append("SELECT * FROM ")
@@ -1959,34 +1946,6 @@ public class MusicMixin implements MusicInterface {
return rows;
}
- private RangeMriRow findRangeRow(Range range) throws MDBCServiceException {
- RangeMriRow row = null;
- final ResultSet musicResults = getAllMriCassandraRows();
- while (!musicResults.isExhausted()) {
- Row musicRow = musicResults.one();
- final MusicRangeInformationRow mriRow = getMRIRowFromCassandraRow(musicRow);
- final List<Range> musicRanges = getRanges(musicRow);
- //\TODO optimize this for loop to avoid redudant access
- for(Range retrievedRange : musicRanges) {
- if (retrievedRange.overlaps(range)) {
- if(row==null){
- row = new RangeMriRow(range);
- row.setCurrentRow(mriRow);
- }
- else if(row.getCurrentRow().getTimestamp() < mriRow.getTimestamp()){
- row.addOldRow(row.getCurrentRow());
- row.setCurrentRow(mriRow);
- }
- }
- }
- }
- if(row==null){
- logger.error("Row in MRI doesn't exist for Range "+range.toString());
- throw new MDBCServiceException("Row in MRI doesn't exist for Range "+range.toString());
- }
- return row;
- }
-
/**
* This function is used to find all the related uuids associated with the required ranges
* @param ranges ranges to be find
@@ -2037,18 +1996,6 @@ public class MusicMixin implements MusicInterface {
return result;
}
- private List<Range> lockRow(LockRequest request, DatabasePartition partition,Map<UUID, LockResult> rowLock)
- throws MDBCServiceException {
- if(partition.getMRIIndex().equals(request.getId()) && partition.isLocked()){
- return new ArrayList<>();
- }
- //\TODO: this function needs to be improved, to track possible changes in the owner of a set of ranges
- String fullyQualifiedMriKey = music_ns+"."+ this.musicRangeInformationTableName+"."+request.getId().toString();
- //return List<Range> knownRanges, UUID mriIndex, String lockId
- DatabasePartition newPartition = new DatabasePartition(request.getToLockRanges(),request.getId(),null);
- return waitForLock(request,newPartition,rowLock);
- }
-
private void unlockKeyInMusic(String table, String key, String lockref) {
String fullyQualifiedKey= music_ns+"."+ table+"."+lockref;
MusicCore.destroyLockRef(fullyQualifiedKey,lockref);
@@ -2182,8 +2129,6 @@ public class MusicMixin implements MusicInterface {
return new OwnershipReturn(ownershipId, ownRow.getOwnerId(), ownRow.getIndex(),ranges,extendedDag);
}
-
-
/**
* This function is used to check if we need to create a new row in MRI, beacause one of the new ranges is not contained
* @param ranges ranges that should be contained in the partition
@@ -2199,78 +2144,7 @@ public class MusicMixin implements MusicInterface {
return false;
}
- private Map<UUID,String> mergeMriRows(String newId, Map<UUID,LockResult> lock, DatabasePartition partition)
- throws MDBCServiceException {
- Map<UUID,String> oldIds = new HashMap<>();
- List<Range> newRanges = new ArrayList<>();
- for (Map.Entry<UUID,LockResult> entry : lock.entrySet()) {
- oldIds.put(entry.getKey(),entry.getValue().getOwnerId());
- //\TODO check if we need to do a locked get? Is that even required?
- final MusicRangeInformationRow mriRow = getMusicRangeInformation(entry.getKey());
- final DatabasePartition dbPartition = mriRow.getDBPartition();
- newRanges.addAll(dbPartition.getSnapshot());
- }
- DatabasePartition newPartition = new DatabasePartition(newRanges,UUID.fromString(newId),null);
- String fullyQualifiedMriKey = music_ns+"."+ this.musicRangeInformationTableName+"."+newId;
- UUID newUUID = UUID.fromString(newId);
- LockRequest newRequest = new LockRequest(musicRangeInformationTableName,newUUID,newRanges);
- waitForLock(newRequest, newPartition,lock);
- if(!lock.containsKey(newUUID)||!lock.get(newUUID).isNewLock()){
- logger.error("When merging rows, lock returned an invalid error");
- throw new MDBCServiceException("When merging MRI rows, lock returned an invalid error");
- }
- final LockResult lockResult = lock.get(newUUID);
- partition.updateDatabasePartition(newPartition);
- logger.info("Creating MRI " +partition.getMRIIndex()+ " for ranges " + partition.getSnapshot());
- createEmptyMriRow(this.music_ns,this.musicRangeInformationTableName,partition.getMRIIndex(),myId,
- lockResult.getOwnerId(),partition.getSnapshot(),true);
- return oldIds;
- }
-
- private void obtainAllLocks(NavigableMap<UUID, List<Range>> rowsToLock,DatabasePartition partition,
- List<Range> newRanges,Map<UUID, LockResult> rowLock) throws MDBCServiceException {
- //\TODO: perform this operations in parallel
- for(Map.Entry<UUID,List<Range>> row : rowsToLock.entrySet()){
- List<Range> additionalRanges;
- try {
- LockRequest newRequest = new LockRequest(musicRangeInformationTableName,row.getKey(),row.getValue());
- additionalRanges =lockRow(newRequest, partition, rowLock);
- } catch (MDBCServiceException e) {
- //TODO: Make a decision if retry or just fail?
- logger.error("Error locking row",e);
- throw e;
- }
- newRanges.addAll(additionalRanges);
- }
- }
-
-/* @Override
- public OwnershipReturn appendRange(String rangeId, List<Range> ranges, DatabasePartition partition)
- throws MDBCServiceException {
- if(!isAppendRequired(ranges,partition)){
- return new OwnershipReturn(partition.getLockId(),UUID.fromString(rangeId),null,null);
- }
- Map<Range, RangeMriRow> rows = findRangeRows(ranges);
- final NavigableMap<UUID, List<Range>> rowsToLock = getPendingRows(rows);
- HashMap<UUID, LockResult> rowLock = new HashMap<>();
- List<Range> newRanges = new ArrayList<>();
-
- obtainAllLocks(rowsToLock,partition,newRanges,rowLock);
- String lockId;
- Map<UUID,String> oldIds = null;
- if(rowLock.size()!=1){
- oldIds = mergeMriRows(rangeId, rowLock, partition);
- lockId = partition.getLockId();
- }
- else{
- List<LockResult> list = new ArrayList<>(rowLock.values());
- LockResult lockResult = list.get(0);
- lockId = lockResult.getOwnerId();
- }
-
- return new OwnershipReturn(lockId,UUID.fromString(rangeId),oldIds,newRanges);
- }*/
@Override
public void relinquish(String ownerId, String rangeId) throws MDBCServiceException{
@@ -2290,7 +2164,9 @@ public class MusicMixin implements MusicInterface {
* @return true if we should try to relinquish, else should avoid relinquishing in this iteration
*/
private boolean canTryRelinquishing(){
- return true;
+ //\TODO: Fix this!!!! REALLY IMPORTANT TO BE FIX
+ // This should actually have some mechanism to relinquish ownership
+ return false;
}
@Override
@@ -2446,7 +2322,7 @@ public class MusicMixin implements MusicInterface {
}
public void createMusicNodeInfoTable() throws MDBCServiceException {
- createMusicNodeInfoTable(-1);
+ createMusicNodeInfoTable(musicNodeInfoTableName,music_ns,-1);
}
/**
@@ -2460,8 +2336,8 @@ public class MusicMixin implements MusicInterface {
* * TxTimeID, TIMEUUID.
* * LastTxDigestID, uuid. (not needed as of now!!)
*/
- private void createMusicNodeInfoTable(int nodeInfoTableNumber) throws MDBCServiceException {
- String tableName = this.musicNodeInfoTableName;
+ public static void createMusicNodeInfoTable(String musicNodeInfoTableName, String musicNamespace, int nodeInfoTableNumber) throws MDBCServiceException {
+ String tableName = musicNodeInfoTableName;
if(nodeInfoTableNumber >= 0) {
tableName = tableName +
"-" +
@@ -2478,13 +2354,13 @@ public class MusicMixin implements MusicInterface {
String cql = String.format(
"CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));",
- this.music_ns,
+ musicNamespace,
tableName,
fields,
priKey);
try {
- executeMusicWriteQuery(this.music_ns,tableName,cql);
+ executeMusicWriteQuery(musicNamespace,tableName,cql);
} catch (MDBCServiceException e) {
logger.error("Initialization error: Failure to create node information table");
throw(e);
@@ -2514,4 +2390,19 @@ public class MusicMixin implements MusicInterface {
}
+ @Override
+ public void deleteMriRow(MusicRangeInformationRow row) throws MDBCServiceException{
+ String cql = String.format("DELETE FROM %s.%s WHERE rangeid = ?;", music_ns, musicRangeInformationTableName);
+ PreparedQueryObject pQueryObject = new PreparedQueryObject();
+ pQueryObject.appendQueryString(cql);
+ pQueryObject.addValue(row.getPartitionIndex());
+ ReturnType rt ;
+ try {
+ rt = MusicCore.atomicPut(music_ns, musicRangeDependencyTableName, row.getPartitionIndex().toString(),
+ pQueryObject, null);
+ } catch (MusicLockingException|MusicQueryException|MusicServiceException e) {
+ logger.error("Failure when deleting mri row");
+ new MDBCServiceException("Error deleting mri row",e);
+ }
+ }
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java
index aecee24..820817b 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java
@@ -74,13 +74,15 @@ public class MySQLMixin implements DBInterface {
public static final String TRANS_TBL = "MDBC_TRANSLOG";
private static final String CREATE_TBL_SQL =
"CREATE TABLE IF NOT EXISTS "+TRANS_TBL+
- " (IX INT AUTO_INCREMENT, OP CHAR(1), TABLENAME VARCHAR(255),KEYDATA VARCHAR(1024), ROWDATA VARCHAR(1024), CONNECTION_ID INT,PRIMARY KEY (IX))";
+ " (IX INT AUTO_INCREMENT, OP CHAR(1), TABLENAME VARCHAR(255),KEYDATA VARCHAR(1024), ROWDATA VARCHAR(1024), " +
+ "CONNECTION_ID INT, PRIMARY KEY (IX));";
private final MusicInterface mi;
private final int connId;
private final String dbName;
private final Connection jdbcConn;
private final Map<String, TableInfo> tables;
+ private PreparedStatement deleteStagingStatement;
private boolean server_tbl_created = false;
public MySQLMixin() {
@@ -89,14 +91,20 @@ public class MySQLMixin implements DBInterface {
this.dbName = null;
this.jdbcConn = null;
this.tables = null;
+ this.deleteStagingStatement = null;
}
- public MySQLMixin(MusicInterface mi, String url, Connection conn, Properties info) {
+ public MySQLMixin(MusicInterface mi, String url, Connection conn, Properties info) throws SQLException {
this.mi = mi;
this.connId = generateConnID(conn);
this.dbName = getDBName(conn);
this.jdbcConn = conn;
this.tables = new HashMap<String, TableInfo>();
}
+
+ private PreparedStatement getStagingDeletePreparedStatement() throws SQLException {
+ return jdbcConn.prepareStatement("DELETE FROM "+TRANS_TBL+" WHERE (IX BETWEEN ? AND ? ) AND " +
+ "CONNECTION_ID = ?;");
+ }
// This is used to generate a unique connId for this connection to the DB.
private int generateConnID(Connection conn) {
int rv = (int) System.currentTimeMillis(); // random-ish
@@ -297,6 +305,7 @@ mysql> describe tables;
Statement stmt = jdbcConn.createStatement();
stmt.execute(CREATE_TBL_SQL);
stmt.close();
+ this.deleteStagingStatement = getStagingDeletePreparedStatement();
logger.info(EELFLoggerDelegate.applicationLogger,"createSQLTriggers: Server side dirty table created.");
server_tbl_created = true;
} catch (SQLException e) {
@@ -594,11 +603,15 @@ NEW.field refers to the new value
// copy from DB.MDBC_TRANSLOG where connid == myconnid
// then delete from MDBC_TRANSLOG
String sql2 = "SELECT IX, TABLENAME, OP, ROWDATA,KEYDATA FROM "+TRANS_TBL +" WHERE CONNECTION_ID = " + this.connId;
+ Integer biggestIx = Integer.MIN_VALUE;
+ Integer smallestIx = Integer.MAX_VALUE;
try {
ResultSet rs = executeSQLRead(sql2);
Set<Integer> rows = new TreeSet<Integer>();
while (rs.next()) {
int ix = rs.getInt("IX");
+ biggestIx = Integer.max(biggestIx,ix);
+ smallestIx = Integer.min(smallestIx,ix);
String op = rs.getString("OP");
OperationType opType = toOpEnum(op);
String tbl = rs.getString("TABLENAME");
@@ -609,17 +622,13 @@ NEW.field refers to the new value
rows.add(ix);
}
rs.getStatement().close();
+ // batch delete operations
if (rows.size() > 0) {
- //TODO: DO batch deletion
- sql2 = "DELETE FROM "+TRANS_TBL+" WHERE IX = ?";
- PreparedStatement ps = jdbcConn.prepareStatement(sql2);
- logger.debug("Executing: "+sql2);
- logger.debug(" For ix = "+rows);
- for (int ix : rows) {
- ps.setInt(1, ix);
- ps.execute();
- }
- ps.close();
+ this.deleteStagingStatement.setInt(1,smallestIx);
+ this.deleteStagingStatement.setInt(2,biggestIx);
+ this.deleteStagingStatement.setInt(3,this.connId);
+ logger.debug("Staging delete: Executing with vals ["+smallestIx+","+biggestIx+","+this.connId+"]");
+ this.deleteStagingStatement.execute();
}
} catch (SQLException e) {
logger.warn("Exception in postStatementHook: "+e);
@@ -1047,4 +1056,9 @@ NEW.field refers to the new value
String sql = "DELETE FROM " + TRANS_TBL + " WHERE CONNECTION_ID = " + this.connId;
jdbcStmt.executeQuery(sql);
}
+
+ @Override
+ public Connection getSQLConnection(){
+ return jdbcConn;
+ }
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpoint.java b/mdbc-server/src/main/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpoint.java
index 057b550..e76e1b1 100644
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpoint.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpoint.java
@@ -214,12 +214,7 @@ public class OwnershipAndCheckpoint{
checkpointLock.unlock();
break;
} else {
- final StagingTable txDigest = mi.getTxDigest(pair.getKey());
- applyTxDigest(rangesToWarmup,di, txDigest);
- for (Range r : pair.getValue()) {
- MusicRangeInformationRow row = node.getRow();
- alreadyApplied.put(r, Pair.of(new MriReference(row.getPartitionIndex()), pair.getKey().index));
- }
+ applyDigestAndUpdateDataStructures(mi, di, rangesToWarmup, node, pair);
}
pair = node.nextNotAppliedTransaction(rangeSet);
enableForeignKeys(di);
@@ -233,6 +228,24 @@ public class OwnershipAndCheckpoint{
}
}
+ private void applyDigestAndUpdateDataStructures(MusicInterface mi, DBInterface di, List<Range> ranges, DagNode node,
+ Pair<MusicTxDigestId, List<Range>> pair) throws MDBCServiceException {
+ final StagingTable txDigest;
+ try {
+ txDigest = mi.getTxDigest(pair.getKey());
+ } catch (MDBCServiceException e) {
+ logger.warn("Transaction digest was not found, this could be caused by a failure of the previous owner"
+ +"And would normally only happen as the last ID of the corresponding redo log. Please check that this is the"
+ +" case for txID "+pair.getKey().transactionId.toString());
+ return;
+ }
+ applyTxDigest(ranges,di, txDigest);
+ for (Range r : pair.getValue()) {
+ MusicRangeInformationRow row = node.getRow();
+ alreadyApplied.put(r, Pair.of(new MriReference(row.getPartitionIndex()), pair.getKey().index));
+ }
+ }
+
private void applyRequiredChanges(MusicInterface mi, DBInterface db, Dag extendedDag, List<Range> ranges, UUID ownOpId)
throws MDBCServiceException {
Set<Range> rangeSet = new HashSet<Range>(ranges);
@@ -242,12 +255,7 @@ public class OwnershipAndCheckpoint{
if(node!=null) {
Pair<MusicTxDigestId, List<Range>> pair = node.nextNotAppliedTransaction(rangeSet);
while (pair != null) {
- final StagingTable txDigest = mi.getTxDigest(pair.getKey());
- applyTxDigest(ranges, db, txDigest);
- for (Range r : pair.getValue()) {
- MusicRangeInformationRow row = node.getRow();
- alreadyApplied.put(r, Pair.of(new MriReference(row.getPartitionIndex()), pair.getKey().index));
- }
+ applyDigestAndUpdateDataStructures(mi, db, ranges, node, pair);
pair = node.nextNotAppliedTransaction(rangeSet);
if (timeout(ownOpId)) {
enableForeignKeys(db);
@@ -393,6 +401,7 @@ public class OwnershipAndCheckpoint{
return rowsPerLatestRange;
}
+
public Map<Range, Pair<MriReference, Integer>> getAlreadyApplied() {
return this.alreadyApplied;
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigest.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigest.java
deleted file mode 100644
index 5b3872a..0000000
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * ============LICENSE_START====================================================
- * org.onap.music.mdbc
- * =============================================================================
- * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
- * =============================================================================
- * 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.mdbc.tables;
-
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import org.onap.music.exceptions.MDBCServiceException;
-import org.onap.music.logging.EELFLoggerDelegate;
-import org.onap.music.mdbc.DatabasePartition;
-import org.onap.music.mdbc.MdbcConnection;
-import org.onap.music.mdbc.Range;
-import org.onap.music.mdbc.StateManager;
-import org.onap.music.mdbc.mixins.DBInterface;
-import org.onap.music.mdbc.mixins.MusicInterface;
-
-public class MusicTxDigest {
- private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicTxDigest.class);
-
- //private MdbcServerLogic mdbcServer;
- //private NodeConfiguration config;
- private StateManager stateManager;
-
- public MusicTxDigest(StateManager stateManager) {
- this.stateManager = stateManager;
- }
-
- /**
- * Runs the body of the background daemon
- * @param daemonSleepTimeS time, in seconds, between updates
- * @throws InterruptedException
- */
- public void backgroundDaemon(int daemonSleepTimeS) throws InterruptedException {
- MusicInterface mi = stateManager.getMusicInterface();
- DBInterface dbi = ((MdbcConnection) stateManager.getConnection("daemon")).getDBInterface();
-
- while (true) {
- Thread.sleep(TimeUnit.SECONDS.toMillis(daemonSleepTimeS));
- //update
- logger.info(String.format("[%s] Background MusicTxDigest daemon updating local db",
- new Timestamp(System.currentTimeMillis())));
-
- //1) get all other partitions from musicrangeinformation
- List<UUID> partitions = null;
- try {
- partitions = mi.getPartitionIndexes();
- } catch (MDBCServiceException e) {
- logger.error("Error obtainting partition indexes, trying again next iteration");
- continue;
- }
- //2) for each partition I don't own
- final Set<Range> warmupRanges = stateManager.getRangesToWarmup();
- final List<DatabasePartition> currentPartitions = stateManager.getPartitions();
- if (currentPartitions.size() != 0) {
- for (DatabasePartition part : currentPartitions) {
- List<Range> partitionRanges = part.getSnapshot();
- warmupRanges.removeAll(partitionRanges);
- }
- try {
- stateManager.getOwnAndCheck().warmup(mi, dbi, new ArrayList<>(warmupRanges));
- } catch (MDBCServiceException e) {
- logger.error("Unable to update for partition : " + warmupRanges + ". " + e.getMessage());
- continue;
- }
- }
-
- //Step 3: ReplayDigest() for E.C conditions
- try {
- replayDigest(mi,dbi, stateManager.getEventualRanges());
- } catch (MDBCServiceException e) {
- logger.error("Unable to perform Eventual Consistency operations" + e.getMessage());
- continue;
- }
-
- }
- }
-
- /**
- * Replay the digest for eventual consistency.
- * @param mi music interface
- * @param dbi interface to the database that will replay the operations
- * @param ranges only these ranges will be applied from the digests
- * @throws MDBCServiceException
- */
- public void replayDigest(MusicInterface mi, DBInterface dbi, List<Range> ranges) throws MDBCServiceException {
- StagingTable transaction;
- String nodeName = stateManager.getMdbcServerName();
-
- LinkedHashMap<UUID,StagingTable> ecDigestInformation = mi.getEveTxDigest(nodeName);
- Set<UUID> keys = ecDigestInformation.keySet();
- for(UUID txTimeID:keys){
- transaction = ecDigestInformation.get(txTimeID);
- try {
- dbi.replayTransaction(transaction, ranges); // I think this Might change if the data is coming from a new table.. ( what is the new table structure??)
- } catch (SQLException e) {
- logger.error("EC:Rolling back the entire digest replay.");
- return;
- }
- logger.info("EC: Successfully replayed transaction ");
-
- try {
- mi.updateNodeInfoTableWithTxTimeIDKey(txTimeID, nodeName);
- } catch (MDBCServiceException e) {
- logger.error("EC:Rolling back the entire digest replay.");
- }
- }
-;
- }
-
-
- /**
- * Replay the digest for a given partition
- * @param mi music interface
- * @param partitionId the partition to be replayed
- * @param dbi interface to the database that will replay the operations
- * @throws MDBCServiceException
- */
- public static void replayDigestForPartition(MusicInterface mi, UUID partitionId, DBInterface dbi) throws MDBCServiceException {
- final MusicRangeInformationRow row = mi.getMusicRangeInformation(partitionId);
- List<MusicTxDigestId> partitionsRedoLogTxIds = row.getRedoLog();
- for (MusicTxDigestId txId: partitionsRedoLogTxIds) {
- StagingTable transaction = mi.getTxDigest(txId);
- try {
- //\TODO do this two operations in parallel
- dbi.replayTransaction(transaction, row.getDBPartition().getSnapshot());
- mi.replayTransaction(transaction);
- } catch (SQLException e) {
- logger.error("Rolling back the entire digest replay. " + partitionId);
- return;
- }
- logger.info("Successfully replayed transaction " + txId);
- }
- //todo, keep track of where I am in pointer
- }
-
- /**
- * Start the background daemon defined by this object
- * Spawns a new thread and runs "backgroundDaemon"
- * @param daemonSleepTimeS time, in seconds, between updates run by daemon
- */
- public void startBackgroundDaemon(int daemonSleepTimeS) {
- class MusicTxBackgroundDaemon implements Runnable {
- public void run() {
- while (true) {
- try {
- logger.info("MusicTxDigest background daemon started");
- backgroundDaemon(daemonSleepTimeS);
- } catch (InterruptedException e) {
- logger.error("MusicTxDigest background daemon stopped " + e.getMessage());
- }
- }
- }
- }
- Thread t = new Thread(new MusicTxBackgroundDaemon());
- t.start();
-
- }
-}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestDaemon.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestDaemon.java
new file mode 100644
index 0000000..4f3a3bf
--- /dev/null
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestDaemon.java
@@ -0,0 +1,144 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc.tables;
+
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import org.onap.music.exceptions.MDBCServiceException;
+import org.onap.music.logging.EELFLoggerDelegate;
+import org.onap.music.mdbc.DatabasePartition;
+import org.onap.music.mdbc.MdbcConnection;
+import org.onap.music.mdbc.Range;
+import org.onap.music.mdbc.StateManager;
+import org.onap.music.mdbc.mixins.DBInterface;
+import org.onap.music.mdbc.mixins.MusicInterface;
+
+public class MusicTxDigestDaemon implements Runnable {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicTxDigestDaemon.class);
+
+ private StateManager stateManager;
+ private int daemonSleepTimeS;
+
+ public MusicTxDigestDaemon(int daemonSleepTimeS, StateManager stateManager) {
+ this.stateManager = stateManager;
+ this.daemonSleepTimeS = daemonSleepTimeS;
+ }
+
+ /**
+ * Replay the digest for eventual consistency.
+ *
+ * @param mi music interface
+ * @param dbi interface to the database that will replay the operations
+ * @param ranges only these ranges will be applied from the digests
+ */
+ public void replayDigest(MusicInterface mi, DBInterface dbi, List<Range> ranges) throws MDBCServiceException {
+ StagingTable transaction;
+ String nodeName = stateManager.getMdbcServerName();
+
+ LinkedHashMap<UUID, StagingTable> ecDigestInformation = mi.getEveTxDigest(nodeName);
+ Set<UUID> keys = ecDigestInformation.keySet();
+ for (UUID txTimeID : keys) {
+ transaction = ecDigestInformation.get(txTimeID);
+ try {
+ dbi.replayTransaction(transaction,
+ ranges); // I think this Might change if the data is coming from a new table.. ( what is the new table structure??)
+ } catch (SQLException e) {
+ logger.error("EC:Rolling back the entire digest replay.");
+ return;
+ }
+ logger.info("EC: Successfully replayed transaction ");
+
+ try {
+ mi.updateNodeInfoTableWithTxTimeIDKey(txTimeID, nodeName);
+ } catch (MDBCServiceException e) {
+ logger.error("EC:Rolling back the entire digest replay.");
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ logger.info("MusicTxDigest background daemon started");
+ if (stateManager == null) {
+ logger.error("State manager is null in background daemon");
+ return;
+ }
+ MusicInterface mi = stateManager.getMusicInterface();
+
+ if (mi == null) {
+ logger.error("Music interface or DB interface is null in background daemon");
+ return;
+ }
+ while (true) {
+ try {
+ MdbcConnection conn = (MdbcConnection) stateManager.getConnection("daemon");
+ if (conn == null) {
+ logger.error("Connection created is null in background daemon");
+ return;
+ }
+ DBInterface dbi = (conn).getDBInterface();
+ //update
+ logger.info(String.format("[%s] Background MusicTxDigest daemon updating local db",
+ new Timestamp(System.currentTimeMillis())));
+
+ //1) get all other partitions from musicrangeinformation
+ List<UUID> partitions = null;
+ try {
+ partitions = mi.getPartitionIndexes();
+ } catch (MDBCServiceException e) {
+ logger.error("Error obtainting partition indexes, trying again next iteration");
+ continue;
+ }
+ //2) for each partition I don't own
+ final Set<Range> warmupRanges = stateManager.getRangesToWarmup();
+ final List<DatabasePartition> currentPartitions = stateManager.getPartitions();
+ List<Range> missingRanges = new ArrayList<>();
+ if (currentPartitions.size() != 0) {
+ for (DatabasePartition part : currentPartitions) {
+ List<Range> partitionRanges = part.getSnapshot();
+ warmupRanges.removeAll(partitionRanges);
+ }
+ try {
+ stateManager.getOwnAndCheck().warmup(mi, dbi, new ArrayList<>(warmupRanges));
+ } catch (MDBCServiceException e) {
+ logger.error("Unable to update for partition : " + warmupRanges + ". " + e.getMessage());
+ continue;
+ }
+ }
+
+ //Step 3: ReplayDigest() for E.C conditions
+ try {
+ replayDigest(mi, dbi, stateManager.getEventualRanges());
+ } catch (MDBCServiceException e) {
+ logger.error("Unable to perform Eventual Consistency operations" + e.getMessage());
+ continue;
+ }
+ conn.close();
+ Thread.sleep(TimeUnit.SECONDS.toMillis(this.daemonSleepTimeS));
+ } catch (InterruptedException | SQLException e) {
+ logger.error("MusicTxDigest background daemon stopped " + e.getMessage(), e);
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestId.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestId.java
index 1c37db0..8fa49a9 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestId.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/MusicTxDigestId.java
@@ -22,16 +22,16 @@ package org.onap.music.mdbc.tables;
import java.util.UUID;
public final class MusicTxDigestId {
- public final UUID txId;
+ public final UUID transactionId;
public final int index;
- public MusicTxDigestId(UUID primaryKey, int index) {
- this.txId= primaryKey;
+ public MusicTxDigestId(UUID digestId, int index) {
+ this.transactionId= digestId;
this.index=index;
}
public boolean isEmpty() {
- return (this.txId==null);
+ return (this.transactionId==null);
}
@Override
@@ -40,11 +40,11 @@ public final class MusicTxDigestId {
if(o == null) return false;
if(!(o instanceof MusicTxDigestId)) return false;
MusicTxDigestId other = (MusicTxDigestId) o;
- return other.txId.equals(this.txId);
+ return other.transactionId.equals(this.transactionId);
}
@Override
public int hashCode(){
- return txId.hashCode();
+ return transactionId.hashCode();
}
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java
index a9ab25f..eda6191 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java
@@ -43,6 +43,18 @@ public final class Operation implements Serializable{
KEY = key;
}
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ Operation clone = null;
+ try {
+ clone = (Operation) super.clone();
+ }
+ catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ return clone;
+ }
+
public String getTable(){
return TABLE;
}
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java
index 03c7259..dbed9e4 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java
@@ -21,11 +21,14 @@ package org.onap.music.mdbc.tables;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+import javax.validation.constraints.Null;
import org.onap.music.exceptions.MDBCServiceException;
import org.onap.music.logging.EELFLoggerDelegate;
import org.onap.music.mdbc.Range;
@@ -36,7 +39,7 @@ import org.onap.music.mdbc.proto.ProtoDigest.Digest.Row.OpType;
public class StagingTable {
- private transient static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(StagingTable.class);
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(StagingTable.class);
private ArrayList<Operation> operations;
boolean builderInitialized;
Builder digestBuilder;
@@ -47,6 +50,40 @@ public class StagingTable {
this(new HashSet<>());
logger.debug("Creating staging table with no parameters, most likely this is wrong, unless you are testing");
}
+
+ public StagingTable(StagingTable other) throws CloneNotSupportedException {
+ if(other==null){
+ throw new NullPointerException("Invalid constructor parameter passed, it is null");
+ }
+ //TODO this is a highly inefficient deep copy, please don't use in prod
+ operations=null;
+ if(other.operations!=null) {
+ Iterator<Operation> iterator = other.operations.iterator();
+ operations = new ArrayList<>();
+ while (iterator.hasNext()) {
+ operations.add((Operation) iterator.next().clone());
+ }
+ }
+ builderInitialized=other.builderInitialized;
+ digestBuilder=null;
+ if(other.digestBuilder!=null) {
+ CompleteDigest build = other.digestBuilder.build();
+ digestBuilder = build.toBuilder();
+ }
+ eventuallyBuilder=null;
+ if(other.eventuallyBuilder!=null) {
+ CompleteDigest build2 = other.digestBuilder.build();
+ eventuallyBuilder = build2.toBuilder();
+ }
+ eventuallyConsistentRanges=null;
+ if(other.eventuallyConsistentRanges!=null) {
+ eventuallyConsistentRanges = new HashSet<>();
+ Iterator<Range> rangeIter = other.eventuallyConsistentRanges.iterator();
+ while (rangeIter.hasNext()) {
+ eventuallyConsistentRanges.add(rangeIter.next().clone());
+ }
+ }
+ }
public StagingTable(Set<Range> eventuallyConsistentRanges) {
//operations = new ArrayList<Operation>();
@@ -74,6 +111,67 @@ public class StagingTable {
}
}
+ public static ByteBuffer Compress(ByteBuffer serializedStaging) throws MDBCServiceException {
+ if(serializedStaging.hasArray()) {
+ //\TODO: Use JAVA 11 to simplify this process using ByteBuffer natively
+ Deflater compressor = new Deflater();
+ final byte[] inputArray = serializedStaging.array();
+ compressor.setInput(inputArray);
+ compressor.finish();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(serializedStaging.array().length);
+ byte[] buf = new byte[1024];
+ try {
+ while (!compressor.finished()) {
+ int i = compressor.deflate(buf);
+ bos.write(buf, 0, i);
+ }
+ } finally {
+ compressor.end();
+ try {
+ bos.close();
+ } catch (IOException e) {
+ throw new MDBCServiceException("Error closing ByetArrayOutputStream:",e);
+ }
+ }
+ byte[] output = bos.toByteArray();
+ logger.debug("Staging table compressed from: "+inputArray.length+" to "+output.length);
+ return ByteBuffer.wrap(output);
+ }
+ else{
+ throw new MDBCServiceException("Byte buffer was not created correctly, it should wrap an array");
+ }
+ }
+
+ public static ByteBuffer Decompress(ByteBuffer compressedStaging) throws MDBCServiceException {
+ if(compressedStaging.hasArray()) {
+ //\TODO: Use JAVA 11 to simplify this process using ByteBuffer natively
+ Inflater decompressor = new Inflater();
+ byte[] inputArray = compressedStaging.array();
+ decompressor.setInput(inputArray);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(inputArray.length);
+ byte[] buffer = new byte[1024];
+ while (!decompressor.finished()) {
+ int decompressSize = 0;
+ try {
+ decompressSize = decompressor.inflate(buffer);
+ } catch (DataFormatException e) {
+ throw new MDBCServiceException("error decompressing input data",e);
+ }
+ outputStream.write(buffer, 0, decompressSize);
+ }
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ throw new MDBCServiceException("Error closing output byte stream",e);
+ }
+ byte[] output = outputStream.toByteArray();
+ return ByteBuffer.wrap(output);
+ }
+ else{
+ throw new MDBCServiceException("Byte buffer was not created correctly, it should wrap an array");
+ }
+ }
+
synchronized public boolean isBuilderInitialized(){
return isBuilderInitialized();
}
@@ -108,7 +206,7 @@ public class StagingTable {
}
logger.warn("Get operation list with this type of initialization is not suggested for the"
+ "staging table");
- ArrayList newOperations = new ArrayList();
+ ArrayList<Operation> newOperations = new ArrayList<>();
for(Row row : digestBuilder.getRowsList()){
final OpType type = row.getType();
OperationType newType = (type==OpType.INSERT)?OperationType.INSERT:(type==OpType.DELETE)?
@@ -123,9 +221,10 @@ public class StagingTable {
throw new MDBCServiceException("This type of staging table is unmutable, please use the constructor"
+ "with no parameters");
}
- ByteString serialized = digestBuilder.build().toByteString();
+ byte[] bytes = digestBuilder.build().toByteArray();
+ ByteBuffer serialized = ByteBuffer.wrap(bytes);
digestBuilder.clear();
- return serialized.asReadOnlyByteBuffer();
+ return serialized;
}
synchronized public ByteBuffer getSerializedEventuallyStagingAndClean() throws MDBCServiceException {
@@ -136,9 +235,10 @@ public class StagingTable {
if(eventuallyBuilder == null || eventuallyBuilder.getRowsCount()==0){
return null;
}
- ByteString serialized = eventuallyBuilder.build().toByteString();
+ byte[] bytes = eventuallyBuilder.build().toByteArray();
+ ByteBuffer serialized = ByteBuffer.wrap(bytes);
eventuallyBuilder.clear();
- return serialized.asReadOnlyByteBuffer();
+ return serialized;
}
synchronized public boolean isEmpty() {
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tools/ClusterSetup.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tools/ClusterSetup.java
new file mode 100644
index 0000000..d560915
--- /dev/null
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/tools/ClusterSetup.java
@@ -0,0 +1,80 @@
+/*
+ * ============LICENSE_START====================================================
+ * org.onap.music.mdbc
+ * =============================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * =============================================================================
+ * 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.mdbc.tools;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import java.io.FileNotFoundException;
+import org.onap.music.exceptions.MDBCServiceException;
+import org.onap.music.logging.EELFLoggerDelegate;
+import org.onap.music.main.MusicUtil;
+import org.onap.music.mdbc.configurations.ClusterConfiguration;
+
+public class ClusterSetup {
+ public static final EELFLoggerDelegate LOG = EELFLoggerDelegate.getLogger(ClusterSetup.class);
+
+ @Parameter(names = { "-c", "--configuration" }, required = true,
+ description = "This is the input file that is going to have the configuration to setup the cluster")
+ private String configurationFile;
+ @Parameter(names = { "-h", "-help", "--help" }, help = true,
+ description = "Print the help message")
+ private boolean help = false;
+
+ private ClusterConfiguration inputConfig;
+
+ public ClusterSetup(){}
+
+
+ public void readInput(){
+ LOG.info("Reading inputs");
+ try {
+ inputConfig = ClusterConfiguration.readJsonFromFile(configurationFile);
+ } catch (FileNotFoundException e) {
+ LOG.error("Input file is invalid or not found");
+ System.exit(1);
+ }
+ }
+
+ public void createAll() throws MDBCServiceException {
+ inputConfig.initNamespaces();
+ inputConfig.initTables();
+ }
+
+ public static void main(String[] args) {
+ LOG.info("Starting cassandra cluster initializer");
+ LOG.info("Using music file configuration:"+ MusicUtil.getMusicPropertiesFilePath());
+ ClusterSetup configs = new ClusterSetup();
+ @SuppressWarnings("deprecation")
+ JCommander jc = new JCommander(configs, args);
+ if (configs.help) {
+ jc.usage();
+ System.exit(1);
+ return;
+ }
+ configs.readInput();
+ try {
+ configs.createAll();
+ } catch (MDBCServiceException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.exit(0);
+ }
+}
diff --git a/mdbc-server/src/main/resources/music.properties b/mdbc-server/src/main/resources/music.properties
index 0b34ff9..1aaf7fd 100755
--- a/mdbc-server/src/main/resources/music.properties
+++ b/mdbc-server/src/main/resources/music.properties
@@ -5,4 +5,4 @@ cassandra.user =\
cassandra.password =\
cassandra
music_namespace =\
- mdbc_namespace \ No newline at end of file
+ mdbc_namespace
diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/MusicTxDigestTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/MusicTxDigestTest.java
index 11ec272..7f1c0e1 100644
--- a/mdbc-server/src/test/java/org/onap/music/mdbc/MusicTxDigestTest.java
+++ b/mdbc-server/src/test/java/org/onap/music/mdbc/MusicTxDigestTest.java
@@ -26,7 +26,7 @@ import java.io.IOException;
import java.util.HashMap;
import org.junit.Test;
-import org.onap.music.mdbc.tables.MusicTxDigest;
+import org.onap.music.mdbc.tables.MusicTxDigestDaemon;
import org.onap.music.mdbc.tables.StagingTable;
diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java b/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java
index 291179a..e5a3252 100755
--- a/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java
+++ b/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java
@@ -20,11 +20,8 @@
package org.onap.music.mdbc;
import com.datastax.driver.core.*;
-import com.datastax.driver.core.exceptions.QueryExecutionException;
-import com.datastax.driver.core.exceptions.SyntaxError;
import org.onap.music.exceptions.MDBCServiceException;
import org.onap.music.exceptions.MusicLockingException;
-import org.onap.music.lockingservice.cassandra.CassaLockStore;
import org.onap.music.lockingservice.cassandra.MusicLockState;
import org.onap.music.logging.EELFLoggerDelegate;
import org.onap.music.main.MusicCore;
@@ -38,16 +35,12 @@ import java.util.*;
import org.onap.music.mdbc.mixins.MusicInterface;
import org.onap.music.mdbc.tables.MusicRangeInformationRow;
-import static junit.framework.TestCase.assertNotNull;
-import static junit.framework.TestCase.fail;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
public class TestUtils {
private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(TestUtils.class);
- public static DatabasePartition createBasicRow(Range range, MusicInterface mixin, String mdbcServerName){
+ public static DatabasePartition createBasicRow(Range range, MusicInterface mixin, String mdbcServerName)
+ throws MDBCServiceException {
final UUID uuid = MDBCUtils.generateTimebasedUniqueKey();
List<Range> ranges = new ArrayList<>();
ranges.add(range);
@@ -55,21 +48,14 @@ public class TestUtils {
MusicRangeInformationRow newRow = new MusicRangeInformationRow(uuid,dbPartition, new ArrayList<>(), "",
mdbcServerName, true);
DatabasePartition partition=null;
- try {
- partition = mixin.createMusicRangeInformation(newRow);
- } catch (MDBCServiceException e) {
- fail("failure when creating new row");
- }
+ partition = mixin.createMusicRangeInformation(newRow);
return partition;
}
- public static void unlockRow(String keyspace, String mriTableName, DatabasePartition partition){
+ public static void unlockRow(String keyspace, String mriTableName, DatabasePartition partition)
+ throws MusicLockingException {
String fullyQualifiedMriKey = keyspace+"."+ mriTableName+"."+partition.getMRIIndex().toString();
- try {
- MusicLockState musicLockState = MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey, partition.getLockId());
- } catch (MusicLockingException e) {
- fail("failure when releasing lock");
- }
+ MusicLockState musicLockState = MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey, partition.getLockId());
}
public static void createKeyspace(String keyspace, Session session) {
@@ -78,15 +64,7 @@ public class TestUtils {
" WITH REPLICATION " +
"= {'class':'SimpleStrategy', 'replication_factor':1}; ";
ResultSet res=null;
- try {
- res = session.execute(queryOp);
- }
- catch(QueryExecutionException e){
- fail("Failure executing creation of keyspace with error: " + e.getMessage());
- } catch(SyntaxError e){
- fail("Failure executing creation of keyspace with syntax error: " + e.getMessage());
- }
- assertTrue("Keyspace "+keyspace+" is already being used, please change it to avoid loosing data",res.wasApplied());
+ res = session.execute(queryOp);
}
public static void deleteKeyspace(String keyspace, Session session){
@@ -94,7 +72,6 @@ public class TestUtils {
keyspace +
";";
ResultSet res = session.execute(queryBuilder);
- assertTrue("Keyspace "+keyspace+" doesn't exist and it should",res.wasApplied());
}
public static HashSet<String> getMriColNames(){
@@ -109,14 +86,18 @@ public class TestUtils {
);
}
- public static HashMap<String, DataType> getMriColTypes(Cluster cluster){
+ public static HashMap<String, DataType> getMriColTypes(Cluster cluster) throws Exception {
HashMap<String, DataType> expectedTypes = new HashMap<>();
expectedTypes.put("rangeid",DataType.uuid());
expectedTypes.put("keys",DataType.set(DataType.text()));
ProtocolVersion currentVer = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();
- assertNotNull("Protocol version for cluster is invalid", currentVer);
+ if(currentVer != null) {
+ throw new Exception("Protocol version for cluster is invalid");
+ }
CodecRegistry registry = cluster.getConfiguration().getCodecRegistry();
- assertNotNull("Codec registry for cluster is invalid", registry);
+ if(registry!= null) {
+ throw new Exception("Codec registry for cluster is invalid");
+ }
expectedTypes.put("txredolog",DataType.list(TupleType.of(currentVer,registry,DataType.text(),DataType.uuid())));
expectedTypes.put("ownerid",DataType.text());
expectedTypes.put("metricprocessid",DataType.text());
@@ -131,15 +112,19 @@ public class TestUtils {
}
public static void checkDataTypeForTable(List<ColumnMetadata> columnsMeta, HashSet<String> expectedColumns,
- HashMap<String,DataType> expectedTypes){
+ HashMap<String,DataType> expectedTypes) throws Exception {
for(ColumnMetadata cMeta : columnsMeta){
String columnName = cMeta.getName();
DataType type = cMeta.getType();
- assertTrue("Invalid column name: "+columnName,expectedColumns.contains(columnName));
- assertTrue("Fix the contents of expectedtypes for column: "+columnName,
- expectedTypes.containsKey(columnName));
- assertEquals("Invalid type for column: "+columnName,
- expectedTypes.get(columnName),type);
+ if(!expectedColumns.contains(columnName)){
+ throw new Exception("Invalid column name: ");
+ }
+ if(!expectedTypes.containsKey(columnName)){
+ throw new Exception("Fix the contents of expectedtypes for column: "+columnName);
+ }
+ if(expectedTypes.get(columnName)!=type) {
+ throw new Exception("Invalid type for column: "+columnName);
+ }
}
}
diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java
index e8b7511..aba8cb4 100644
--- a/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java
+++ b/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java
@@ -122,8 +122,18 @@ public class MusicMixinTest {
// Range range = new Range("TABLE1");
// List<Range> ranges = new ArrayList<>();
// ranges.add(range);
-// final DatabasePartition partition = TestUtils.createBasicRow(range, mixin, mdbcServerName);
-// TestUtils.unlockRow(keyspace,mriTableName,partition);
+// DatabasePartition partition=null;
+// try {
+// partition = TestUtils.createBasicRow(range, mixin, mdbcServerName);
+// }
+// catch(Exception e){
+// fail(e.getMessage());
+// }
+// try {
+// TestUtils.unlockRow(keyspace,mriTableName,partition);
+// } catch (MusicLockingException e) {
+// fail(e.getMessage());
+// }
//
// DatabasePartition currentPartition = new DatabasePartition(MDBCUtils.generateTimebasedUniqueKey());
// try {
@@ -229,7 +239,6 @@ public class MusicMixinTest {
// assertFalse(node3Row.getIsLatest());
// }
-
@Test
public void relinquish() {
}
diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java
index 7db973c..eb01bcd 100644
--- a/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java
+++ b/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java
@@ -149,6 +149,7 @@ public class OwnershipAndCheckpointTest {
Properties properties = new Properties();
properties.setProperty(MusicMixin.KEY_MY_ID,mdbcServerName);
properties.setProperty(MusicMixin.KEY_MUSIC_NAMESPACE,keyspace);
+ properties.setProperty(MusicMixin.KEY_MUSIC_RFACTOR,"1");
//StateManager stateManager = new StateManager("dbUrl", properties, "serverName", "dbName");
ownAndCheck = new OwnershipAndCheckpoint();
musicMixin =new MusicMixin(stateManager, mdbcServerName,properties);
@@ -175,7 +176,12 @@ public class OwnershipAndCheckpointTest {
TxCommitProgress progressKeeper = new TxCommitProgress();
progressKeeper.createNewTransactionTracker(id ,this.conn);
musicMixin.commitLog(partition, null, stagingTable, id, progressKeeper);
- TestUtils.unlockRow(keyspace,mriTableName,partition);
+ try {
+ TestUtils.unlockRow(keyspace, mriTableName, partition);
+ }
+ catch(Exception e){
+ fail(e.getMessage());
+ }
}
private OwnershipReturn cleanAndOwnPartition(List<Range> ranges, UUID ownOpId) throws SQLException {
@@ -265,4 +271,4 @@ public class OwnershipAndCheckpointTest {
private void cleanAlreadyApplied(OwnershipAndCheckpoint ownAndCheck) {
ownAndCheck.getAlreadyApplied().clear();
}
-} \ No newline at end of file
+}
diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java
index 63147e3..e39cc95 100644
--- a/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java
+++ b/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java
@@ -22,7 +22,7 @@ import java.util.HashMap;
import java.util.List;
import org.apache.calcite.sql.parser.SqlParseException;
import org.junit.Test;
-import org.onap.music.mdbc.tables.MusicTxDigest;
+import org.onap.music.mdbc.tables.MusicTxDigestDaemon;
import org.onap.music.mdbc.tables.StagingTable;
diff --git a/pom.xml b/pom.xml
index 33acc6e..c59e7b2 100755
--- a/pom.xml
+++ b/pom.xml
@@ -99,6 +99,7 @@
<module>mdbc-server</module>
<module>mdbc-packages</module>
<module>mdbc-benchmark</module>
+ <module>mdbc-internal-benchmark</module>
</modules>
<dependencies>
@@ -128,11 +129,6 @@
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
- <dependency>
- <groupId>org.mariadb.jdbc</groupId>
- <artifactId>mariadb-java-client</artifactId>
- <version>2.3.0</version>
- </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>