From 05951ebb15b5af7a514883f780f7a164bb9f3782 Mon Sep 17 00:00:00 2001 From: NataS Date: Tue, 5 Mar 2024 11:13:19 -0600 Subject: [PATCH] Fixes #547: Add MSSQL Driver Features Support (#548) * Fixes #547: Add MSSQL Driver Features Support Add an Example on how to connect with MSSQL using ZDBC natively. Adding the entry into main ZDBC Readme, on features for MSSQL and Redshift. * Fixes #547: Add MSSQL Driver Features Support Add an Example on how to connect with MSSQL using ZDBC natively. Adding the entry into main ZDBC Readme, on features for MSSQL and Redshift. Signed-off-by: NataS --------- Signed-off-by: NataS --- .gitignore | 1 + samples/settings.gradle | 1 + samples/ziti-jdbc-mssql/README.md | 47 +++++++++++++ samples/ziti-jdbc-mssql/build.gradle | 38 +++++++++++ samples/ziti-jdbc-mssql/network/README.md | 2 + samples/ziti-jdbc-mssql/pom.xml | 63 +++++++++++++++++ .../java/org/openziti/jdbc/MSSQLExample.java | 68 +++++++++++++++++++ ziti-jdbc/README.md | 24 ++++--- 8 files changed, 234 insertions(+), 10 deletions(-) create mode 100644 samples/ziti-jdbc-mssql/README.md create mode 100644 samples/ziti-jdbc-mssql/build.gradle create mode 100644 samples/ziti-jdbc-mssql/network/README.md create mode 100644 samples/ziti-jdbc-mssql/pom.xml create mode 100644 samples/ziti-jdbc-mssql/src/main/java/org/openziti/jdbc/MSSQLExample.java diff --git a/.gitignore b/.gitignore index 73038c31..f211ea5d 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ samples/ziti-jdbc-spring-jpa/network/.env samples/ziti-jdbc-postgresql/network/databaseClient.json samples/ziti-jdbc-postgresql/network/tunnel +samples/ziti-jdbc-mssql/network/DBClient.json diff --git a/samples/settings.gradle b/samples/settings.gradle index e33a3210..51ff5c87 100644 --- a/samples/settings.gradle +++ b/samples/settings.gradle @@ -27,6 +27,7 @@ include 'sample-okhttp' include 'ziti-spring-boot' include 'ziti-spring-boot-client' include 'ziti-jdbc-postgresql' +include 'ziti-jdbc-mssql' include 'ziti-jdbc-spring-jpa:initial:server' include 'ziti-jdbc-spring-jpa:initial:client' include ':ziti-jdbc-spring-jpa:complete:server' diff --git a/samples/ziti-jdbc-mssql/README.md b/samples/ziti-jdbc-mssql/README.md new file mode 100644 index 00000000..792e709c --- /dev/null +++ b/samples/ziti-jdbc-mssql/README.md @@ -0,0 +1,47 @@ +# Microsoft SQL Server Example +This project contains a simple java application that uses the [OpenZiti](https://openziti.github.io/ziti/overview.html) Java SDK to connect to a Microsoft SQL Server (MSSQL) database and read the contents of a table. + +# What you will need +* (Maven) [https://maven.apache.org/] to build the sample +* A Java JDK to build and run the sample. If you don't have one you can get one from the [Oracle Open JDK download site](https://jdk.java.net/) + +# Building the sample +Compilation is done using the Maven build tooling. + +1. Change into the `ziti-sdk-jvm/samples/ziti-jdbc-mssql` sample directory +1. execute `../../gradlew -PbuildForAndroid=false build` + +# Running the example +Running the example is done using the gradle run facility. +It's assumed you already have the OpenZiti network running and the ziti services configured. + +Your services must have as intercept configuration the host `mssql_host` with the port `1433`; if different you may change the connection string in the `MSSQLExample.java` file. + +It's also assumed you have a Microsoft SQL Server running and a database named `DBNAME` with a table called `TABLENAME` with two columns `column_1` and `column_2`. + + +You can run the example from the sample directory using: + +``` +../../gradlew -PbuildForAndroid=false run +``` + +## Example Output +``` +> Task :ziti-jdbc-mssql:runWithJavaExec +[main] INFO org.openziti.impl.ZitiImpl - ZitiSDK version 0.25.1 @344b49b() +Feb 22, 2024 5:32:02 PM org.openziti.jdbc.ZitiDriver setupZiti +INFO: Ziti JDBC wrapper is configuring Ziti identities. Production applications should manage Ziti identities directly +[DefaultDispatcher-worker-2] INFO org.openziti.api.Controller - controller[https://ziti-edge-controller/] version(v0.28.1/f9a62c0baf1c) +[DefaultDispatcher-worker-1] INFO org.openziti.api.Controller - controller[https://ziti-edge-controller/] version(v0.28.1/f9a62c0baf1c) +Column_1: AAA0000 - Column_2: 10.10.10.0 +Column_1: AAA0001 - Column_2: 10.10.10.1 +Column_1: AAA0002 - Column_2: 10.10.10.2 +Column_1: AAA0003 - Column_2: 10.10.10.3 +Column_1: AAA0004 - Column_2: 10.10.10.4 +Column_1: AAA0005 - Column_2: 10.10.10.5 +Column_1: AAA0006 - Column_2: 10.10.10.6 +Column_1: AAA0007 - Column_2: 10.10.10.7 +Column_1: AAA0008 - Column_2: 10.10.10.8 +Column_1: AAA0009 - Column_2: 10.10.10.9 +``` diff --git a/samples/ziti-jdbc-mssql/build.gradle b/samples/ziti-jdbc-mssql/build.gradle new file mode 100644 index 00000000..27efac6a --- /dev/null +++ b/samples/ziti-jdbc-mssql/build.gradle @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2024 NetFoundry, 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 + * + * https://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. + */ + +plugins { + id 'java' +} + +ext { + javaMainClass = "org.openziti.jdbc.MSSQLExample" +} + +dependencies { + implementation "org.openziti:ziti-jdbc:${versions.ziti}" + implementation deps.ziti + implementation files('lib/mssql-jdbc-12.6.0.jre11.jar') + implementation deps.slf4jSimple +} + +task runWithJavaExec(type: JavaExec) { + group = "Execution" + description = "Run the ZDBC example" + classpath = sourceSets.main.runtimeClasspath + mainClass = javaMainClass + args "network/DBClient.json" +} diff --git a/samples/ziti-jdbc-mssql/network/README.md b/samples/ziti-jdbc-mssql/network/README.md new file mode 100644 index 00000000..c0d34594 --- /dev/null +++ b/samples/ziti-jdbc-mssql/network/README.md @@ -0,0 +1,2 @@ +# Microsoft SQL Server Test Network +This directory contains the identity JSON. diff --git a/samples/ziti-jdbc-mssql/pom.xml b/samples/ziti-jdbc-mssql/pom.xml new file mode 100644 index 00000000..33f677fe --- /dev/null +++ b/samples/ziti-jdbc-mssql/pom.xml @@ -0,0 +1,63 @@ + + 4.0.0 + org.openziti.jdbc.samples + mssql + 0.0.1-SNAPSHOT + + UTF-8 + 11 + 11 + + + + + + + com.microsoft.sqlserver + mssql-jdbc + 12.6.0.jre11 + + + + + org.openziti + zdbc + + + + + org.openziti + ziti + + + + + org.slf4j + slf4j-api + 1.7.22 + + + org.slf4j + slf4j-simple + 1.7.22 + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + org.openziti.jdbc.MSSQLExample + + network/DBClient.json + + + + + + diff --git a/samples/ziti-jdbc-mssql/src/main/java/org/openziti/jdbc/MSSQLExample.java b/samples/ziti-jdbc-mssql/src/main/java/org/openziti/jdbc/MSSQLExample.java new file mode 100644 index 00000000..e55643e6 --- /dev/null +++ b/samples/ziti-jdbc-mssql/src/main/java/org/openziti/jdbc/MSSQLExample.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) NetFoundry, 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 + * + * https://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.openziti.jdbc; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.Properties; + +import org.openziti.Ziti; +import org.openziti.ZitiContext; + +public class MSSQLExample { + public static void main(String[] args) throws Exception { + if (args.length != 1) { + System.out.println("Usage: App "); + System.exit(1); + } + + // Initialize the OpenZiti Java SDK with our identity + final ZitiContext zitiContext = Ziti.newContext(args[0], "".toCharArray()); + + String url = "zdbc:sqlserver://mssql_host:1433;databaseName=DBNAME"; + + Properties props = new Properties(); + + // General MSSQL properties + props.setProperty("user", "zdbc"); + props.setProperty("password", "netfoundry!1"); + props.setProperty("connectTimeout", "240"); + props.setProperty("encrypt", "False"); + + // To use MSSQL with zdbc driver we need to set the mssql driver's socketFactoryClass to ZitiSocketFactory + props.setProperty("socketFactoryClass", "org.openziti.net.ZitiSocketFactory"); + + // Ziti specific properties + props.setProperty("zitiIdentityFile", "network\\DBClient.json"); + props.setProperty("zitiDriverUrlPattern", "^zdbc:sqlserver:.*"); + props.setProperty("zitiDriverClassname", "com.microsoft.sqlserver.jdbc.SQLServerDriver"); + + + try (Connection conn = DriverManager.getConnection(url, props)) { + try (Statement stmt = conn.createStatement()) { + try (ResultSet rs = stmt.executeQuery("select top 10 * from dbo.TABLE")) { + while (rs.next()) { + System.out.println("Column_1: " + rs.getString(1) + " - Column_2: " + rs.getString(2)); + } + } + } + } finally { + Ziti.getContexts().forEach(c -> c.destroy()); + } + + System.exit(0); + } +} \ No newline at end of file diff --git a/ziti-jdbc/README.md b/ziti-jdbc/README.md index cf09bd30..8bee732c 100644 --- a/ziti-jdbc/README.md +++ b/ziti-jdbc/README.md @@ -12,12 +12,14 @@ The goals of this project are: ## Driver Features Each JDBC driver needs specific ziti features in order to work. This table attempts to capture which each driver requires -| Driver | Shim Included | Ziti Features | Notes | -| ------ | :------------:| ------------- | ----- | -| org.postgresql.Driver | Y | Socket Factory | Requires jdbc property socketFactory | -| oracle.jdbc.OracleDriver | Y | init with seamless mode |
  • The current Oracle shim does not support NIO or OOB. As such, the shim will set the following property values
    • oracle.jdbc.javaNetNio=false
    • oracle.net.disableOob=false
  • Tested with public and private autonomous databases
  • Requires the database host to be resolvable (1)
