Monday Feb 11, 2008

Up the Metro stack to JMX Technology: A Wise Man's Journey

Up the Metro stack to JMX Technology: A Wise Man's Journey


What a long trip... We started by driving on the HTTP highway, slid on SOAP, turned left at the XML crossroads, passed over the WS-Addressing bridge, visited WS-Enumeration, WS-Eventing and WS-Transfer, got a bit lost in WS-Management country, discovered that JMX was not so far off, and finally took a rest (but not a RESTful one) in the Web Services Connector... Did we do all that on our own? No, we did it with a set of friends, the Metros, or the high-performance, extensible, easy-to-use web service stack.


OK, I guess you get it. This little journey lists the set of standards that have been pressed into service to expose JMX MBeans as WS-Management resources. Luckily we didn't have to implement them all. The JAX-WS (a core Metro component) and WiseMan (a WS-Management Java implementation) projects have been of great help.

Now Sun has announced that the WiseMan project is to become part of the Glassfish community. So, it seems to be an appropriate time to look at how the Web Services Connector for JMX Agent RI makes use of WiseMan and Metro.


In this article, I will describe how we changed WiseMan to use part of the Metro stack, what the benefits were, and finally how these technologies are leveraged in the Web Services Connector for JMX Technology

Moving WiseMan to the Stack

In 2007, some significant engineering tasks were undertaken in the WiseMan project to bring the benefits of Metro to WiseMan. This section outlines the steps that were needed to make this move a reality.

The details of this technology switch are of interest to anyone who wants to make their existing applications benefit from Metro's features.

From Servlet to JAX-WS 2.0

WiseMan, was, in its pre-1.0 release, closely coupled with Servlet. At the time, Servlet container was the only way to deploy a WiseMan-based application. We decided to add a JAX-WS Endpoint to the WiseMan project and suddenly we found we could be much more agile. Deployments like the Java SE and Java EE platforms became possible. What a change! For example, being able to base our test suite on the lightweight HTTP server bundled with JAX-WS made our lives much easier...

The JAX-WS Endpoint we developed is a Provider<SOAPMessage>. Simply annotating with @WebService was not possible. WS-Addressing makes intensive use of SOAP headers to convey part of the protocol information. To access to such headers, we need full access to the SOAP Message. After some redesigning of the existing code we extracted a WSManAgent Class that is accessible from a JAX-WS Endpoint or a Servlet.

We took this opportunity to switch to the JAXB release contained in Metro.

So we were happy and impatient to move forward. We already knew that the JAX-WS team was working on adding WS-Addressing support and were waiting for it eagerly.

From JAX-WS 2.0 to JAX-WS 2.1

JAX-WS 2.1 comes with support for WS-Addressing. It's a very smart integration. By just using annotations, your Endpoint becomes addressable thanks to WS-A.

The @Addressing annotation that you can use to tag your Endpoint implies that the WS-Addressing 1.0 release is to be used. However, WS-Management requires the use of another release of the WS-A standard, which is a great pity. We discovered that we were not able to leverage this support. We were afraid this was the end of the road, but the JAX-WS engineering team came back to us showing us the Metro specific API. We were not the first customer with a dependency on a Membership Submission and they defined another “non standard but supported” Annotation to express our requirement : com.sun.xml.ws.developer.MemberSubmissionAddressing

With this annotation added, we removed all the code related to WS-A request-response headers.

So we were happy...but not for long. Our great friends Yves and Sandra of the JMX QA team started to develop some simple stress tests and we started to discover horrible things...

From SOAPMessage to Message

We discovered that 80% of the time spent handling a request was spent in the DOM/SAAJ layer. That's 80% of some big numbers, too...

You remember? Our Endpoint is a Provider<SOAPMessage>. This means that when called, a SOAPMessage object is injected and a SOAPMessage object is expected as the returned value. So we were either stuck, or we had to re-implement the SOAP layer to rely on the STAX API, or we were left with our disapointing figures.

Could the Metro API solve this issue? Yes, the Metro API solved this issue. Once again we were not the first customer, etc., etc., etc. As a solution, an efficient implementation of SAAJ, that is very well integrated with JAXB, is exposed as the Message API (located in the com.sun.xml.ws.api.message package). In order to benefit from its power, you must completely forget all the development you have done on top of SAAJ and rewrite everything on top of this new API. Which is exactly what we did. OK, we re-designed it to make both approaches live together nicely, but we also designed a new API for WiseMan, that was completely isolated from SAAJ. And things started to work much faster (3 to 4 times quicker). The numbers were becoming acceptable, for this kind of XML based processing.


