jsr342-experts@javaee-spec.java.net

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

From: Adam Bien <abien_at_adam-bien.com>
Date: Mon, 12 Sep 2011 13:18:42 +0200

Hi Linda,

please see inline comments:
On 09.09.2011, at 20:46, Linda DeMichiel wrote:

> 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";
Why not an Enum with: TopicConnectionFactory, QueueConnectionFactory and just ConnectionFactory?
> String resourceAdapterName() default "";
> String user() default "";
> String password() default "";
> String clientId() default "";
> boolean transactional() default true;
Is it enough? I would expect an enum with the values: No, Local and XA.
> int initialPoolSize() default -1;
> int maxPoolSize() default -1;
> int minPoolSize() default -1;
> int maxIdleTime() default -1;
> int connectionTimeout() default -1;
> String[] properties() default {};
> }
>

I miss pool resize quantity.
>
> 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?

I like your proposal. The Configurability, however, adds additional noise. I'm not sure where we should maintain the Configurability
with the resources.

I would like to add s Stage or at least a Debug element to each resource description. In case of Stage.DEV or debug = true, I would expect the server to provide more debugging / tracing information.

Then we could also use the annotations as a base to create classes which would be the parameters of the Configuration API / REST API,


thanks,

adam
>
> 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
>>
>>