jsr342-experts@javaee-spec.java.net

[jsr342-experts] resource-specific resource configuration metadata options

From: Linda DeMichiel <linda.demichiel_at_oracle.com>
Date: Fri, 09 Sep 2011 11:46:59 -0700

I appreciate all the members who have weighed in on these issues so far.

Since the responses have indicated a preference for the resource-specific
over the generic metadata approach, I want to double-check whether we're
all on the same page with regard to what the typed approach might entail,
particularly when configurability options are added. The examples
below are an attempt to assess this at a greater level of detail.

First, consider an example of the typed approach without configurability
options. For JMS Connection Factory resources, an annotation might
potentially be defined as follows:


@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD})
public @interface JMSConnectionFactory {
     String description() default "";
     String name();
     String resourceType() default "javax.jms.ConnectionFactory";
     String resourceAdapterName() default "";
     String user() default "";
     String password() default "";
     String clientId() default "";
     boolean transactional() default true;
     int initialPoolSize() default -1;
     int maxPoolSize() default -1;
     int minPoolSize() default -1;
     int maxIdleTime() default -1;
     int connectionTimeout() default -1;
     String[] properties() default {};
}


Now, for each of these elements, if we add a configurability
specification, we need to replace the primitive-valued element with an
annotation-valued one. To preserve typing, some (or all??) of these
would entail the use of separate annotation types, as below. I've
defined default values for these to try to reduce verbosity. If we take
such an approach, we'd need to make sure we set defaults appropriately
(i.e., the defaults below should be regarded as a strawman for now). Ditto
for the use of "value" elements.


For example:

@Retention(RUNTIME)
@Target{}
public @interface Name {
   String name() default "";
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface ResourceType {
   String type() default "javax.jms.ConnectionFactory";
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface ResourceAdapterName {
   String name() default "";
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface User {
   String value() default "";
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface Password {
   String value() default "";
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface ClientId {
   String value() default "";
   Configurability configurability() default Configurability.MUST_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface Transactional {
   boolean value() default true;
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface PoolSize {
   int value() default -1;
   Configurability configurability() default Configurability.MAY_MODIFY;
}


@Retention(RUNTIME)
@Target{}
public @interface MaxIdleTime {
   int value() default -1;
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface Timeout {
   int value() default -1;
   Configurability configurability() default Configurability.MAY_MODIFY;
}

@Retention(RUNTIME)
@Target{}
public @interface Property {
   String name();
   String value();
   Configurability configurability() default Configurability.MAY_MODIFY;
}


Our expanded annotation then looks something like this:

@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD})
public @interface JMSConnectionFactory {
     String description() default "";
     Name name() default @Name;
     ResourceType resourceType() default @ResourceType;
     ResourceAdapterName resourceAdapterName() default @ResourceAdapterName;
     User user() default @User;
     Password password() default @Password;
     ClientId clientId() default @ClientId;
     Transactional transactional() default @Transactional;
     PoolSize initialPoolSize() default @PoolSize;
     PoolSize maxPoolSize() default @PoolSize;
     PoolSize minPoolSize() default @PoolSize;
     MaxIdleTime maxIdleTime() default @IdleTime;
     Timeout connectionTimeout() default @Timeout;
     Properties[] properties() default {};
}


The filled out version appearing in application code might look like this
(assuming some use of defaults):

@JMSConnectionFactory (
     description="my JMF CF",
     name=_at_Name(name="myJMSCF", configurability=MUST_NOT_MODIFY),
     resourceType=_at_ResourceType(type="javax.jms.QueueConnectionFactory"),
     resourceAdapterName=_at_ResourceAdapterName(name="myRA"),
     clientId=_at_ClientId("foo"),
     initialPoolSize = @PoolSize(2),
     minPoolSize = @PoolSize(2),
     properties = {_at_Property(name="vendorProp1",
                             value="someValue",
                             configurability=MUST_NOT_MODIFY},
                   @Property(name="vendorProp2",
                             value="someValue"),
                   @Property(name="vendorProp3",
                             value="someValue")}
)



Is this what you have in mind in terms of the resource-specific approach?

If so, are you sure this is what you want?

Or something else?


thanks again,

-Linda




On 8/25/2011 6:13 PM, Linda DeMichiel wrote:
> Aside from Reza's email (thanks, Reza!), we haven't received much
> feedback on the resource configuration front. Under the assumption
> that silence implies consent, we'd like to move on to the next steps
> in this direction.
>
> This email contains a number of items that require your input.
> Briefly, we need feedback on the following aspects:
>
> 1. The use of annotations for resource configuration.
> 2. The form that such annotations (if supported) should take.
> 3. The form of XML elements for resource configuration.
> 4. How metadata related to per-tenant (re)configurability should be
> specified.
> 5. Whether the XML elements should be embedded in the current descriptors
> or there should be a separate descriptor.
>
> These items are discussed further in the message below. I have
> flagged specific items on which we need your feedback as "ISSUE:"
>
> Since the decision on how to specify metadata for reconfigurability
> may likely impact the decision on the format to use to specify
> annotations and XML for resource configuration, I recommend that you
> make 2 passes to work through this:
> (1) to review the options and how they interact;
> (2) to provide your opinions on the issues.
>
> thanks,
>
> -Linda
>
> ---------------------------
>
> 1. Annotations for resource configuration
>
> Java EE 6 currently supports use of the DataSourceDefinition annotation.
> This annotation is defined as follows:
>
> package javax.annotation.sql;
>
> @Retention(RUNTIME)
> @Target({TYPE})
> public @interface DataSourceDefinition {
> String name();
> String className();
> String description() default "";
> String url() default "";
> String user() default "";
> String password() default "";
> String databaseName() default "";
> int portNumber() default -1;
> String serverName() default "localhost";
> int isolationLevel() default -1;
> boolean transactional() default true;
> int initialPoolSize() default -1;
> int maxPoolSize() default -1;
> int minPoolSize() default -1;
> int maxIdleTime() default -1;
> int maxStatements() default -1;
> String[] properties() default {};
> int loginTimeout() default 0;
> }
>
>
> Following this pattern, we might define similar annotations for the other
> standard resource types -- e.g., define JMSConnectionFactory, JMSDestination,
> MailSession, and ConnectorResource annotations.
>
>
> An alternative is to take a more generic approach, and instead of
> these support a generic ResourceDefinition annotation:
>
> package javax.annotation.resource;
>
> @Retention(RUNTIME)
> @Target({TYPE})
> public @interface ResourceDefinition {
> String description() default "";
> String name();
> String className();
> String[] properties() default {};
> }
>
> With the generic ResourceDefinition approach, all resource-specific
> information would be provided as properties. For that reason, the generic
> approach relies heavily on the use of strings and therefore has less
> type safety. We would need to standardize on the property names to be
> used, and we would also need to decide whether to require a
> package-specific prefix on the property names (as illustrated in the
> examples below) to distinguish them from vendor properties.
>
>
> Examples:
>
> Example 1: data sources
>
> @DataSourceDefinition(
> name="java:app/MyDataSource",
> className="com.foobar.MyDataSource",
> portNumber=6689,
> serverName="myserver.com",
> user="lance",
> password="secret"
> )
>
> vs
>
> @ResourceDefinition(
> name="java:app/MyDataSource",
> className="com.foobar.MyDataSource",
> properties={
> "javax.sql.portNumber=6689",
> "javax.sql.serverName=myserver.com",
> "javax.sql.user=lance",
> "javax.sql.password=secret"
> }
> )
>
>
> Example 2: JMS connection factories
>
> @JMSConnectionFactory(
> name="java:app/MyJMSFactory",
> resourceType="javax.jms.QueueConnectionFactory",
> clientId="foo",
> connectionTimeout=10,
> initialPoolSize=5,
> maxPoolSize=15
> )
>
> vs
>
> @ResourceDefinition(
> name="java:app/MyJMSFactory",
> className="javax.jms.QueueConnectionFactory",
> properties={
> "javax.jms.clientId=foo",
> "javax.jms.connectionTimeout=10",
> "javax.jms.initialPoolSize=5",
> "javax.jms.maxPoolSize=15"
> }
> )
>
>
> Example 3: JMS destinations
>
> @JMSDestination(
> name="java:app/MyQueue",
> resourceType="javax.jms.Queue",
> resourceName="queue124"
> )
>
> vs
>
> @ResourceDefinition(
> name="java:app/MyQueue",
> className="javax.jms.Queue",
> properties={
> "javax.jms.resourceName=queue124"
> }
> )
>
>
> ISSUE 1: Should we support the use of annotations for resource configuration
> (in addition to DataSourceDefinition) or should we require that resource
> configurability metadata be specified in XML?
>
> ISSUE 2: If we support the use of annotations, which of the above
> approaches should we take -- resource-specific or generic?
>
> ISSUE 3: How should we name the standard properties? Do they require
> a "package"-specific prefix?
>
> ISSUE 4: If we take a generic approach, should we use this for
> DataSourceDefinition as well, treating the existing DataSourceDefinition
> annotation and XML as "legacy"?
>
>
> ------------------
>
>
> 2. XML for resource configuration
>
> We currently support the use of the data-source element in the Java EE 6
> descriptors as part of the jndiEnvironmentRefsGroup type. (See
> http://java.sun.com/xml/ns/javaee/javaee_6.xsd for the details.)
>
> For the new elements, the choices are again whether to have elements
> that are resource-specific or generic.
>
>
> Example:
>
> Resource-specific approach, JMS connection factory:
>
> <jms-connection-factory>
> <name>MyJMSFactory</name>
> <resource-type>javax.jms.QueueConnectionFactory</resource-type>
> <client-id>foo</client-id>
> <connection-timeout>10</connection-timeout>
> <initial-pool-size>5</initial-pool-size>
> <max-pool-size>15</max-pool-size>
> </jms-connection-factory>
>
>
> Generic approach:
>
> <resource-definition>
> <name>MyJMSFactory</name>
> <resource-type>javax.jms.QueueConnectionFactory</resource-type>
> <property>
> <name>clientId</name>
> <value>foo</value>
> </property>
> <property>
> <name>connectionTimeout</name>
> <value>10</value>
> </property>
> <property>
> <name>initialPoolSize</name>
> <value>5</value>
> </property>
> <property>
> <name>maxPoolSize</name>
> <value>15</value>
> </property>
> </resource-definition>
>
>
> Note that the specification of properties could be made somewhat less
> verbose by the use of attributes. The example above uses elements
> to be more consistent with the current style of our deployment
> descriptors.
>
>
> With XML, we again have the issue as to whether properties in the
> generic approach should use a resource-specific prefix, e.g.,
>
> <resource-definition>
> <name>MyJMSFactory</name>
> <resource-type>javax.jms.QueueConnectionFactory</resource-type>
> <property>
> <name>javax.jms.clientId</name>
> <value>foo</value>
> </property>
> <property>
> <name>javax.jms.connectionTimeout</name>
> <value>10</value>
> </property>
> <property>
> <name>javax.jms.initialPoolSize</name>
> <value>5</value>
> </property>
> <property>
> <name>javax.jms.maxPoolSize</name>
> <value>15</value>
> </property>
> </resource-definition>
>
>
> ISSUE 5: Which XML format should we use? Resource-specific or generic ?
>
>
> ----------------------------
>
>
> 3. Specification of per-tenant reconfigurability
>
> In the resource configuration document that I circulated several weeks
> ago, I noted that we needed a means to include information about which
> attributes of a resource definition must be modified by a tenant, which
> must not be modified, and which may be modified.
>
> The remainder of this message outlines how that might be handled in
> the various approaches.
>
> If we take a generic approach (@ResourceDefinition), the property elements
> could be expanded to specify a configurability element. For example:
>
> @Retention(RUNTIME)
> @Target({TYPE})
> public @interface ResourceDefinition {
> String description() default "";
> String name();
> String className();
> ConfigProperty[] configProperties() default {};
> }
>
> @Retention(RUNTIME)
> @Target({})
> public @interface ConfigProperty {
> String name();
> String value();
> Configurability configurability() default Configurability.MAY_MODIFY;
> }
>
> public enum Configurability {
> MUST_MODIFY,
> MUST_NOT_MODIFY,
> MAY_MODIFY,
> }
>
>
>
> Example:
>
> @ResourceDefinition(
> name="java:app/MyJMSFactory",
> className="javax.jms.QueueConnectionFactory",
> configProperties={
> @ConfigProperty(
> name="clientId",
> value="foo",
> configurability=MUST_MODIFY),
> @ConfigProperty(
> name="connectionTimeout",
> value="10"),
> @ConfigProperty(
> name="initialPoolSize",
> value="5"),
> @ConfigProperty(
> name="maxPoolSize",
> value="15")
> }
> )
>
>
> A possible alternative to the use of the embedded @ConfigProperty
> annotation approach might be to embed further syntax into the property
> specification to capture configurabilty semantics. For example:
>
> @ResourceDefinition(
> name="java:app/MyJMSFactory",
> className="javax.jms.QueueConnectionFactory",
> properties={
> "javax.jms.clientId=foo", // must modify
> "javax.jms.connectionTimeout=?10", // may modify
> "javax.jms.transactional==true" // must not modify
> }
> )
>
>
>
> Things get more complicated with the typed resource definition
> approach. Consider what happens to JMSConnectionFactory, where some
> of the non-property elements are optional.
>
> Maintaining typing using the separate elements approach leads to
> a proliferation of annotations.
>
> For example:
>
> @JMSConnectionFactory(
> name="java:app/MyJMSFactory",
> resourceType="javax.jms.QueueConnectionFactory",
> clientId=_at_ClientId(value="foo",
> configurability=Configurability.MUST_MODIFY),
> connectionTimeout=_at_ConnectionTimeout(10),
> initialPoolSize=_at_PoolSize(5),
> maxPoolSize=_at_PoolSize(15)
> )
>
>
> An alternative is that only string-valued elements are used, and all
> elements are of type ResourceElement:
>
> @Retention(RUNTIME) @Target({})
> public @interface ResourceElement {
> String value();
> Configurability configurability() default Configurability.MAY_MODIFY;
> }
>
>
> Example:
>
> @JMSConnectionFactory(
> name="java:app/MyJMSFactory",
> resourceType="javax.jms.QueueConnectionFactory",
> clientId=_at_ResourceElement(value="foo", configurability=MUST_MODIFY),
> connectionTimeout=_at_ResourceElement("10"),
> initialPoolSize=_at_ResourceElement("5"),
> maxPoolSize=_at_ResourceElement("15")
> )
>
>
> ISSUE 6: Should we support the use of annotations for the specification
> of per-tenant reconfigurability?
>
> ISSUE 7: If we support the use of annotations for the specification of
> per-tenant reconfigurability, which approach should we take:
> (1) Generic ResourceDefinition annotation
> (2) Resource-specific annotations, using separate typed elements
> (3) Resource-specific annotations, using ResourceElement approach
> (4) Other?
>
>
> ---------------------------
>
>
> 4. Specification of per-tenant reconfigurability using XML
>
> With XML on the other hand, extension is fairly straightforward. The
> various types could be augmented with attributes.
>
>
> Example:
>
> <jms-connection-factory>
> <name configurability=MUST_NOT_MODIFY>java:app/MyJMSFactory</name>
> <resource-type configurability=MUST_NOT_MODIFY>
> javax.jms.QueueConnectionFactory
> </resource-type>
> <client-id configurability=MUST_MODIFY>foo</client-id>
> <connection-timeout>10</connection-timeout>
> <initial-pool-size>5</initial-pool-size>
> <max-pool-size>15</max-pool-size>
> </jms-connection-factory>
>
>
>
> With the generic approach, this would look as follows, assuming
> again a default of MAY_MODIFY if no attribute is specified:
>
> <resource-definition>
> <name configurability=MUST_NOT_MODIFY>java:app/MyJMSFactory</name>
> <resource-type configurability=MUST_NOT_MODIFY>
> javax.jms.QueueConnectionFactory
> </resource-type>
> <property configurability=MUST_MODIFY>
> <name>clientId</name>
> <value>foo</value>
> </property>
> <property>
> <name>connectionTimeout</name>
> <value>10</value>
> </property>
> <property>
> <name>initialPoolSize</name>
> <value>5</value>
> </property>
> <property>
> <name>maxPoolSize</name>
> <value>15</value>
> </property>
> </resource-definition>
>
>
> ISSUE 8: Which approach should we take for the specification of
> per-tenant reconfigurability using XML: type-specific XML elements
> or generic resource-definition elements?
>
>
> ---------------------------------------
>
> 5. XML Descriptors for the specification of resource configuration.
>
> A further item pertains to where the XML elements for resource
> configuration should be located -- i.e., in the existing Java EE
> descriptors, or in a separate resources.xml (or services.xml)
> descriptor. In our view, the fact that these resource configuration
> elements are applicable to the application as a whole argues that there
> should be a separate descriptor.
>
> ISSUE 9: Should resource configuration definitions be embedded in
> the existing descriptors or should there be a separate XML descriptor?
>
> ---------------------------
>
>
> RECAP OF THE ISSUES. ALL OF THESE NEED YOUR INPUT:
>
>
> ISSUE 1: Should we support the use of annotations for resource configuration
> (in addition to DataSourceDefinition) or should we require that resource
> configurability metadata be specified in XML?
>
> ISSUE 2: If we support the use of annotation, which of the above
> approaches should we take -- resource-specific or generic?
>
> ISSUE 3: How should we name the standard properties? Do they require
> a "package"-specific prefix?
>
> ISSUE 4: If we take a generic approach, should we use this for
> DataSourceDefinition as well, treating the existing DataSourceDefinition
> annotation and XML as "legacy"?
>
> ISSUE 5: Which XML format should we use? Resource-specific or generic ?
>
> ISSUE 6: Should we support the use of annotations for the specification
> of per-tenant reconfigurability?
>
> ISSUE 7: If we support the use of annotations for the specification of
> per-tenant reconfigurability, which approach should we take:
> (1) Generic ResourceDefinition annotation
> (2) Resource-specific annotations, using separate typed elements
> (3) Resource-specific annotations, using ResourceElement approach
> (4) Other?
>
> ISSUE 8: Which approach should we take for the specification of
> per-tenant reconfigurability using XML: type-specific XML elements
> or generic resource-definition elements?
>
> ISSUE 9: Should resource configuration definitions be embedded in
> the existing descriptors or should there be a separate XML descriptor?
>
> --------
>
> Thanks in advance for your feedback!
>
> -Linda
>
>