Hi Sergey, Okay I understand. :)
Is this available in the current snapshot? Thanks -----Original Message----- From: Sergey Beryozkin [mailto:[email protected]] Sent: Monday, October 01, 2012 5:19 PM To: Voß, Marko Cc: [email protected] Subject: Re: UnmarshalException instead of SchemaValidationException Hi On 01/10/12 15:22, Voß, Marko wrote: > Hi Sergey, > > I am a bit confused now... so I should create one SchemaHandler per schema > then? > The original problem is that you have a set of schemas validating the incoming XML for all of the service and thus this wide-enough schema accepts A whereas it should actually be only B that can be accepted in scope of the current request. Thus, one option is to split the endpoint into multiple ones and have a 'stricter' schema validation on per-endpoint basis. If this option is not acceptable then another option is to group the schemas such that only a subset of all the schemas is used to validate a current request. SchemaHolder is just a utility that groups a collection of schema references, it does not have to be a single SchemaHolder per every single schema document. Example: @Path("/service") class MyServiceEvolvedOverTime { @POST @Path("/a") // original method public void postA(A a) { } @POST @Path("/b") // newly added method public void postB(B a) { } } When you have a set of schemas validating all the service it is not possible to block the schemas from 'accepting' A for request URIs ending with "/b". One option is to split into multiple endpoints. Another one, register a map property linking specific schemas with types... However if your schema has both A & B in the same target namespace then neither of the options will work to get SchemaValidationException instead of UnmarshalException Does it make sense ? Sergey > > > -----Original Message----- > From: Sergey Beryozkin [mailto:[email protected]] > Sent: Monday, October 01, 2012 3:11 PM > To: Voß, Marko > Cc: [email protected] > Subject: Re: UnmarshalException instead of SchemaValidationException > > 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 > > > ------------------------------------------------------- > > 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.
