Hi
On 01/10/12 13:46, Voß, Marko wrote:
Hello Sergey,
well, we are talking about a case, when a client is sending wrong XML to a
service. Changing the concept of a service just because of that is way too much
I think. Our services look like this:
- CRUD operations for one resource this service is about (schema A)
- Retrieve sub-resources of this resource (schema A)
- Retrieve virtual resources related to this resource (one schema per virtual
resource)
- Perform tasks on this resource (one schema per task)
- (Special operations) (special schemas)
This concept is grown in history so changing all this because of this negative
scenario is not very nice.
I do not really understand, what is different with the concept of multiple
SchemaHandlers. Could you please explain this to me?
This allows you to have a single service implementation but select only
those schemas which can reliably validate that the wrong XML is sent for
a given type, as opposed to having a single set of schemas used to
validate the whole service
Cheers, Sergey
Best
-----Original Message-----
From: Sergey Beryozkin [mailto:[email protected]]
Sent: Tuesday, September 25, 2012 1:00 PM
To: [email protected]
Cc: Voß, Marko
Subject: Re: UnmarshalException instead of SchemaValidationException
After realizing we ship a SchemaHandler utility class (which just groups schema
locations and an optional catalogLocation plus a resulting
Schema) I proceeded with implementing the suggestion from Dan re
method/type-specific input validation, adding a Map<String,
SchemaHandler> was all that was needed...
Example, when a service wide validation does not work:
<bean id="handler1" class="org.apache.cxf.jaxrs.util.SchemaHandler">
<!-- set schemaLocations and, if needed, catalogLocation</bean>
<bean id="handler2" class="org.apache.cxf.jaxrs.util.SchemaHandler">
<!-- set schemaLocations and, if needed, catalogLocation</bean>
<bean id="jaxbProvider"
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<!-- link class names with individual handlers, using a schemaHandlers map property
--> </bean>
So if you have A and B classes requiring individual schemas, then use a
'schemaHandlers' property. Ideally, the refactoring (splitting the service into
multiple endpoints, etc) is preferred - but I guess that may not be easy in
some cases, especially when splitting affects the actual request URI, etc...
I have no much time to add more tests at the moment but I have a test where a
single SchemaHandler is shared between JAXB and JSON providers, so
SchemaHandler itself works, Marko if you can test the snapshots in a day or two
then it would be good too
Cheers, Sergey
On 20/09/12 17:28, Sergey Beryozkin wrote:
a would be ServiceB was wrongly typed, should be
@Path("/root/b")
public void ServiceB {
@POST
public B postB(B) {}
}
Sergey
On 20/09/12 17:26, Sergey Beryozkin wrote:
On 20/09/12 17:11, Daniel Kulp wrote:
On Sep 20, 2012, at 12:04 PM, "Voß,
Marko"<[email protected]> wrote:
I'll talk to the team tomorrow. Maybe the new behavior is
acceptable but I doubt that.
CXF just keeps a javax.xml.validation.Schema object around that
represents the schema for the entire service. We pass that into JAXB.
We don't have the ability to have a separate Schema object per
operation at this time. I'd be open for a patch for this, but quite
honestly, I'm not sure how the configuration for that would look.
You would need a way to configure a unique schema for each
operation/type which would result in a bunch of .xsd files, etc.
Indeed. May be one more option, if that is possible, to split the
original endpoint into two ones, say if we have
@Path("/root")
public void Service {
@Path("/a")
@POST
public A postA(A) {}
@Path("/b")
@POST
public B postA(B) {}
}
then it can be split into two endpoints. with each of them - having
unique schemas:
@Path("/root/a")
public void ServiceA {
@POST
public A postA(A) {}
}
@Path("/root/b")
public void ServiceB {
@Path("/b")
@POST
public B postA(B) {}
}
Cheers, Sergey
Dan
Best,
-----Original Message-----
From: Sergey Beryozkin [mailto:[email protected]]
Sent: Thursday, September 20, 2012 5:26 PM
To: Voß, Marko
Cc: [email protected]
Subject: Re: UnmarshalException instead of
SchemaValidationException
One more thing, after seeing a response from Dan in the other
thread,
Unmarshaller.Listener can also be registered with the provider, not
sure it can help in your case, but mentioning it just in case
Sergey
On 20/09/12 16:06, Sergey Beryozkin wrote:
On 20/09/12 15:48, Sergey Beryozkin wrote:
On 20/09/12 15:39, Voß, Marko wrote:
I guess I'm not understanding the problem well. You said earlier:
In a negative test, I send some XML to this service, which is
wrong XML for type A. Let's say the XML is of type B. The XML
passes the schema validation, because of it is valid for type B".
AFAIK, at the schema validation level, all JAXB does is ensures
the incoming XML is valid according to the schema, which it is
according to what you said earlier on.
In the old code of this service, the service validated the
incoming XML against the schema of the expected type.
In the example, the XML got validated against the schema of type
A, no matter what XML was incoming. I expected the same behavior
with CXF, since I define the expected type in the signature.
Unmarshalling is at the next stage, so if the previous stage
let 'B'
to come in then obviously the unmarshaller expecting it to be 'A'
throws UnmarshallException. I do not see how to make
SchemaValidationException thrown if the schema validation phase
passes...
I meant, that the schema validation phase should not pass,
because the wrong schema is being used right now.
Well, you have a schema document which is registered with the
JAXB provider so this is what is used to validate the incoming XML.
It should use the schema of the type defined in the signature
and not the schema, which fits to the incoming XML.
Is it possible in JAXB to configure Unmrashaller such that it
validates the incoming XML based on the information it obtains
while populating A, some kind of Java-based in validation ?
If yes we can do that
In fact this can probably be enforced at the custom
XMLStreamReader level.
What about this:
- register custom RequestHandler filter
- at that level we know the matching Method
- know, register the basic XMLStreamReader on the current message
(extending the CXF helper reader), initialized with the info
obtained from the Method or say from XmlType annotation on the relevant class).
If the root XML name is not matching the expectations - throw the
schema validation exception...
Not sure if it is something that will do in your case, but
technically it can be easily done, can provide more info if needed...
Cheers, Sergey
Cheers, Sergey
-----Original Message-----
From: Sergey Beryozkin [mailto:[email protected]]
Sent: Thursday, September 20, 2012 4:21 PM
To: Voß, Marko
Cc: [email protected]
Subject: Re: UnmarshalException instead of
SchemaValidationException
On 20/09/12 14:08, Voß, Marko wrote:
Hello,
I guess if a schema is open enough to accept either A or B
representations, then there's no bug.
That is not the case here.
I guess I'm not understanding the problem well. You said earlier:
In a negative test, I send some XML to this service, which is
wrong
XML for type A. Let's say the XML is of type B. The XML passes
the schema validation, because of it is valid for type B".
AFAIK, at the schema validation level, all JAXB does is ensures
the incoming XML is valid according to the schema, which it is
according to what you said earlier on.
Unmarshalling is at the next stage, so if the previous stage let 'B'
to come in then obviously the unmarshaller expecting it to be 'A'
throws UnmarshallException. I do not see how to make
SchemaValidationException thrown if the schema validation phase
passes...
I can see that Unmarshaller can also accept
ValidationEventHandler ("validationHandler" provider
property). Not sure if it can help - may be you can restrict it there somehow.
Well, we are using the schema validation setup this way already:
<bean name"myJaxbProvider" class="..."> <property
name="catalogLocation" value="..."/> <property
name="schemaLocations" value="..."> <list>
<value>classpath:/xsd/foo.xsd</value>
...
</list>
</property>
</bean>
So we have to setup the validation twice or remove this kind of
validation, we have been talking about lately, and use the
validationHandler instead?
I think ValidationEventHandler is there to complement the
validation set up, for the handler to get more info about the
validation process
May my using JAXBElement<A> instead of A is more restrictive,
can you try it ?
Tested this with no difference in the result.
OK...
Cheers, Sergey
Best,
-----Original Message-----
From: Sergey Beryozkin [mailto:[email protected]]
Sent: Thursday, September 20, 2012 2:27 PM
To: [email protected]
Cc: Voß, Marko
Subject: Re: UnmarshalException instead of
SchemaValidationException
Hi
On 20/09/12 13:02, Voß, Marko wrote:
Hello,
Say, we have a JAX-RS method like this:
@PUT
@Path("/foo")
@Produces(MediaType.TEXT_XML)
@Consumes(MediaType.TEXT_XML)
public static A create(A a);
In a negative test, I send some XML to this service, which is
wrong XML for type A. Let's say the XML is of type B. The XML
passes the schema validation, because of it is valid for type
B but this method expects type A and so we get a
UnmarshalException instead of the SchemaValidationException
complaining about the wrong element found.
Is it a bug, that the schema validation is not using the
schema for type A? It looks like it is using the schema, which
is responsible for the root element of the passed XML if found.
I guess if a schema is open enough to accept either A or B
representations, then there's no bug.
I can see that Unmarshaller can also accept
ValidationEventHandler ("validationHandler" provider property).
Not sure if it can help - may be you can restrict it there somehow.
May my using JAXBElement<A> instead of A is more restrictive,
can you try it ?
Cheers, Sergey
best,
-------------------------------------------------------
Fachinformationszentrum Karlsruhe, Gesellschaft für
wissenschaftlich-technische Information mbH.
Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht
Mannheim HRB 101892.
Geschäftsführerin: Sabine Brünger-Weilandt.
Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
-------------------------------------------------------
Fachinformationszentrum Karlsruhe, Gesellschaft für
wissenschaftlich-technische Information mbH.
Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht
Mannheim HRB 101892.
Geschäftsführerin: Sabine Brünger-Weilandt.
Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
-------------------------------------------------------
Fachinformationszentrum Karlsruhe, Gesellschaft für
wissenschaftlich-technische Information mbH.
Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht
Mannheim HRB 101892.
Geschäftsführerin: Sabine Brünger-Weilandt.
Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
-------------------------------------------------------
Fachinformationszentrum Karlsruhe, Gesellschaft für
wissenschaftlich-technische Information mbH.
Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht
Mannheim HRB 101892.
Geschäftsführerin: Sabine Brünger-Weilandt.
Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
-------------------------------------------------------
Fachinformationszentrum Karlsruhe, Gesellschaft für wissenschaftlich-technische
Information mbH.
Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht Mannheim HRB
101892.
Geschäftsführerin: Sabine Brünger-Weilandt.
Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com