Current WiseMan Architecture




The diagram above shows the different products that are used to build the WiseMan stack on the client and the server. You can see that the WiseMan client stack doesn't rely on Metro, yet. A work-in-progress aims to define and implement such a move, which will greatly improve performance and ease of use.

Improvements for the WiseMan Project

This move helped the project to:

  • Improve deployability

  • Improve alignment and reuse

  • Improve interoperability

  • Improve performance

Deployability, interoperability and performance are the key words of the Web Services Connector for JMX Technology. Based on these new capabilities, WiseMan is becoming the WS-Man implementation of choice for the Web Services Connector for JMX.

When using this connector you are not directly in contact with the stack but you indirectly benefit from the properties you are interested in.


Web Services Connector for JMX Continues Leveraging Metro

This section looks at how the the Web Services Connector for JMX Technology continues leveraging Metro.

Fast Infoset

- "Increase performance!"

- "Increase performance? Hmm..."

Simple, use Fast Infoset! It comes with the stack, it's efficient, it doesn't break interoperability and it's easy to use. We did it and we experienced another big improvement. To enable Fast Infoset in your client API, access the BindingProvider and provide a Fast Infoset key to the request context. For example:

BindingProvider provider = (BindingProvider) port;

Map<String, Object> requestContext = provider.getRequestContext();

requestContext.put("com.sun.xml.ws.client.ContentNegotiation", "pessimistic");

Dispatch<Message> on the client side.

On the client side of the connector, we use the JAX-WS Dispatch class. A Dispatch instance can be seen as an Endpoint proxy that deals with the complete SOAP Message (as opposed to classical JAX-WS proxies that expose a service level API). Since JAX-WS 2.1, Dispatch also handles WS-Addressing. Using Metro specific API, we are creating an efficient Dispatch that is compliant with the WS-Addressing Membership Submission release.

The following code extract shows how to create a Dispatch<Message> for Membership Submission:

Dispatch<Message> port = service.createDispatch(JMXWSConfiguration.JMX_WS_CONNECTOR_PORT, Message.class, Service.Mode.MESSAGE, new MemberSubmissionAddressingFeature(true, true));

Endpoint on the client side

WS-Management defines a way for a WS-Management Agent to deliver its Events in a PUSH mode. This delivery mode implies that the event sink (the client) is itself an Endpoint. We deploy a JAX-WS Endpoint (Provider<Message>) inside our connector client to receive pushed events.

WS-A EndPointReference API

The JMX Web Services Connector RI exposes a non-standard API to customize the mapping of MBeans to WS-Management resources. In this API, we allow customers to hook their customization as low as the WS-Management protocol itself. We needed a WS-Addressing Endpoint reference to expose.

The JAX-WS class javax.xml.ws.EndpointReference offers a standard 1.0 representation that we are internally translating into a Membership Submission via the Metro API (using the class com.sun.xml.ws.developer.MemberSubmissionEndpointReference).

Security

JAX-WS offers support for HTTP Basic Authentication and HTTPS. We are leveraging both.

HTTP Basic Auth

You provide the credentials to a Dispatcher via the request context. The following code extract shows how to provide your credentials.

BindingProvider provider = (BindingProvider) port;

Map<String, Object> requestContext = provider.getRequestContext(); requestContext.put(BindingProvider.USERNAME_PROPERTY, “user); requestContext.put(BindingProvider.PASSWORD_PROPERTY, “password”);

Server Side Security

The way you secure the server side depends on the container in which the Connector is deployed. For more details about how to use the HTTP server bundled in Metro, check the HTTP server API documentation.

Current Web Services Connector Architecture




Interoperability

