How to enumerate Jaboss AS 7 datasource properties in Java code?

I am running JBoss AS 7.1.0.CR1b. I have multiple data sources defined in my standalone.xml file for example.

        <subsystem xmlns="urn:jboss:domain:datasources:1.0">
            <datasources>
                <datasource jndi-name="java:/MyDS" pool-name="MyDS_Pool" enabled="true" use-java-context="true" use-ccm="true">
                    <connection-url>some-url</connection-url>
                    <driver>the-driver</driver>
                    [etc]

      

Everything works fine.

I am trying to access the information contained here in my code, specifically the properties connection-url

and driver

.

I tried to get Datasource from JNDI as usual, but it doesn't provide access to these properties:

// catches removed
InitialContext context;
DataSource dataSource = null;
context = new InitialContext();
dataSource = (DataSource) context.lookup(jndi);

      

ClientInfo and DatabaseMetadata from the Connection object from this Datasource also do not contain these granular JBoss properties.

My code will run inside a container with a datasource parameter, so everything should be available. I've looked at the IronJacamar interface org.jboss.jca.common.api.metadata.ds.DataSource

and its implementation class and they seem to have available bindings to the information I need, but I can't find any information on how to create such objects with these resources already deployed inside the container (only the constructor on impl implies entering all properties manually).

The JBoss AS 7 CLI allows you to navigate and list data sources as a directory system. http://www.paykin.info/java/add-datasource-programaticaly-cli-jboss-7/ is a great post on how to use what I believe is the Java Management API to interact with the subsystem, but that is, by - Apparently related to the connection to the target JBoss server. My code is already running on this server, so of course there must be an easier way to do this?

Hope someone can help. Many thanks.

+3


source to share


1 answer


What you are really trying to do is control action. The best way to use the available management API.

Here's a simple example:



public class Main {

    public static void main(final String[] args) throws Exception {
        final List<ModelNode> dataSources = getDataSources();
        for (ModelNode dataSource : dataSources) {
            System.out.printf("Datasource: %s%n", dataSource.asString());
        }
    }

    public static List<ModelNode> getDataSources() throws IOException {
        final ModelNode request = new ModelNode();
        request.get(ClientConstants.OP).set("read-resource");
        request.get("recursive").set(true);
        request.get(ClientConstants.OP_ADDR).add("subsystem", "datasources");
        ModelControllerClient client = null;
        try {
            client = ModelControllerClient.Factory.create(InetAddress.getByName("127.0.0.1"), 9999);
            final ModelNode response = client.execute(new OperationBuilder(request).build());
            reportFailure(response);
            return response.get(ClientConstants.RESULT).get("data-source").asList();
        } finally {
            safeClose(client);
        }
    }

    public static void safeClose(final Closeable closeable) {
        if (closeable != null) try {
            closeable.close();
        } catch (Exception e) {
            // no-op
        }
    }


    private static void reportFailure(final ModelNode node) {
        if (!node.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
            final String msg;
            if (node.hasDefined(ClientConstants.FAILURE_DESCRIPTION)) {
                if (node.hasDefined(ClientConstants.OP)) {
                    msg = String.format("Operation '%s' at address '%s' failed: %s", node.get(ClientConstants.OP), node.get(ClientConstants.OP_ADDR), node.get(ClientConstants.FAILURE_DESCRIPTION));
                } else {
                    msg = String.format("Operation failed: %s", node.get(ClientConstants.FAILURE_DESCRIPTION));
                }
            } else {
                msg = String.format("Operation failed: %s", node);
            }
            throw new RuntimeException(msg);
        }
    }
}

      

The only way I can think of is to add a module based on internal servers. It can be done, but I would probably use the management API first.

+5


source







All Articles