Repository: microsoft/mssql-jdbc
Pull request #2017 (2022-12-28 13:23:22)

Upgrade to the latest OSGi JDBC specification
In the latest release of the JDBC specification there was a requirement added that datasources should promote what methods they implement. mssql-jdbc implements all methods and could therefore promote all.

This also migrates from the org.osgi.enterprise artifact to the more specific org.osgi.service.jdbc one and adds the official TCK test as part of the JUnit-Suite.

FYI @stbischof

Jeffery-Wasty: Hi @laeubi,

We'll look into this, confirm whether these are all the changes we need to make spec, and get back to you. Thank you for your contribution.
Jeffery-Wasty: Hi @laeubi,

I'm unable to find the specification you're referring to. Do you happen to have a link?
Jeffery-Wasty: I see that OSGI compendium on maven has migrated to here: https://mvnrepository.com/artifact/org.osgi/osgi.cmpn, which is probably why we're still using version 5. We missed that the page had changed. However this page only has up to version 7, is there a maven repository for compendium 8?
laeubi: R8 do not has a "fat compendium jar" anymore but many small dedicated items and therefore uses

```
<dependency>
  <groupId>org.osgi</groupId>
  <artifactId>org.osgi.service.jdbc</artifactId>
  <version>${osgi.jdbc.version}</version>
  <scope>provided</scope>
</dependency>
```
now.
Jeffery-Wasty: I see, thank you. And thanks for the quick reply!
Jeffery-Wasty: Hi @laeubi,

The dependency changes are causing test failures, as seen below, coming from the `org.eclipse.osgi` dependency. I don't see this as a dependency of `org.osgi.service.jdbc`, what is this needed for?
laeubi: @Jeffery-Wasty I'll try to take a look the next days, I think I might perform the upgrade in smaller steps to see whats going on here...
laeubi: @Jeffery-Wasty I have now started with a very minimal change, that just upgrades to the new artifact location from central:
- https://github.com/microsoft/mssql-jdbc/pull/2064

It would be great if you can take a look, probably this could even be merged already as a first step.
laeubi: I created another one that do the actual code changes here:
- https://github.com/microsoft/mssql-jdbc/pull/2065

with those it should be possible to see if that alone causes any issues 
Jeffery-Wasty: Thanks @laeubi, we'll take a look at each of the PRs you have linked.
Jeffery-Wasty: As stated in #2066, lets use this as the sole PR. If you're able to fix the test to not use Junit5 it can be included, otherwise we'll move forward without it.
laeubi: I fear the test requires JUnit5 
laeubi: My only idea is that one probabbly can create a new module that only contains this single test ... but the repo seems not really a multi-module one... so for now then we should go without the test.
Jeffery-Wasty: I see, thank you for looking into this. If we end up being able to use Junit5 moving forward, we can revisit adding the test on, its always good to have additional testing. For now, if we can ask you to push a commit removing the test, we can review the PR and get it merged.
laeubi: Now everything should be cleaned up and rebased

Patch:
diff --git a/pom.xml b/pom.xml
index 8a44976d..37540dac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,7 +66,7 @@
 		<azure-security-keyvault-keys.version>4.5.3</azure-security-keyvault-keys.version>
 		<azure-identity.version>1.7.0</azure-identity.version>
 		<msal.version>1.13.3</msal.version>
-		<org.osgi.compendium.version>5.0.0</org.osgi.compendium.version>
+		<osgi.jdbc.version>1.1.0</osgi.jdbc.version>
 		<antlr-runtime.version>4.9.3</antlr-runtime.version>
 		<com.google.code.gson.version>2.9.0</com.google.code.gson.version>
 		<bcprov-jdk15on.version>1.70</bcprov-jdk15on.version>
@@ -150,8 +150,8 @@
 		</dependency>
 		<dependency>
 			<groupId>org.osgi</groupId>
-			<artifactId>org.osgi.compendium</artifactId>
-			<version>${org.osgi.compendium.version}</version>
+			<artifactId>org.osgi.service.jdbc</artifactId>
+			<version>${osgi.jdbc.version}</version>
 			<scope>provided</scope>
 		</dependency>
 
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java b/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java
index 241448ca..df29400e 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java
@@ -38,6 +38,12 @@ public class Activator implements BundleActivator {
         properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_NAME, "Microsoft JDBC Driver for SQL Server");
         properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_VERSION,
                 driver.getMajorVersion() + "." + driver.getMinorVersion());
+        properties.put(DataSourceFactory.OSGI_JDBC_CAPABILITY, new String[] {
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DRIVER,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_CONNECTIONPOOLDATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_XADATASOURCE
+        });
         service = context.registerService(DataSourceFactory.class, new SQLServerDataSourceFactory(), properties);
         SQLServerDriver.register();
     }


Test patch:
diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java
index bfa8c3fe..62731692 100644
--- a/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java
+++ b/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java
@@ -10,8 +10,11 @@ import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.Arrays;
 import java.util.Dictionary;
+import java.util.HashSet;
 import java.util.Properties;
+import java.util.Set;
 
 import javax.sql.ConnectionPoolDataSource;
 import javax.sql.DataSource;
@@ -19,7 +22,6 @@ import javax.sql.PooledConnection;
 import javax.sql.XAConnection;
 import javax.sql.XADataSource;
 
-import com.microsoft.sqlserver.jdbc.TestUtils;
 import org.eclipse.gemini.blueprint.mock.MockBundleContext;
 import org.eclipse.gemini.blueprint.mock.MockServiceRegistration;
 import org.junit.jupiter.api.BeforeAll;
@@ -87,6 +89,12 @@ public class DataFactoryTest extends AbstractTest {
         boolean correctClass = false;
         boolean correctName = false;
         boolean correctVersion = false;
+        String[] required_capabilities=new String[] {
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DRIVER,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_CONNECTIONPOOLDATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_XADATASOURCE};
+        boolean driverCap = false;
         SQLServerDriver driver = new SQLServerDriver();
 
         for (String key : propertyKeys) {
@@ -110,9 +118,18 @@ public class DataFactoryTest extends AbstractTest {
                         "Driver version mismatch. Expected: " + bundleDriverVer + ", Actual: " + actualDriverVer + ".",
                         bundleDriverVer.equals(actualDriverVer));
                 correctVersion = true;
+            }else if (key.equals(DataSourceFactory.OSGI_JDBC_CAPABILITY)) {
+                Object property = sr.getProperty(key);
+                if (property instanceof String[]) {
+                    Set<String> set = new HashSet<>(Arrays.asList( (String[]) property));
+                    for (String cap : required_capabilities) {
+                        assertTrue("Capability "+cap+" is missing!", set.contains(cap));
+                    }
+                }
+                driverCap=true;
             }
         }
-        assertTrue("Not all properties were checked.", correctClass && correctName && correctVersion);
+        assertTrue("Not all properties were checked.", correctClass && correctName && correctVersion && driverCap);
         DataSourceFactory dsf = bc.getService(sr);
         verifyFactoryNormalConnection(dsf);
         verifyFactoryPooledConnection(dsf);