BTM
  1. BTM
  2. BTM-50

Improve JndiXAConnectionFactory in order to be able to use SonicMQ

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.3.2
    • Fix Version/s: 1.3.3
    • Labels:
      None
    • Number of attachments :
      1

      Description

      To obtain a SonicMQ connection factory using JNDI, you have to use non-standard JNDI environment entries. More details are available at page 148 of the PDF file located at http://communities.progress.com/pcom/servlet/JiveServlet/download/10701-3-10072/mq_application_program_76.pdf
      The JndiXAConnectionFactory doesn't allow setting these non-standard properties.
      Moreover, the PortableRemoteObject.narrow() call fails with an exception when using the SonicMQ JNDI provider. A simple cast must be made instead.
      It should thus be util to be able

      • to pass arbitrary extra environment entries to the JndiXAConnectionFactory
      • to enable/disable the call to PRO.narrow()
        These new properties should be settable via the resource loader.

      I've been able to use the following subclass to get a connection factory from SonicMQ.

      public class SonicMQJndiXAConnectionFactory extends JndiXAConnectionFactory {

      private String domain;

      private XAConnectionFactory wrappedFactory;

      public String getDomain()

      { return domain; }

      public void setDomain(String domain)

      { this.domain = domain; }

      @Override
      protected void init() throws NamingException {
      if (wrappedFactory != null)

      { return; }

      String initialContextFactory = getInitialContextFactory();
      String providerUrl = getProviderUrl();
      String securityPrincipal = getSecurityPrincipal();
      String securityCredentials = getSecurityCredentials();
      String name = getName();

      Context ctx;
      if (!isEmpty(initialContextFactory) && !isEmpty(providerUrl)) {
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
      env.put(Context.PROVIDER_URL, providerUrl);
      if (!isEmpty(securityPrincipal))

      { env.put(Context.SECURITY_PRINCIPAL, securityPrincipal); }

      if (!isEmpty(securityCredentials))

      { env.put(Context.SECURITY_CREDENTIALS, securityCredentials); }

      if (!isEmpty(domain))

      { env.put("com.sonicsw.jndi.mfcontext.domain", domain); }

      ctx = new InitialContext(env);
      }
      else

      { ctx = new InitialContext(); }

      wrappedFactory = (XAConnectionFactory) ctx.lookup(name);
      }

      @Override
      public XAConnection createXAConnection() throws JMSException {
      String name = getName();
      try

      { init(); return wrappedFactory.createXAConnection(); }

      catch (NamingException ex)

      { throw (JMSException) new JMSException("error looking up wrapped XAConnectionFactory at " + name).initCause(ex); }
      }

      @Override
      public XAConnection createXAConnection(String userName, String password) throws JMSException {
      String name = getName();
      try { init(); return wrappedFactory.createXAConnection(userName, password); }
      catch (NamingException ex) { throw (JMSException) new JMSException("error looking up wrapped XAConnectionFactory at " + name).initCause(ex); }

      }

      private static boolean isEmpty(String str)

      { return str == null || str.trim().equals(""); }

      }

      1. BTM-50.patch
        1 kB
        Jean-Baptiste Nizet

        Activity

        Hide
        Ludovic Orban added a comment -

        I think this can be done simply by adding a new Properties property which will contain extra properties to be added to the InitialContext's environment.

        Another boolean property like 'narrowJndiObject' can be added too to tell the JndiXAConnectionFactory if PortableRemoteObject.narrow() should be applied on the object acquired from JNDI.

        What do you think ?

        Show
        Ludovic Orban added a comment - I think this can be done simply by adding a new Properties property which will contain extra properties to be added to the InitialContext's environment. Another boolean property like 'narrowJndiObject' can be added too to tell the JndiXAConnectionFactory if PortableRemoteObject.narrow() should be applied on the object acquired from JNDI. What do you think ?
        Hide
        Jean-Baptiste Nizet added a comment -

        This would be perfect.
        Thanks for the quick answer.

        Show
        Jean-Baptiste Nizet added a comment - This would be perfect. Thanks for the quick answer.
        Hide
        Jean-Baptiste Nizet added a comment -

        Now that I think about it a bit more, what could be the syntax of the resource loader properties file?
        Would resource.mq1.jndiProperties.com.sonicsw.jndi.mfcontext.domain=myDomain work as expected?

        Show
        Jean-Baptiste Nizet added a comment - Now that I think about it a bit more, what could be the syntax of the resource loader properties file? Would resource.mq1.jndiProperties.com.sonicsw.jndi.mfcontext.domain=myDomain work as expected?
        Hide
        Ludovic Orban added a comment -

        This has been implemented and committed in trunk. A few minor enhancements and cleanups have been done as well.

        The exact syntax is now:
        resource.mq1.extraJndiProperties.com.sonicsw.jndi.mfcontext.domain=myDomain

        which required a minor change in the PropertyUtils class to be able to insert dotted keys in Properties object.

        Can you please try to build from trunk and report if what I committed meets your requirements ?

        Show
        Ludovic Orban added a comment - This has been implemented and committed in trunk. A few minor enhancements and cleanups have been done as well. The exact syntax is now: resource.mq1.extraJndiProperties.com.sonicsw.jndi.mfcontext.domain=myDomain which required a minor change in the PropertyUtils class to be able to insert dotted keys in Properties object. Can you please try to build from trunk and report if what I committed meets your requirements ?
        Hide
        Jean-Baptiste Nizet added a comment -

        Although the PropertyUtils class now accepts dotted keys, the ResourceLoader still ignores keys which have more than 4 elements. I'll attach a patch which solves this issue.

        Show
        Jean-Baptiste Nizet added a comment - Although the PropertyUtils class now accepts dotted keys, the ResourceLoader still ignores keys which have more than 4 elements. I'll attach a patch which solves this issue.
        Hide
        Jean-Baptiste Nizet added a comment -

        This patch modified the ResourceLoader class in order for it to accept property keys that have more than 4 elements. With this modification, the initial problem is solved.

        Show
        Jean-Baptiste Nizet added a comment - This patch modified the ResourceLoader class in order for it to accept property keys that have more than 4 elements. With this modification, the initial problem is solved.
        Hide
        Ludovic Orban added a comment -

        Patch applied, thanks.

        Show
        Ludovic Orban added a comment - Patch applied, thanks.
        Hide
        Gérald Quintana added a comment -

        The real configuration syntax is:

        resource.myCF.driverProperties.extraJndiProperties.com.sonicsw.jndi.mfcontext.domain=dmBoironRct
        

        The driverProperties is missing in Ludovic's comment

        Show
        Gérald Quintana added a comment - The real configuration syntax is: resource.myCF.driverProperties.extraJndiProperties.com.sonicsw.jndi.mfcontext.domain=dmBoironRct The driverProperties is missing in Ludovic's comment

          People

          • Assignee:
            Ludovic Orban
            Reporter:
            Jean-Baptiste Nizet
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: