Repository: incubator-nifi
Updated Branches:
  refs/heads/develop 8c7dd6ab3 -> 149ad130d


Initial Database connection pooling service implementation NIFI-322

Signed-off-by: Toivo Adams <toivo.ad...@gmail.com>
Signed-off-by: Mark Payne <marka...@hotmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/589e2b7e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/589e2b7e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/589e2b7e

Branch: refs/heads/develop
Commit: 589e2b7ebf6ef70307ff1a2ab67c473d2f19a9a9
Parents: 5273a63
Author: Toivo Adams <toivo.ad...@gmail.com>
Authored: Sun Mar 1 22:27:06 2015 +0200
Committer: Mark Payne <marka...@hotmail.com>
Committed: Wed May 20 08:35:53 2015 -0400

----------------------------------------------------------------------
 .../nifi-dbcp-service-api/pom.xml               |  18 ++
 .../java/org/apache/nifi/dbcp/DBCPService.java  |  38 ++++
 .../nifi-dbcp-service-nar/pom.xml               |  28 +++
 .../nifi-dbcp-service/pom.xml                   |  49 +++++
 .../nifi/dbcp/DBCPServiceApacheDBCP14.java      | 208 ++++++++++++++++++
 .../nifi/dbcp/DatabaseSystemDescriptor.java     |  51 +++++
 .../org/apache/nifi/dbcp/DatabaseSystems.java   |  78 +++++++
 .../org/apache/nifi/dbcp/DBCPServiceTest.java   | 214 +++++++++++++++++++
 .../apache/nifi/dbcp/TestDatabaseSystems.java   |  37 ++++
 .../org/apache/nifi/dbcp/TestProcessor.java     |  47 ++++
 .../nifi-dbcp-service-bundle/pom.xml            |  18 ++
 .../nifi-standard-services-api-nar/pom.xml      |   6 +
 .../nifi-standard-services/pom.xml              |   1 +
 13 files changed, 793 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml
