You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2007/02/14 02:37:17 UTC
svn commit: r507347 - in /webservices/axis2/trunk/java/modules/jaxws:
src/org/apache/axis2/jaxws/message/
src/org/apache/axis2/jaxws/message/impl/ src/org/apache/axis2/jaxws/server/
src/org/apache/axis2/jaxws/spi/ test/org/apache/axis2/jaxws/message/
Author: scheu
Date: Tue Feb 13 17:37:16 2007
New Revision: 507347
URL: http://svn.apache.org/viewvc?view=rev&rev=507347
Log:
AXIS2-2166
Contributor: Rich Scheuerle
Improvements to the JAX-WS message processing to 'support' persistance of request message by outbound handlers.
Added:
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/Constants.java
Modified:
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockImpl.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageTests.java
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java?view=diff&rev=507347&r1=507346&r2=507347
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java Tue Feb 13 17:37:16 2007
@@ -106,4 +106,16 @@
* @param mhs MimeHeaders
*/
public void setMimeHeaders(MimeHeaders mhs);
+
+ /**
+ * Indicate that this message is passed the pivot point.
+ * For example, this is set in the JAX-WS Dispatcher
+ * to indicate
+ */
+ public void setPostPivot();
+
+ /**
+ * @return true if post pivot
+ */
+ public boolean isPostPivot();
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockImpl.java?view=diff&rev=507347&r1=507346&r2=507347
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockImpl.java Tue Feb 13 17:37:16 2007
@@ -17,6 +17,7 @@
package org.apache.axis2.jaxws.message.impl;
import java.io.OutputStream;
+import java.io.StringReader;
import java.io.Writer;
import javax.xml.namespace.QName;
@@ -37,6 +38,7 @@
import org.apache.axis2.jaxws.message.XMLPart;
import org.apache.axis2.jaxws.message.factory.BlockFactory;
import org.apache.axis2.jaxws.message.util.Reader2Writer;
+import org.apache.axis2.jaxws.spi.Constants;
import org.apache.axis2.jaxws.utility.JavaUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -186,7 +188,12 @@
public XMLStreamReader getXMLStreamReader(boolean consume) throws XMLStreamException, WebServiceException {
XMLStreamReader newReader = null;
if (consumed) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage("BlockImplErr1", this.getClass().getName()));
+ // In some scenarios, the message is written out after the service instance is invoked.
+ // In these situations, it is preferable to simply ignore this block.
+ if (this.getParent() != null && getParent().isPostPivot()) {
+ return _postPivot_getXMLStreamReader();
+ }
+ throw ExceptionFactory.makeWebServiceException(Messages.getMessage("BlockImplErr1", this.getClass().getName()));
}
if (omElement != null) {
if (consume) {
@@ -294,6 +301,11 @@
public void outputTo(XMLStreamWriter writer, boolean consume) throws XMLStreamException, WebServiceException {
if (consumed) {
+ // In some scenarios, the message is written out after the service instance is invoked.
+ // In these situations, it is preferable to simply ignore this block.
+ if (this.getParent() != null && getParent().isPostPivot()) {
+ _postPivot_outputTo(writer);
+ }
throw ExceptionFactory.makeWebServiceException(Messages.getMessage("BlockImplErr1", this.getClass().getName()));
}
if (omElement != null) {
@@ -309,6 +321,40 @@
setConsumed(consume);
return;
}
+
+ /**
+ * Called if we have passed the pivot point but someone wants to output the block.
+ * The actual block implementation may choose to override this setting
+ */
+ protected void _postPivot_outputTo(XMLStreamWriter writer) throws XMLStreamException, WebServiceException {
+ if (log.isDebugEnabled()) {
+ QName theQName = isQNameAvailable() ? getQName() : new QName("unknown");
+ log.debug("The Block for " + theQName + " is already consumed and therefore it is not written.");
+ log.debug("If you need this block preserved, please set the " + Constants.SAVE_REQUEST_MSG + " property on the MessageContext.");
+ }
+ return;
+ }
+
+ /**
+ * Called if we have passed the pivot point but someone wants to output the block.
+ * The actual block implementation may choose to override this setting.
+ */
+ protected XMLStreamReader _postPivot_getXMLStreamReader() throws XMLStreamException, WebServiceException {
+ if (log.isDebugEnabled()) {
+ QName theQName = isQNameAvailable() ? getQName() : new QName("unknown");
+ log.debug("The Block for " + theQName + " is already consumed and therefore it is only partially read.");
+ log.debug("If you need this block preserved, please set the " + Constants.SAVE_REQUEST_MSG + " property on the MessageContext.");
+ }
+ QName qName = getQName();
+ String text = "";
+ if (qName.getNamespaceURI().length() > 0) {
+ text = "<prefix:" + qName.getLocalPart() + " xmlns:prefix='" + qName.getNamespaceURI() + "'/>";
+ } else {
+ text = "<" + qName.getLocalPart() + "/>";
+ }
+ StringReader sr = new StringReader(text);
+ return StAXUtils.createXMLStreamReader(sr);
+ }
/**
* @return true if the representation of the block is currently a business object.
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java?view=diff&rev=507347&r1=507346&r2=507347
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java Tue Feb 13 17:37:16 2007
@@ -69,6 +69,8 @@
boolean mtomEnabled;
private MimeHeaders mimeHeaders = new MimeHeaders();
+ private boolean postPivot = false;
+
// Constants
private static final String SOAP11_ENV_NS = "http://schemas.xmlsoap.org/soap/envelope/";
private static final String SOAP12_ENV_NS = "http://www.w3.org/2003/05/soap-envelope";
@@ -426,6 +428,14 @@
public void setBodyBlock(Block block) throws WebServiceException {
xmlPart.setBodyBlock(block);
+ }
+
+ public void setPostPivot() {
+ this.postPivot = true;
+ }
+
+ public boolean isPostPivot() {
+ return postPivot;
}
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java?view=diff&rev=507347&r1=507346&r2=507347
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java Tue Feb 13 17:37:16 2007
@@ -17,9 +17,17 @@
package org.apache.axis2.jaxws.server;
import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.ws.WebServiceException;
+
+import java.io.StringReader;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
+import org.apache.axiom.om.impl.builder.StAXBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.java.security.AccessController;
@@ -43,6 +51,7 @@
import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactory;
import org.apache.axis2.jaxws.server.endpoint.lifecycle.EndpointLifecycleManager;
import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory;
+import org.apache.axis2.jaxws.spi.Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -112,14 +121,33 @@
MessageContext responseMsgContext = null;
try {
+ // Get the service instance. This will run the @PostConstruct code.
EndpointLifecycleManager elm = createEndpointlifecycleManager();
Object serviceInstance = elm.createServiceInstance(requestMsgCtx, implClass);
- EndpointDispatcher dispatcher = getEndpointDispatcher(implClass, serviceInstance);
+
+ // The application handlers and dispatcher invoke will
+ // modify/destroy parts of the message. Make sure to save
+ // the request message if appropriate.
+ saveRequestMessage(requestMsgCtx);
+
+ // @TODO Invoke inbound application handlers.
+
+ // Dispatch to the
+ EndpointDispatcher dispatcher = getEndpointDispatcher(implClass, serviceInstance);
+ try {
+ responseMsgContext = dispatcher.invoke(requestMsgCtx);
+ } finally {
+ // Passed pivot point
+ requestMsgCtx.getMessage().setPostPivot();
+ }
+
+ // @TODO Invoke outbound application handlers
- responseMsgContext = dispatcher.invoke(requestMsgCtx);
} catch (Exception e) {
// TODO for now, throw it. We probably should try to make an XMLFault object and set it on the message
throw ExceptionFactory.makeWebServiceException(e);
+ } finally {
+ restoreRequestMessage(requestMsgCtx);
}
// The response MessageContext should be set on the InvocationContext
@@ -262,5 +290,56 @@
// TODO for now, throw it. We probably should try to make an XMLFault object and set it on the message
throw ExceptionFactory.makeWebServiceException(e);
}
+ }
+
+ /**
+ * Save the request message if indicated by the SAVE_REQUEST_MSG property
+ * @param requestMsgContext
+ */
+ private void saveRequestMessage(MessageContext requestMsgContext) {
+
+ // TESTING...FORCE SAVING THE REQUEST MESSAGE
+ // requestMsgContext.getAxisMessageContext().setProperty(Constants.SAVE_REQUEST_MSG, Boolean.TRUE);
+ // END TESTING
+
+ Boolean value = (Boolean)
+ requestMsgContext.getAxisMessageContext().getProperty(Constants.SAVE_REQUEST_MSG);
+ if (value != null && value == Boolean.TRUE) {
+ // REVIEW: This does not properly account for attachments.
+ Message m = requestMsgContext.getMessage();
+ String savedMsg = m.getAsOMElement().toString();
+ requestMsgContext.getAxisMessageContext().setProperty(Constants.SAVED_REQUEST_MSG_TEXT, savedMsg);
+ }
+ }
+
+ /**
+ * Restore the request message from the saved message text
+ * @param requestMsgContext
+ */
+ private void restoreRequestMessage(MessageContext requestMsgContext) {
+
+ Boolean value = (Boolean)
+ requestMsgContext.getAxisMessageContext().getProperty(Constants.SAVE_REQUEST_MSG);
+ if (value != null && value == Boolean.TRUE) {
+ // REVIEW: This does not properly account for attachments.
+ String savedMsg = (String) requestMsgContext.getAxisMessageContext().getProperty(Constants.SAVED_REQUEST_MSG_TEXT);
+ if (savedMsg != null && savedMsg.length() > 0) {
+ try {
+ StringReader sr = new StringReader(savedMsg);
+ XMLStreamReader xmlreader = StAXUtils.createXMLStreamReader(sr);
+ MessageFactory mf = (MessageFactory)
+ FactoryRegistry.getFactory(MessageFactory.class);
+ Message msg = mf.createFrom(xmlreader);
+ requestMsgContext.setMessage(msg);
+ } catch (Throwable e) {
+ ExceptionFactory.makeWebServiceException(e);
+ }
+ }
+ }
+
+ // TESTING....SIMULATE A PERSIST OF THE REQUEST MESSAGE
+ // String text = requestMsgContext.getMessage().getAsOMElement().toString();
+ // System.out.println("Persist Message" + text);
+ // END TESTING
}
}
Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/Constants.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/Constants.java?view=auto&rev=507347
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/Constants.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/Constants.java Tue Feb 13 17:37:16 2007
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.spi;
+
+/**
+ * JAXWS SPI Constants
+ */
+public class Constants {
+
+ // ----------------------------
+ // MessageContext Property Keys
+ // ----------------------------
+
+ // Value = Boolean
+ // Usage: Setting this property to true will cause the entire request message
+ // to be saved and restored. A reliable messaging inbound handler should set
+ // this flag if the entire message should be saved. Setting this flag will substantially
+ // degrade performance.
+ //
+ // The default is to not save the entire message. After server dispatch processing, the
+ // body of the request message will not be available. This is acceptable in most scenarios.
+ //
+ // REVIEW Only honored on the server: Saved before inbound application handler processing and
+ // restored after outbound application handler processing.
+ //
+ public static final String SAVE_REQUEST_MSG = "org.apache.axis2.jaxws.spi.SAVE_REQUEST_MSG";
+
+ // Value = String
+ // Usage: Value of saved request
+ //
+ public static final String SAVED_REQUEST_MSG_TEXT = "org.apache.axis2.jaxws.spi.SAVED_REQUEST_MSG_TEXT";
+
+ /**
+ * Intentionally Private
+ */
+ private Constants() { }
+
+}
Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageTests.java?view=diff&rev=507347&r1=507346&r2=507347
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageTests.java Tue Feb 13 17:37:16 2007
@@ -758,13 +758,28 @@
assertTrue(newText.contains("Body"));
}
+ private final int NO_PERSIST = 0;
+ private final int PERSIST = 1;
+ private final int SAVE_AND_PERSIST = 2;
public void testJAXBInflow_soap11() throws Exception {
- _testJAXBInflow(sampleJAXBEnvelope11);
+ _testJAXBInflow(sampleJAXBEnvelope11, NO_PERSIST);
}
public void testJAXBInflow_soap12() throws Exception {
- _testJAXBInflow(sampleJAXBEnvelope12);
+ _testJAXBInflow(sampleJAXBEnvelope12, NO_PERSIST);
}
- public void _testJAXBInflow(String sampleJAXBEnvelope) throws Exception {
+ public void testJAXBInflow_soap11_withPersist() throws Exception {
+ _testJAXBInflow(sampleJAXBEnvelope11, PERSIST);
+ }
+ public void testJAXBInflow_soap12_withPersist() throws Exception {
+ _testJAXBInflow(sampleJAXBEnvelope12, PERSIST);
+ }
+ public void testJAXBInflow_soap11_withSaveAndPersist() throws Exception {
+ _testJAXBInflow(sampleJAXBEnvelope11, SAVE_AND_PERSIST);
+ }
+ public void testJAXBInflow_soap12_withSaveAndPersist() throws Exception {
+ _testJAXBInflow(sampleJAXBEnvelope12, SAVE_AND_PERSIST);
+ }
+ public void _testJAXBInflow(String sampleJAXBEnvelope, int persist) throws Exception {
// Create a SOAP OM out of the sample incoming XML. This
// simulates what Axis2 will be doing with the inbound message.
StringReader sr = new StringReader(sampleJAXBEnvelope);
@@ -784,6 +799,12 @@
assertTrue("XMLPart Representation is " + m.getXMLPartContentType(),
"OM".equals(m.getXMLPartContentType()));
+ String saveMsgText = "";
+ if (persist == SAVE_AND_PERSIST) {
+ // Simulate saving the message so that it can be fully rebuilt.
+ saveMsgText = m.getAsOMElement().toString();
+ }
+
// Get the BlockFactory
JAXBBlockFactory bf = (JAXBBlockFactory)
FactoryRegistry.getFactory(JAXBBlockFactory.class);
@@ -805,6 +826,17 @@
// Get the business object from the block, which should be a
// JAX-B object
Object bo = b.getBusinessObject(true);
+ m.setPostPivot();
+
+ // Simulate restoring the message
+ if (persist == SAVE_AND_PERSIST) {
+ sr = new StringReader(saveMsgText);
+ XMLStreamReader saveMsgReader = inputFactory.createXMLStreamReader(sr);
+ builder = new StAXSOAPModelBuilder(saveMsgReader, null);
+ omElement = builder.getSOAPEnvelope();
+ m = mf.createFrom(omElement);
+ }
+
// Check to make sure the right object was returned
assertNotNull(bo);
@@ -814,6 +846,22 @@
EchoStringResponse esr = (EchoStringResponse) bo;
assertNotNull(esr.getEchoStringReturn());
assertTrue(esr.getEchoStringReturn().equals("sample return value"));
+
+ // Simulate outbound
+ if (persist == PERSIST) {
+ String persistMsg = m.getAsOMElement().toString();
+ // We should be able to persist the message, but the persisted message WON'T contain the echoStringResponse contents
+ assertTrue(persistMsg.contains("Body"));
+ assertTrue(persistMsg.contains("echoStringResponse"));
+ assertTrue(!persistMsg.contains("sample return value"));
+
+ } else if (persist == SAVE_AND_PERSIST) {
+ String persistMsg = m.getAsOMElement().toString();
+ // We should be able to persist the message, and the persisted message WILL contain the echoStringResponse contents
+ assertTrue(persistMsg.contains("Body"));
+ assertTrue(persistMsg.contains("echoStringResponse"));
+ assertTrue(persistMsg.contains("sample return value"));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org