diff --git a/.gitignore b/.gitignore
index 63b666d..207ce65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ target
.project
.settings
.classpath
+.factorypath
# Mobile Tools for Java (J2ME)
.mtj.tmp/
diff --git a/connectors/pom.xml b/connectors/pom.xml
index 12d3abf..edb1d59 100644
--- a/connectors/pom.xml
+++ b/connectors/pom.xml
@@ -36,6 +36,7 @@
twitter-mention-connector
twitter-search-connector
salesforce-upsert-contact-connector
+ sql-connector
day-trade-get-connector
day-trade-place-connector
trade-insight-buy-connector
diff --git a/connectors/sql-stored-connector/pom.xml b/connectors/sql-stored-connector/pom.xml
new file mode 100644
index 0000000..51ffdb1
--- /dev/null
+++ b/connectors/sql-stored-connector/pom.xml
@@ -0,0 +1,208 @@
+
+
+
+ 4.0.0
+
+
+ io.syndesis
+ connectors
+ 0.4-SNAPSHOT
+
+
+ sql-stored-connector
+ jar
+ Camel Sql Stored Connector
+
+
+ UTF-8
+ UTF-8
+ 2.20.0.fuse-000091
+
+
+
+
+
+
+ org.apache.camel
+ camel-parent
+ ${camel.version}
+ import
+ pom
+
+
+
+
+
+
+
+
+ org.apache.camel
+ camel-sql
+
+
+ org.apache.camel
+ camel-sql-starter
+
+
+
+
+ org.apache.camel
+ camel-connector
+
+
+
+
+ org.apache.camel
+ apt
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ ${spring-boot.version}
+
+
+
+ commons-dbcp
+ commons-dbcp
+
+
+
+
+ org.apache.derby
+ derby
+
+
+ org.postgresql
+ postgresql
+
+
+
+
+
+ org.apache.logging.log4j
+ log4j-api
+ test
+
+
+ org.apache.logging.log4j
+ log4j-core
+ test
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ test
+
+
+
+
+ org.apache.camel
+ camel-test
+ test
+
+
+
+
+ install
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.0
+
+
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.0.1
+
+ UTF-8
+
+
+
+
+
+
+
+
+
+
+
+
+ jboss-ea
+ JBoss Early-access repository
+ https://repository.jboss.org/nexus/content/groups/ea/
+
+ true
+
+
+ false
+
+
+
+
+
+
diff --git a/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorComponent.java b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorComponent.java
new file mode 100644
index 0000000..b551a41
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorComponent.java
@@ -0,0 +1,31 @@
+/**
+ * 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 io.syndesis.connector;
+
+import org.apache.camel.component.connector.DefaultConnectorComponent;
+
+/**
+ * Camel SqlStoredConnector connector
+ */
+public class SqlStoredConnectorComponent extends DefaultConnectorComponent {
+
+ public SqlStoredConnectorComponent() {
+ super("sqlStoredConnector", "io.syndesis.connector.SqlStoredConnectorComponent");
+ registerExtension(SqlStoredConnectorVerifierExtension::new);
+// registerExtension(SqlStoredConnectorMetaDataExtension::new);
+ }
+}
diff --git a/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorMetaDataExtension.java b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorMetaDataExtension.java
new file mode 100644
index 0000000..1be1855
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorMetaDataExtension.java
@@ -0,0 +1,268 @@
+/**
+ * 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 io.syndesis.connector;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.JDBCType;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.camel.component.extension.metadata.AbstractMetaDataExtension;
+import org.apache.camel.component.extension.metadata.DefaultMetaData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SqlStoredConnectorMetaDataExtension extends AbstractMetaDataExtension {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SqlStoredConnectorMetaDataExtension.class);
+
+ @Override
+ public Optional meta(Map properties) {
+
+ MetaData metaData = null;
+ if (properties.containsKey("procedure")) {
+ StoredProcedure storedProcedure = storedProcedure(properties);
+ metaData = new DefaultMetaData(null, null, storedProcedure);
+ } else {
+ List list = storedProcedureList(properties);
+ metaData = new DefaultMetaData(null, null, list);
+ }
+ return Optional.of(metaData);
+ }
+
+ private List storedProcedureList(Map parameters) {
+
+ List storedProcedureList = new ArrayList();
+ Connection connection = null;
+ ResultSet procedureSet = null;
+ try {
+ String driver = parameters.get("driver").toString();
+ Class.forName(driver);
+ connection = DriverManager.getConnection(
+ parameters.get("url").toString(),
+ parameters.get("user").toString(),
+ parameters.get("password").toString());
+ DatabaseMetaData meta = connection.getMetaData();
+ String catalog = (String) parameters.getOrDefault("catalog", null);
+ String defaultSchema = getDefaultSchema(meta.getDatabaseProductName(), parameters);
+ String schemaPattern = (String) parameters.getOrDefault("schema-pattern", defaultSchema);
+ String procedurePattern = (String) parameters.getOrDefault("procedure-pattern", null);
+
+ if (meta.getDatabaseProductName().equalsIgnoreCase(DatabaseProduct.POSTGRESQL.name())) {
+ procedureSet = meta.getFunctions(catalog, schemaPattern, procedurePattern);
+ } else {
+ procedureSet = meta.getProcedures(catalog, schemaPattern, procedurePattern);
+ }
+ while (procedureSet.next()) {
+ StoredProcedure storedProcedure = new StoredProcedure();
+ storedProcedure.setName(procedureSet.getString("PROCEDURE_NAME"));
+ storedProcedure.setType(procedureSet.getString("PROCEDURE_TYPE"));
+ storedProcedure.setRemark(procedureSet.getString("REMARKS"));
+ storedProcedureList.add(storedProcedure);
+ }
+ return storedProcedureList;
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (procedureSet != null) {
+ try {
+ if (!procedureSet.isClosed()) {
+ procedureSet.close();
+ }
+ } catch (SQLException e) {
+ LOGGER.warn(e.getMessage());
+ }
+ }
+ if (connection!=null) {
+ try {
+ if (!connection.isClosed()) {
+ connection.close();
+ }
+ } catch (SQLException e) {
+ LOGGER.warn(e.getMessage());
+ }
+ }
+ }
+
+ }
+
+ private String getDefaultSchema(String databaseProductName, Map parameters) {
+
+ String defaultSchema = null;
+ //Oracle uses the username as schema
+ if (databaseProductName.equalsIgnoreCase(DatabaseProduct.ORACLE.name())) {
+ defaultSchema = parameters.get("user").toString();
+ }
+ return defaultSchema;
+ }
+
+ private StoredProcedure storedProcedure(Map parameters) {
+
+ Connection connection = null;
+ ResultSet columnSet = null;
+ try {
+ String driver = parameters.get("driver").toString();
+ Class.forName(driver);
+ connection = DriverManager.getConnection(
+ parameters.get("url").toString(),
+ parameters.get("user").toString(),
+ parameters.get("password").toString());
+ DatabaseMetaData meta = connection.getMetaData();
+ String catalog = (String) parameters.getOrDefault("catalog", null);
+ String defaultSchema = getDefaultSchema(meta.getDatabaseProductName(), parameters);
+ String schema = (String) parameters.getOrDefault("schema", defaultSchema);
+ String procedureName = (String) parameters.getOrDefault("procedure", null);
+
+ StoredProcedure storedProcedure = new StoredProcedure();
+ storedProcedure.setName(procedureName);
+
+ if (meta.getDatabaseProductName().equalsIgnoreCase(DatabaseProduct.POSTGRESQL.name())) {
+ columnSet = meta.getFunctionColumns(catalog, schema, procedureName, null);
+ } else {
+ columnSet = meta.getProcedureColumns(catalog, schema, procedureName, null);
+ }
+
+ List columnList = new ArrayList();
+ String template = procedureName + "(";
+ while (columnSet.next()) {
+ Column column = new Column();
+ column.setName(columnSet.getString("COLUMN_NAME"));
+ column.setMode(ColumnMode.valueOf(columnSet.getInt("COLUMN_TYPE")));
+ column.setJdbcType(JDBCType.valueOf(columnSet.getInt("DATA_TYPE")));
+ template += " " + column.getMode().name() + " " + column.getJdbcType() + " " + column.getName() + ", ";
+ columnList.add(column);
+ }
+ template = template.substring(0,template.length()-2) + ")";
+ storedProcedure.setTemplate(template);
+ storedProcedure.setColumnList(columnList);
+ return storedProcedure;
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (columnSet != null) {
+ try {
+ if (!columnSet.isClosed()) {
+ columnSet.close();
+ }
+ } catch (SQLException e) {
+ LOGGER.warn(e.getMessage());
+ }
+ }
+ if (connection!=null) {
+ try {
+ if (!connection.isClosed()) {
+ connection.close();
+ }
+ } catch (SQLException e) {
+ LOGGER.warn(e.getMessage());
+ }
+ }
+ }
+ }
+
+ public class StoredProcedure {
+ private String name;
+ private String type;
+ private String remark;
+ private List columnList;
+ private String template;
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+ public String getRemark() {
+ return remark;
+ }
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+ public List getColumnList() {
+ return columnList;
+ }
+ public void setColumnList(List columnList) {
+ this.columnList = columnList;
+ }
+ public String getTemplate() {
+ return template;
+ }
+ public void setTemplate(String template) {
+ this.template = template;
+ }
+ }
+
+ public class Column {
+ private int ordinal;
+ private String name;
+ private ColumnMode mode;
+ private JDBCType jdbcType;
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public ColumnMode getMode() {
+ return mode;
+ }
+ public void setMode(ColumnMode mode) {
+ this.mode = mode;
+ }
+ public JDBCType getJdbcType() {
+ return jdbcType;
+ }
+ public void setJdbcType(JDBCType jdbcType) {
+ this.jdbcType = jdbcType;
+ }
+ }
+
+ public enum ColumnMode {
+ UNKNOWN, IN, INOUT, RESULT, OUT, RETURN;
+
+ public static ColumnMode valueOf(int columnType) {
+ return ColumnMode.values()[columnType];
+ }
+ }
+
+ public enum DatabaseProduct {
+ ORACLE, POSTGRESQL;
+ }
+
+}
diff --git a/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorVerifierExtension.java b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorVerifierExtension.java
new file mode 100644
index 0000000..ae034fb
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/SqlStoredConnectorVerifierExtension.java
@@ -0,0 +1,108 @@
+/**
+ * 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 io.syndesis.connector;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Enumeration;
+import java.util.Map;
+
+import org.apache.camel.component.extension.verifier.DefaultComponentVerifierExtension;
+import org.apache.camel.component.extension.verifier.ResultBuilder;
+import org.apache.camel.component.extension.verifier.ResultErrorBuilder;
+import org.apache.camel.component.extension.verifier.ResultErrorHelper;
+
+public class SqlStoredConnectorVerifierExtension extends DefaultComponentVerifierExtension {
+
+ public SqlStoredConnectorVerifierExtension() {
+ super("sql-stored-connector");
+ }
+
+ public SqlStoredConnectorVerifierExtension(String scheme) {
+ super(scheme);
+ }
+
+ // *********************************
+ // Parameters validation
+ // *********************************
+
+ @Override
+ protected Result verifyParameters(Map parameters) {
+ ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS)
+ .error(ResultErrorHelper.requiresOption("driver", parameters))
+ .error(ResultErrorHelper.requiresOption("url", parameters))
+ .error(ResultErrorHelper.requiresOption("user", parameters))
+ .error(ResultErrorHelper.requiresOption("password", parameters));
+
+
+ if (builder.build().getErrors().isEmpty() && parameters.containsKey("driver")) {
+ try {
+ Class.forName(parameters.get("driver").toString());
+ } catch (Exception e) {
+ Enumeration drivers = DriverManager.getDrivers();
+ StringBuffer supportedDrivers = new StringBuffer("[");
+ while (drivers.hasMoreElements()) {
+ String driverName = drivers.nextElement().getClass().getName();
+ if (supportedDrivers.length() > 1 ) {
+ supportedDrivers.append(", ");
+ }
+ supportedDrivers.append(driverName);
+ }
+ supportedDrivers.append("]. ");
+ String msgPrefix = "Unsupported Database, could not find Driver with class ";
+ String msgPostfix = ". Drivers on classpath are: " + supportedDrivers;
+ builder.error(ResultErrorBuilder.withCodeAndDescription(
+ VerificationError.StandardCode.UNSUPPORTED,
+ msgPrefix + parameters.get("driver").toString() + msgPostfix).build()).build();
+ }
+ }
+ return builder.build();
+
+ }
+
+ // *********************************
+ // Connectivity validation
+ // *********************************
+
+ @Override
+ protected Result verifyConnectivity(Map parameters) {
+ return ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY)
+ .error(parameters, this::verifyCredentials)
+ .build();
+ }
+
+ private void verifyCredentials(ResultBuilder builder, Map parameters) {
+ try {
+ Class.forName(parameters.get("driver").toString());
+
+ Connection connection = DriverManager.getConnection(
+ parameters.get("url").toString(),
+ parameters.get("user").toString(),
+ parameters.get("password").toString());
+
+ if (connection == null) {
+ throw new SQLException("No Connection");
+ }
+ } catch (Exception e) {
+ ResultErrorBuilder errorBuilder = ResultErrorBuilder.withCodeAndDescription(
+ VerificationError.StandardCode.AUTHENTICATION, e.getMessage());
+ builder.error(errorBuilder.build());
+ }
+ }
+}
diff --git a/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorAutoConfiguration.java b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorAutoConfiguration.java
new file mode 100644
index 0000000..d6ab8de
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorAutoConfiguration.java
@@ -0,0 +1,106 @@
+package io.syndesis.connector.springboot;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Generated;
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+
+import io.syndesis.connector.SqlStoredConnectorComponent;
+import org.apache.camel.CamelContext;
+import org.apache.camel.util.IntrospectionSupport;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+/**
+ * Generated by camel-connector-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.connector.SpringBootAutoConfigurationMojo")
+@Configuration
+@ConditionalOnBean(type = "org.apache.camel.spring.boot.CamelAutoConfiguration")
+@AutoConfigureAfter(name = "org.apache.camel.spring.boot.CamelAutoConfiguration")
+@EnableConfigurationProperties(SqlStoredConnectorConnectorConfiguration.class)
+public class SqlStoredConnectorConnectorAutoConfiguration {
+
+ @Autowired
+ private CamelContext camelContext;
+ @Autowired
+ private SqlStoredConnectorConnectorConfiguration configuration;
+
+ @Lazy
+ @Bean(name = "sql-stored-connector-component")
+ @ConditionalOnClass(CamelContext.class)
+ @ConditionalOnMissingBean(name = "sql-stored-connector-component")
+ public SqlStoredConnectorComponent configureSqlStoredConnectorComponent()
+ throws Exception {
+ SqlStoredConnectorComponent connector = new SqlStoredConnectorComponent();
+ connector.setCamelContext(camelContext);
+ Map parameters = new HashMap<>();
+ IntrospectionSupport.getProperties(configuration, parameters, null,
+ false);
+ IntrospectionSupport.setProperties(camelContext,
+ camelContext.getTypeConverter(), connector, parameters);
+ connector.setComponentOptions(parameters);
+ return connector;
+ }
+
+
+ @PostConstruct
+ public void postConstructSqlStoredConnectorComponent() {
+ if (camelContext != null) {
+ Map parameters = new HashMap<>();
+ for (Map.Entry entry : configuration
+ .getConfigurations().entrySet()) {
+ parameters.clear();
+ SqlStoredConnectorComponent connector = new SqlStoredConnectorComponent();
+ connector.setCamelContext(camelContext);
+ try {
+ IntrospectionSupport.getProperties(entry.getValue(),
+ parameters, null, false);
+ IntrospectionSupport.setProperties(camelContext,
+ camelContext.getTypeConverter(), connector,
+ parameters);
+ connector.setComponentOptions(parameters);
+ camelContext.addComponent(entry.getKey(), connector);
+ } catch (Exception e) {
+ throw new BeanCreationException(entry.getKey(),
+ e.getMessage(), e);
+ }
+ }
+ try {
+
+ createDataSource(configuration);
+ } catch (Exception e) {
+ throw new BeanCreationException(
+ e.getMessage(), e);
+ }
+ }
+ }
+
+ private void createDataSource(SqlStoredConnectorConnectorConfiguration configuration) throws ClassNotFoundException {
+
+ if (configuration.getDriver()!=null) {
+ BasicDataSource ds = new BasicDataSource();
+ ds.setDriverClassName(configuration.getDriver());
+ Class.forName(configuration.getDriver());
+ configuration.setDriver(null);
+ ds.setUsername(configuration.getUser());
+ configuration.setUser(null);
+ ds.setPassword(configuration.getPassword());
+ configuration.setPassword(null);
+ ds.setUrl(configuration.getUrl());
+ configuration.setUrl(null);
+
+ configuration.setDataSource(ds);
+ }
+ }
+}
\ No newline at end of file
diff --git a/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorConfiguration.java b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorConfiguration.java
new file mode 100644
index 0000000..716111d
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorConfiguration.java
@@ -0,0 +1,23 @@
+package io.syndesis.connector.springboot;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Generated;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Generated("org.apache.camel.maven.connector.SpringBootAutoConfigurationMojo")
+@ConfigurationProperties(prefix = "sql-stored-connector")
+public class SqlStoredConnectorConnectorConfiguration
+ extends
+ SqlStoredConnectorConnectorConfigurationCommon {
+
+ /**
+ * Define additional configuration definitions
+ */
+ private Map configurations = new HashMap<>();
+
+ public Map getConfigurations() {
+
+ return configurations;
+ }
+}
\ No newline at end of file
diff --git a/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorConfigurationCommon.java b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorConfigurationCommon.java
new file mode 100644
index 0000000..8ee2ba8
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/java/io/syndesis/connector/springboot/SqlStoredConnectorConnectorConfigurationCommon.java
@@ -0,0 +1,112 @@
+package io.syndesis.connector.springboot;
+
+import javax.annotation.Generated;
+import javax.sql.DataSource;
+
+/**
+ * The sql connector allows you to work with databases using JDBC Stored
+ * Procedure queries.
+ *
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.connector.SpringBootAutoConfigurationMojo")
+public class SqlStoredConnectorConnectorConfigurationCommon {
+
+ /**
+ * Sets the DataSource to use to communicate with the database.
+ */
+ private DataSource dataSource;
+ /**
+ * Sets the StoredProcedure template to perform
+ */
+ private String template;
+ /**
+ * Enables or disables batch mode
+ */
+ private boolean batch = false;
+ /**
+ * If set will ignore the results of the template and use the existing IN
+ * message as the OUT message for the continuation of processing
+ */
+ private boolean noop = false;
+ /**
+ * Sets the user to use for the database connection
+ */
+ private String user;
+ /**
+ * Sets the password to use for the database connection
+ */
+ private String password;
+ /**
+ * Sets the driver class to use for the database connection
+ */
+ private String driver;
+ /**
+ * Sets the connection url to use for the database connection
+ */
+ private String url;
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public void setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ public String getTemplate() {
+ return template;
+ }
+
+ public void setTemplate(String template) {
+ this.template = template;
+ }
+
+ public boolean isBatch() {
+ return batch;
+ }
+
+ public void setBatch(boolean batch) {
+ this.batch = batch;
+ }
+
+ public boolean isNoop() {
+ return noop;
+ }
+
+ public void setNoop(boolean noop) {
+ this.noop = noop;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getDriver() {
+ return driver;
+ }
+
+ public void setDriver(String driver) {
+ this.driver = driver;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+}
\ No newline at end of file
diff --git a/connectors/sql-stored-connector/src/main/resources/META-INF/services/org/apache/camel/component/sql-stored-connector b/connectors/sql-stored-connector/src/main/resources/META-INF/services/org/apache/camel/component/sql-stored-connector
new file mode 100644
index 0000000..d26e3e1
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/resources/META-INF/services/org/apache/camel/component/sql-stored-connector
@@ -0,0 +1 @@
+class=io.syndesis.connector.SqlStoredConnectorComponent
\ No newline at end of file
diff --git a/connectors/sql-stored-connector/src/main/resources/META-INF/spring.factories b/connectors/sql-stored-connector/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..dbe4c6a
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,3 @@
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+io.syndesis.connector.springboot.SqlStoredConnectorConnectorAutoConfiguration
diff --git a/connectors/sql-stored-connector/src/main/resources/camel-connector-schema.json b/connectors/sql-stored-connector/src/main/resources/camel-connector-schema.json
new file mode 100644
index 0000000..f7d2edd
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/resources/camel-connector-schema.json
@@ -0,0 +1,30 @@
+{
+ "component": {
+ "kind": "component",
+ "baseScheme": "sql-stored",
+ "scheme": "sql-stored-connector",
+ "syntax": "sql-stored-connector:template",
+ "title": "SqlStoredConnector",
+ "description": "SQL Stored Procedure Connector to invoke a SQL Stored Procedure",
+ "label": "sql-stored",
+ "deprecated": false,
+ "async": false,
+ "producerOnly": true,
+ "lenientProperties": false,
+ "javaType": "io.syndesis.connector.SqlStoredConnectorComponent",
+ "groupId": "io.syndesis",
+ "artifactId": "sql-stored-connector",
+ "version": "0.4-SNAPSHOT"
+ },
+ "componentProperties": {
+ "driver": { "kind": "path", "displayName": "Driver", "group": "producer", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the database Driver" },
+ "url": { "kind": "path", "displayName": "Connection URL", "group": "producer", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the database URL" },
+ "user": { "kind": "path", "displayName": "User", "group": "producer", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets database user" },
+ "password": { "kind": "path", "displayName": "Password", "group": "producer", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": true, "description": "Sets the database password" }
+ },
+ "properties": {
+ "template": { "kind": "path", "displayName": "Template", "group": "producer", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the StoredProcedure template to perform" },
+ "batch": { "kind": "parameter", "displayName": "Batch", "group": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Enables or disables batch mode" },
+ "noop": { "kind": "parameter", "displayName": "Noop", "group": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "If set will ignore the results of the template and use the existing IN message as the OUT message for the continuation of processing" }
+ }
+}
diff --git a/connectors/sql-stored-connector/src/main/resources/camel-connector.json b/connectors/sql-stored-connector/src/main/resources/camel-connector.json
new file mode 100644
index 0000000..6ce9997
--- /dev/null
+++ b/connectors/sql-stored-connector/src/main/resources/camel-connector.json
@@ -0,0 +1,21 @@
+{
+ "baseScheme" : "sql-stored",
+ "baseGroupId" : "org.apache.camel",
+ "baseArtifactId" : "camel-sql",
+ "baseVersion" : "2.20.0-SNAPSHOT",
+ "baseJavaType" : "org.apache.camel.component.sql.stored.SqlStoredComponent",
+ "name" : "SqlStoredConnector",
+ "scheme" : "sql-stored-connector",
+ "javaType" : "io.syndesis.connector.SqlStoredConnectorComponent",
+ "groupId" : "io.syndesis",
+ "artifactId" : "sql-stored-connector",
+ "version" : "0.4-SNAPSHOT",
+ "description" : "SQL Stored Procedure Connector to invoke a SQL Stored Procedure",
+ "labels" : [ "sql-stored" ],
+ "pattern" : "To",
+ "inputDataType" : "*",
+ "outputDataType" : "none",
+ "componentOptions" : [ "driver", "user", "password", "url" ],
+ "endpointOptions" : [ "template", "batch", "noop" ],
+ "endpointValues" : {}
+}
\ No newline at end of file
diff --git a/examples/pom.xml b/examples/pom.xml
index 6d4c1f0..e8a6adf 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -37,6 +37,7 @@
http-pingcheck-example
salesforce-pingcheck-example
twitter-pingcheck-example
+ sql-stored-example
diff --git a/examples/sql-stored-example/README.md b/examples/sql-stored-example/README.md
new file mode 100644
index 0000000..810e7e8
--- /dev/null
+++ b/examples/sql-stored-example/README.md
@@ -0,0 +1,14 @@
+## Sql Stored Ping Check Example
+
+This example performs a ping check to a Database to check if the user credentials are valid
+and that you can connect.
+
+### How to run
+
+This example can be run from the command line using:
+
+ mvn exec:java
+
+### Configuring Credentials
+
+You can configure your own accounts in the `application.properties` file.
diff --git a/examples/sql-stored-example/pom.xml b/examples/sql-stored-example/pom.xml
new file mode 100644
index 0000000..bca2ec8
--- /dev/null
+++ b/examples/sql-stored-example/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+ io.syndesis
+ examples
+ 0.4-SNAPSHOT
+
+ 4.0.0
+
+ sql-stored-example
+ Syndesis Connectors :: Sql Stored Example
+ Validate database credentials can connect
+ jar
+
+
+
+
+
+ io.syndesis
+ sql-stored-connector
+ ${project.version}
+
+
+ ch.qos.logback
+ logback-classic
+
+
+
+
+
+
+ org.apache.logging.log4j
+ log4j-api
+
+
+ org.apache.logging.log4j
+ log4j-core
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.5.0
+
+ io.syndesis.example.TwitterPingCheckMain
+ false
+
+
+
+
+
+
diff --git a/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredApplication.java b/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredApplication.java
new file mode 100644
index 0000000..0a12445
--- /dev/null
+++ b/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredApplication.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.syndesis.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//CHECKSTYLE:OFF
+@SpringBootApplication
+public class SqlStoredApplication {
+
+ /**
+ * A main method to start this application.
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(SqlStoredApplication.class, args);
+ try {
+ Thread.sleep(60000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
+//CHECKSTYLE:ON
\ No newline at end of file
diff --git a/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredPingCheck.java b/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredPingCheck.java
new file mode 100644
index 0000000..e2b16fa
--- /dev/null
+++ b/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredPingCheck.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.syndesis.example;
+
+import java.io.FileInputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.component.extension.ComponentVerifierExtension;
+import org.apache.camel.component.extension.ComponentVerifierExtension.Result;
+import org.apache.camel.impl.DefaultCamelContext;
+
+import io.syndesis.connector.SqlStoredConnectorVerifierExtension;
+
+public class SqlStoredPingCheck {
+
+ public void ping() throws Exception {
+ // need to create Camel
+ CamelContext camel = new DefaultCamelContext();
+ camel.start();
+
+ // get the connector to use
+ Component sqlstored = camel.getComponent("sql-stored-connector");
+
+ // the connector must support ping check if its verifiable
+ Optional vce = sqlstored.getExtension(SqlStoredConnectorVerifierExtension.class);
+ if (vce.isPresent()) {
+ ComponentVerifierExtension verifier = vce.get();
+
+ Map parameters = loadParameters();
+
+ ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters);
+
+ System.out.println("=============================================");
+ System.out.println("");
+ System.out.println("Parameters check result: " + result.getStatus());
+ if (result.getStatus().equals(Result.Status.ERROR)) {
+ System.out.println(result.getErrors());
+ }
+ System.out.println("");
+ System.out.println("=============================================");
+
+ ComponentVerifierExtension.Result result2 = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters);
+
+ System.out.println("=============================================");
+ System.out.println("");
+ System.out.println("Ping check result: " + result2.getStatus());
+ if (result2.getStatus().equals(Result.Status.ERROR)) {
+ System.out.println(result2.getErrors());
+ }
+ System.out.println("");
+ System.out.println("=============================================");
+
+ } else {
+ System.out.println("Component does not support ping check");
+ }
+
+ camel.stop();
+ }
+
+ /**
+ * Helper to load parameters from a .properties file
+ */
+ private Map loadParameters() throws Exception {
+ Properties prop = new Properties();
+ prop.load(new FileInputStream("src/main/resources/application.properties"));
+
+ Map answer = new HashMap<>();
+ Enumeration> en = prop.propertyNames();
+ while (en.hasMoreElements()) {
+ String key = (String) en.nextElement();
+ if (key.startsWith("sql-stored-connector.")) {
+ String shortKey = key.substring(21, key.length());
+ Object value = prop.getProperty(key);
+ answer.put(shortKey, value);
+ }
+ }
+ return answer;
+ }
+
+
+}
diff --git a/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredPingCheckMain.java b/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredPingCheckMain.java
new file mode 100644
index 0000000..aab059a
--- /dev/null
+++ b/examples/sql-stored-example/src/main/java/io/syndesis/example/SqlStoredPingCheckMain.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.syndesis.example;
+
+public class SqlStoredPingCheckMain {
+
+ public static void main(String[] args) throws Exception {
+
+ SqlStoredPingCheck check = new SqlStoredPingCheck();
+ check.ping();
+ System.exit(0);
+ }
+
+}
diff --git a/examples/sql-stored-example/src/main/java/io/syndesis/example/TimerSqlStoredRoute.java b/examples/sql-stored-example/src/main/java/io/syndesis/example/TimerSqlStoredRoute.java
new file mode 100644
index 0000000..0e899ee
--- /dev/null
+++ b/examples/sql-stored-example/src/main/java/io/syndesis/example/TimerSqlStoredRoute.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.syndesis.example;
+
+import java.util.Properties;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.stereotype.Component;
+
+@Component
+public class TimerSqlStoredRoute extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+
+ Properties values = new Properties();
+ values.setProperty("a","1");
+ values.setProperty("b","6");
+
+ from("timer://myTimer?period=2000")
+ .setBody().constant(values)
+ .to("sql-stored-connector:DEMO_ADD( "
+ + "NUMERIC ${body[a]}, "
+ + "NUMERIC ${body[b]}, "
+ + "OUT NUMERIC c)")
+ .process(new Processor() {
+
+ public void process(Exchange exchange)
+ throws Exception {
+ System.out.println(exchange.getIn()
+ .getBody().getClass());
+ System.out.println(exchange.getIn()
+ .getBody());
+ }
+ });
+ }
+}
diff --git a/examples/sql-stored-example/src/main/resources/application.properties b/examples/sql-stored-example/src/main/resources/application.properties
new file mode 100644
index 0000000..6180297
--- /dev/null
+++ b/examples/sql-stored-example/src/main/resources/application.properties
@@ -0,0 +1,14 @@
+## name of CamelContext
+camel.springboot.name=sql-stored-connector
+
+# Oracle database configuration to use
+# sql-stored-connector.driver=oracle.jdbc.driver.OracleDriver
+# sql-stored-connector.url=jdbc:oracle:thin:@::
+# sql-stored-connector.user=
+# sql-stored-connector.password=
+
+# Postgres database configuration
+# sql-stored-connector.driver=org.postgresql.Driver
+# sql-stored-connector.url=jdbc:postgresql://localhost:5432/test
+# sql-stored-connector.user=
+# sql-stored-connector.password=
diff --git a/examples/sql-stored-example/src/main/resources/log4j2.properties b/examples/sql-stored-example/src/main/resources/log4j2.properties
new file mode 100644
index 0000000..f83ffbe
--- /dev/null
+++ b/examples/sql-stored-example/src/main/resources/log4j2.properties
@@ -0,0 +1,6 @@
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = out
diff --git a/examples/sql-stored-example/src/main/resources/sql/oracle/stored_procedures.sql b/examples/sql-stored-example/src/main/resources/sql/oracle/stored_procedures.sql
new file mode 100644
index 0000000..3883eab
--- /dev/null
+++ b/examples/sql-stored-example/src/main/resources/sql/oracle/stored_procedures.sql
@@ -0,0 +1,9 @@
+create or replace PROCEDURE DEMO_ADD
+(
+ A IN INTEGER
+, B IN INTEGER
+, C OUT INTEGER
+) AS
+BEGIN
+ c := a + b;
+END DEMO_ADD;
\ No newline at end of file
diff --git a/examples/sql-stored-example/src/main/resources/sql/postgresql/stored_procedures.sql b/examples/sql-stored-example/src/main/resources/sql/postgresql/stored_procedures.sql
new file mode 100644
index 0000000..cc89e64
--- /dev/null
+++ b/examples/sql-stored-example/src/main/resources/sql/postgresql/stored_procedures.sql
@@ -0,0 +1,25 @@
+-- FUNCTION: public.demo_add(numeric, numeric)
+
+-- DROP FUNCTION public.demo_add(numeric, numeric);
+
+CREATE OR REPLACE FUNCTION public.demo_add(
+ a numeric,
+ b numeric,
+ OUT c numeric)
+ RETURNS numeric
+ LANGUAGE 'plpgsql'
+
+ COST 100
+ VOLATILE
+ ROWS 0
+AS $BODY$
+
+BEGIN
+ c := a + b;
+ return;
+END;
+$BODY$;
+
+ALTER FUNCTION public.demo_add(numeric, numeric)
+ OWNER TO postgres;
+