I need to create a Mock Service for EWS and I have gotten hold of the WSDL file and .XSD from the Exchange server endpoint (I am logged with my credentials)
https://outlook.office365.com/EWS/Services.wsdl
https://outlook.office365.com/EWS/Messages.xsd
https://outlook.office365.com/EWS/Types.xsd
I have created a project in SOAP UI and when I generated a Mock Service only the following WSDL operations's responses are mocked:
AddDelegate
AddDistributionGroupToImList
AddImContactToGroup
AddImGroup
AddNewImContactToGroup
AddNewTelUriContactToGroup
AddTag
At a closer look and testing the validity of the WSDL as well as the .XSDs, the following errors are highlighted:
Services.wsdl: "
Referenced file contains errors (file:/pathToFile/types.xsd).
I then look at the error in types.xsd and it seems to point to the attribute in:
<xs:complexType name="ReplyBody">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Message" type="xs:string"/>
</xs:sequence>
<xs:attribute ref="xml:lang" use="optional"/>
</xs:complexType>
with the following error message (I am validating within Eclipse Neon):
Multiple annotations found at this line:
- s4s-elt-invalid-content.1: The content of 'ReplyBody' is invalid. Element 'attribute' is invalid, misplaced, or occurs too often.
- src-resolve: Cannot resolve the name 'xml:lang' to a(n) 'attribute declaration' component.
I have tried to remove that attribute, but the issue remains. Am I missing anything obvious?
Can you please help?
Thanks,
I.
EDIT 1
My main concern is that I am possibly going completely wrong in the way I am getting hold of the EWS WSDL and schemas. Is that the right way to do it?
EDIT 2
I have also try to import the WSDL directly from the URL and I am returned with the same missing operations.
Related
I implemented a working web service using CXF (2.7.1) with a WSDL & XSD that include, among other things, the following type:
<xs:simpleType name="SimpleIdType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Za-z0-9:\.\-]{20}"/>
</xs:restriction>
</xs:simpleType>
I interpret this to be: Accept only 20 character strings which only contain alphanumeric characaters and ':', '.' and '-'.
When I send a SOAP message to my web service with the corresponding element containing FAAAAAAAAAAAAAAAAAAA, the service of course accepts properly without any error.
However, if I send an identical SOAP message with the # instead of F (i.e. #AAAAAAAAAAAAAAAAAAA), the service still accepts the message, without issuing any validation error (unmarshalling or otherwise).
Why?
Isn't the default ValidationEventHandler supposed to handle that by throwing an "Unmarshalling Error"?
The JAXB model (generated or hand coded) does not contain all the metadata from the XML schema in its annotations. If you want to validate against all aspects of the schema you can enable this be specifying an instance of Schema on the Unmarshaller.
http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html
I finally found the correct answer for this CXF-based case.
CXF already has runtime schema validation built-in. It is named schema validation via configuration and the only thing that was missing in my code was the XML to enable it, inside the already existing <jaxws:endpoint element in beans.xml AKA application-context.xml:
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
This discovery was made possible thanks to the answer by #Patrick.
I'm currently working with the Dynamics CRM 4.0 webservice. First thing I did, was generating the right classes with wsimport for Java/JAX-WS based on the WSDL of the webservice. While generating the classes I got some errors:
[ERROR] A class/interface with the same name
"com.microsoft.schemas.crm._2007.webservices.RetrieveResponse" is already in use. Use a class customization to resolve this conflict.
line 979 of file://src/main/webapp/WEB-INF/classes/META-INF/wsdl/CrmServiceWsdl.wsdl
[ERROR] (Relevant to above error) another "RetrieveResponse" is generated from here.
line 12274 of file://src/main/webapp/WEB-INF/classes/META-INF/wsdl/CrmServiceWsdl.wsdl
Line 979 tells us:
<s:element name="RetrieveResponse">
<s:complexType>
<s:sequence>
<s:element name="RetrieveResult" type="s3:BusinessEntity" />
</s:sequence>
</s:complexType>
</s:element>
And line 12274 gives us:
<s:complexType name="RetrieveResponse">
<s:complexContent mixed="false">
<s:extension base="tns:Response">
<s:sequence>
<s:element ref="s3:BusinessEntity" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
Both parts are in the same namespace. Both will be generated as RetrieveResponse.class and so they are colliding. I've found a solution for this problem which is the JAX-B binding xml file:
<bindings node="//xsd:complexType[#name='RetrieveResponse']">
<jaxb:class name="RetrieveResponseType"/>
</bindings>
This works (not sure if this is the correct approach..?)..
So after this, I've managed to create some successful calls to the webservice, which is great!
Now comes the problem: some business entities in dynamics crm uses the class Picklist. This type of entity can be queried with the Metadata service: http://msdn.microsoft.com/en-us/library/bb890248.aspx
So the next thing I did was, again, generating the classes for the metadata service, based on it's WSDL. The result of the generated classes are not as we except. For example, it generates a class 'com.microsoft.schemas.crm._2007.webservices.ExecuteResponse'. But this class also exists in the exact same package of the CrmService generated classes. Differences between the 2 are:
Metadataservice ExecuteReponse:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"response"
})
#XmlRootElement(name = "ExecuteResponse")
public class ExecuteResponse {
#XmlElement(name = "Response")
protected MetadataServiceResponse response;
etc...
CrmService ExecuteReponse:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"response"
})
#XmlRootElement(name = "ExecuteResponse")
public class ExecuteResponse {
#XmlElement(name = "Response", required = true)
protected ResponseType response;
etc...
Now this class is just one example (another example is CrmAuthenticationToken), which is a almost exact duplicate of another class. To be able to use the same classes, I've added a package-suffix to the CrmService classes (displayed as prefix.).
So now when I try to call the CrmService, I get the following exception:
Two classes have the same XML type name "{http://schemas.microsoft.com/crm/2007/CoreTypes}CrmAuthenticationToken". Use #XmlType.name and #XmlType.namespace to assign different names to them.
this problem is related to the following location:
at com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken
at public com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken *prefix*.com.microsoft.schemas.crm._2007.coretypes.ObjectFactory.createCrmAuthenticationToken()
at *prefix*.com.microsoft.schemas.crm._2007.coretypes.ObjectFactory
this problem is related to the following location:
at *prefix*.com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken
at public javax.xml.bind.JAXBElement *prefix*.com.microsoft.schemas.crm._2007.webservices.ObjectFactory.createCrmAuthenticationToken(*prefix*.com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken)
at *prefix*.com.microsoft.schemas.crm._2007.webservices.ObjectFactory
I personally think it's weird they put different classes with the same name in the same package structure. This means you can never use the 2 webservices at the same time..
Is this a Microsoft, a WSimport bug or just a stupid mistake at my end? Hope somebody can help me with this problem!
Thanks for your time!
This is Microsoft inconsistency combined with wsimport being somewhat hard to use.
The PickList and the CRMAuthenticationToken sound like custom datatypes, you'd expect for these to get reused from service to service.
You'd also expect certain CRM-specific entities (say, Customer or Business or Address) to get reused from service to service.
It is bad manners on the Microsoft side of things that they define these differently for different services. This makes it hard to take the answer of one service and send it on to another service.
Had the services shared one or more common schemas, you could've compiled those first, using xjc. Then you could've provided a so-called episode file to wsimport to tell it to use those classes instead of generating new ones. See the metro guide. This is quite a puzzle, I can tell you from experience, I ran into bug JAXB-829, xjc forgets to generate if-exists attributes in the episode file.
What I'd do, I'd compile each wsdl to its own package and treat the generated classes as simple unintelligent Data Transfer Objects.
If I wanted to send an object I'd just retrieved from one service on to a second service, I'd convert between the both.
If this results in terribly unwieldy code, or if you wish to add logic to certain entities, I'd suggest you write your own proper model classes for the Entities you wish to share and write converters to and from the DTO objects in the web services packages you wish to use them with.
The default for minOccurs property of an <element> in an XSD file is 1 (source).
Consider you have an XSD specifying a complex type containing 2 elements: <el1> and <el2>.
If you provide an XDocument only containing <el2>, the XDocument will not validate.
Instead you'll get the message:
The element Message in namespace ___ has invalid child element el2 in namespace ___.
List of possible elements expected: el1
This basically is an error on <el2> where one would expect an error on the complex type for not containing <el1>.
My question is:
Is there a way to check if all <element>-tags which have minOccurs > 0 are present?
I would say this is a very basic check when validating XML with an XSD.
Depending on the way you defined your schema, the order of appearance of elements will matter.
In this case the validator is expecting a <el1> but is seeing the element <el2> so the error is that <el2> is appearing where it should not. I belive that means you used a "sequence" when defining your complex type. So the error you at getting is correct.
If this still bothers you, and the order of the elements does not matter to your parsing use "all" instead of "sequence" which will not enforce order. The validator should then prompt you that a required element <el1> is missing. It should look something like the following:
<xsd:complexType name="MyType">
<xsd:all>
<xsd:element name="el1" minOccurs="1"/>
<xsd:element name="el2" minOccurs="1"/>
</xsd:all>
</xsd:complexType>
I hope this helps.
I'm using JAXB 2.1.10 from Sun's JDK 1.6.0_18:
D:\apps\jdk160_18\bin>xjc.exe -version
xjc version "JAXB 2.1.10 in JDK 6"
JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.10 in JDK 6)
I need to have JAXB's marshaller produce an empty element (e.g. <someStringField></someStringField> or <someStringField/>) when the JAXB object has the value of the empty string (""). However, rather than doing that, JAXB omits the element altogether from its output (as if it where an optional element).
My searches in the Internet indicated that JAXB should normally create this tag, as long as you set the field to the non-null empty string (i.e. myJAXBObject.setSomeStringField(""); ):
How to instantiate an empty element with JAXB
https://jaxb.dev.java.net/tutorial/section_2_2_12_8-No-Value.html#No%20Value
In my XSD, I've tried to indicate (in every way I know) that the element's presence is mandatory even if it is empty:
<xs:element name="outerElement">
<xs:complexType>
<xs:sequence>
<xs:element name="someStringField" type="xs:string" nillable="false" minOccurs="1" />
<xs:element name="someOtherStringField" type="xs:string" />
The generated code looks like this (it's the same for both elements):
#XmlElement(name = "someStringField", required = true)
protected String someStringField;
#XmlElement(name = "someOtherStringField", required = true)
protected String someOtherStringField;
However, when I marshal the following object...
outerElement.setSomeStringField("");
outerElement.setSomeOtherStringField("Value was set");
I get:
<outerElement>
<someOtherStringField>Value was set</someOtherStringField>
</outerElement>
When I was expecting:
<outerElement>
<someStringField></someStringField>
<someOtherStringField>Value was set</someOtherStringField>
</outerElement>
Or:
<outerElement>
<someStringField/>
<someOtherStringField>Value was set</someOtherStringField>
</outerElement>
Can anyone spot what I'm doing wrong?
Thank you for bringing this issue (https://bugs.eclipse.org/319028) to our attention. The bug has been fixed and will be included in the EclipseLink 2.1.1 maintenance release. If you want access to this fix earlier you can pick up the nightly download starting July 8th from:
http://www.eclipse.org/eclipselink/downloads/nightly.php
Apologies. I THOUGHT I was using JAXB from Sun's JDK, but I wasn't. There was a left-over jaxb.properties in my classes/ folder that was created by JDeveloper when I generated the bindings. I was actually using JAXB2.0 from EclipseLink/MOXy.
Removing the properties file allowed JAXB2.1 to be used and fixed my issue.
I have a .xsd file which I use to generate code with the xsd.exe tool from Visual Studio.
Some class members are Guids and the xsd.exe tool gives 2 warnings:
Namespace 'http://microsoft.com/wsdl/types/' is not available to be referenced in this schema.
Type 'http://microsoft.com/wsdl/types/:guid' is not declared.
The Guid type is recognized because the generated C# file is valid and works.
Anyone knows how to get rid of those warnings?
What is the correct syntax for the XSD to be validated AND class members being generated as System.Guid?
Thank you all,
I found how to remove the warnings.
As sysrqb said, the wsdl namespace has either been deleted or never existed. It seems that the xsd.exe tool knows the Guid definition internally, but it cannot validate the xsd schema.
As boj pointed out, the only way to validate the schema with Guids in it, is to (re)define that type in a schema. The trick here is to add the Guid type to the same "http://microsoft.com/wsdl/types" namespace. This way, the xsd.exe will do the proper association between http://microsoft.com/wsdl/types:Guid and System.Guid
I made a new xsd file for the guid type:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://microsoft.com/wsdl/types/" >
<xs:simpleType name="guid">
<xs:annotation>
<xs:documentation xml:lang="en">
The representation of a GUID, generally the id of an element.
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:pattern value="\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\}"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Then, I run xsd.exe with both my original xsd file and this new xsd file:
xsd.exe myschema.xsd guid.xsd /c
Citation from here:
XmlSchema guidSchema = new XmlSchema();
guidSchema.TargetNamespace = "http://microsoft.com/wsdl/types/";
XmlSchemaSimpleTypeRestriction guidRestriction = new XmlSchemaSimpleTypeRestriction();
guidRestriction.BaseTypeName = new XmlQualifiedName("string", XmlSchema.Namespace);
XmlSchemaPatternFacet guidPattern = new XmlSchemaPatternFacet();
guidPattern.Value = #"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
guidRestriction.Facets.Add(guidPattern);
XmlSchemaSimpleType guidType = new XmlSchemaSimpleType();
guidType.Name = "guid";
guidType.Content = guidRestriction;
guidSchema.Items.Add(guidType);
schemaSet.Add(guidSchema);
XmlSchema speakerSchema = new XmlSchema();
speakerSchema.TargetNamespace = "http://www.microsoft.com/events/teched2005/";
// ...
XmlSchemaElement idElement = new XmlSchemaElement();
idElement.Name = "ID";
// Here's where the magic happens...
idElement.SchemaTypeName = new XmlQualifiedName("guid", "http://microsoft.com/wsdl/types/");
It looks like that wsdl namespace extension page was deleted, so it can't find the type information you need.