| -| com.mysql.jdbc.Driver | Y | init with seamless mode | | -| org.h2.Driver | N | init with seamless mode | Requires the database host to be resolvable (1) | +| Driver | Shim Included | Ziti Features | Notes | +| ------ |:-------------:| ------------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| org.postgresql.Driver | Y | Socket Factory | Requires jdbc property socketFactory | +| oracle.jdbc.OracleDriver | Y | init with seamless mode |
  • The current Oracle shim does not support NIO or OOB. As such, the shim will set the following property values
    • oracle.jdbc.javaNetNio=false
    • oracle.net.disableOob=false
  • Tested with public and private autonomous databases
  • Requires the database host to be resolvable (1)
| +| com.mysql.jdbc.Driver | Y | init with seamless mode | | +| org.h2.Driver | N | init with seamless mode | Requires the database host to be resolvable (1) | +| com.microsoft.sqlserver.jdbc.SQLServerDriver| N | Socket Factory |
  • Requires MSSQL jdbc property socketFactoryClass set as: `org.openziti.net.ZitiSocketFactory`
  • Requires Custom URL pattern, set as: `^zdbc:sqlserver:.*`
  • Connection string set as: `zdbc:sqlserver://:;databaseName=`
| +| com.amazon.redshift.jdbc.Driver | N | init with seamless mode |
  • Requires Custom URL pattern, set as: `^zdbc:redshift:.*`
  • Connection string set as: `zdbc:redshift://:/`