Based on this architecture, we performed interoperability testing with WinRM (Microsoft's WS-Management based set of tools and API).

This document sums up the scenarios we are testing.

We didn't experience any problems related to interoperability.

Conclusion

Choosing Metro was definitely the right choice. On nearly all levels it has offered the features we were hoping for. When the boundaries of the standards were reached, Metro-specific API entered the scene and offered a solution. Metro really is ahead of the field in terms of improving performance.

So who is the wise man? The ones who defined such long stacks? No, I don't think so....

But Glassfish could be. Its management and monitoring features are based on JMX technology.

So?

So, by deploying the Web Services Connector for JMX (for which the Public Review specification and Early Access 3 RI will be available mid-February) in a Glassfish Server, all the existing MBeans (such as those defined by AMX, by JSR 77, and by you) are automatically exposed as WS-Management resources.

You can imagine the long journey we went through. Would you want to do this on your own, to expose your tiniest resources?

Be wise and use JMX, let us fill in the gaps!

Jean-François Denise

PS: My sincere thanks to Jitendra and Rama from the JAX-WS team for their help. Special thanks to Stuart Clements, my personnal editor and grammar checker.

Wednesday Sep 05, 2007

WS-Security to secure JMX Web Services Connector

In a previous post, Securing JMX Web Services Connector, I explained how to enable HTTPS when using the JSR 262 RI. Basic Authentication and HTTPS are the basic building blocks on which you can rely to secure remote WS access to your JMX instrumentation. These technologies are very commonly used and are simple to put in place when you need point-to-point security. For more complex architectures, however, where messages contexts contain multiple nodes, HTTPS is not the best solution.

WS-Security

WS-Security, a Web Services standard defined by OASIS, aims to secure communication at the SOAP message level (as opposed to HTTPS, that secures messages at the transport level) in a unified, flexible and extensible way. WS-Security supports partial message signing and encryption, in case you need to encrypt the SOAP message body element and keep the headers non-encrypted; for example, when encrypting credit card numbers or any XML subtrees.

In addition to confidentiality and authentication (also offered by HTTPS + Basic Authentication), WS-Security offers message integrity, thanks to XML signatures. With XML signatures, you can protect your communication against message-tampering.

Interoperability at the security level

Due to the huge number of alternatives you can use when trying to secure your communications, you will generally run into interoperability problems. WS-Security has been designed to offer interoperability while still allowing you to plug in various technologies. The WSIT project on java.net (JavaOne 2007 Technical Session TS-4865 offers a good introduction to WSIT) offers an interoperable WS-\* stack that, along with a full set of other WS standards, integrates a Java technology implementation of WS-Security. WSIT is the solution I have adopted to plug WS-Security into the Connector.

Plugging WS-Security into the JMX Web Services Connector

Now that we have briefly introduced WS-Security and WSIT, let's go back to what really interests us, namely plugging WS-Security into the Web Services Connector. The XWSS project, that is part of WSIT, offers everything we need to enable WS-Security in our context. How is this achieved? Simply because the JMX Connector is a JAX-WS Web Service (compliant with WS-Management but still a classical JAX-WS Web Service) and XWSS works well with JAX-WS.

So, I started by reading a XWSS article on how to add WS-Security to your Web Services on top of the Java SE 6 platform. I then adapted the XWSS sample application to create a simple JMX client and server. I interacted with Kumar Jayanti from the XWSS team to get our two technologies working well together. We encountered some issues with WSIT Milestone 6 (mainly related to the fact that WS-Policy was still linked to a Java EE platform type of deployment, and the JMX Connector was being deployed on the Java SE platform), but these have been fixed in the latest WSIT builds. The next WSIT FCS Milestone should contain all the necessary fixes. The usage of WS-Policy makes for a transparent usage of WS-Security. If you package your WS-Security configuration files properly, you can enable WS-Security on the client side and on the server side without touching a single line of code (see the next section for full details of how to make this work).
To enable WS-Security you simply need to package your application with the WSIT binaries and the WS-Security configuration file.

Building and Running the JMX WS Connector Sample Secured with WS-Security

  1. Dowload the XWSS sample application.
  2. Unzip it. A directory named src is created.
  3. Download the sample JMX Agent Main.java file.
  4. Copy Main.java into the src/simplejdk6ws/ directory. The ConnectorServer is started on port 8080. In case of conflict, update the Main.java file (be sure to update the client code accordingly, see the next section for the client side).
  5. Download the sample JMX Client SimpleWSClient.java file.
  6. Copy SimpleWSClient.java into the src/simplejdk6ws/ directory. The Connector connects to port 8080. In case of conflict, update the SimpleWSClient.java file (it should follow the value you previously provided when starting the server). This client application is a very simple one, it connects to the server and asks for the Default Management domain (MBeanServerConnection.getDefaultDomain()).
  7. The server side security configuration file is src/META-INF/server_security_config.xml. Any message received and response sent is Authenticated, Signed and Encrypted according to the configuration defined in this configuration file. You don't need to update this file.
  8. The c lient side security configuration file is src/META-INF/client_security_config.xml. Any message sent and response received is Authenticated (user Ron), Signed and Encrypted according to the configuration defined in this configuration file. Again, you don't need to update this file.
  9. Download WSIT (which contains JAX-WS).
  10. Install WSIT with the following command:
    java -jar jax-ws-latest-wsit-installer_nightly.jar
    The jax-ws-latest-wsit directory is created.
  11. Create a directory named endorsed. Move jax-ws-latest-wsit/lib/webservices-api.jar into this directory.
  12. If you have not already done so ;-), download JMX Web Services Connector Early Access 2.
  13. Call the following command:
    java -jar jsr262-ri.jar
    The jsr262-ri directory is created.
  14. To build your sample, go to the src directory and type the following command:
    javac -cp :../endorsed/webservices-api.jar:../jax-ws-latest-wsit/lib/webservices-rt.jar simplejdk6ws/\*.java
  15. Download the Java mail JAR file .
  16. Start your server from the src directory. The command should be something similar to the following:
    java -cp .:../mail-1.4.jar:../jsr262-ri/lib/jmxws.jar:../jsr262-ri/lib/wiseman-core.jar:../jax-ws-latest-wsit/lib/webservices-rt.jar -Djava.endorsed.dirs=../endorsed/ simplejdk6ws.Main
    You should see the following message:
    JSR 262 ConnectorServer is ready to serve on http://localhost:8080/jmxws
  17. Start your client from the src directory. The command should be something similar to the following:
    java -cp .:../mail-1.4.jar:../jsr262-ri/lib/jmxws.jar:../jsr262-ri/lib/wiseman-core.jar:../jax-ws-latest-wsit/lib/webservices-rt.jar -Djava.endorsed.dirs=../endorsed/ simplejdk6ws.SimpleWSClient
    You should observe a very verbose output containing the secured received and sent SOAP messages. You will notice that the user Ron never appears in the messages, because the user name is encrypted. At the end, the Default Management domain will be displayed.
  18. You are done. Not a line of code was written, and all that was needed was some configuration and packaging.

