You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gg...@apache.org on 2018/11/20 10:24:19 UTC
[karaf] branch master updated: [KARAF-6014] Improve jdbc:* commands
This is an automated email from the ASF dual-hosted git repository.
ggrzybek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/karaf.git
The following commit(s) were added to refs/heads/master by this push:
new d52ca6e [KARAF-6014] Improve jdbc:* commands
d52ca6e is described below
commit d52ca6e9c74373cb1961ed81a8bdcafe9338d5f0
Author: Grzegorz Grzybek <gr...@gmail.com>
AuthorDate: Tue Nov 20 10:44:40 2018 +0100
[KARAF-6014] Improve jdbc:* commands
---
.../java/org/apache/karaf/jdbc/JdbcService.java | 8 ++
.../apache/karaf/jdbc/command/ExecuteCommand.java | 2 +-
.../apache/karaf/jdbc/command/QueryCommand.java | 2 +-
.../apache/karaf/jdbc/command/TablesCommand.java | 2 +-
.../completers/DataSourcesFileNameCompleter.java | 55 -------------
.../karaf/jdbc/command/ds/DSFactoriesCommand.java | 92 +++++++++++++++++++++-
.../karaf/jdbc/command/ds/DeleteCommand.java | 4 +-
.../apache/karaf/jdbc/command/ds/InfoCommand.java | 2 +-
.../apache/karaf/jdbc/command/ds/ListCommand.java | 25 ++++--
.../apache/karaf/jdbc/internal/JdbcMBeanImpl.java | 20 ++---
.../karaf/jdbc/internal/JdbcServiceImpl.java | 30 ++++++-
manual/src/main/asciidoc/user-guide/jdbc.adoc | 11 ++-
12 files changed, 168 insertions(+), 85 deletions(-)
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/JdbcService.java b/jdbc/src/main/java/org/apache/karaf/jdbc/JdbcService.java
index 5c245e2..c937a9f 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/JdbcService.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/JdbcService.java
@@ -65,6 +65,14 @@ public interface JdbcService {
List<String> datasources() throws Exception;
/**
+ * List service IDs of JDBC datasource OSGi services available
+ *
+ * @return A {@link List} of datasources OSGi service IDs.
+ * @throws Exception If the service fails.
+ */
+ List<Long> datasourceServiceIds() throws Exception;
+
+ /**
* Execute a SQL query on a given JDBC datasource.
*
* @param datasource The JDBC datasource name.
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ExecuteCommand.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ExecuteCommand.java
index 137f085..a17cc64 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ExecuteCommand.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ExecuteCommand.java
@@ -30,7 +30,7 @@ import org.apache.karaf.shell.api.action.lifecycle.Service;
@Service
public class ExecuteCommand extends JdbcCommandSupport {
- @Argument(index = 0, name = "datasource", description = "The JDBC datasource", required = true, multiValued = false)
+ @Argument(index = 0, name = "datasource", description = "The JDBC datasource name, its JNDI name or service.id", required = true, multiValued = false)
@Completion(DataSourcesNameCompleter.class)
String datasource;
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/QueryCommand.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/QueryCommand.java
index 34089b3..20c0ed9 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/QueryCommand.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/command/QueryCommand.java
@@ -35,7 +35,7 @@ import org.apache.karaf.shell.support.table.ShellTable;
@Service
public class QueryCommand extends JdbcCommandSupport {
- @Argument(index = 0, name = "datasource", description = "The JDBC datasource to use", required = true, multiValued = false)
+ @Argument(index = 0, name = "datasource", description = "The JDBC datasource name, its JNDI name or service.id to use", required = true, multiValued = false)
@Completion(DataSourcesNameCompleter.class)
String datasource;
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/TablesCommand.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/TablesCommand.java
index 04baa70..afa3a53 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/TablesCommand.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/command/TablesCommand.java
@@ -31,7 +31,7 @@ import org.apache.karaf.shell.support.table.ShellTable;
@Service
public class TablesCommand extends JdbcCommandSupport {
- @Argument(index = 0, name = "datasource", description = "The JDBC datasource to use", required = true, multiValued = false)
+ @Argument(index = 0, name = "datasource", description = "The JDBC datasource name, its JNDI name or service.id to use", required = true, multiValued = false)
@Completion(DataSourcesNameCompleter.class)
String datasource;
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/completers/DataSourcesFileNameCompleter.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/completers/DataSourcesFileNameCompleter.java
deleted file mode 100644
index 98fcb38..0000000
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/completers/DataSourcesFileNameCompleter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.karaf.jdbc.command.completers;
-
-import org.apache.karaf.jdbc.JdbcService;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-
-import java.util.List;
-
-/**
- * Completer on the JDBC datasources file name.
- */
-@Service
-public class DataSourcesFileNameCompleter implements Completer {
-
- @Reference
- private JdbcService jdbcService;
-
- @Override
- public int complete(Session session, CommandLine commandLine, List<String> candidates) {
- StringsCompleter delegate = new StringsCompleter();
- try {
- for (String datasourceFileName : jdbcService.datasources()) {
- delegate.getStrings().add(datasourceFileName);
- }
- } catch (Exception e) {
- // nothing to do
- }
- return delegate.complete(session, commandLine, candidates);
- }
-
- public void setJdbcService(JdbcService jdbcService) {
- this.jdbcService = jdbcService;
- }
-
-}
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DSFactoriesCommand.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DSFactoriesCommand.java
index 9cf5c9d..a0aa8e4 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DSFactoriesCommand.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DSFactoriesCommand.java
@@ -17,6 +17,10 @@
package org.apache.karaf.jdbc.command.ds;
import java.util.Collection;
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeSet;
import org.apache.karaf.jdbc.command.JdbcCommandSupport;
import org.apache.karaf.shell.api.action.Command;
@@ -33,6 +37,8 @@ public class DSFactoriesCommand extends JdbcCommandSupport {
@Reference
BundleContext context;
+
+ private Comparator<DataSourceFactoryInfo> comparator = new DataSourceFactoryComparator();
@Override
public Object execute() throws Exception {
@@ -40,15 +46,93 @@ public class DSFactoriesCommand extends JdbcCommandSupport {
table.column("Name");
table.column("Class");
table.column("Version");
+ table.column("Registration bundle");
+
+ Set<DataSourceFactoryInfo> factories = new TreeSet<>(comparator);
+
Collection<ServiceReference<DataSourceFactory>> refs = context.getServiceReferences(DataSourceFactory.class, null);
for (ServiceReference<DataSourceFactory> ref : refs) {
- String driverName = (String)ref.getProperty(DataSourceFactory.OSGI_JDBC_DRIVER_NAME);
- String driverClass = (String)ref.getProperty(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS);
- String driverVersion = (String)ref.getProperty(DataSourceFactory.OSGI_JDBC_DRIVER_VERSION);
- table.addRow().addContent(driverName, driverClass, driverVersion);
+ DataSourceFactoryInfo info = new DataSourceFactoryInfo();
+ info.driverName = (String)ref.getProperty(DataSourceFactory.OSGI_JDBC_DRIVER_NAME);
+ info.driverClass = (String)ref.getProperty(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS);
+ info.driverVersion = (String)ref.getProperty(DataSourceFactory.OSGI_JDBC_DRIVER_VERSION);
+ if (ref.getBundle() != null && ref.getBundle().getSymbolicName() != null) {
+ info.bundle = String.format("%s [%s]",
+ ref.getBundle().getSymbolicName(),
+ ref.getBundle().getBundleId());
+ } else {
+ info.bundle = "";
+ }
+ factories.add(info);
+ }
+ for (DataSourceFactoryInfo info : factories) {
+ table.addRow().addContent(info.driverName, info.driverClass, info.driverVersion, info.bundle);
}
+
table.print(System.out);
return null;
}
+ private static class DataSourceFactoryComparator implements Comparator<DataSourceFactoryInfo> {
+ @Override
+ public int compare(DataSourceFactoryInfo dsf1, DataSourceFactoryInfo dsf2) {
+ int r1 = 0;
+ int r2 = 0;
+ int r3 = 0;
+
+ if (dsf1.bundle != null || dsf2.bundle != null) {
+ if (dsf1.bundle == null) {
+ r1 = -1;
+ } else if (dsf2.bundle == null) {
+ r1 = 1;
+ } else {
+ r1 = dsf1.bundle.compareTo(dsf2.bundle);
+ }
+ }
+ if (dsf1.driverName != null || dsf2.driverName != null) {
+ if (dsf1.driverName == null) {
+ r2 = -1;
+ } else if (dsf2.driverName == null) {
+ r2 = 1;
+ } else {
+ r2 = dsf1.driverName.compareTo(dsf2.driverName);
+ }
+ }
+ if (dsf1.driverClass != null || dsf2.driverClass != null) {
+ if (dsf1.driverClass == null) {
+ r3 = -1;
+ } else if (dsf2.driverClass == null) {
+ r3 = 1;
+ } else {
+ r3 = dsf1.driverClass.compareTo(dsf2.driverClass);
+ }
+ }
+
+ return r1 == 0 ? (r2 == 0 ? r3 : r2) : r1;
+ }
+ }
+
+ private static class DataSourceFactoryInfo {
+ public String driverName;
+ public String driverClass;
+ public String driverVersion;
+ public String bundle;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DataSourceFactoryInfo that = (DataSourceFactoryInfo) o;
+ return Objects.equals(driverName, that.driverName) &&
+ Objects.equals(driverClass, that.driverClass) &&
+ Objects.equals(driverVersion, that.driverVersion) &&
+ Objects.equals(bundle, that.bundle);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(driverName, driverClass, driverVersion, bundle);
+ }
+ }
+
}
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DeleteCommand.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DeleteCommand.java
index afa025d..7f268dd 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DeleteCommand.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/DeleteCommand.java
@@ -17,7 +17,7 @@
package org.apache.karaf.jdbc.command.ds;
import org.apache.karaf.jdbc.command.JdbcCommandSupport;
-import org.apache.karaf.jdbc.command.completers.DataSourcesFileNameCompleter;
+import org.apache.karaf.jdbc.command.completers.DataSourcesNameCompleter;
import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Completion;
@@ -28,7 +28,7 @@ import org.apache.karaf.shell.api.action.lifecycle.Service;
public class DeleteCommand extends JdbcCommandSupport {
@Argument(index = 0, name = "name", description = "The JDBC datasource name (the one used at creation time)", required = true, multiValued = false)
- @Completion(DataSourcesFileNameCompleter.class)
+ @Completion(DataSourcesNameCompleter.class)
String name;
@Override
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/InfoCommand.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/InfoCommand.java
index 0ab22c5..deff3bd 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/InfoCommand.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/InfoCommand.java
@@ -30,7 +30,7 @@ import java.util.Map;
@Service
public class InfoCommand extends JdbcCommandSupport {
- @Argument(index = 0, name = "datasource", description = "The JDBC datasource name", required = true, multiValued = false)
+ @Argument(index = 0, name = "datasource", description = "The JDBC datasource name, its JNDI name or service.id", required = true, multiValued = false)
@Completion(DataSourcesNameCompleter.class)
String datasource;
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/ListCommand.java b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/ListCommand.java
index d665fa5..5353872 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/ListCommand.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/command/ds/ListCommand.java
@@ -16,6 +16,8 @@
*/
package org.apache.karaf.jdbc.command.ds;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -32,22 +34,35 @@ public class ListCommand extends JdbcCommandSupport {
public Object execute() throws Exception {
ShellTable table = new ShellTable();
table.column("Name");
+ table.column("Service Id");
table.column("Product");
table.column("Version");
table.column("URL");
table.column("Status");
- List<String> datasources = this.getJdbcService().datasources();
- for (String dsName: datasources) {
+ boolean duplication = false;
+ Map<String, Long> nameToId = new HashMap<>();
+
+ List<Long> datasources = this.getJdbcService().datasourceServiceIds();
+ Collections.sort(datasources);
+ for (Long id: datasources) {
try {
- Map<String, String> info = this.getJdbcService().info(dsName);
- table.addRow().addContent(dsName, info.get("db.product"), info.get("db.version"), info.get("url"), "OK");
+ Map<String, String> info = this.getJdbcService().info(Long.toString(id));
+ table.addRow().addContent(info.get("name"), info.get("service.id"), info.get("db.product"), info.get("db.version"), info.get("url"), "OK");
+ if (nameToId.put(info.get("name"), id) != null) {
+ duplication = true;
+ }
} catch (Exception e) {
- table.addRow().addContent(dsName, "", "", "", "Error " + e.getMessage());
+ table.addRow().addContent(id, "", "", "", "", "Error " + e.getMessage());
}
}
table.print(System.out);
+
+ if (duplication) {
+ System.out.println("\nThere are multiple data source services registered with the same name. Please review your configuration.");
+ }
+
return null;
}
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcMBeanImpl.java b/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcMBeanImpl.java
index 630106c..22128bf 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcMBeanImpl.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcMBeanImpl.java
@@ -36,24 +36,24 @@ public class JdbcMBeanImpl implements JdbcMBean {
public TabularData getDatasources() throws MBeanException {
try {
CompositeType type = new CompositeType("DataSource", "JDBC DataSource",
- new String[]{ "name", "product", "version", "url", "status"},
- new String[]{ "Name", "Database product", "Database version", "JDBC URL", "Status" },
- new OpenType[]{ SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING });
+ new String[]{ "name", "product", "version", "url", "status", "service.id"},
+ new String[]{ "Name", "Database product", "Database version", "JDBC URL", "Status", "Service ID" },
+ new OpenType[]{ SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING });
TabularType tableType = new TabularType("JDBC DataSources", "Table of the JDBC DataSources",
- type, new String[]{ "name" });
+ type, new String[]{ "service.id" });
TabularData table = new TabularDataSupport(tableType);
- for (String datasource : jdbcService.datasources()) {
+ for (Long datasource : jdbcService.datasourceServiceIds()) {
try {
- Map<String, String> info = jdbcService.info(datasource);
+ Map<String, String> info = jdbcService.info(Long.toString(datasource));
CompositeData data = new CompositeDataSupport(type,
- new String[]{"name", "product", "version", "url", "status"},
- new Object[]{datasource, info.get("db.product"), info.get("db.version"), info.get("url"), "OK"});
+ new String[]{"name", "product", "version", "url", "status", "service.id"},
+ new Object[]{info.get("name"), info.get("db.product"), info.get("db.version"), info.get("url"), "OK", info.get("service.id")});
table.put(data);
} catch (Exception e) {
CompositeData data = new CompositeDataSupport(type,
- new String[]{"name", "product", "version", "url", "status"},
- new Object[]{datasource, "", "", "", "ERROR"});
+ new String[]{"name", "product", "version", "url", "status", "service.id"},
+ new Object[]{datasource, "", "", "", "ERROR", ""});
table.put(data);
}
}
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java b/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java
index 896bce8..7cf52c9 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java
@@ -117,6 +117,22 @@ public class JdbcServiceImpl implements JdbcService {
}
@Override
+ public List<Long> datasourceServiceIds() throws Exception {
+ List<Long> datasources = new ArrayList<>();
+
+ ServiceReference<?>[] references = bundleContext.getServiceReferences((String) null,
+ "(|(" + Constants.OBJECTCLASS + "=" + DataSource.class.getName() + ")("
+ + Constants.OBJECTCLASS + "=" + XADataSource.class.getName() + "))");
+ if (references != null) {
+ for (ServiceReference reference : references) {
+ datasources.add((Long) reference.getProperty(Constants.SERVICE_ID));
+ }
+ }
+
+ return datasources;
+ }
+
+ @Override
public Map<String, List<String>> query(String datasource, String query) throws Exception {
try (JdbcConnector jdbcConnector = new JdbcConnector(bundleContext, lookupDataSource(datasource))) {
Map<String, List<String>> map = new HashMap<>();
@@ -163,9 +179,21 @@ public class JdbcServiceImpl implements JdbcService {
@Override
public Map<String, String> info(String datasource) throws Exception {
- try (JdbcConnector jdbcConnector = new JdbcConnector(bundleContext, lookupDataSource(datasource))) {
+ ServiceReference<?> reference = lookupDataSource(datasource);
+ String dsName = datasource;
+ if (reference.getProperty("osgi.jndi.service.name") != null) {
+ dsName = (String) reference.getProperty("osgi.jndi.service.name");
+ } else if (reference.getProperty("datasource") != null) {
+ dsName = (String) reference.getProperty("datasource");
+ } else if (reference.getProperty("name") != null) {
+ dsName = (String) reference.getProperty("name");
+ }
+
+ try (JdbcConnector jdbcConnector = new JdbcConnector(bundleContext, reference)) {
DatabaseMetaData dbMetaData = jdbcConnector.connect().getMetaData();
Map<String, String> map = new HashMap<>();
+ map.put("name", dsName);
+ map.put("service.id", reference.getProperty(Constants.SERVICE_ID).toString());
map.put("db.product", dbMetaData.getDatabaseProductName());
map.put("db.version", dbMetaData.getDatabaseProductVersion());
map.put("url", dbMetaData.getURL());
diff --git a/manual/src/main/asciidoc/user-guide/jdbc.adoc b/manual/src/main/asciidoc/user-guide/jdbc.adoc
index 8ed2562..873a632 100644
--- a/manual/src/main/asciidoc/user-guide/jdbc.adoc
+++ b/manual/src/main/asciidoc/user-guide/jdbc.adoc
@@ -110,20 +110,22 @@ The `jdbc:ds-list` command lists the JDBC datasources:
----
karaf@root()> jdbc:ds-list
-Name | Product | Version | URL | Status
----------------------------------------
-
+Name │ Service Id │ Product │ Version │ URL │ Status
+─────┼────────────┼────────────────┼──────────────────────┼─────────────────┼───────
+test │ 112 │ Apache Derby │ 10.8.2.2 - (1181258) │ jdbc:derby:test │ OK
----
===== `jdbc:ds-info`
-The `jdbc:ds-info` command provides details about a JDBC datasource:
+The `jdbc:ds-info` command provides details about a JDBC datasource. The data source may be specified using name
+or service.id:
----
karaf@root()> jdbc:ds-info test
Property | Value
--------------------------------------------------
driver.version | 10.8.2.2 - (1181258)
+service.id | 112
username | APP
db.version | 10.8.2.2 - (1181258)
db.product | Apache Derby
@@ -208,6 +210,7 @@ The object name to use is `org.apache.karaf:type=jdbc,name=*`.
The `Datasources` attribute provides a tabular data of all JDBC datasource, containing:
* `name` is the JDBC datasource name
+* `service.id` is the JDBC datasource ID of OSGi service
* `product` is the database product backend
* `url` is the JDBC URL used by the datasource
* `version` is the database version backend.