| (1) These drivers attempt to resolve the name of the database host via a DNS request before connecting to them. The database hostname must be resolvable until something like is adopted. No connection attempt will be made to this host, it is simply required to satisfy the driver DNS resolution. @@ -41,8 +43,10 @@ The zdbc driver needs your ziti network identity to connect. There are three way 1. Configure a ziti network and postgres database following the cheatsheet 1. Copy the Ziti all-in-one jar into the Squirrel-Sql `lib` folder -> ls $SQUIRREL_HOME\lib | grep ziti
- ziti-jdbc-0.23.14-full.jar +> ls $SQUIRREL_HOME\lib | grep ziti
+ ziti-0.25.1-full.jar
+ ziti-jdbc-0.25.1.jar + 1. Start Squirrel-Sql 1. Configure the Squirrel-Sql PostgreSQL driver @@ -65,5 +69,5 @@ The zdbc driver needs your ziti network identity to connect. There are three way # Example of integrating into a Java application This repository includes a coupld of examples using Java to connect to a dark database. -* [samples/postgresql/README.md](samples/postgresql/README.md): Postgresql example using the JDBC DriverManager to connect to a dark database. -* [samples/spring-jpa/README.md](samples/spring-jpa/README.md): A learning excercise adding spring-data-jpa and spring-data-rest to host a dark http server that connects to a dark postgres database +* [samples/postgresql/README.md](https://github.com/openziti/ziti-sdk-jvm/blob/main/samples/jdbc-postgres/cheatsheet.md): Postgresql example using the JDBC DriverManager to connect to a dark database. +* [samples/spring-jpa/README.md](https://github.com/openziti/ziti-sdk-jvm/tree/main/samples/ziti-jdbc-spring-jpa): A learning exercise adding spring-data-jpa and spring-data-rest to host a dark http server that connects to a dark postgres database