new file mode 100644
index 0000000..f8ea08a
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml
@@ -0,0 +1,18 @@
+<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.apache.nifi</groupId>
+        <artifactId>nifi-standard-services</artifactId>
+        <version>0.0.2-incubating-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-dbcp-service-api</artifactId>
+    <packaging>jar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/main/java/org/apache/nifi/dbcp/DBCPService.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/main/java/org/apache/nifi/dbcp/DBCPService.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/main/java/org/apache/nifi/dbcp/DBCPService.java
new file mode 100644
index 0000000..8f2aa5a
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/main/java/org/apache/nifi/dbcp/DBCPService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+import java.sql.Connection;
+
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.processor.exception.ProcessException;
+
+/**
+ * Definition for Database Connection Pooling Service.
+ *
+ */
+@Tags({"dbcp", "jdbc", "database", "connection", "pooling", "store"})
+@CapabilityDescription("Provides Database Connection Pooling Service. 
Connections can be asked from pool and returned after usage."
+        )
+public interface DBCPService extends ControllerService {
+
+ 
+    public Connection getConnection()  throws ProcessException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
new file mode 100644
index 0000000..37722db
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service-nar/pom.xml
@@ -0,0 +1,28 @@
+<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.apache.nifi</groupId>
+        <artifactId>nifi-dbcp-service-bundle</artifactId>
+        <version>0.0.2-incubating-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-dbcp-service-nar</artifactId>
+    <packaging>nar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-standard-services-api-nar</artifactId>
+            <type>nar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-dbcp-service</artifactId>
+            <version>0.0.2-incubating-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+  
+  
+  
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
new file mode 100644
index 0000000..d06a14c
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/pom.xml
@@ -0,0 +1,49 @@
+<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.apache.nifi</groupId>
+        <artifactId>nifi-dbcp-service-bundle</artifactId>
+        <version>0.0.2-incubating-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-dbcp-service</artifactId>
+    <packaging>jar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-dbcp-service-api</artifactId>
+            <version>0.0.2-incubating-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-processor-utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-mock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+               <groupId>commons-dbcp</groupId>
+               <artifactId>commons-dbcp</artifactId>
+               <version>1.4</version>
+        </dependency>
+               <dependency>
+                   <groupId>org.apache.derby</groupId>
+                   <artifactId>derby</artifactId>
+                   <version>10.11.1.1</version>
+           </dependency>        
+        
+    </dependencies>
+  
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPServiceApacheDBCP14.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPServiceApacheDBCP14.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPServiceApacheDBCP14.java
new file mode 100644
index 0000000..eb0a950
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPServiceApacheDBCP14.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.annotation.lifecycle.OnEnabled;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.controller.AbstractControllerService;
+import org.apache.nifi.controller.ConfigurationContext;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.reporting.InitializationException;
+
+/**
+ * Implementation of for Database Connection Pooling Service.
+ * Apache DBCP is used for connection pooling functionality.
+ *
+ */
+@Tags({"dbcp", "jdbc", "database", "connection", "pooling", "store"})
+@CapabilityDescription("Provides Database Connection Pooling Service. 
Connections can be asked from pool and returned after usage."
+        )
+public class DBCPServiceApacheDBCP14 extends AbstractControllerService 
implements DBCPService {
+
+       public static final DatabaseSystemDescriptor DEFAULT_DATABASE_SYSTEM = 
DatabaseSystems.getDescriptor("JavaDB");
+
+    public static final PropertyDescriptor DATABASE_SYSTEM = new 
PropertyDescriptor.Builder()
+    .name("Database")
+    .description("Database management system")
+//    .allowableValues(POSTGRES, JavaDB, DERBY, MariaDB, OtherDB)
+    .allowableValues(DatabaseSystems.knownDatabaseSystems)
+    .defaultValue(DEFAULT_DATABASE_SYSTEM.getValue())
+    .required(true)
+    .build();    
+
+    public static final PropertyDescriptor DB_HOST = new 
PropertyDescriptor.Builder()
+    .name("Database host")
+    .description("Database host")
+    .defaultValue(null)
+    .required(true)
+    .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+    .build();
+
+    public static final PropertyDescriptor DB_PORT = new 
PropertyDescriptor.Builder()
+    .name("Database port")
+    .description("Database server port")
+    .defaultValue(DEFAULT_DATABASE_SYSTEM.defaultPort.toString())
+    .required(true)
+    .addValidator(StandardValidators.PORT_VALIDATOR)
+    .build();
+
+    public static final PropertyDescriptor DB_DRIVERNAME = new 
PropertyDescriptor.Builder()
+    .name("Database driver class name")
+    .description("Database driver class name")
+    .defaultValue(DEFAULT_DATABASE_SYSTEM.driverClassName)
+    .required(true)
+    .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+    .build();
+
+    public static final PropertyDescriptor DB_NAME = new 
PropertyDescriptor.Builder()
+    .name("Database name")
+    .description("Database name")
+    .defaultValue(null)
+    .required(true)
+    .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+    .build();
+
+    public static final PropertyDescriptor DB_USER = new 
PropertyDescriptor.Builder()
+    .name("Database user")
+    .description("Database user name")
+    .defaultValue(null)
+    .required(true)
+    .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+    .build();
+
+    public static final PropertyDescriptor DB_PASSWORD = new 
PropertyDescriptor.Builder()
+    .name("Password")
+    .description("The password for the database user")
+    .defaultValue(null)
+    .required(true)
+    .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+    .sensitive(true)
+    .build();
+
+    private static final List<PropertyDescriptor> properties;
+
+    static {
+        List<PropertyDescriptor> props = new ArrayList<>();
+        props.add(DATABASE_SYSTEM);
+        props.add(DB_HOST);
+        props.add(DB_PORT);
+        props.add(DB_DRIVERNAME);
+        props.add(DB_NAME);
+        props.add(DB_USER);
+        props.add(DB_PASSWORD);
+        
+        properties = Collections.unmodifiableList(props);
+    }
+    
+    private ConfigurationContext configContext;
+    private volatile BasicDataSource dataSource;
+
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        return properties;
+    }
+    
+    //=================================   Apache DBCP pool parameters  
================================ 
+    
+    /** The maximum number of milliseconds that the pool will wait (when there 
are no available connections) 
+     * for a connection to be returned before throwing an exception, or -1 to 
wait indefinitely. 
+     */
+    static final long maxWaitMillis = 500;
+   
+    /** The maximum number of active connections that can be allocated from 
this pool at the same time, 
+     * or negative for no limit.
+     */
+    static final int maxTotal          = 8;
+
+    
//=================================================================================================
+    
+    /**
+     * Idea was to dynamically set port, driver and url properties default 
values after user select database system.
+     * As of 01mar2015 such functionality is not supported.
+     * 
+    @Override
+    public void onPropertyModified(final PropertyDescriptor descriptor, final 
String oldValue, final String newValue) {
+        super.onPropertyModified(descriptor, oldValue, newValue);
+
+        if (descriptor.equals(DATABASE_SYSTEM)) {
+               
+               DatabaseSystemDescriptor databaseSystemDescriptor = 
DatabaseSystems.getDescriptor(newValue);
+        }        
+    }
+       */
+
+    @OnEnabled
+    public void onConfigured(final ConfigurationContext context) throws 
InitializationException {
+        configContext = context;
+
+        DatabaseSystemDescriptor dbsystem = DatabaseSystems.getDescriptor( 
context.getProperty(DATABASE_SYSTEM).getValue() );
+        
+        String host   = context.getProperty(DB_HOST).getValue();
+        Integer port  = context.getProperty(DB_PORT).asInteger();
+        String drv    = context.getProperty(DB_DRIVERNAME).getValue();
+        String dbname = context.getProperty(DB_NAME).getValue();
+        String user   = context.getProperty(DB_USER).getValue();
+        String passw  = context.getProperty(DB_PASSWORD).getValue();
+        
+        String dburl  = dbsystem.buildUrl(host, port, dbname);
+        
+        dataSource = new BasicDataSource();
+        dataSource.setMaxWait(maxWaitMillis);
+        dataSource.setMaxActive(maxTotal);
+
+        dataSource.setUrl(dburl);
+        dataSource.setDriverClassName(drv);
+        dataSource.setUsername(user);
+        dataSource.setPassword(passw);
+
+        // verify connection can be established.
+        try {
+                       Connection con = dataSource.getConnection();
+                       if (con==null)
+                               throw new InitializationException("Connection 
to database cannot be established.");
+                       con.close();
+               } catch (SQLException e) {
+                       throw new InitializationException(e);
+               }
+    }
+    
+       @Override
+       public Connection getConnection() throws ProcessException {
+               try {
+                       Connection con = dataSource.getConnection();
+                       return con;
+               } catch (SQLException e) {
+                       throw new ProcessException(e);
+               }
+       }
+
+    @Override
+    public String toString() {
+        return "DBCPServiceApacheDBCP14[id=" + getIdentifier() + "]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystemDescriptor.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystemDescriptor.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystemDescriptor.java
new file mode 100644
index 0000000..d456c3b
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystemDescriptor.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+import java.text.MessageFormat;
+
+import org.apache.nifi.components.AllowableValue;
+
+/**
+ * An immutable object for holding information about a database system.
+ *
+ */
+public class DatabaseSystemDescriptor extends AllowableValue {
+
+       public final String driverClassName;
+       public final Integer defaultPort;
+       public final String urlTemplate;
+       public final boolean internalDriverJar;
+       
+       public DatabaseSystemDescriptor(String value, String description,
+                       String driverClassName, Integer defaultPort, String 
urlTemplate, boolean internalDriverJar) {
+               super(value, value, description);
+               
+               if (defaultPort==null)
+                       throw new IllegalArgumentException("defaultPort cannot 
be null");
+
+               this.driverClassName = driverClassName;
+               this.defaultPort         = defaultPort;
+               this.urlTemplate         = urlTemplate;
+               this.internalDriverJar = internalDriverJar;
+       }
+
+       public String buildUrl(String host, Integer port, String dbname) {
+               return MessageFormat.format(urlTemplate, host, port.toString(), 
dbname);
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystems.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystems.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystems.java
new file mode 100644
index 0000000..1859b72
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DatabaseSystems.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+public class DatabaseSystems {
+
+       /**
+        *      {0}             host name/ip
+        *      {1}             port number  
+        *  {2}         database name
+        * 
+        * for example url template
+        *   "jdbc:postgresql://{0}:{1}/{2}"
+        * will be after building
+        *  "jdbc:postgresql://bighost:5432/Trove"
+        * 
+        */
+       
+       public static DatabaseSystemDescriptor[] knownDatabaseSystems = { 
+               
+               // =================  JDBC driver jar should be included in nar 
(in pom.xml dependencies) =======================
+               
+               new DatabaseSystemDescriptor("Postgres", "PostgreSQL open soure 
object-relational database.", 
+                               "org.postgresql.Driver", 5432, 
"jdbc:postgresql://{0}:{1}/{2}", true),
+
+               new DatabaseSystemDescriptor("JavaDB", "Java DB is Oracle's 
supported distribution of the Apache Derby open source database. Included in 
JDK.", 
+                               "org.apache.derby.jdbc.EmbeddedDriver", 1, 
"jdbc:derby:{2};create=true", true),
+                               
+               new DatabaseSystemDescriptor("Derby", "Apache Derby is an open 
source relational database.", 
+                               "org.apache.derby.jdbc.EmbeddedDriver", 1, 
"jdbc:derby:{2};create=true", true),
+       
+
+               // =================  JDBC driver jar must be loaded from 
external location  =======================
+                               
+               new DatabaseSystemDescriptor("MariaDB",
+                               "MariaDB is a community-developed fork of the 
MySQL relational database management system intended to remain free under the 
GNU GPL.", 
+                               "org.mariadb.jdbc.Driver", 3306, 
"jdbc:mariadb://{0}:{1}/{2}", false),
+
+               new DatabaseSystemDescriptor("Oracle",
+                               "Oracle Database is an object-relational 
database management system.", 
+                               "oracle.jdbc.OracleDriver", 1521, 
"jdbc:oracle:thin:@//{0}:{1}/{2}", false),
+
+               new DatabaseSystemDescriptor("Sybase",
+                               "Sybase is an relational database management 
system.", 
+                               "com.sybase.jdbc3.jdbc.SybDriver", 5000, 
"jdbc:sybase:Tds:{0}:{1}/{2}", false),
+
+
+               // =================  Unknown JDBC driver, user must provide 
connection details =====================           
+                               
+               new DatabaseSystemDescriptor("Other DB", "Other JDBC compliant 
JDBC driver", 
+                               null, 1, null, false),
+               
+       };
+       
+       public static DatabaseSystemDescriptor getDescriptor(String name) {
+               for ( DatabaseSystemDescriptor descr : 
DatabaseSystems.knownDatabaseSystems) {
+                       if (descr.getValue().equalsIgnoreCase(name))
+                               return descr;
+               }
+               throw new IllegalArgumentException("Can't find 
DatabaseSystemDescriptor by name " + name);
+       }
+       
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
new file mode 100644
index 0000000..684cc76
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.activation.DataSource;
+
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class DBCPServiceTest {
+    
+       final static String DB_LOCATION = "/var/tmp/testdb";
+       
+       /**
+        *      Unknown database system.  
+        * 
+        */
+    @Test
+    public void testBad1() throws InitializationException {
+        final TestRunner runner = 
TestRunners.newTestRunner(TestProcessor.class);
+        final DBCPServiceApacheDBCP14 service = new DBCPServiceApacheDBCP14();
+        final Map<String, String> properties = new HashMap<String, String>();
+        properties.put(DBCPServiceApacheDBCP14.DATABASE_SYSTEM.getName(), 
"garbage");
+        runner.addControllerService("test-bad2", service, properties);
+        runner.assertNotValid(service);
+    }
+    
+    /**
+     *  Missing property values.
+     */    
+    @Test
+    public void testGood1() throws InitializationException {
+        final TestRunner runner = 
TestRunners.newTestRunner(TestProcessor.class);
+        final DBCPServiceApacheDBCP14 service = new DBCPServiceApacheDBCP14();
+        final Map<String, String> properties = new HashMap<String, String>();
+        runner.addControllerService("test-bad1", service, properties);
+        runner.assertNotValid(service);
+    }
+
+    /**
+     *         Test database connection using Derby.
+     * Connect, create table, insert, select, drop table. 
+     * 
+     */
+    @Test
+    public void testGood2() throws InitializationException, SQLException {
+        final TestRunner runner = 
TestRunners.newTestRunner(TestProcessor.class);
+        final DBCPServiceApacheDBCP14 service = new DBCPServiceApacheDBCP14();
+        runner.addControllerService("test-good1", service);
+        
+        // remove previous test database, if any
+        File dbLocation = new File(DB_LOCATION);
+        dbLocation.delete();
+        
+        // Should setProperty call also generate 
DBCPServiceApacheDBCP14.onPropertyModified() method call? 
+        // It does not currently.
+        
+        // Some properties already should have JavaDB/Derby default values, 
let's set only missing values.
+        
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_HOST, "NA");    
// Embedded Derby don't use host
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_NAME, 
DB_LOCATION);
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_USER,   
"tester");
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_PASSWORD, 
"testerp");
+        
+        runner.enableControllerService(service);
+
+        runner.assertValid(service);
+        DBCPService dbcpService = (DBCPService) 
runner.getProcessContext().getControllerServiceLookup().getControllerService("test-good1");
+        Assert.assertNotNull(dbcpService);
+        Connection connection = dbcpService.getConnection();
+        Assert.assertNotNull(connection);
+        
+        createInsertSelectDrop(connection);
+        
+        connection.close();            // return to pool
+    }
+
+    
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+    
+    /**
+     *         Test get database connection using Derby.
+     * Get many times, after a while pool should not contain any available 
connection
+     * and getConnection should fail.    
+     */
+    @Test
+    public void testExhaustPool() throws InitializationException, SQLException 
{
+        final TestRunner runner = 
TestRunners.newTestRunner(TestProcessor.class);
+        final DBCPServiceApacheDBCP14 service = new DBCPServiceApacheDBCP14();
+        runner.addControllerService("test-exhaust", service);
+        
+        // remove previous test database, if any
+        File dbLocation = new File(DB_LOCATION);
+        dbLocation.delete();
+        
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_HOST, "NA");    
// Embedded Derby don't use host
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_NAME, 
DB_LOCATION);
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_USER,   
"tester");
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_PASSWORD, 
"testerp");
+        
+        runner.enableControllerService(service);
+
+        runner.assertValid(service);
+        DBCPService dbcpService = (DBCPService) 
runner.getProcessContext().getControllerServiceLookup().getControllerService("test-exhaust");
+        Assert.assertNotNull(dbcpService);
+        
+        exception.expect(ProcessException.class);
+        for (int i = 0; i < 100; i++) {
+            Connection connection = dbcpService.getConnection();
+            Assert.assertNotNull(connection);
+               }
+    }
+
+    /**
+     *         Test get database connection using Derby.
+     * Get many times, release immediately
+     * and getConnection should not fail.    
+     */
+    @Test
+    public void testGetMany() throws InitializationException, SQLException {
+        final TestRunner runner = 
TestRunners.newTestRunner(TestProcessor.class);
+        final DBCPServiceApacheDBCP14 service = new DBCPServiceApacheDBCP14();
+        runner.addControllerService("test-exhaust", service);
+        
+        // remove previous test database, if any
+        File dbLocation = new File(DB_LOCATION);
+        dbLocation.delete();
+        
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_HOST, "NA");    
// Embedded Derby don't use host
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_NAME, 
DB_LOCATION);
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_USER,   
"tester");
+        runner.setProperty(service, DBCPServiceApacheDBCP14.DB_PASSWORD, 
"testerp");
+        
+        runner.enableControllerService(service);
+
+        runner.assertValid(service);
+        DBCPService dbcpService = (DBCPService) 
runner.getProcessContext().getControllerServiceLookup().getControllerService("test-exhaust");
+        Assert.assertNotNull(dbcpService);
+        
+        for (int i = 0; i < 1000; i++) {
+            Connection connection = dbcpService.getConnection();
+            Assert.assertNotNull(connection);
+            connection.close();
+               }
+    }
+    
+    
+    @Test
+    public void testDriverLaod() throws ClassNotFoundException {
+       Class<?> clazz = Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
+       assertNotNull(clazz);
+    }
+    
+    
+       String createTable = "create table restaurants(id integer, name 
varchar(20), city varchar(50))";
+       String dropTable = "drop table restaurants";
+    
+    protected void createInsertSelectDrop( Connection con) throws SQLException 
{
+       
+       Statement st = con.createStatement();
+       
+       try {
+               st.executeUpdate(dropTable);
+               } catch (Exception e) {
+                       // table may not exist, this is not serious problem.
+               }
+       
+               st.executeUpdate(createTable);
+       
+       st.executeUpdate("insert into restaurants values (1, 'Irifunes', 'San 
Mateo')");
+       st.executeUpdate("insert into restaurants values (2, 'Estradas', 'Daly 
City')");
+       st.executeUpdate("insert into restaurants values (3, 'Prime Rib House', 
'San Francisco')");
+
+       int nrOfRows = 0;
+       ResultSet resultSet = st.executeQuery("select * from restaurants");
+       while (resultSet.next())
+               nrOfRows++;
+       assertEquals(3, nrOfRows);
+
+       st.close();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestDatabaseSystems.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestDatabaseSystems.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestDatabaseSystems.java
new file mode 100644
index 0000000..2a360b2
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestDatabaseSystems.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import static org.apache.nifi.dbcp.DatabaseSystems.getDescriptor;
+
+public class TestDatabaseSystems {
+
+       @Test
+       public void testKnownDatabaseSystems() {
+               
+               assertEquals( "jdbc:postgresql://bighost:5432/Trove", 
getDescriptor("Postgres").buildUrl("bighost",5432,"Trove") ); 
+               
+       }
+
+       
+       
+       
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestProcessor.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestProcessor.java
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestProcessor.java
new file mode 100644
index 0000000..b25d3f1
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/TestProcessor.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.dbcp;
+
+import org.apache.nifi.dbcp.DBCPService;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.processor.AbstractProcessor;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.util.StandardValidators;
+
+public class TestProcessor extends AbstractProcessor {
+
+    @Override
+    public void onTrigger(ProcessContext context, ProcessSession session) 
throws ProcessException {
+    }
+
+    @Override
+    protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+        List<PropertyDescriptor> propDescs = new ArrayList<>();
+        propDescs.add(new PropertyDescriptor.Builder()
+                .name("DBCPService test processor")
+                .description("DBCPService test processor")
+                
.addValidator(StandardValidators.createControllerServiceExistsValidator(DBCPService.class))
+                .required(true)
+                .build());
+        return propDescs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml
new file mode 100644
index 0000000..2a2c74b
--- /dev/null
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/pom.xml
@@ -0,0 +1,18 @@
+<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.apache.nifi</groupId>
+        <artifactId>nifi-standard-services</artifactId>
+        <version>0.0.2-incubating-SNAPSHOT</version>
+    </parent>
+    <artifactId>nifi-dbcp-service-bundle</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>nifi-dbcp-service</module>
+        <module>nifi-dbcp-service-nar</module>
+    </modules>
+    
+    
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
index b3a6c80..fbc20c6 100644
--- 
a/nifi/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
+++ 
b/nifi/nifi-nar-bundles/nifi-standard-services/nifi-standard-services-api-nar/pom.xml
@@ -42,5 +42,11 @@
                        <artifactId>nifi-http-context-map-api</artifactId>
                        <scope>compile</scope>
                </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-dbcp-service-api</artifactId>
+            <version>0.1.0-incubating-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/589e2b7e/nifi/nifi-nar-bundles/nifi-standard-services/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-services/pom.xml 
b/nifi/nifi-nar-bundles/nifi-standard-services/pom.xml
index 083fb26..d225986 100644
--- a/nifi/nifi-nar-bundles/nifi-standard-services/pom.xml
+++ b/nifi/nifi-nar-bundles/nifi-standard-services/pom.xml
@@ -31,5 +31,6 @@
         <module>nifi-ssl-context-service-api</module>
                <module>nifi-http-context-map-bundle</module>
         <module>nifi-standard-services-api-nar</module>
+        <module>nifi-dbcp-service-api</module>
     </modules>
 </project>


Reply via email to