aboutsummaryrefslogtreecommitdiffstats
path: root/dblib
diff options
context:
space:
mode:
Diffstat (limited to 'dblib')
-rwxr-xr-xdblib/.gitignore34
-rwxr-xr-xdblib/README.md6
-rwxr-xr-xdblib/features/pom.xml133
-rwxr-xr-xdblib/features/src/main/resources/features.xml17
-rwxr-xr-xdblib/installer/pom.xml136
-rwxr-xr-xdblib/installer/src/assembly/assemble_installer_zip.xml37
-rwxr-xr-xdblib/installer/src/assembly/assemble_mvnrepo_zip.xml27
-rw-r--r--dblib/installer/src/main/resources/scripts/install-feature.sh19
-rwxr-xr-xdblib/pom.xml126
-rwxr-xr-xdblib/provider/pom.xml74
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java521
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java47
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java47
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java113
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java39
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java940
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java27
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java33
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java33
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java46
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java45
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java82
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java104
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java60
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java31
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JndiConfiguration.java62
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java46
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java106
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java103
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java37
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java186
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java220
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java167
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java131
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java217
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java237
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java37
-rwxr-xr-xdblib/provider/src/main/resources/dblib.properties13
-rwxr-xr-xdblib/provider/src/test/resources/dblib.properties16
39 files changed, 4355 insertions, 0 deletions
diff --git a/dblib/.gitignore b/dblib/.gitignore
new file mode 100755
index 0000000..b73caf3
--- /dev/null
+++ b/dblib/.gitignore
@@ -0,0 +1,34 @@
+#####standard .git ignore entries#####
+
+## IDE Specific Files ##
+org.eclipse.core.resources.prefs
+.classpath
+.project
+.settings
+.idea
+.externalToolBuilders
+maven-eclipse.xml
+workspace
+
+## Compilation Files ##
+*.class
+**/target
+target
+target-ide
+MANIFEST.MF
+
+## Misc Ignores (OS specific etc) ##
+bin/
+dist
+*~
+*.ipr
+*.iml
+*.iws
+classes
+out/
+.DS_STORE
+.metadata
+
+## Folders which contain auto generated source code ##
+yang-gen-config
+yang-gen-sal
diff --git a/dblib/README.md b/dblib/README.md
new file mode 100755
index 0000000..19e3a34
--- /dev/null
+++ b/dblib/README.md
@@ -0,0 +1,6 @@
+DBLIB Urility
+---------------------
+
+DBKLIB utility is designed as a high availability connection manager.
+It is configured to use multiple databases, and based on the configured rules
+always provide the connection to te active database.
diff --git a/dblib/features/pom.xml b/dblib/features/pom.xml
new file mode 100755
index 0000000..b3fc853
--- /dev/null
+++ b/dblib/features/pom.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>dblib</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>dblib-features</artifactId>
+ <name>DBLIB Adaptor - Features</name>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <version>${odl.mdsal.features.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+
+ <scope>runtime</scope>
+ </dependency>
+
+
+ <!-- dependency for opendaylight-karaf-empty for use by testing -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>opendaylight-karaf-empty</artifactId>
+ <version>${odl.karaf.empty.distro.version}</version>
+ <type>zip</type>
+ </dependency>
+
+ <dependency>
+ <!-- Required for launching the feature tests -->
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-test</artifactId>
+ <version>${odl.commons.opendaylight.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${odl.yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- launches the feature test, which validates that your karaf feature
+ can be installed inside of a karaf container. It doesn't validate that your
+ functionality works correctly, just that you have all of the dependent bundles
+ defined correctly.
+ <plugin>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/dblib/features/src/main/resources/features.xml b/dblib/features/src/main/resources/features.xml
new file mode 100755
index 0000000..cc080aa
--- /dev/null
+++ b/dblib/features/src/main/resources/features.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="sdnc-dblib-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository>
+
+
+ <feature name='sdnc-dblib' description="sdnc-dblib" version='${project.version}'>
+ <!-- Most applications will have a dependency on the ODL MD-SAL Broker -->
+ <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
+ <bundle>mvn:org.openecomp.sdnc.core/dblib-provider/${project.version}</bundle>
+ <bundle>mvn:mysql/mysql-connector-java/${mysql.connector.version}</bundle>
+ </feature>
+
+</features>
diff --git a/dblib/installer/pom.xml b/dblib/installer/pom.xml
new file mode 100755
index 0000000..ba452e3
--- /dev/null
+++ b/dblib/installer/pom.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>dblib</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>dblib-installer</artifactId>
+ <name>DBLIB Adaptor - Karaf Installer</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>sdnc-dblib</application.name>
+ <features.boot>sdnc-dblib</features.boot>
+ <features.repositories>mvn:org.openecomp.sdnc.core/dblib-features/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>maven-repo-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <attach>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ <execution>
+ <id>installer-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <attach>true</attach>
+ <finalName>${application.name}-${project.version}-installer</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_installer_zip.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <transitive>false</transitive>
+ <outputDirectory>${project.build.directory}/assembly/system</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <useRepositoryLayout>true</useRepositoryLayout>
+ <addParentPoms>false</addParentPoms>
+ <copyPom>false</copyPom>
+ <includeGroupIds>org.openecomp.sdnc</includeGroupIds>
+ <excludeArtifactIds>sli-common,sli-provider</excludeArtifactIds>
+ <scope>provided</scope>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <execution>
+ <id>copy-version</id>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals><!-- here the phase you need -->
+ <phase>validate</phase>
+ <configuration>
+ <outputDirectory>${basedir}/target/stage</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources/scripts</directory>
+ <includes>
+ <include>install-feature.sh</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+
+</project>
diff --git a/dblib/installer/src/assembly/assemble_installer_zip.xml b/dblib/installer/src/assembly/assemble_installer_zip.xml
new file mode 100755
index 0000000..4716c7a
--- /dev/null
+++ b/dblib/installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,37 @@
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>755</fileMode>
+ <includes>
+ <include>*.sh</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>644</fileMode>
+ <excludes>
+ <exclude>*.sh</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/dblib/installer/src/assembly/assemble_mvnrepo_zip.xml b/dblib/installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100755
index 0000000..92cd930
--- /dev/null
+++ b/dblib/installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,27 @@
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/dblib/installer/src/main/resources/scripts/install-feature.sh b/dblib/installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 0000000..16b5be8
--- /dev/null
+++ b/dblib/installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+INSTALLERDIR=$(dirname $0)
+
+REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip
+
+if [ -f ${REPOZIP} ]
+then
+ unzip -d ${ODL_HOME} ${REPOZIP}
+else
+ echo "ERROR : repo zip ($REPOZIP) not found"
+ exit 1
+fi
+
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
diff --git a/dblib/pom.xml b/dblib/pom.xml
new file mode 100755
index 0000000..4d02c7d
--- /dev/null
+++ b/dblib/pom.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sdnc-core</artifactId>
+ <version>1.0.0</version>
+ </parent>
+
+
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>pom</packaging>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib</artifactId>
+
+
+ <name>DBLIB Adaptor</name>
+ <description>The DBLIB adaptor allows service logic to access persistent data in a local sql database</description>
+
+ <version>1.0.0</version>
+
+ <build>
+ <plugins>
+ <plugin>
+
+ <groupId>org.codehaus.mojo</groupId>
+
+ <artifactId>license-maven-plugin</artifactId>
+
+ <version>1.9</version>
+
+ <configuration>
+
+ <licenseName>apache_v2</licenseName>
+
+ <inceptionYear>2016</inceptionYear>
+
+ <organizationName>AT&amp;T</organizationName>
+
+ <projectName>openecomp</projectName>
+
+ <roots>
+
+ <root>src/main/java</root>
+
+ </roots>
+
+ <excludes>
+
+ <exclude>*.png</exclude>
+
+ </excludes>
+
+ </configuration>
+
+ </plugin>
+ </plugins>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.4</version>
+ <dependencies>
+ <dependency><!-- add support for ssh/scp -->
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven.compile.plugin.version}</version>
+ <configuration>
+ <source>${java.version.source}</source>
+ <target>${java.version.target}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10</version>
+
+ <executions>
+ <execution>
+ <id>aggregate</id>
+ <goals>
+ <goal>aggregate</goal>
+ </goals>
+ <phase>site</phase>
+
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.1</version>
+ <executions>
+ <execution>
+ <id>bundle-sources</id>
+ <phase>package</phase>
+ <goals>
+ <!-- produce source artifact for main project sources -->
+ <goal>jar-no-fork</goal>
+
+ <!-- produce source artifact for project test sources -->
+ <goal>test-jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </pluginManagement>
+ </build>
+ <organization>
+ <name>AT&amp;T</name>
+ </organization>
+ <modules>
+ <module>provider</module>
+ <module>features</module>
+ <module>installer</module>
+ </modules>
+</project>
diff --git a/dblib/provider/pom.xml b/dblib/provider/pom.xml
new file mode 100755
index 0000000..c46b2e8
--- /dev/null
+++ b/dblib/provider/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>dblib-provider</artifactId>
+ <version>1.0.0</version>
+ <packaging>bundle</packaging>
+ <name>DBLIB Adaptor - Provider</name>
+ <url>http://maven.apache.org</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>${equinox.osgi.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${mysql.connector.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.openecomp.sdnc.sli.resource.dblib</Bundle-SymbolicName>
+ <Bundle-Activator>org.openecomp.sdnc.sli.resource.dblib.DBLIBResourceActivator</Bundle-Activator>
+ <Export-Package>org.openecomp.sdnc.sli.resource.dblib;version=${project.version}</Export-Package>
+ <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.mysql.jdbc.*,javax.sql.*</Import-Package>
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+ </configuration>
+
+ </plugin>
+
+
+ </plugins>
+ </build>
+</project>
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java
new file mode 100644
index 0000000..e21e2be
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java
@@ -0,0 +1,521 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Observer;
+
+import javax.sql.DataSource;
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.RowSetProvider;
+
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitor;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitorObserver;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitor.TestObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * @version $Revision: 1.13 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+
+public abstract class CachedDataSource implements DataSource, SQLExecutionMonitorObserver
+{
+ private static Logger LOGGER = LoggerFactory.getLogger(CachedDataSource.class);
+
+ protected static final String AS_CONF_ERROR = "AS_CONF_ERROR: ";
+
+ protected long CONN_REQ_TIMEOUT = 30L;
+ protected long DATA_REQ_TIMEOUT = 100L;
+
+ private final SQLExecutionMonitor monitor;
+ protected DataSource ds = null;
+ protected String connectionName = null;
+ protected boolean initialized = false;
+
+ private long interval = 1000;
+ private long initisalDelay = 5000;
+ private long expectedCompletionTime = 50L;
+ private boolean canTakeOffLine = true;
+ private long unprocessedFailoverThreshold = 3L;
+
+
+ public CachedDataSource(BaseDBConfiguration jdbcElem) throws DBConfigException
+ {
+ configure(jdbcElem);
+ monitor = new SQLExecutionMonitor(this);
+ }
+
+ protected abstract void configure(BaseDBConfiguration jdbcElem) throws DBConfigException;
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException
+ {
+ return ds.getConnection();
+ }
+
+ public CachedRowSet getData(String statement, ArrayList<String> arguments) throws SQLException, Throwable
+ {
+ TestObject testObject = null;
+ testObject = monitor.registerRequest();
+
+ Connection connection = null;
+ try {
+ connection = this.getConnection();
+ if(connection == null ) {
+ throw new SQLException("Connection invalid");
+ }
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Obtained connection <" + connectionName + ">: "+connection.toString());
+ return executePreparedStatement(connection, statement, arguments);
+ } finally {
+ try {
+ if(connection != null && !connection.isClosed()) {
+ connection.close();
+ }
+ } catch(Throwable exc) {
+ // the exception not monitored
+ } finally {
+ connection = null;
+ }
+
+ monitor.deregisterReguest(testObject);
+ }
+ }
+
+ public boolean writeData(String statement, ArrayList<String> arguments) throws SQLException, Throwable
+ {
+ TestObject testObject = null;
+ testObject = monitor.registerRequest();
+
+ Connection connection = null;
+ try {
+ connection = this.getConnection();
+ if(connection == null ) {
+ throw new SQLException("Connection invalid");
+ }
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Obtained connection <" + connectionName + ">: "+connection.toString());
+ return executeUpdatePreparedStatement(connection, statement, arguments);
+ } finally {
+ try {
+ if(connection != null && !connection.isClosed()) {
+ connection.close();
+ }
+ } catch(Throwable exc) {
+ // the exception not monitored
+ } finally {
+ connection = null;
+ }
+
+ monitor.deregisterReguest(testObject);
+ }
+ }
+
+ private CachedRowSet executePreparedStatement(Connection conn, String statement, ArrayList<String> arguments) throws SQLException, Throwable {
+ long time = System.currentTimeMillis();
+
+ CachedRowSet data = null;
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL Statement: "+ statement);
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.debug("Argunments: "+ Arrays.toString(arguments.toArray()));
+ }
+ }
+
+ ResultSet rs = null;
+ try {
+ data = RowSetProvider.newFactory().createCachedRowSet();
+ PreparedStatement ps = conn.prepareStatement(statement);
+ if(arguments != null)
+ {
+ for(int i = 0, max = arguments.size(); i < max; i++){
+ ps.setObject(i+1, arguments.get(i));
+ }
+ }
+ rs = ps.executeQuery();
+ data.populate(rs);
+ // Point the rowset Cursor to the start
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL SUCCESS. count=" + data.size()+ ", time(ms): "+ (System.currentTimeMillis() - time)); }
+ } catch(SQLException exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ try { conn.rollback(); } catch(Throwable thr){}
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc;
+ } catch(Throwable exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc; // new SQLException(exc);
+ } finally {
+
+ try {
+ if(rs != null){
+ rs.close();
+ rs = null;
+ }
+ } catch(Exception exc){
+
+ }
+ try {
+ if(conn != null){
+ conn.close();
+ conn = null;
+ }
+ } catch(Exception exc){
+
+ }
+ }
+
+ return data;
+ }
+
+ private boolean executeUpdatePreparedStatement(Connection conn, String statement, ArrayList<String> arguments) throws SQLException, Throwable {
+ long time = System.currentTimeMillis();
+
+ CachedRowSet data = null;
+
+ int rs = -1;
+ try {
+ data = RowSetProvider.newFactory().createCachedRowSet();
+ PreparedStatement ps = conn.prepareStatement(statement);
+ if(arguments != null)
+ {
+ for(int i = 0, max = arguments.size(); i < max; i++){
+ ps.setObject(i+1, arguments.get(i));
+ }
+ }
+ rs = ps.executeUpdate();
+ // Point the rowset Cursor to the start
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL SUCCESS. count=" + data.size()+ ", time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ } catch(SQLException exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ try { conn.rollback(); } catch(Throwable thr){}
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc;
+ } catch(Throwable exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc; // new SQLException(exc);
+ } finally {
+
+ try {
+ if(conn != null){
+ conn.close();
+ conn = null;
+ }
+ } catch(Exception exc){
+
+ }
+ }
+
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
+ */
+ public Connection getConnection(String username, String password)
+ throws SQLException
+ {
+ return ds.getConnection(username, password);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getLogWriter()
+ */
+ public PrintWriter getLogWriter() throws SQLException
+ {
+ return ds.getLogWriter();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getLoginTimeout()
+ */
+ public int getLoginTimeout() throws SQLException
+ {
+ return ds.getLoginTimeout();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#setLogWriter(java.io.PrintWriter)
+ */
+ public void setLogWriter(PrintWriter out) throws SQLException
+ {
+ ds.setLogWriter(out);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#setLoginTimeout(int)
+ */
+ public void setLoginTimeout(int seconds) throws SQLException
+ {
+ ds.setLoginTimeout(seconds);
+ }
+
+
+ public final String getDbConnectionName(){
+ return connectionName;
+ }
+
+ protected final void setDbConnectionName(String name) {
+ this.connectionName = name;
+ }
+
+ public void cleanUp(){
+ ds = null;
+ monitor.deleteObservers();
+ monitor.cleanup();
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ protected boolean testConnection(){
+ return testConnection(false);
+ }
+
+ protected boolean testConnection(boolean error_level){
+ Connection conn = null;
+ ResultSet rs = null;
+ Statement stmt = null;
+ try
+ {
+ Boolean readOnly = null;
+ String hostname = null;
+ conn = this.getConnection();
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery("SELECT @@global.read_only, @@global.hostname"); //("SELECT 1 FROM DUAL"); //"select BANNER from SYS.V_$VERSION"
+ while(rs.next())
+ {
+ readOnly = rs.getBoolean(1);
+ hostname = rs.getString(2);
+// if(rs.getInt(1)==1){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL DataSource <"+getDbConnectionName() + "> connected to " + hostname + ", read-only is " + readOnly + ", tested successfully ");
+ }
+// }
+ }
+
+ } catch (Throwable exc) {
+ if(error_level) {
+ LOGGER.error("SQL DataSource <" + this.getDbConnectionName() + "> test failed. Cause : " + exc.getMessage());
+ } else {
+ LOGGER.info("SQL DataSource <" + this.getDbConnectionName() + "> test failed. Cause : " + exc.getMessage());
+ }
+ return false;
+ } finally {
+ if(rs != null) {
+ try {
+ rs.close();
+ rs = null;
+ } catch (SQLException e) {
+ }
+ }
+ if(stmt != null) {
+ try {
+ stmt.close();
+ stmt = null;
+ } catch (SQLException e) {
+ }
+ }
+ if(conn !=null){
+ try {
+ conn.close();
+ conn = null;
+ } catch (SQLException e) {
+ }
+ }
+ }
+ return true;
+ }
+
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ return false;
+ }
+
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ return null;
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setConnectionCachingEnabled(boolean state)
+ {
+// if(ds != null && ds instanceof OracleDataSource)
+// try {
+// ((OracleDataSource)ds).setConnectionCachingEnabled(true);
+// } catch (SQLException exc) {
+// LOGGER.warn("", exc);
+// }
+ }
+
+ public void addObserver(Observer observer) {
+ monitor.addObserver(observer);
+ }
+
+ public void deleteObserver(Observer observer) {
+ monitor.deleteObserver(observer);
+ }
+
+ public long getInterval() {
+ return interval;
+ }
+
+ public long getInitialDelay() {
+ return initisalDelay;
+ }
+
+ public void setInterval(long value) {
+ interval = value;
+ }
+
+ public void setInitialDelay(long value) {
+ initisalDelay = value;
+ }
+
+ public long getExpectedCompletionTime() {
+ return expectedCompletionTime;
+ }
+
+ public void setExpectedCompletionTime(long value) {
+ expectedCompletionTime = value;
+ }
+
+ public long getUnprocessedFailoverThreshold() {
+ return unprocessedFailoverThreshold;
+ }
+
+ public void setUnprocessedFailoverThreshold(long value) {
+ this.unprocessedFailoverThreshold = value;
+ }
+
+ public boolean canTakeOffLine() {
+ return canTakeOffLine;
+ }
+
+ public void blockImmediateOffLine() {
+ canTakeOffLine = false;
+ final Thread offLineTimer = new Thread()
+ {
+ public void run(){
+ try {
+ Thread.sleep(30000L);
+ }catch(Throwable exc){
+
+ }finally{
+ canTakeOffLine = true;
+ }
+ }
+ };
+ offLineTimer.setDaemon(true);
+ offLineTimer.start();
+ }
+
+ /**
+ * @return the monitor
+ */
+ final SQLExecutionMonitor getMonitor() {
+ return monitor;
+ }
+
+ protected boolean isSlave() {
+ CachedRowSet rs = null;
+ boolean isSlave = true;
+ String hostname = "UNDETERMINED";
+ try {
+// rs = this.getData("show slave status", new ArrayList<String>());
+// while(rs.next()) {
+// String master = rs.getString(2);
+// LOGGER.debug("database <"+connectionName+"> defines master as " + master);
+// if(master == null || master.isEmpty() || master.equals(this.getDbConnectionName())) {
+// isSlave = false;
+// } else {
+// isSlave = true;
+// }
+// }
+
+ boolean localSlave = true;
+ rs = this.getData("SELECT @@global.read_only, @@global.hostname", new ArrayList<String>());
+ while(rs.next()) {
+ localSlave = rs.getBoolean(1);
+ hostname = rs.getString(2);
+ }
+ isSlave = localSlave;
+ } catch (SQLException e) {
+ LOGGER.error("", e);
+ isSlave = true;
+ } catch (Throwable e) {
+ LOGGER.error("", e);
+ isSlave = true;
+ }
+ if(isSlave){
+ LOGGER.debug("SQL SLAVE : "+connectionName + " on server " + hostname);
+ } else {
+ LOGGER.debug("SQL MASTER : "+connectionName + " on server " + hostname);
+ }
+ return isSlave;
+ }
+
+ public boolean isFabric() {
+ return false;
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java
new file mode 100644
index 0000000..f774748
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.MySQLCachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.jndi.JndiCachedDataSource;
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class CachedDataSourceFactory {
+
+ public static CachedDataSource createDataSource(BaseDBConfiguration config) {
+ if(config instanceof JDBCConfiguration)
+ return MySQLCachedDataSource.createInstance(config);
+ if(config instanceof JndiConfiguration)
+ return JndiCachedDataSource.createInstance(config);
+ return (CachedDataSource)null;
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java
new file mode 100644
index 0000000..b324e6a
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class DBConfigException extends RuntimeException
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4752405152537680257L;
+
+ public DBConfigException(Exception e)
+ {
+ super(e.toString());
+ }
+
+ public DBConfigException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java
new file mode 100644
index 0000000..85cf834
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java
@@ -0,0 +1,113 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Properties;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DBLIBResourceActivator implements BundleActivator {
+
+ private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
+
+ private static final String DBLIB_PROP_PATH = "/dblib.properties";
+
+ private ServiceRegistration registration = null;
+
+ private static final Logger LOG = LoggerFactory.getLogger(DBLIBResourceActivator.class);
+
+ @Override
+ public void start(BundleContext ctx) throws Exception {
+ LOG.info("entering DBLIBResourceActivator.start");
+
+ DbLibService jdbcDataSource = null;
+ // Read properties
+ Properties props = new Properties();
+
+ File file = null;
+ URL propURL = null;
+ String propDir = System.getenv(SDNC_CONFIG_DIR);
+ if ((propDir == null) || (propDir.length() == 0)) {
+ propDir = "/opt/sdnc/data/properties";
+ }
+ file = new File(propDir + DBLIB_PROP_PATH);
+ if(file.exists()) {
+ propURL = file.toURI().toURL();
+ LOG.info("Using property file (1): " + file.toString());
+ } else {
+ propURL = ctx.getBundle().getResource("dblib.properties");
+ URL tmp = null;
+ if (propURL == null) {
+ file = new File(DBLIB_PROP_PATH);
+ tmp = this.getClass().getResource(DBLIB_PROP_PATH);
+// if(!file.exists()) {
+ if(tmp == null) {
+ throw new DblibConfigurationException("Missing configuration properties resource(3) : " + DBLIB_PROP_PATH);
+ } else {
+ propURL = tmp; //file.toURI().toURL();
+ LOG.info("Using property file (4): " + file.toString());
+ }
+ } else {
+ LOG.info("Using property file (2): " + propURL.toString());
+ }
+ }
+
+
+ try {
+ props.load(propURL.openStream());
+ } catch (Exception e) {
+ throw new DblibConfigurationException("Could not load properties at URL " + propURL.toString(), e);
+
+ }
+
+
+
+ try {
+ jdbcDataSource = DBResourceManager.create(props);
+ } catch (Exception exc) {
+ throw new DblibConfigurationException("Could not get initialize database", exc);
+ }
+
+ String regName = jdbcDataSource.getClass().getName();
+
+ LOG.info("Registering DBResourceManager service "+regName);
+// registration = ctx.registerService(regName, jdbcDataSource, null);
+ registration = ctx.registerService(new String[] { regName, DbLibService.class.getName(), "javax.sql.DataSource" }, jdbcDataSource, null);
+ }
+
+ @Override
+ public void stop(BundleContext ctx) throws Exception {
+ LOG.info("entering DBLIBResourceActivator.stop");
+ if (registration != null)
+ {
+ registration.unregister();
+ registration = null;
+ LOG.debug("Deregistering DBResourceManager service");
+ }
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java
new file mode 100644
index 0000000..cc80741
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLException;
+
+/**
+ * An exception time for handling DBLIB specific error handling.
+ */
+public class DBLibException extends SQLException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5345059355083984696L;
+
+ public DBLibException(String message){
+ super(message);
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java
new file mode 100644
index 0000000..7f85c42
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java
@@ -0,0 +1,940 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLDataException;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLIntegrityConstraintViolationException;
+import java.sql.SQLSyntaxErrorException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Observable;
+import java.util.PriorityQueue;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.sql.DataSource;
+import javax.sql.rowset.CachedRowSet;
+
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractDBResourceManagerFactory;
+import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractResourceManagerFactory;
+import org.openecomp.sdnc.sli.resource.dblib.factory.DBConfigFactory;
+import org.openecomp.sdnc.sli.resource.dblib.pm.PollingWorker;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.rowset.providers.RIOptimisticProvider;
+
+/**
+ * @version $Revision: 1.15 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class DBResourceManager implements DataSource, DataAccessor, DBResourceObserver, DbLibService {
+ private static Logger LOGGER = LoggerFactory.getLogger(DBResourceManager.class);
+
+ transient boolean terminating = false;
+ transient protected long retryInterval = 10000L;
+ transient boolean recoveryMode = true;
+
+ protected final AtomicBoolean dsSelector = new AtomicBoolean();
+
+// Queue<CachedDataSource> dsQueue = new ConcurrentLinkedQueue<CachedDataSource>();
+ Queue<CachedDataSource> dsQueue = new PriorityQueue<CachedDataSource>(4, new Comparator<CachedDataSource>(){
+
+ @Override
+ public int compare(CachedDataSource left, CachedDataSource right) {
+ try {
+ if(!left.isSlave())
+ return -1;
+ if(!right.isSlave())
+ return 1;
+
+ } catch (Throwable e) {
+ LOGGER.warn("", e);
+ }
+ return 0;
+ }
+
+ });
+ protected final Set<CachedDataSource> broken = Collections.synchronizedSet(new HashSet<CachedDataSource>());
+ protected final Object monitor = new Object();
+ protected final Properties configProps;
+ protected final Thread worker;
+
+ protected final long terminationTimeOut;
+ protected final boolean monitorDbResponse;
+ protected final long monitoringInterval;
+ protected final long monitoringInitialDelay;
+ protected final long expectedCompletionTime;
+ protected final long unprocessedFailoverThreshold;
+
+ public DBResourceManager(Properties props){
+ this.configProps = props;
+
+ // get retry interval value
+ retryInterval = getLongFromProperties(props, "org.openecomp.dblib.connection.retry", 10000L);
+
+ // get recovery mode flag
+ recoveryMode = getBooleanFromProperties(props, "org.openecomp.dblib.connection.recovery", true);
+ if(!recoveryMode)
+ {
+ recoveryMode = false;
+ LOGGER.info("Recovery Mode disabled");
+ }
+ // get time out value for thread cleanup
+ terminationTimeOut = getLongFromProperties(props, "org.openecomp.dblib.termination.timeout", 300000L);
+ // get properties for monitoring
+ monitorDbResponse = getBooleanFromProperties(props, "org.openecomp.dblib.connection.monitor", false);
+ monitoringInterval = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.interval", 1000L);
+ monitoringInitialDelay = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.startdelay", 5000L);
+ expectedCompletionTime = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.expectedcompletiontime", 5000L);
+ unprocessedFailoverThreshold = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.unprocessedfailoverthreshold", 3L);
+
+ // initialize performance monitor
+ PollingWorker.createInistance(props);
+
+ // initialize recovery thread
+ worker = new RecoveryMgr();
+ worker.setName("DBResourcemanagerWatchThread");
+ worker.setDaemon(true);
+ worker.start();
+
+ try {
+ RIOptimisticProvider rio = new RIOptimisticProvider();
+ LOGGER.info("Class " + rio.getClass().getName() + " found.");
+ Class clas = this.getClass().getClassLoader().loadClass("com.sun.rowset.providers.RIOptimisticProvider");
+ if(clas != null) {
+ LOGGER.info("Class " + rio.getClass().getName() + " found by classloader.");
+ }
+ } catch(Exception exc) {
+ LOGGER.info("Failed resolving RIOptimisticProvider class", exc);
+ }
+ }
+
+ private void config(Properties ctx) throws Exception {
+
+ DbConfigPool dbConfig = DBConfigFactory.createConfig(this.configProps);
+
+ try {
+ AbstractResourceManagerFactory factory = AbstractDBResourceManagerFactory.getFactory(dbConfig.getType());
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info("Default DB config is : " + dbConfig.getType());
+ LOGGER.info("Using factory : " + factory.getClass().getName());
+ }
+ CachedDataSource[] cachedDS = factory.initDBResourceManager(dbConfig, this);
+ if(cachedDS == null || cachedDS.length == 0) {
+ LOGGER.error("Initialization of CachedDataSources failed. No instance was created.");
+ throw new Exception("Failed to initialize DB Library. No data source was created.");
+ }
+
+ for(int i=0; i<cachedDS.length; i++){
+ if(cachedDS[i] != null && cachedDS[i].isInitialized()){
+ setDataSource(cachedDS[i]);
+ cachedDS[i].setInterval(monitoringInterval);
+ cachedDS[i].setInitialDelay(monitoringInitialDelay);
+ cachedDS[i].setExpectedCompletionTime(expectedCompletionTime);
+ cachedDS[i].setUnprocessedFailoverThreshold(unprocessedFailoverThreshold);
+ cachedDS[i].addObserver(this);
+ }
+ }
+
+ } catch(Exception exc){
+ throw exc;
+ }
+ }
+
+ private long getLongFromProperties(Properties props, String property, long defaultValue)
+ {
+ String value = null;
+ long tmpLongValue = defaultValue;
+ try {
+ value = (String)props.getProperty(property);
+ if(value != null)
+ tmpLongValue = Long.parseLong(value);
+
+ } catch(NumberFormatException exc) {
+ if(LOGGER.isWarnEnabled()){
+ LOGGER.warn("'"+property+"'=" + value+" is invalid. It should be a numeric value");
+ }
+ } catch(Exception exc) {
+ }
+ return tmpLongValue;
+
+ }
+
+ private boolean getBooleanFromProperties(Properties props, String property, boolean defaultValue)
+ {
+ boolean tmpValue = defaultValue;
+ String value = null;
+
+ try {
+ value = (String)props.getProperty(property);
+ if(value != null)
+ tmpValue = Boolean.parseBoolean(value);
+
+ } catch(NumberFormatException exc) {
+ if(LOGGER.isWarnEnabled()){
+ LOGGER.warn("'"+property+"'=" + value+" is invalid. It should be a boolean value");
+ }
+ } catch(Exception exc) {
+ }
+ return tmpValue;
+
+ }
+
+
+ public void update(Observable observable, Object data) {
+ // if observable is active and there is a standby available, switch
+ if(observable instanceof SQLExecutionMonitor)
+ {
+ SQLExecutionMonitor monitor = (SQLExecutionMonitor)observable;
+ if(monitor.getParent() instanceof CachedDataSource)
+ {
+ CachedDataSource dataSource = (CachedDataSource)monitor.getParent();
+ if(dataSource == dsQueue.peek())
+ {
+ if(recoveryMode && dsQueue.size() > 1){
+ handleGetConnectionException(dataSource, new Exception(data.toString()));
+ }
+ }
+ }
+ }
+ }
+
+ public void testForceRecovery()
+ {
+ CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
+ handleGetConnectionException(active, new Exception("test"));
+ }
+
+ class RecoveryMgr extends Thread {
+
+ public void run() {
+ while(!terminating)
+ {
+ try {
+ Thread.sleep(retryInterval);
+ } catch (InterruptedException e1) { }
+ CachedDataSource brokenSource = null;
+ try {
+ if (!broken.isEmpty()) {
+ CachedDataSource[] sourceArray = broken.toArray(new CachedDataSource[0]);
+ for (int i = 0; i < sourceArray.length; i++)
+ {
+ brokenSource = sourceArray[i];
+ if (brokenSource instanceof TerminatingCachedDataSource)
+ break;
+ if (resetConnectionPool(brokenSource)) {
+ broken.remove(brokenSource);
+ brokenSource.blockImmediateOffLine();
+ dsQueue.add(brokenSource);
+ LOGGER.info("DataSource <"
+ + brokenSource.getDbConnectionName()
+ + "> recovered.");
+ }
+ brokenSource = null;
+ }
+ }
+ } catch (Exception exc) {
+ LOGGER.warn(exc.getMessage());
+ if(brokenSource != null){
+ try {
+ if(!broken.contains(brokenSource))
+ broken.add(brokenSource);
+ brokenSource = null;
+ } catch (Exception e1) { }
+ }
+ }
+ }
+ LOGGER.info("DBResourceManager.RecoveryMgr <"+this.toString() +"> terminated." );
+ }
+
+ private boolean resetConnectionPool(CachedDataSource dataSource){
+ try {
+ return dataSource.testConnection();
+ } catch (Exception exc) {
+ LOGGER.info("DataSource <" + dataSource.getDbConnectionName() + "> resetCache failed with error: "+ exc.getMessage());
+ return false;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.dblib.DataAccessor#getData(java.lang.String, java.util.ArrayList)
+ */
+ /* (non-Javadoc)
+ * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#getData(java.lang.String, java.util.ArrayList, java.lang.String)
+ */
+ @Override
+ public CachedRowSet getData(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
+ if(recoveryMode)
+ return requestDataWithRecovery(statement, arguments, preferredDS);
+ else
+ return requestDataNoRecovery(statement, arguments, preferredDS);
+ }
+
+ private CachedRowSet requestDataWithRecovery(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
+ Throwable lastException = null;
+ CachedDataSource active = null;
+
+ // test if there are any connection pools available
+ LinkedList<CachedDataSource> sources = new LinkedList<CachedDataSource>(this.dsQueue);
+ if(sources.isEmpty()){
+ LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
+ throw new DBLibException("No active DB connection pools are available in RequestDataWithRecovery call.");
+ }
+ if(preferredDS != null && !sources.peek().getDbConnectionName().equals(preferredDS)) {
+ Collections.reverse(sources);
+ }
+
+
+ // loop through available data sources to retrieve data.
+ while(!sources.isEmpty())
+ {
+ active = sources.peek();
+
+ long time = System.currentTimeMillis();
+ try {
+ if(!active.isFabric()) {
+ CachedDataSource master = findMaster();
+ if(master != null) {
+ active = master;
+ master = null;
+ }
+ }
+ sources.remove(active);
+ return active.getData(statement, arguments);
+ } catch(SQLDataException exc){
+ throw exc;
+ } catch(SQLSyntaxErrorException exc){
+ throw exc;
+ } catch(SQLIntegrityConstraintViolationException exc){
+ throw exc;
+ } catch(Throwable exc){
+ lastException = exc;
+ String message = exc.getMessage();
+ if(message == null) {
+ if(exc.getCause() != null) {
+ message = exc.getCause().getMessage();
+ }
+ if(message == null)
+ message = exc.getClass().getName();
+ }
+ LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ handleGetConnectionException(active, exc);
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ time = (System.currentTimeMillis() - time);
+ LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ }
+ }
+ }
+ if(lastException instanceof SQLException){
+ throw (SQLException)lastException;
+ }
+ // repackage the exception
+ // you are here because either you run out of available data sources
+ // or the last exception was not of SQLException type.
+ // repackage the exception
+ if(lastException == null) {
+ throw new DBLibException("The operation timed out while waiting to acquire a new connection." );
+ } else {
+ SQLException exception = new DBLibException(lastException.getMessage());
+ exception.setStackTrace(lastException.getStackTrace());
+ if(lastException.getCause() instanceof SQLException) {
+ throw (SQLException)lastException.getCause();
+ }
+ throw exception;
+ }
+ }
+
+ private CachedRowSet requestDataNoRecovery(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
+ if(dsQueue.isEmpty()){
+ LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
+ throw new DBLibException("No active DB connection pools are available in RequestDataNoRecovery call.");
+ }
+ CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
+ long time = System.currentTimeMillis();
+ try {
+ if(!active.isFabric()) {
+ CachedDataSource master = findMaster();
+ if(master != null)
+ active = master;
+ }
+ return active.getData(statement, arguments);
+// } catch(SQLDataException exc){
+// throw exc;
+ } catch(Throwable exc){
+ String message = exc.getMessage();
+ if(message == null)
+ message = exc.getClass().getName();
+ LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ if(exc instanceof SQLException)
+ throw (SQLException)exc;
+ else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ time = (System.currentTimeMillis() - time);
+ LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ }
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.openecomp.dblib.DataAccessor#writeData(java.lang.String, java.util.ArrayList)
+ */
+ /* (non-Javadoc)
+ * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#writeData(java.lang.String, java.util.ArrayList, java.lang.String)
+ */
+ @Override
+ public boolean writeData(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
+ return writeDataNoRecovery(statement, arguments, preferredDS);
+ }
+
+ CachedDataSource findMaster() {
+ CachedDataSource master = null;
+ CachedDataSource[] dss = this.dsQueue.toArray(new CachedDataSource[0]);
+ for(int i=0; i<dss.length; i++) {
+ if(!dss[i].isSlave()) {
+ master = dss[i];
+ if(i != 0) {
+ dsQueue.remove(master);
+ dsQueue.add(master);
+ }
+ return master;
+ }
+ }
+ if(master == null) {
+ LOGGER.warn("MASTER not found.");
+ }
+ return master;
+ }
+
+
+ private boolean writeDataNoRecovery(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
+ if(dsQueue.isEmpty()){
+ LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
+ throw new DBLibException("No active DB connection pools are available in RequestDataNoRecovery call.");
+ }
+
+ boolean initialRequest = true;
+ boolean retryAllowed = true;
+ CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
+ long time = System.currentTimeMillis();
+ while(initialRequest) {
+ initialRequest = false;
+ try {
+ if(!active.isFabric()) {
+ CachedDataSource master = findMaster();
+ if(master != null) {
+ active = master;
+ }
+ }
+
+ return active.writeData(statement, arguments);
+ } catch(Throwable exc){
+ String message = exc.getMessage();
+ if(message == null)
+ message = exc.getClass().getName();
+ LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ if(exc instanceof SQLException) {
+ SQLException sqlExc = SQLException.class.cast(exc);
+ // handle read-only exception
+ if(sqlExc.getErrorCode() == 1290 && "HY000".equals(sqlExc.getSQLState())) {
+ LOGGER.warn("retrying due to: " + sqlExc.getMessage());
+ dsQueue.remove(active);
+ dsQueue.add(active);
+ if(retryAllowed){
+ retryAllowed = false;
+ initialRequest = true;
+ continue;
+ }
+ }
+ throw (SQLException)exc;
+ } else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ time = (System.currentTimeMillis() - time);
+ LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ }
+ }
+ }
+ return true;
+ }
+
+ private void setDataSource(CachedDataSource dataSource) {
+ if(dataSource.testConnection(true)){
+ this.dsQueue.add(dataSource);
+ } else {
+ this.broken.add(dataSource);
+ }
+ }
+
+ public Connection getConnection() throws SQLException {
+ Throwable lastException = null;
+ CachedDataSource active = null;
+
+ if(dsQueue.isEmpty()){
+ throw new DBLibException("No active DB connection pools are available in GetConnection call.");
+ }
+
+ try {
+ active = dsQueue.peek();
+ CachedDataSource tmpActive = findMaster();
+ if(tmpActive != null) {
+ active = tmpActive;
+ }
+ return active.getConnection();
+ } catch(javax.sql.rowset.spi.SyncFactoryException exc){
+ LOGGER.debug("Free memory (bytes): " + Runtime.getRuntime().freeMemory());
+ LOGGER.warn("CLASSPATH issue. Allowing retry", exc);
+ lastException = exc;
+ } catch(Exception exc){
+ lastException = exc;
+ if(recoveryMode){
+ handleGetConnectionException(active, exc);
+ } else {
+ if(exc instanceof SQLException)
+ throw (SQLException)exc;
+ else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ }
+ } catch (Throwable trwb) {
+ DBLibException excptn = new DBLibException(trwb.getMessage());
+ excptn.setStackTrace(trwb.getStackTrace());
+ throw excptn;
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ displayState();
+ }
+ }
+
+ if(lastException instanceof SQLException){
+ throw (SQLException)lastException;
+ }
+ // repackage the exception
+ if(lastException == null) {
+ throw new DBLibException("The operation timed out while waiting to acquire a new connection." );
+ } else {
+ SQLException exception = new DBLibException(lastException.getMessage());
+ exception.setStackTrace(lastException.getStackTrace());
+ if(lastException.getCause() instanceof SQLException) {
+// exception.setNextException((SQLException)lastException.getCause());
+ throw (SQLException)lastException.getCause();
+ }
+ throw exception;
+ }
+ }
+
+ public Connection getConnection(String username, String password)
+ throws SQLException {
+ CachedDataSource active = null;
+
+ if(dsQueue.isEmpty()){
+ throw new DBLibException("No active DB connection pools are available in GetConnection call.");
+ }
+
+
+ try {
+ active = dsQueue.peek();
+ CachedDataSource tmpActive = findMaster();
+ if(tmpActive != null) {
+ active = tmpActive;
+ }
+ return active.getConnection(username, password);
+ } catch(Throwable exc){
+ if(recoveryMode){
+ handleGetConnectionException(active, exc);
+ } else {
+ if(exc instanceof SQLException)
+ throw (SQLException)exc;
+ else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ }
+
+ }
+
+ throw new DBLibException("No connections available in DBResourceManager in GetConnection call.");
+ }
+
+ private void handleGetConnectionException(CachedDataSource source, Throwable exc) {
+ try {
+ if(!source.canTakeOffLine())
+ {
+ LOGGER.error("Could not switch due to blocking");
+ return;
+ }
+
+ boolean removed = dsQueue.remove(source);
+ if(!broken.contains(source))
+ {
+ if(broken.add(source))
+ {
+ LOGGER.warn("DB Recovery: DataSource <" + source.getDbConnectionName() + "> put in the recovery mode. Reason : " + exc.getMessage());
+ } else {
+ LOGGER.warn("Error putting DataSource <" +source.getDbConnectionName()+ "> in recovery mode.");
+ }
+ } else {
+ LOGGER.info("DB Recovery: DataSource <" + source.getDbConnectionName() + "> already in recovery queue");
+ }
+ if(removed)
+ {
+ if(!dsQueue.isEmpty())
+ {
+ LOGGER.warn("DB DataSource <" + dsQueue.peek().getDbConnectionName() + "> became active");
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error("", e);
+ }
+ }
+
+ public void cleanUp() {
+ for(Iterator<CachedDataSource> it=dsQueue.iterator();it.hasNext();){
+ CachedDataSource cds = (CachedDataSource)it.next();
+ it.remove();
+ cds.cleanUp();
+ }
+
+ try {
+ this.terminating = true;
+ if(broken != null)
+ {
+ try {
+ broken.add( new TerminatingCachedDataSource(null));
+ } catch(Exception exc){
+ LOGGER.error("Waiting for Worker to stop", exc);
+ }
+ }
+ worker.join(terminationTimeOut);
+ LOGGER.info("DBResourceManager.RecoveryMgr <"+worker.toString() +"> termination was successful: " + worker.getState());
+ } catch(Exception exc){
+ LOGGER.error("Waiting for Worker thread to terminate ", exc);
+ }
+ }
+
+ public static DBResourceManager create(Properties props) throws Exception {
+ DBResourceManager dbmanager = new DBResourceManager(props);
+ dbmanager.config(props);
+ return dbmanager;
+ }
+
+ public PrintWriter getLogWriter() throws SQLException {
+ return ((CachedDataSource)this.dsQueue.peek()).getLogWriter();
+ }
+
+ public int getLoginTimeout() throws SQLException {
+ return ((CachedDataSource)this.dsQueue.peek()).getLoginTimeout();
+ }
+
+ public void setLogWriter(PrintWriter out) throws SQLException {
+ ((CachedDataSource)this.dsQueue.peek()).setLogWriter(out);
+ }
+
+ public void setLoginTimeout(int seconds) throws SQLException {
+ ((CachedDataSource)this.dsQueue.peek()).setLoginTimeout(seconds);
+ }
+
+ public void displayState(){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("POOLS : Active = "+dsQueue.size() + ";\t Broken = "+broken.size());
+ CachedDataSource current = (CachedDataSource)dsQueue.peek();
+ if(current != null) {
+ LOGGER.debug("POOL : Active name = \'"+current.getDbConnectionName()+ "\'");
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#isActive()
+ */
+ @Override
+ public boolean isActive() {
+ return this.dsQueue.size()>0;
+ }
+
+ public String getActiveStatus(){
+ return "Connected: " + dsQueue.size()+"\tIn-recovery: "+broken.size();
+ }
+
+ public String getDBStatus(boolean htmlFormat) {
+ StringBuilder buffer = new StringBuilder();
+
+ ArrayList<CachedDataSource> list = new ArrayList<CachedDataSource>();
+ list.addAll(dsQueue);
+ list.addAll(broken);
+ if (htmlFormat)
+ {
+ buffer.append("<tr class=\"headerRow\"><th id=\"header1\">")
+ .append("Name:").append("</th>");
+ for (int i = 0; i < list.size(); i++) {
+ buffer.append("<th id=\"header").append(2 + i).append("\">");
+ buffer.append(((CachedDataSource) list.get(i)).getDbConnectionName()).append("</th>");
+ }
+ buffer.append("</tr>");
+
+ buffer.append("<tr><td>State:</td>");
+ for (int i = 0; i < list.size(); i++) {
+ if (broken.contains(list.get(i))) {
+ buffer.append("<td>in recovery</td>");
+ }
+ if (dsQueue.contains(list.get(i))) {
+ if (dsQueue.peek() == list.get(i))
+ buffer.append("<td>active</td>");
+ else
+ buffer.append("<td>standby</td>");
+ }
+ }
+ buffer.append("</tr>");
+
+ } else {
+ for (int i = 0; i < list.size(); i++) {
+ buffer.append("Name: ").append(((CachedDataSource) list.get(i)).getDbConnectionName());
+ buffer.append("\tState: ");
+ if (broken.contains(list.get(i))) {
+ buffer.append("in recovery");
+ } else
+ if (dsQueue.contains(list.get(i))) {
+ if (dsQueue.peek() == list.get(i))
+ buffer.append("active");
+ else
+ buffer.append("standby");
+ }
+
+ buffer.append("\n");
+
+ }
+ }
+ return buffer.toString();
+ }
+
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ return false;
+ }
+
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ return null;
+ }
+
+ /**
+ * @return the monitorDbResponse
+ */
+ public final boolean isMonitorDbResponse() {
+ return recoveryMode && monitorDbResponse;
+ }
+
+ public void test(){
+ CachedDataSource obj = dsQueue.peek();
+ Exception ption = new Exception();
+ try {
+ for(int i=0; i<5; i++)
+ {
+ handleGetConnectionException(obj, ption);
+ }
+ } catch(Throwable exc){
+ LOGGER.warn("", exc);
+ }
+ }
+
+ public String getPreferredDSName(){
+ if(isActive()){
+ return getPreferredDataSourceName(dsSelector);
+ }
+ return "";
+ }
+
+ private String getPreferredDataSourceName(AtomicBoolean flipper) {
+
+ LinkedList<CachedDataSource> snapshot = new LinkedList<CachedDataSource>(dsQueue);
+ if(snapshot.size() > 1){
+ CachedDataSource first = snapshot.getFirst();
+ CachedDataSource last = snapshot.getLast();
+
+ int delta = first.getMonitor().getPorcessedConnectionsCount() - last.getMonitor().getPorcessedConnectionsCount();
+ if(delta < 0) {
+ flipper.set(false);
+ } else if(delta > 0) {
+ flipper.set(true);
+ } else {
+ // check the last value and return !last
+ flipper.getAndSet(!flipper.get());
+ }
+
+ if (flipper.get())
+ Collections.reverse(snapshot);
+ }
+ return snapshot.peek().getDbConnectionName();
+ }
+
+ public java.util.logging.Logger getParentLogger()
+ throws SQLFeatureNotSupportedException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getMasterName() {
+ if(isActive()){
+ return getMasterDataSourceName(dsSelector);
+ }
+ return "";
+ }
+
+
+ private String getMasterDataSourceName(AtomicBoolean flipper) {
+
+ LinkedList<CachedDataSource> snapshot = new LinkedList<CachedDataSource>(dsQueue);
+ if(snapshot.size() > 1){
+ CachedDataSource first = snapshot.getFirst();
+ CachedDataSource last = snapshot.getLast();
+
+ int delta = first.getMonitor().getPorcessedConnectionsCount() - last.getMonitor().getPorcessedConnectionsCount();
+ if(delta < 0) {
+ flipper.set(false);
+ } else if(delta > 0) {
+ flipper.set(true);
+ } else {
+ // check the last value and return !last
+ flipper.getAndSet(!flipper.get());
+ }
+
+ if (flipper.get())
+ Collections.reverse(snapshot);
+ }
+ return snapshot.peek().getDbConnectionName();
+ }
+
+ /*
+ private void runTest(){
+ Thread producer = null;
+
+ producer = new ProducerThread("Prod1");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod2");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod3");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod4");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod5");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod6");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod7");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod8");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Prod9");
+ producer.setDaemon(true);
+ producer.start();
+
+ producer = new ProducerThread("Pro10");
+ producer.setDaemon(true);
+ producer.start();
+
+ }
+
+ private final class ProducerThread extends Thread {
+ private ProducerThread(String threadName) {
+ super(threadName);
+ }
+
+ public void run()
+ {
+ String name = null;
+ for(int i=0; i<(Integer.MAX_VALUE-1); i++)
+ {
+ try {
+ name = getPreferredDataSourceName(dsSelector);
+ if(name.contains("BACK")){
+ LOGGER.error(this.getName()+": <====== ");
+ } else {
+ LOGGER.error(this.getName()+": ======>");
+ }
+ CachedRowSet rs = null;
+ rs = getData("select 1 from dual", new ArrayList<String>(), name);
+ rs.close();
+ rs = getData("select 1 from dual", new ArrayList<String>(), name);
+ rs.close();
+ rs = getData("select 1 from dual", new ArrayList<String>(), name);
+ rs.close();
+ rs = getData("select 1 from dual", new ArrayList<String>(), name);
+ rs.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ try {
+ Thread.sleep(50L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ return;
+ }
+ }
+*/
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java
new file mode 100644
index 0000000..e06779f
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.util.Observer;
+
+public interface DBResourceObserver extends Observer {
+ public boolean isMonitorDbResponse();
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java
new file mode 100644
index 0000000..cd054a5
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+import javax.sql.rowset.CachedRowSet;
+
+public interface DataAccessor {
+
+ public abstract CachedRowSet getData(String statement, ArrayList<String> arguments, String preferredDS)
+ throws SQLException;
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java
new file mode 100644
index 0000000..37d6251
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.util.Comparator;
+
+public interface DataSourceComparator extends Comparator <CachedDataSource>{
+
+ public abstract CachedDataSource getLastUsed();
+
+ public abstract void setLastUsed(CachedDataSource lastUsed);
+
+ public abstract int compare(CachedDataSource ds1, CachedDataSource ds2);
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java
new file mode 100644
index 0000000..25edd1f
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+import javax.sql.rowset.CachedRowSet;
+
+public interface DbLibService {
+
+ /* (non-Javadoc)
+ * @see DataAccessor#getData(java.lang.String, java.util.ArrayList)
+ */
+ public abstract CachedRowSet getData(String statement,
+ ArrayList<String> arguments, String preferredDS)
+ throws SQLException;
+
+ /* (non-Javadoc)
+ * @see DataAccessor#writeData(java.lang.String, java.util.ArrayList)
+ */
+ public abstract boolean writeData(String statement,
+ ArrayList<String> arguments, String preferredDS)
+ throws SQLException;
+
+ public abstract boolean isActive();
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java
new file mode 100644
index 0000000..17700a5
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+
+public class DblibConfigurationException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public DblibConfigurationException()
+ {
+ super();
+ }
+
+ public DblibConfigurationException(String msg)
+ {
+ super(msg);
+ }
+
+ public DblibConfigurationException(String msg, Throwable t)
+ {
+ super(msg, t);
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java
new file mode 100644
index 0000000..234bbed
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.logging.Logger;
+
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitorObserver;
+
+
+public class TerminatingCachedDataSource extends CachedDataSource implements SQLExecutionMonitorObserver {
+
+ public TerminatingCachedDataSource(BaseDBConfiguration jdbcElem) throws DBConfigException {
+ super(jdbcElem);
+ }
+
+ protected void configure(BaseDBConfiguration jdbcElem) throws DBConfigException {
+ // no action
+ }
+
+ public long getInterval() {
+ return 1000;
+ }
+
+ public long getInitialDelay() {
+ return 1000;
+ }
+
+ public long getExpectedCompletionTime() {
+ return 50;
+ }
+
+ public void setExpectedCompletionTime(long value) {
+
+ }
+
+ public void setInterval(long value) {
+
+ }
+
+ public void setInitialDelay(long value) {
+
+ }
+
+ public long getUnprocessedFailoverThreshold() {
+ return 3;
+ }
+
+ public void setUnprocessedFailoverThreshold(long value) {
+
+ }
+
+ public int compareTo(CachedDataSource ods)
+ {
+ return 0;
+ }
+
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java
new file mode 100644
index 0000000..976b1cf
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.config;
+
+import java.util.Properties;
+
+public abstract class BaseDBConfiguration {
+ public static final String DATABASE_TYPE = "org.openecomp.sdnc.sli.dbtype";
+ public static final String DATABASE_URL = "org.openecomp.sdnc.sli.jdbc.url";
+ public static final String DATABASE_NAME = "org.openecomp.sdnc.sli.jdbc.database";
+ public static final String CONNECTION_NAME = "org.openecomp.sdnc.sli.jdbc.connection.name";
+ public static final String DATABASE_USER = "org.openecomp.sdnc.sli.jdbc.user";
+ public static final String DATABASE_PSSWD = "org.openecomp.sdnc.sli.jdbc.password";
+ public static final String CONNECTION_TIMEOUT="org.openecomp.sdnc.sli.jdbc.connection.timeout";
+ public static final String REQUEST_TIMEOUT = "org.openecomp.sdnc.sli.jdbc.request.timeout";
+ public static final String MIN_LIMIT = "org.openecomp.sdnc.sli.jdbc.limit.min";
+ public static final String MAX_LIMIT = "org.openecomp.sdnc.sli.jdbc.limit.max";
+ public static final String INIT_LIMIT = "org.openecomp.sdnc.sli.jdbc.limit.init";
+ public static final String DATABASE_HOSTS = "org.openecomp.sdnc.sli.jdbc.hosts";
+
+
+ protected final Properties props;
+
+ public BaseDBConfiguration(Properties properties) {
+ this.props = properties;
+ }
+
+ public int getConnTimeout() {
+ try {
+ String value = props.getProperty(CONNECTION_TIMEOUT);
+ return Integer.parseInt(value);
+ } catch(Exception exc) {
+ return -1;
+ }
+ }
+
+ public int getRequestTimeout() {
+ try {
+ String value = props.getProperty(REQUEST_TIMEOUT);
+ if(value == null)
+ return -1;
+ return Integer.parseInt(value);
+ } catch(Exception exc) {
+ return -1;
+ }
+ }
+
+ public String getDbConnectionName() {
+ return props.getProperty(CONNECTION_NAME);
+ }
+
+ public String getDatabaseName() {
+ return props.getProperty(DATABASE_NAME);
+ }
+
+ public String getDbUserId() {
+ return props.getProperty(DATABASE_USER);
+ }
+
+ public String getDbPasswd() {
+ return props.getProperty(DATABASE_PSSWD);
+ }
+
+ public int getDbMinLimit() {
+ String value = props.getProperty(MIN_LIMIT);
+ return Integer.parseInt(value);
+ }
+
+ public int getDbMaxLimit() {
+ String value = props.getProperty(MAX_LIMIT);
+ return Integer.parseInt(value);
+ }
+
+ public int getDbInitialLimit() {
+ String value = props.getProperty(INIT_LIMIT);
+ return Integer.parseInt(value);
+ }
+
+ public String getDbUrl() {
+ return props.getProperty(DATABASE_URL);
+ }
+
+ public String getServerGroup() {
+ return null;
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java
new file mode 100644
index 0000000..90ea6bc
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.config;
+
+import java.util.ArrayList;
+import java.util.Properties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DbConfigPool {
+ private static Logger LOGGER = LoggerFactory.getLogger(DbConfigPool.class);
+
+ private final String type;
+
+ private ArrayList<BaseDBConfiguration> configurations = new ArrayList<BaseDBConfiguration>();
+
+ public DbConfigPool(Properties properties) {
+ LOGGER.debug("Initializing DbConfigType");
+ type = properties.getProperty(BaseDBConfiguration.DATABASE_TYPE, "JDBC").toUpperCase();
+ }
+
+ public int getTimeout() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public JndiConfiguration[] getJndiDbSourceArray() {
+ return configurations.toArray(new JndiConfiguration[configurations.size()]);
+ }
+
+ public JDBCConfiguration[] getJDBCbSourceArray() {
+ return configurations.toArray(new JDBCConfiguration[configurations.size()]);
+ }
+
+ public void addConfiguration(BaseDBConfiguration config) {
+ configurations.add(config);
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java
new file mode 100644
index 0000000..cb6ea3e
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.config;
+
+import java.util.Properties;
+
+public class JDBCConfiguration extends BaseDBConfiguration {
+
+ public JDBCConfiguration(Properties xmlElem) {
+ super(xmlElem);
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JndiConfiguration.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JndiConfiguration.java
new file mode 100644
index 0000000..292372b
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JndiConfiguration.java
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.config;
+
+import java.util.Properties;
+
+public class JndiConfiguration extends BaseDBConfiguration{
+
+ public JndiConfiguration(Properties xmlElem) {
+ super(xmlElem);
+ // TODO Auto-generated constructor stub
+ }
+
+ public String getJndiConnectionName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getJndiContextFactory() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getJndiURL() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getJndiSource() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setJndiContextFactory(String jndiContextFactoryStr) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setJndiURL(String jndiURLStr) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java
new file mode 100644
index 0000000..e6b1a35
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.JdbcDbResourceManagerFactory;
+import org.openecomp.sdnc.sli.resource.dblib.jndi.JNDIDbResourceManagerFactory;
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class AbstractDBResourceManagerFactory {
+
+ public static AbstractResourceManagerFactory getFactory(String type) throws FactoryNotDefinedException {
+
+ if("JNDI".equals(type)){
+ try {
+ return JNDIDbResourceManagerFactory.createIntstance();
+ } catch (Exception e) {
+ }
+ }
+ // JDBC
+ return JdbcDbResourceManagerFactory.createIntstance();
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java
new file mode 100644
index 0000000..148ddac
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+
+import java.sql.SQLException;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSourceFactory;
+import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
+import org.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Revision: 1.6 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public abstract class AbstractResourceManagerFactory {
+ private static Logger LOGGER = LoggerFactory.getLogger(AbstractResourceManagerFactory.class);
+
+ public abstract CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) throws Exception;
+ public abstract CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager dbResourceManager, String sourceName) throws SQLException ;
+
+
+ public static AbstractResourceManagerFactory createIntstance() throws FactoryNotDefinedException {
+ throw new FactoryNotDefinedException("Factory method 'createIntstance' needs to be overriden in DBResourceManagerFactory");
+ }
+
+ public class DBInitTask implements Callable<CachedDataSource>
+ {
+ private BaseDBConfiguration config = null;
+ private Set<DBInitTask> activeTasks;
+
+ public DBInitTask(JndiConfiguration jndiConfig, Set<DBInitTask> tasks){
+ this.config = jndiConfig;
+ this.activeTasks = tasks;
+ }
+
+ public DBInitTask(JDBCConfiguration jdbcconfig, Set<DBInitTask> tasks) {
+ this.config = jdbcconfig;
+ this.activeTasks = tasks;
+ }
+
+ public CachedDataSource call() throws Exception {
+ CachedDataSource ds = null;
+ try {
+ ds = CachedDataSourceFactory.createDataSource(config);
+ return ds;
+ } finally {
+ synchronized(activeTasks){
+ activeTasks.remove(this);
+ if(activeTasks.isEmpty()){
+ final Runnable closure = new Runnable() {
+
+ public void run() {
+ try {
+ Thread.sleep(300);
+ } catch (Exception e) {
+ }
+ synchronized(activeTasks){
+ activeTasks.notifyAll();
+ }
+ }
+ };
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Completed CachedDataSource.Call and notifyAll from "+ds.getDbConnectionName());
+ Thread worker = new Thread(closure);
+ worker.setDaemon(true);
+ worker.start();
+ } else {
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Completed CachedDataSource.Call from "+ds.getDbConnectionName());
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java
new file mode 100644
index 0000000..7044082
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki 01/17/08 Initial version
+ */
+public class DBConfigFactory {
+
+ public static DbConfigPool createConfig(Properties resource) {
+ return getConfigparams(resource);
+ }
+
+ static DbConfigPool getConfigparams(Properties properties){
+ org.slf4j.LoggerFactory.getLogger(DBConfigFactory.class).info(properties.toString());
+ DbConfigPool xmlConfig = new DbConfigPool(properties);
+ ArrayList<Properties> propertySets = new ArrayList<Properties>();
+
+ if("JDBC".equalsIgnoreCase(xmlConfig.getType())) {
+ String hosts = properties.getProperty(BaseDBConfiguration.DATABASE_HOSTS);
+ if(hosts == null || hosts.isEmpty()) {
+ propertySets.add(properties);
+ } else {
+ String[] newhost = hosts.split(",");
+ for(int i=0; i< newhost.length; i++) {
+ Properties localset = new Properties();
+ localset.putAll(properties);
+ String url = localset.getProperty(BaseDBConfiguration.DATABASE_URL);
+ if(url.contains("DBHOST"))
+ url = url.replace("DBHOST", newhost[i]);
+ if(url.contains("dbhost"))
+ url = url.replace("dbhost", newhost[i]);
+ localset.setProperty(BaseDBConfiguration.DATABASE_URL, url);
+ localset.setProperty(BaseDBConfiguration.CONNECTION_NAME, newhost[i]);
+ propertySets.add(localset);
+ }
+ }
+ } else {
+ propertySets.add(properties);
+ }
+ try {
+ Iterator<Properties> it = propertySets.iterator();
+ while(it.hasNext()) {
+ BaseDBConfiguration config = parse(it.next());
+ xmlConfig.addConfiguration(config);
+ }
+
+ } catch (Exception e) {
+ org.slf4j.LoggerFactory.getLogger(DBConfigFactory.class).warn("",e);
+ }
+
+ return xmlConfig;
+ }
+
+ public static BaseDBConfiguration parse(Properties props) throws Exception {
+
+ String type = props.getProperty(BaseDBConfiguration.DATABASE_TYPE);
+
+ BaseDBConfiguration config = null;
+
+ if("JNDI".equalsIgnoreCase(type)) {
+ config = new JndiConfiguration(props);
+ }
+ if("JDBC".equalsIgnoreCase(type)) {
+ config = new JDBCConfiguration(props);
+ }
+
+ return config;
+
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java
new file mode 100644
index 0000000..e38cd35
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+
+/**
+ * @version 1.3
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki 01/16/08 Initial version
+ */
+public class FactoryNotDefinedException extends Exception {
+
+ public FactoryNotDefinedException(String message) {
+ super(message);
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java
new file mode 100644
index 0000000..0afb621
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java
@@ -0,0 +1,186 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.jdbc;
+
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSourceFactory;
+import org.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
+import org.openecomp.sdnc.sli.resource.dblib.DataSourceComparator;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractResourceManagerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Revision: 1.6 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class JdbcDbResourceManagerFactory extends AbstractResourceManagerFactory {
+ private static Logger LOGGER = LoggerFactory.getLogger(JdbcDbResourceManagerFactory.class );
+ private JdbcDbResourceManagerFactory(){
+
+ }
+
+ class MyFutureTask extends FutureTask<DBInitTask>
+ {
+
+ public MyFutureTask(Callable<CachedDataSource> result) {
+ super((Callable)result);
+ }
+
+ }
+
+ public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager, String sourceName) throws SQLException
+ {
+ // here create the data sources objects
+ JDBCConfiguration[] list = dbConfig.getJDBCbSourceArray();
+ CachedDataSource[] cachedDS = new CachedDataSource[1];
+
+ for(int i=0, max=list.length; i<max; i++){
+ if(!sourceName.equals(list[i].getDbConnectionName()))
+ continue;
+
+ JDBCConfiguration config = list[i];
+ CachedDataSource dataSource = CachedDataSourceFactory.createDataSource(config);
+ cachedDS[0] = dataSource;
+ }
+ return cachedDS;
+ }
+
+ public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) /* throws Exception */ {
+
+ ExecutorService threadExecutor = Executors.newFixedThreadPool(2);
+ // here create the data sources objects
+ JDBCConfiguration[] list = dbConfig.getJDBCbSourceArray();
+
+ FutureTask<DBInitTask>[] futures = new MyFutureTask[list.length];
+ final Set<DBInitTask> tasks = new HashSet<DBInitTask>();
+ if(LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Creating " + list.length + " datasources.");
+ }
+
+ for(int i=0, max=list.length; i<max; i++){
+ JDBCConfiguration config = list[i];
+
+ DBInitTask task = new DBInitTask(config, tasks);
+ tasks.add(task);
+ futures[i] = new MyFutureTask(task);
+ }
+
+ try {
+ synchronized(tasks){
+ for(int i=0, max=list.length; i<max; i++){
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Starting executor tasks.");
+ threadExecutor.execute(futures[i]);
+ }
+ // the timeout param is set is seconds.
+ long timeout = ((dbConfig.getTimeout() <= 0) ? 60L : dbConfig.getTimeout());
+ LOGGER.debug("Timeout set to " +timeout+" seconds");
+ timeout *= 1000;
+ // the timeout param is set is seconds, hence it needs to be multiplied by 1000.
+ tasks.wait(timeout);
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("initDBResourceManager wait completed.");
+ }
+ } catch(Exception exc) {
+ LOGGER.error("Failed to initialize JndiCachedDataSource. Reason: ", exc);
+ }
+
+ if(threadExecutor != null){
+ try {
+ threadExecutor.shutdown();
+ } catch(Exception exc){}
+ }
+
+ CachedDataSource[] cachedDS = new CachedDataSource[futures.length];
+
+ boolean initialized = false;
+ for(int i=0; i<futures.length; i++){
+ Object obj = null;
+ if(futures[i].isDone()){
+ try {
+ obj = futures[i].get();
+ if(obj instanceof CachedDataSource){
+ cachedDS[i] = (CachedDataSource)obj;
+ initialized |= cachedDS[i].isInitialized();
+ if(cachedDS[i].isInitialized())
+ LOGGER.info("DataSource "+list[i].getDbConnectionName()+" initialized successfully");
+ else
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed");
+ } else {
+ if(obj == null) {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is null");
+ } else {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is " + obj.getClass().getName());
+ }
+ }
+ } catch (InterruptedException exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ } catch (ExecutionException exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ } catch (Exception exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ }
+ } else {
+ try {
+ obj = futures[i].get();
+ if(obj instanceof CachedDataSource){
+ LOGGER.warn("DataSource "+((CachedDataSource)obj).getDbConnectionName()+" failed");
+ } else {
+ if(obj == null) {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is null");
+ } else {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is " + obj.getClass().getName());
+ }
+ }
+ } catch (Exception exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ }
+ }
+ }
+
+ if(!initialized){
+ new Error("Failed to initialize DB Library.");
+ }
+ return cachedDS;
+ }
+
+ public static AbstractResourceManagerFactory createIntstance() {
+ return new JdbcDbResourceManagerFactory();
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java
new file mode 100644
index 0000000..ebfd473
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java
@@ -0,0 +1,220 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.jdbc;
+
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
+
+
+
+
+/**
+ * @version $Revision: 1.7 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+
+public class MySQLCachedDataSource extends CachedDataSource
+{
+ private String dbUserId;
+ private String dbPasswd;
+ private String dbUrl;
+
+ private String minLimit;
+ private String maxLimit;
+ private String initialLimit;
+
+ private static final String AS_CONF_ERROR = "AS_CONF_ERROR: ";
+
+ private static Logger LOGGER = LoggerFactory.getLogger(MySQLCachedDataSource.class);
+
+ /**
+ * @param jdbcElem
+ * @param alarmLog
+ * @param occManager
+ * @throws Exception
+ */
+ public MySQLCachedDataSource(BaseDBConfiguration jdbcElem)
+ {
+ super(jdbcElem);
+ }
+
+ @Override
+ protected void configure(BaseDBConfiguration xmlElem) throws DBConfigException
+ {
+ BaseDBConfiguration jdbcConfig = (BaseDBConfiguration)xmlElem;
+ if(jdbcConfig.getConnTimeout() > 0){
+ this.CONN_REQ_TIMEOUT = jdbcConfig.getConnTimeout();
+ }
+ if(jdbcConfig.getRequestTimeout() > 0){
+ this.DATA_REQ_TIMEOUT = jdbcConfig.getRequestTimeout();
+ }
+
+ // set connection pool name
+ String dbConnectionName = jdbcConfig.getDbConnectionName();
+ super.setDbConnectionName(dbConnectionName);
+ // Configure the JDBC connection
+ dbUserId = jdbcConfig.getDbUserId();
+ if (dbUserId == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbUserId attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ dbPasswd = jdbcConfig.getDbPasswd();
+ if (dbPasswd == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbPasswd attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+ /*
+ dbDriver = jdbcConfig.getDbDriver();
+ if (dbDriver == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbDriver attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new ScpTblUpdateError(errorMsg);
+ }
+ */
+
+ minLimit = Integer.toString(jdbcConfig.getDbMinLimit());
+ if (minLimit == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBC Connection missing minLimit attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+ maxLimit = Integer.toString(jdbcConfig.getDbMaxLimit());
+ if (maxLimit == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBC Connection missing maxLimit attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+ initialLimit = Integer.toString(jdbcConfig.getDbInitialLimit());
+ if (initialLimit == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBC Connection missing initialLimit attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ dbUrl = jdbcConfig.getDbUrl();
+ if(dbUrl == null){
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbUrl attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ try {
+
+ MysqlDataSource dataSource = new MysqlDataSource();
+ dataSource.setUser(dbUserId);
+ dataSource.setPassword(dbPasswd);
+ dataSource.setURL(dbUrl);
+// dataSource.setInitialSize(5);
+// dataSource.setMaxTotal(60);
+// dataSource.setMaxActive(100);
+// dataSource.setMaxWait(10000);
+// dataSource.setMaxIdle(10);
+
+ Properties connAttr = new Properties();
+
+ connAttr.setProperty("MinLimit", minLimit);
+ connAttr.setProperty("MaxLimit", maxLimit);
+ connAttr.setProperty("InitialLimit", initialLimit);
+ connAttr.setProperty("TRANSACTION_ISOLATION","SERIALIZABLE");
+ connAttr.setProperty("CONNECTION_TAG", dbConnectionName.toUpperCase()+"_CONNECTION");
+ connAttr.setProperty("InactivityTimeout", "900");
+ connAttr.setProperty("AbandonedConnectionTimeout", "600");
+ connAttr.setProperty("PropertyCheckInterval", "60");
+ connAttr.setProperty("ValidateConnection", "true");
+
+
+ synchronized(this)
+ {
+ this.ds = dataSource;
+
+ initialized = true;
+ LOGGER.info("MySQLDataSource <"+dbConnectionName+"> configured successfully. Using URL: "+dbUrl);
+ }
+
+// } catch (SQLException exc) {
+// initialized = false;
+// StringBuffer sb = new StringBuffer();
+// sb.append("Failed to initialize MySQLDataSource<");
+// sb.append(dbConnectionName).append(">. Reason: ");
+// sb.append(exc.getMessage());
+// LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+//// throw new DBConfigException(e.getMessage());
+ } catch (Exception exc) {
+ initialized = false;
+ StringBuffer sb = new StringBuffer();
+ sb.append("Failed to initialize MySQLCachedDataSource <");
+ sb.append(dbConnectionName).append(">. Reason: ");
+ sb.append(exc.getMessage());
+ LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+// throw new DBConfigException(e.getMessage());
+ }
+ }
+
+ public final String getDbUrl()
+ {
+ return dbUrl;
+ }
+
+ public final String getDbUserId()
+ {
+ return dbUserId;
+ }
+
+ public final String getDbPasswd()
+ {
+ return dbPasswd;
+ }
+
+ public static MySQLCachedDataSource createInstance(BaseDBConfiguration config) /*throws Exception*/ {
+ return new MySQLCachedDataSource(config);
+ }
+
+ public String toString(){
+ return getDbConnectionName();
+ }
+
+ public java.util.logging.Logger getParentLogger()
+ throws SQLFeatureNotSupportedException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java
new file mode 100644
index 0000000..2888bc5
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.jndi;
+
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSourceFactory;
+import org.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractResourceManagerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Revision: 1.6 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class JNDIDbResourceManagerFactory extends AbstractResourceManagerFactory {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(JNDIDbResourceManagerFactory.class);
+
+ class MyFutureTask extends FutureTask<DBInitTask>
+ {
+
+ public MyFutureTask(Callable<CachedDataSource> result) {
+ super((Callable)result);
+ }
+
+ }
+
+ public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager, String sourceName) throws SQLException
+ {
+ // here create the data sources objects
+ JndiConfiguration[] list = dbConfig.getJndiDbSourceArray();
+ CachedDataSource[] cachedDS = new CachedDataSource[1];
+
+ for(int i=0, max=list.length; i<max; i++){
+ if(!sourceName.equals(list[i].getJndiConnectionName()))
+ continue;
+
+ JndiConfiguration config = list[i];
+ CachedDataSource dataSource = CachedDataSourceFactory.createDataSource(config);
+ cachedDS[0] = dataSource;
+ }
+ return cachedDS;
+ }
+
+ public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) /* throws Exception */ {
+// WSConfigManagement ws = WSConfigManagement.getInstance();
+
+ ExecutorService threadExecutor = Executors.newFixedThreadPool(2);
+ // here create the data sources objects
+ JndiConfiguration[] list = dbConfig.getJndiDbSourceArray();
+ FutureTask<DBInitTask>[] futures = new MyFutureTask[list.length];
+ final Set<DBInitTask> tasks = new HashSet<DBInitTask>();
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Creating datasources.");
+ for(int i=0, max=list.length; i<max; i++){
+ JndiConfiguration config = list[i];
+// if(manager.getJndiContextFactoryStr()!=null && manager.getJndiContextFactoryStr().trim().length()>0){
+// config.setJndiContextFactory(manager.getJndiContextFactoryStr());
+// }
+// if(manager.getJndiURLStr()!=null && manager.getJndiURLStr().trim().length()>0){
+// config.setJndiURL(manager.getJndiURLStr());
+// }
+ DBInitTask task = new DBInitTask(config, tasks);
+ tasks.add(task);
+ futures[i] = new MyFutureTask(task);
+ }
+
+ try {
+ synchronized(tasks){
+ for(int i=0, max=list.length; i<max; i++){
+ threadExecutor.execute(futures[i]);
+ }
+ // the timeout param is set is seconds.
+ long timeout = ((dbConfig.getTimeout() <= 0) ? 60L : dbConfig.getTimeout());
+ timeout *= 1000;
+ // the timeout param is set is seconds, hence it needs to be multiplied by 1000.
+ tasks.wait(timeout);
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("initDBResourceManager wait completed.");
+ }
+ } catch(Exception exc) {
+ LOGGER.error("Failed to initialize JndiCachedDataSource. Reason: ", exc);
+ }
+
+ if(threadExecutor != null){
+ try {
+ threadExecutor.shutdown();
+ } catch(Exception exc){}
+ }
+
+ CachedDataSource[] cachedDS = new CachedDataSource[futures.length];
+
+ boolean initialized = false;
+ for(int i=0; i<futures.length; i++){
+ Object obj = null;
+ if(futures[i].isDone()){
+ try {
+ obj = futures[i].get();
+ if(obj instanceof CachedDataSource){
+ cachedDS[i] = (CachedDataSource)obj;
+ initialized = true;
+ LOGGER.info("DataSource "+list[i].getJndiConnectionName()+" initialized successfully");
+ }
+ } catch (InterruptedException exc) {
+ LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+ } catch (ExecutionException exc) {
+ LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+ } catch (Exception exc) {
+ LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+ }
+ } else {
+ try {
+ obj = futures[i].get();
+ if(obj instanceof CachedDataSource){
+
+ LOGGER.error("DataSource "+((CachedDataSource)obj).getDbConnectionName()+" failed");
+ }
+ } catch (Exception exc) {
+ LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+ }
+ }
+ }
+
+ if(!initialized){
+ new Error("Failed to initialize DB Library.");
+ }
+ return cachedDS;
+ }
+
+ public static AbstractResourceManagerFactory createIntstance() {
+ return new JNDIDbResourceManagerFactory();
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java
new file mode 100644
index 0000000..19fa8e9
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java
@@ -0,0 +1,131 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.jndi;
+
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * @version $Revision: 1.2 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class JndiCachedDataSource extends CachedDataSource
+{
+ private static Logger LOGGER = LoggerFactory.getLogger(JndiCachedDataSource.class);
+ /**
+ * @param alarmLog
+ * @param jdbcElem
+ * @throws SAXException
+ * @throws ScpTblUpdateError
+ */
+ public JndiCachedDataSource(BaseDBConfiguration xmlElem) throws DBConfigException
+ {
+ super(xmlElem);
+ }
+
+ protected void configure(BaseDBConfiguration xmlElem) throws DBConfigException {
+ JndiConfiguration jdbcConfig = (JndiConfiguration)xmlElem;
+ String jndiContextFactoryStr = jdbcConfig.getJndiContextFactory();
+ String jndiURLStr = jdbcConfig.getJndiURL();
+ String jndiSourceStr = jdbcConfig.getJndiSource();
+
+ if(jdbcConfig.getConnTimeout() > 0){
+ this.CONN_REQ_TIMEOUT = jdbcConfig.getConnTimeout();
+ }
+ if(jdbcConfig.getRequestTimeout() > 0){
+ this.DATA_REQ_TIMEOUT = jdbcConfig.getRequestTimeout();
+ }
+
+ super.setDbConnectionName(jdbcConfig.getJndiConnectionName());
+
+ if(jndiContextFactoryStr == null || jndiContextFactoryStr.length() == 0)
+ {
+// throw new DBConfigException("The jndi configuration is incomplete: jndiContextFactory");
+ }
+ if(jndiURLStr == null || jndiContextFactoryStr.length() == 0)
+ {
+// throw new ScpTblUpdateError("The jndi configuration is incomplete: jndiURL");
+ }
+ if(jndiSourceStr == null || jndiSourceStr.length() == 0)
+ {
+ throw new DBConfigException("The jndi configuration is incomplete: jndiSource");
+ }
+
+ Properties env = new Properties();
+ Context ctx;
+ try
+ {
+ if(jndiContextFactoryStr != null && jndiContextFactoryStr.length() != 0){
+ env.put(Context.INITIAL_CONTEXT_FACTORY, jndiContextFactoryStr);
+ ctx = new InitialContext(env);
+ } else {
+ ctx = new InitialContext();
+ }
+ ds = (javax.sql.DataSource) ctx.lookup (jndiSourceStr);
+ if(ds == null)
+ {
+ this.initialized = false;
+ LOGGER.error("AS_CONF_ERROR: Failed to initialize DataSource <"+getDbConnectionName()+"> using JNDI <"+jndiSourceStr+">");
+ return;
+ } else {
+ this.initialized = true;
+ LOGGER.info("JndiCachedDataSource <"+getDbConnectionName()+"> configured successfully.");
+ return;
+ }
+ } catch (NamingException exc) {
+ this.initialized = false;
+ LOGGER.error("AS_CONF_ERROR" + exc.getMessage());
+
+ } catch(Throwable exc) {
+ this.initialized = false;
+ LOGGER.error("AS_CONF_ERROR: " + exc.getMessage());
+ }
+ }
+
+ public static JndiCachedDataSource createInstance(BaseDBConfiguration config) {
+ return new JndiCachedDataSource(config);
+ }
+
+ public String toString(){
+ return getDbConnectionName();
+ }
+
+ public java.util.logging.Logger getParentLogger()
+ throws SQLFeatureNotSupportedException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java
new file mode 100644
index 0000000..de87fa7
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java
@@ -0,0 +1,217 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.pm;
+
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TreeSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class PollingWorker implements Runnable {
+
+ private Logger LOGGER = LoggerFactory.getLogger(PollingWorker.class);
+
+ private static PollingWorker self = null;
+
+ private LinkedBlockingQueue tasks = new LinkedBlockingQueue(100);
+ private long interval = 1000L;
+ private Thread worker = null;
+ private AtomicLong[] counters = null;
+ private int[] bucketUnit = null;
+ private static boolean enabled = false;
+ private Timer timer = null;
+
+ public static void post(long starttime){
+ PollingWorker temp = self;
+ if(temp != null && enabled) {
+ temp.register(new TestSample(starttime));
+ }
+ }
+
+ public static void createInistance(Properties props){
+ self = new PollingWorker(props);
+ }
+
+ private PollingWorker(Properties ctxprops){
+ if(ctxprops==null || ctxprops.getProperty("org.openecomp.sdnc.dblib.pm") == null){
+ enabled = false;
+ } else {
+ if("true".equalsIgnoreCase((String)ctxprops.getProperty("org.openecomp.sdnc.dblib.pm"))){
+ enabled = true;
+ } else {
+ enabled = false;
+ }
+ }
+
+ interval = Long.parseLong(( ctxprops == null || ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.interval") == null) ? "60" : (String)ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.interval"));
+ // '0' bucket is to count exceptions
+ String sampling[] = ((ctxprops == null || ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.sampling")==null) ? "0,2,5,10,20,50,100" : (String)ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.sampling")).split(",");
+
+ if(enabled){
+ bucketUnit = new int[sampling.length];
+ for(int i=0, max = bucketUnit.length; i<max; i++){
+ bucketUnit[i] = Integer.parseInt(sampling[i].trim());
+ }
+ counters = new AtomicLong[bucketUnit.length+1];
+ for(int i=0, max = counters.length; i<max; i++){
+ counters[i] = new AtomicLong();
+ }
+ worker = new Thread(this);
+ worker.setDaemon(true);
+ worker.start();
+ timer = new Timer(true);
+ timer.schedule(new MyTimerTask(), interval*1000L, interval*1000L);
+ }
+ }
+
+ private void register(TestSample object){
+ try {
+ tasks.add(object);
+ } catch(Throwable exc) {
+ // if cannot add an object to the queue, do nothing
+ }
+ }
+
+ private void deRegister(TestSample object){
+ tasks.remove(object);
+ }
+
+ public void run() {
+ for(;;){
+ Set data = new TreeSet();
+ tasks.drainTo(data);
+ for(Iterator it = data.iterator(); it.hasNext(); ){
+ Object next = it.next();
+ if(next instanceof TestSample){
+ consume((TestSample)next);
+ } else {
+ System.out.println(next.getClass().getName());
+ }
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ public void clearReqister(){
+ AtomicLong[] tmp = new AtomicLong[counters.length];
+ for(int i=0, max = tmp.length; i<max; i++){
+ tmp[i] = new AtomicLong();
+ }
+ AtomicLong[] tmp2 = counters;
+ synchronized(tmp2){
+ counters = tmp;
+ }
+ StringBuffer sb = new StringBuffer("CPM: ");
+ for(int i=0, max = tmp2.length; i < max; i++){
+ if(i==0 && bucketUnit[0]==0){
+ sb.append("[Exc]=");
+ } else {
+ sb.append("[");
+ if(i==bucketUnit.length){
+ sb.append("Other]=");
+ } else {
+ sb.append(bucketUnit[i]).append(" ms]=");
+ }
+ }
+ sb.append(tmp2[i].get()).append("\t");
+ }
+ LOGGER.info(sb.toString());
+ }
+
+ class MyTimerTask extends TimerTask{
+
+ public void run() {
+
+ clearReqister();
+ }
+
+ }
+
+ private void consume(TestSample probe) {
+ AtomicLong[] tmp = counters;
+ synchronized(tmp){
+ counters[getBucket(probe.getDuration())].incrementAndGet();
+ }
+ }
+
+ /*
+ * This method is used to find the offset of the bucket in
+ * counters. 'counters' array is 1 size longer than bucketUnit,
+ * hence by default it returns 'bucketUnit.length'
+ */
+ private int getBucket(long difftime){
+ for(int i=0; i<bucketUnit.length; i++){
+ if(difftime < bucketUnit[i]){
+ return i;
+ }
+ }
+ return bucketUnit.length;
+ }
+
+ private static boolean isEnabled() {
+ return enabled;
+ }
+ /**
+ * @author Rich Tabedzki
+ * A helper class to pass measured parameter to the counter.
+ */
+ static class TestSample implements Comparable{
+ private long starttime;
+ private long endtime;
+
+ public TestSample(long starttime) {
+ this.endtime = System.currentTimeMillis();
+ this.starttime = starttime;
+ }
+
+ public long getDuration(){
+ return endtime - starttime;
+ }
+
+ public int compareTo(Object o) {
+ if(o instanceof TestSample){
+ TestSample x = (TestSample)o;
+ if(starttime < x.starttime)
+ return 1;
+ if(endtime < x.endtime)
+ return 1;
+ if(starttime > x.starttime)
+ return -1;
+ if(endtime > x.endtime)
+ return -1;
+ return 0;
+ }
+ return 1;
+ }
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java
new file mode 100644
index 0000000..c58c9db
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java
@@ -0,0 +1,237 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.pm;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.SortedSet;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.openecomp.sdnc.sli.resource.dblib.DBResourceObserver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SQLExecutionMonitor extends Observable
+{
+ private static Logger LOGGER = LoggerFactory.getLogger(SQLExecutionMonitor.class);
+
+ final static long MILISECOND = 1000000L;
+ final static long SECOND = 1000L*MILISECOND;
+
+ private final Timer timer;
+ // collection
+ private final SortedSet<TestObject> innerSet;
+ private SQLExecutionMonitorObserver parent = null;
+ private final AtomicLong completionCounter;
+ private boolean activeState = false;
+ private final long interval;
+ private final long initialDelay;
+ private final long EXPECTED_TIME_TO_COMPLETE;
+ private final long UNPROCESSED_FAILOVER_THRESHOLD;
+
+ private final class MonitoringTask extends TimerTask
+ {
+
+ public void run()
+ {
+ try {
+ TestObject testObj = new TestObject();
+ testObj.setStartTime(testObj.getStartTime() - EXPECTED_TIME_TO_COMPLETE);
+
+ // take a snapshot of the current task list
+ TestObject[] array = innerSet.toArray(new TestObject[0]);
+ SortedSet<TestObject> copyCurrent = new TreeSet<TestObject>(Arrays.asList(array));
+ // get the list of the tasks that are older than the specified
+ // interval.
+ SortedSet<TestObject> unprocessed = copyCurrent.headSet(testObj);
+
+ long succesfulCount = completionCounter.get();
+ int unprocessedCount = unprocessed.size();
+
+ if (!unprocessed.isEmpty() && unprocessedCount > UNPROCESSED_FAILOVER_THRESHOLD && succesfulCount == 0)
+ {
+ // switch the Connection Pool to passive
+ setChanged();
+ notifyObservers("Open JDBC requests=" + unprocessedCount+" in "+SQLExecutionMonitor.this.parent.getDbConnectionName());
+ }
+ } catch (Exception exc) {
+ LOGGER.error("", exc);
+ } finally {
+ completionCounter.set(0L);
+ }
+ }
+ }
+
+ public static class TestObject implements Comparable<TestObject>, Serializable
+ {
+
+ private static final long serialVersionUID = 1L;
+ private long starttime;
+ private long randId;
+
+ public TestObject()
+ {
+ starttime = System.nanoTime();
+ }
+
+ public long getStartTime()
+ {
+ return starttime;
+ }
+
+ public void setStartTime(long newTime)
+ {
+ starttime = newTime;
+ }
+
+ public int compareTo(TestObject o)
+ {
+ if( this == o)
+ return 0;
+ if(this.starttime > o.getStartTime())
+ return 1;
+ if(this.starttime < o.getStartTime())
+ return -1;
+
+ if(this.hashCode() > o.hashCode())
+ return 1;
+ if(this.hashCode() < o.hashCode())
+ return -1;
+
+ return 0;
+ }
+
+ public String toString()
+ {
+ return Long.toString(starttime)+"#"+ this.hashCode();
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+
+ return (obj instanceof TestObject
+ && starttime == ((TestObject) obj).getStartTime()
+ && hashCode() == ((TestObject) obj).hashCode());
+ }
+ }
+
+ public SQLExecutionMonitor(SQLExecutionMonitorObserver parent)
+ {
+ this.parent = parent;
+ completionCounter = new AtomicLong(0L);
+ interval = parent.getInterval();
+ initialDelay = parent.getInitialDelay();
+ this.UNPROCESSED_FAILOVER_THRESHOLD = parent.getUnprocessedFailoverThreshold();
+ this.EXPECTED_TIME_TO_COMPLETE = parent.getExpectedCompletionTime()*MILISECOND;
+
+ innerSet = Collections.synchronizedSortedSet(new TreeSet<TestObject>());
+ timer = new Timer();
+ }
+
+ public void cleanup()
+ {
+ timer.cancel();
+ }
+
+ // registerRequest
+ public TestObject registerRequest()
+ {
+ if(activeState)
+ {
+ TestObject test = new TestObject();
+ if(innerSet.add(test))
+ return test;
+ }
+ return null;
+ }
+
+ // deregisterSuccessfulReguest
+ public boolean deregisterReguest(TestObject test)
+ {
+ if(test == null)
+ return false;
+ // remove from the collection
+ if(innerSet.remove(test) && activeState)
+ {
+ completionCounter.incrementAndGet();
+ return true;
+ }
+ return false;
+ }
+
+ public void terminate() {
+ timer.cancel();
+ }
+
+ /**
+ * @return the parent
+ */
+ public final Object getParent() {
+ return parent;
+ }
+
+ public void addObserver(Observer observer)
+ {
+ if(observer instanceof DBResourceObserver)
+ {
+ DBResourceObserver dbObserver = (DBResourceObserver)observer;
+ if(dbObserver.isMonitorDbResponse())
+ {
+ if(countObservers() == 0)
+ {
+ TimerTask remindTask = new MonitoringTask();
+ timer.schedule(remindTask, initialDelay, interval);
+ activeState = true;
+ }
+ }
+ }
+ super.addObserver(observer);
+ }
+
+ public void deleteObserver(Observer observer)
+ {
+ super.deleteObserver(observer);
+ if(observer instanceof DBResourceObserver)
+ {
+ DBResourceObserver dbObserver = (DBResourceObserver)observer;
+ if(dbObserver.isMonitorDbResponse())
+ {
+ if(countObservers() == 0)
+ {
+ timer.cancel();
+ activeState = false;
+ }
+ }
+ }
+ }
+
+ public final int getPorcessedConnectionsCount() {
+ return innerSet.size();
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java
new file mode 100644
index 0000000..1f32975
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * 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.openecomp.sdnc.sli.resource.dblib.pm;
+
+public interface SQLExecutionMonitorObserver {
+ public String getDbConnectionName();
+
+ public long getInterval();
+ public void setInterval(long value);
+
+ public long getInitialDelay();
+ public void setInitialDelay(long value);
+
+ public long getExpectedCompletionTime();
+ public void setExpectedCompletionTime(long value);
+
+ public long getUnprocessedFailoverThreshold();
+ public void setUnprocessedFailoverThreshold(long value);
+}
diff --git a/dblib/provider/src/main/resources/dblib.properties b/dblib/provider/src/main/resources/dblib.properties
new file mode 100755
index 0000000..3872288
--- /dev/null
+++ b/dblib/provider/src/main/resources/dblib.properties
@@ -0,0 +1,13 @@
+org.openecomp.sdnc.sli.dbtype=jdbc
+org.openecomp.sdnc.sli.jdbc.hosts=sdnctldb01,sdnctldb02
+org.openecomp.sdnc.sli.jdbc.url=jdbc:mysql://DBHOST:3306/sdnctl
+org.openecomp.sdnc.sli.jdbc.database=sdnctl
+org.openecomp.sdnc.sli.jdbc.user=sdnctl
+org.openecomp.sdnc.sli.jdbc.password=gamma
+org.openecomp.sdnc.sli.jdbc.connection.name=sdnctldb01
+
+org.openecomp.sdnc.sli.jdbc.connection.timeout=50
+org.openecomp.sdnc.sli.jdbc.request.timeout=100
+org.openecomp.sdnc.sli.jdbc.limit.init=10
+org.openecomp.sdnc.sli.jdbc.limit.min=10
+org.openecomp.sdnc.sli.jdbc.limit.max=20 \ No newline at end of file
diff --git a/dblib/provider/src/test/resources/dblib.properties b/dblib/provider/src/test/resources/dblib.properties
new file mode 100755
index 0000000..e15e37a
--- /dev/null
+++ b/dblib/provider/src/test/resources/dblib.properties
@@ -0,0 +1,16 @@
+org.openecomp.sdnc.sli.dbtype=jdbc
+
+org.openecomp.sdnc.sli.jdbc.hosts=sdnctldb01
+org.openecomp.sdnc.sli.jdbc.url=jdbc:mysql://dbhost:3306/sdnctl
+org.openecomp.sdnc.sli.jdbc.database=sdnctl
+org.openecomp.sdnc.sli.jdbc.user=user
+org.openecomp.sdnc.sli.jdbc.password=password
+org.openecomp.sdnc.sli.jdbc.connection.name=sdnctldb01
+
+org.openecomp.sdnc.sli.jdbc.connection.timeout=50
+org.openecomp.sdnc.sli.jdbc.request.timeout=100
+org.openecomp.sdnc.sli.jdbc.limit.init=10
+org.openecomp.sdnc.sli.jdbc.limit.min=10
+org.openecomp.sdnc.sli.jdbc.limit.max=20
+
+org.openecomp.dblib.connection.recovery=false \ No newline at end of file