diff -Naur ./main/java/org/jboss/ws/Constants.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/Constants.java --- ./main/java/org/jboss/ws/Constants.java 2006-11-15 16:49:24.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/Constants.java 2007-01-08 17:22:48.860528021 +0100 @@ -75,6 +75,10 @@ static final String URI_SOAP12_ENC = "http://www.w3.org/2003/05/soap-encoding"; /** Literal encoding URI */ static final String URI_LITERAL_ENC = ""; + /** WS-Eventing namespace uri **/ + static final String URI_WS_EVENTING = "http://schemas.xmlsoap.org/ws/2004/08/eventing"; + /** WS-Addressing namespace uri **/ + static final String URI_WS_ADDRESSING = "http://www.w3.org/2005/08/addressing"; /** WSDL 2.0 Encoding Rules */ static final String URI_STYLE_RPC = "http://www.w3.org/2004/03/wsdl/style/rpc"; static final String URI_STYLE_IRI = "http://www.w3.org/2004/03/wsdl/style/iri"; //represents doc @@ -254,9 +258,9 @@ /** Indicates that an output is a return parameter */ static final String WSDL_PROPERTY_RETURN_PART = "http://www.jboss.org/jbossws/return-part"; - static final QName WSDL_ATTRIBUTE_WSA_ACTION = new QName("http://www.w3.org/2005/08/addressing", "Action"); + static final QName WSDL_ATTRIBUTE_WSA_ACTION = new QName(URI_WS_ADDRESSING, "Action"); - static final QName WSDL_ATTRIBUTE_WSE_EVENTSOURCE = new QName("http://schemas.xmlsoap.org/ws/2004/08/eventing", "EventSource"); + static final QName WSDL_ATTRIBUTE_WSE_EVENTSOURCE = new QName(URI_WS_EVENTING, "EventSource"); /** WSDL-2.0 exchange patterns */ static final String WSDL20_PATTERN_IN_ONLY = "http://www.w3.org/2004/08/wsdl/in-only"; diff -Naur ./main/java/org/jboss/ws/deployment/MetaDataBuilder.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/deployment/MetaDataBuilder.java --- ./main/java/org/jboss/ws/deployment/MetaDataBuilder.java 2006-11-15 16:49:20.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/deployment/MetaDataBuilder.java 2007-01-08 17:55:49.089738191 +0100 @@ -30,6 +30,7 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -78,6 +79,11 @@ import org.jboss.ws.metadata.wsdl.WSDLInterfaceOperationOutfault; import org.jboss.ws.metadata.wsdl.WSDLProperty; import org.jboss.ws.metadata.wsdl.WSDLService; +import org.jboss.ws.metadata.wsdl.WSDLUtils; +import org.jboss.ws.metadata.wsdl.xmlschema.JBossXSModel; +import org.jboss.ws.metadata.wsdl.xmlschema.JBossXSNamespaceItem; +import org.jboss.ws.metadata.wsdl.xmlschema.JBossXSNamespaceItemList; +import org.jboss.ws.metadata.wsdl.xmlschema.JBossXSStringList; import org.jboss.ws.metadata.wsse.WSSecurityConfiguration; import org.jboss.ws.metadata.wsse.WSSecurityConfigurationFactory; import org.jboss.ws.server.ServiceEndpointManager; @@ -85,6 +91,7 @@ import org.jboss.ws.utils.ObjectNameFactory; import org.w3c.dom.Element; + /** An abstract meta data builder. * * @author Thomas.Diesler@jboss.org @@ -196,18 +203,43 @@ { ServerEndpointMetaData sepMetaData = (ServerEndpointMetaData)epMetaData; String eventSourceNS = wsdlInterface.getQName().getNamespaceURI() + "/" + wsdlInterface.getQName().getLocalPart(); - Object notificationSchema = null; // todo: resolve schema from operation message - + + JBossXSModel schemaModel = WSDLUtils.getSchemaModel(wsdlDefinitions.getWsdlTypes()); + String notificationRootElementNS = wsdlInterface.getOperations()[0].getOutputs()[0].getElement().getNamespaceURI(); + String[] notificationSchema = this.extractNotificationSchema(schemaModel); + EventingEpMetaExt ext = new EventingEpMetaExt(EventingConstants.NS_EVENTING); ext.setEventSourceNS(eventSourceNS); ext.setNotificationSchema(notificationSchema); + ext.setNotificationRootElementNS(notificationRootElementNS); sepMetaData.addExtension(ext); sepMetaData.setManagedEndpointBean(EventingEndpoint.class.getName()); } } } - + + private String[] extractNotificationSchema(JBossXSModel schemaModel) { + List list = ((JBossXSStringList)schemaModel.getNamespaces()).toList(); + List schemas = new LinkedList(); + for (Iterator it = list.iterator(); it.hasNext(); ) { + String ns = (String)it.next(); + if (!Constants.URI_SOAP11_ENC.equalsIgnoreCase(ns) && + !Constants.NS_SCHEMA_XSI.equalsIgnoreCase(ns) && + !Constants.NS_SCHEMA_XSD.equalsIgnoreCase(ns) && + !Constants.URI_WS_EVENTING.equalsIgnoreCase(ns) && + !Constants.URI_WS_ADDRESSING.equalsIgnoreCase(ns)) { + JBossXSNamespaceItem item = schemaModel.getNamespaceItem(ns); + boolean qElem = item.isQualifiedElements(); + item.setQualifiedElements(true); + schemas.add(item.toString()); + item.setQualifiedElements(qElem); + } + } + return (String[])schemas.toArray(new String[schemas.size()]); + } + + protected ObjectName getServiceEndpointID(UnifiedDeploymentInfo udi, ServerEndpointMetaData sepMetaData) { String endpoint = sepMetaData.getLinkName(); diff -Naur ./main/java/org/jboss/ws/eventing/deployment/EventingEndpointDI.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/deployment/EventingEndpointDI.java --- ./main/java/org/jboss/ws/eventing/deployment/EventingEndpointDI.java 2006-11-15 16:49:34.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/deployment/EventingEndpointDI.java 2007-01-08 12:53:41.548830177 +0100 @@ -17,18 +17,20 @@ private String name; /* notification schema */ - private Object schema; + private String[] schema; + private String notificationRootElementNS; - private Element schemaElement; +// private Element schemaElement; private String portName; // event source endpoint address private String endpointAddress; - public EventingEndpointDI(String name, Object schema) { + public EventingEndpointDI(String name, String[] schema, String notificationRootElementNS) { this.name = name; this.schema = schema; + this.notificationRootElementNS = notificationRootElementNS; } public String getPortName() { @@ -43,7 +45,7 @@ return name; } - public Object getSchema() { + public String[] getSchema() { return schema; } @@ -55,18 +57,26 @@ this.endpointAddress = endpointAddress; } - Element getSchemaElement() { - try - { - if(null == this.schemaElement) - this.schemaElement = DOMUtils.parse((String)getSchema()); - } - catch (IOException e) - { - throw new IllegalArgumentException("Failed to parse notification schema:" +e.getMessage()); - } - - return this.schemaElement; - } +// Element getSchemaElement() { +// try +// { +// if(null == this.schemaElement) +// this.schemaElement = DOMUtils.parse((String)getSchema()); +// } +// catch (IOException e) +// { +// throw new IllegalArgumentException("Failed to parse notification schema:" +e.getMessage()); +// } +// +// return this.schemaElement; +// } + + public String getNotificationRootElementNS() { + return notificationRootElementNS; + } + + public void setNotificationRootElementNS(String notificationRootElementNS) { + this.notificationRootElementNS = notificationRootElementNS; + } } diff -Naur ./main/java/org/jboss/ws/eventing/deployment/EventingEndpoint.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/deployment/EventingEndpoint.java --- ./main/java/org/jboss/ws/eventing/deployment/EventingEndpoint.java 2006-11-15 16:49:46.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/deployment/EventingEndpoint.java 2007-01-08 12:31:35.540270456 +0100 @@ -44,7 +44,7 @@ // See also http://jira.jboss.org/jira/browse/JBWS-770 // create pending incomplete event source - EventingEndpointDI desc = new EventingEndpointDI(ext.getEventSourceNS(), ext.getNotificationSchema()); + EventingEndpointDI desc = new EventingEndpointDI(ext.getEventSourceNS(), ext.getNotificationSchema(), ext.getNotificationRootElementNS()); desc.setEndpointAddress(epMetaData.getEndpointAddress()); desc.setPortName(epMetaData.getPortComponentName()); diff -Naur ./main/java/org/jboss/ws/eventing/DispatchException.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/DispatchException.java --- ./main/java/org/jboss/ws/eventing/DispatchException.java 1970-01-01 01:00:00.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/DispatchException.java 2007-01-05 23:24:53.447045360 +0100 @@ -0,0 +1,14 @@ +package org.jboss.ws.eventing; + +import org.jboss.ws.WSException; + +public class DispatchException extends WSException { + + public DispatchException() { + super(); + } + + public DispatchException(String message) { + super(message); + } +} diff -Naur ./main/java/org/jboss/ws/eventing/metadata/EventingEpMetaExt.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/metadata/EventingEpMetaExt.java --- ./main/java/org/jboss/ws/eventing/metadata/EventingEpMetaExt.java 2006-11-15 16:49:30.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/metadata/EventingEpMetaExt.java 2007-01-08 12:52:11.550213159 +0100 @@ -15,7 +15,8 @@ private boolean isEventSource = true; private String eventSourceNS; - private Object notificationSchema; + private String[] notificationSchema; + private String notificationRootElementNS; public EventingEpMetaExt(String extensionNameSpace) { super(extensionNameSpace); @@ -49,11 +50,19 @@ } } - public Object getNotificationSchema() { + public String[] getNotificationSchema() { return notificationSchema; } - public void setNotificationSchema(Object notificationSchema) { + public void setNotificationSchema(String[] notificationSchema) { this.notificationSchema = notificationSchema; } + + public String getNotificationRootElementNS() { + return notificationRootElementNS; + } + + public void setNotificationRootElementNS(String notificationRootElementNS) { + this.notificationRootElementNS = notificationRootElementNS; + } } diff -Naur ./main/java/org/jboss/ws/eventing/mgmt/EventingBuilder.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/mgmt/EventingBuilder.java --- ./main/java/org/jboss/ws/eventing/mgmt/EventingBuilder.java 2006-11-15 16:49:38.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/mgmt/EventingBuilder.java 2007-01-08 12:37:08.694446320 +0100 @@ -22,7 +22,7 @@ public EventSource newEventSource(EventingEndpointDI desc) { URI eventSourceNS = newEventSourceURI(desc.getName()); - EventSource eventSource = new EventSource(desc.getName(), eventSourceNS, (String)desc.getSchema()); + EventSource eventSource = new EventSource(desc.getName(), eventSourceNS, desc.getSchema(), desc.getNotificationRootElementNS()); eventSource.getSupportedFilterDialects().add(EventingConstants.getDefaultFilterDialect()); return eventSource; } diff -Naur ./main/java/org/jboss/ws/eventing/mgmt/EventSource.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/mgmt/EventSource.java --- ./main/java/org/jboss/ws/eventing/mgmt/EventSource.java 2006-11-15 16:49:34.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/mgmt/EventSource.java 2007-01-08 12:51:43.847024890 +0100 @@ -44,7 +44,8 @@ private String name; private URI nameSpace; - private String notificationSchema; + private String[] notificationSchema; + private String notificationRootElementNS; private URI managerAddress; private List supportedFilter = new ArrayList(); @@ -55,11 +56,12 @@ this.state = State.CREATED; } - public EventSource(String name, URI nameSpace, String schema) + public EventSource(String name, URI nameSpace, String[] schema, String notificationRootElementNS) { this.name = name; this.nameSpace = nameSpace; this.notificationSchema = schema; + this.notificationRootElementNS = notificationRootElementNS; this.state = State.CREATED; } @@ -97,7 +99,7 @@ return supportedFilter; } - public String getNotificationSchema() { + public String[] getNotificationSchema() { return notificationSchema; } @@ -128,4 +130,8 @@ { return "EventSource {" + "nameSpace=" + nameSpace + ", state=" + state + "}"; } + + public String getNotificationRootElementNS() { + return notificationRootElementNS; + } } diff -Naur ./main/java/org/jboss/ws/eventing/mgmt/SubscriptionManager.java /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/mgmt/SubscriptionManager.java --- ./main/java/org/jboss/ws/eventing/mgmt/SubscriptionManager.java 2006-11-15 16:49:30.000000000 +0100 +++ /dati/jbossws-src-1.0.4.GA/src/main/java/org/jboss/ws/eventing/mgmt/SubscriptionManager.java 2007-01-08 20:56:19.188211824 +0100 @@ -26,20 +26,34 @@ import org.jboss.logging.Logger; import org.jboss.util.naming.Util; import org.jboss.ws.WSException; +import org.jboss.ws.eventing.DispatchException; import org.jboss.ws.eventing.EventingConstants; import org.jboss.ws.eventing.deployment.EventingEndpointDI; import org.jboss.ws.eventing.element.EndpointReference; import org.jboss.ws.eventing.element.ReferenceParameters; +import org.jboss.ws.utils.DOMUtils; +import org.jboss.ws.utils.DOMWriter; import org.jboss.ws.utils.ObjectNameFactory; import org.jboss.ws.utils.UUIDGenerator; import org.w3c.dom.Element; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import com.sun.org.apache.xml.internal.utils.DefaultErrorHandler; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.ObjectName; import javax.naming.InitialContext; import javax.naming.NamingException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + import java.io.PrintWriter; +import java.io.StringReader; import java.io.StringWriter; import java.net.URI; import java.net.URISyntaxException; @@ -78,6 +92,11 @@ private static final Logger log = Logger.getLogger(SubscriptionManager.class); private long MAX_LEASE_TIME = 1000 * 60 * 10L; public long DEFAULT_LEASE = 1000 * 60 * 5L; + + /** + * True force validation of every notification message against its schema + */ + private boolean validateNotifications = false; public static final ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.ws:service=SubscriptionManager,module=eventing"); @@ -455,12 +474,71 @@ public void dispatch(URI eventSourceNS, Element payload) { DispatchJob dispatchJob = new DispatchJob(eventSourceNS, payload, subscriptionMapping); + if (validateNotifications && !this.validateMessage(DOMWriter.printNode(payload,false),eventSourceNS)) { + throw new DispatchException("Notification message validation failed!"); + } threadPool.execute(dispatchJob); } - + + private boolean validateMessage(String msg, URI eventSourceNS) { + try { + EventSource es = eventSourceMapping.get(eventSourceNS); + log.info(new StringBuffer("Validating message: \n\n").append(msg) + .append("\n\nagainst the following schema(s): \n").toString()); + for (int i=0;i