Bridging with Authorization

When a request is received, the JMX WS Connector Server looks for the existence of Principals in order to create a javax.security.auth.Subject that will be used to check the Java platform's permissions. XWSS, after having dealt with Security, creates a Subject that contains all the authenticated principals (X500 certificate, Trusted user, etc.). XWSS makes this Subject accessible thanks to the call SubjectAccessor.getRequesterSubject(context). This call is XWSS-implementation-dependent and other WS-Security implementations are likely to offer their own way. This is why we have added a hook to plug a Subject extractor into the ConnectorServer to retrieve the Subject and make it accessible to the ConnectorServer.

The following XWSSSecuritySubjectExtractor class is an example of such an XWSS-aware SubjectExtractor:

        class XWSSSecuritySubjectExtractor extends JMXWSSubjectExtractor {
            protected Subject getExtraSubject(WebServiceContext context) {
                try {
                    return SubjectAccessor.getRequesterSubject(context);
                } catch (XWSSecurityException ex) {
                    ex.printStackTrace();
                }
                return null;
            }
        }
                        

To pass the extractor instance to the ConnectorServer, use the environment map :

        Map env = new HashMap();
        
        // Provide the extended SubjectExtractor to inject WS-Security Subject
        env.put(JMXWSConfiguration.JMX_WS_SUBJECT_EXTRACTOR, new XWSSSecuritySubjectExtractor());
        
        JMXConnectorServer server =
                JMXConnectorServerFactory.
                newJMXConnectorServer(new JMXServiceURL("service:jmx:ws:" +
                "//localhost:8080/jmxws"), env,
                ManagementFactory.getPlatformMBeanServer());
        server.start();
                                                                    

This is the updated Main.java file that contains the Subject Extractor.

WARNING: You need the updated JMX WS Connector RI jmxws.jar and wiseman-core.jar file to use the SubjectExtractor API. You can download these jars here.
Call java -jar jsr262-patch-ws-security.jar to extract the jmxws.jar and wiseman-core.jar files.
When compiling the agent, add both JAR files to your classpath.

So, if one day you reach the limits of the capabilities of HTTPS + Basic Authentication, you should think about using WS-Security. I hope that I have demonstrated to you that enabling it is straightforward. But you should be aware that enabling WS-Security will significantly impact the performance of the WS Connector. The time needed to check security added to the time needed to create and parse a secured SOAP Message (here is an example of a AUTH+PRIV+SIGN getDefaultDomain response SOAP message) makes for much slower client/server interaction.

Enjoy and have fun.

Jean-Francois

About

jeanfrancoisdenise

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today