Changes for page Web Services-Problems

Last modified by Francis Labrie on 2007/10/15 16:21

From version 2.1
edited by Pascal Robert
on 2007/09/03 19:32
Change comment: There is no comment for this version
To version 10.1
edited by Francis Labrie
on 2007/10/15 16:21
Change comment: Migrated to Confluence 5.3

Summary

Details

Page properties
Parent
... ... @@ -1,0 +1,1 @@
1 +Web Services
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.probert
1 +XWiki.flabrie
Content
... ... @@ -1,3 +1,17 @@
1 +|=(((
2 +Contents
3 +)))
4 +|(((
5 +{{section}}
6 +1. [[#Problems>>doc:||anchor="Problems"]]
7 +11. [[#DirectToWebService can't return a WSDL with secure HTTPS references in it>>doc:||anchor="DirectToWebService can't return a WSDL with secure HTTPS references in it"]]
8 +11. [[#SOAP serializers and deserializers registered with ~~{~~{WOWebServiceRegistrar}} class doesn't appear in the WSDL schema>>doc:||anchor="SOAP serializers and deserializers registered with {{WOWebServiceRegistrar}} class doesn't appear in the WSDL schema"]]
9 +11. [[#DirectToWebService can't return a WSDL with custom namespace and definitions name in it>>doc:||anchor="DirectToWebService can't return a WSDL with custom namespace and definitions name in it"]]
10 +11. [[#WOWebServiceClient class can't connect to a server that requires an authentication>>doc:||anchor="WOWebServiceClient class can't connect to a server that requires an authentication"]]
11 +11. [[#Web Services can't return a WSDL with secure HTTPS references specifying port other than the default 443>>doc:||anchor="Web Services can't return a WSDL with secure HTTPS references specifying port other than the default 443"]]
12 +{{/section}}
13 +)))
14 +
1 1  = Problems =
2 2  
3 3  This section describes some problems and bugs that sometimes occur when using //WebObjects Web Services//.
... ... @@ -4,27 +4,17 @@
4 4  
5 5  == DirectToWebService can't return a WSDL with secure HTTPS references in it ==
6 6  
7 - **Authors:** Francis Labrie
8 -
21 +**Authors:** Francis Labrie
9 9   **Affected products:** //WebObjects// 5.2.x, 5.3.x
23 + **Bug reference:** [[rdar:~~/~~/3546304>>url:rdar://3546304||shape="rect"]]
10 10  
11 - **Bug reference:** rdar:~/~/3546304
12 -
13 13  === Problem: ===
14 14  
15 -A //DirectToWebService// defined Web Services doesn't return correct WSDL document, even if the correct procedure (see Secure Web Services) is followed. So only classes oriented Web Services manually registered with the
27 +A //DirectToWebService// defined Web Services doesn't return correct WSDL document, even if the correct procedure (see [[doc:WO.Secure Web Services]]) is followed. So only classes oriented Web Services manually registered with the {{code language="none"}}com.webobjects.appserver.WOWebServiceRegistrar{{/code}} class seems to generate a correct WSDL.
16 16  
17 -{{code}}
18 -
19 -com.webobjects.appserver.WOWebServiceRegistrar
20 -
21 -{{/code}}
22 -
23 -class seems to generate a correct WSDL.
24 -
25 25  === Solution: ===
26 26  
27 -Darel Lee from Apple told me that right now, the dynamic WSDL generation is not exposed to developers so there currently isn't a clean solution to perform this. One workaround is to hardcode rules (ofcom.webobjects.directtoweb.Assignment type) with the serviceLocationURL key for each operation that you want to use secure HTTPS references. For instance:
31 +Darel Lee from Apple told me that right now, the dynamic WSDL generation is not exposed to developers so there currently isn't a clean solution to perform this. One workaround is to hardcode rules (of {{code language="none"}}com.webobjects.directtoweb.Assignment{{/code}} type) with the {{code language="none"}}serviceLocationURL{{/code}} key for each operation that you want to use secure HTTPS references. For instance:
28 28  
29 29  {{code}}
30 30  
... ... @@ -42,15 +42,15 @@
42 42  
43 43  {{/code}}
44 44  
45 -=== SOAP serializers and deserializers registered with WOWebServiceRegistrar class doesn't appear in the WSDL schema ===
49 +== SOAP serializers and deserializers registered with {{code language="none"}}WOWebServiceRegistrar{{/code}} class doesn't appear in the WSDL schema ==
46 46  
47 -Authors:Francis Labrie
48 -Affected products:WebObjects5.2.x, 5.3.x
49 -Bug reference:rdar:~/~/3546330
51 +**Authors:** Francis Labrie
52 + **Affected products:** //WebObjects// 5.2.x, 5.3.x
53 + **Bug reference:** [[rdar:~~/~~/3546330>>url:rdar://3546330||shape="rect"]]
50 50  
51 -==== Problem: ====
55 +=== Problem: ===
52 52  
53 -Custom SOAP serializers and deserializers registered to Web Services with com.webobjects.appserver.WOWebServiceRegistrar class are never added to the types / schema definition of the WSDL. The only type definitions shown are the following:
57 +Custom SOAP serializers and deserializers registered to Web Services with {{code language="none"}}com.webobjects.appserver.WOWebServiceRegistrar{{/code}} class are never added to the types / schema definition of the WSDL. The only type definitions shown are the following:
54 54  
55 55  {{code}}
56 56  
... ... @@ -90,27 +90,43 @@
90 90  
91 91  {{/code}}
92 92  
93 -==== Solution: ====
97 +=== Solution: ===
94 94  
95 -I don't know any dynamic workaround right now... But a static and complete WSDL can be shared through a direct action. It's not very handy though...
99 +You must know that all complexe data types referred in operations will be added to the WSDL types definition. But if a complexe type makes references to others complexe types, you should make sure you add proper calls in the {{code language="none"}}writeSchema(Types){{/code}} method of the class serializer. For example:
96 96  
97 -=== DirectToWebService can't return a WSDL with custom namespace and definitions name in it ===
101 +{{code}}
98 98  
99 -Authors:Francis Labrie
100 -Affected products:WebObjects5.2.x, 5.3.x
101 -Bug reference:
103 +public boolean writeSchema(Types types)
104 +throws Exception {
105 + ...
106 + // Add type for Foo
107 + String prefixedName = types.writeType(Foo.class, _FooQName);
108 + ...
102 102  
103 -==== Problem: ====
110 + return true;
111 +}
104 104  
113 +{{/code}}
114 +
115 +Unfortunately, I don't know a dynamic workaround for all possible cases right now. At least a static and complete WSDL can be shared through a direct action, but it's not very handy though...
116 +
117 +== DirectToWebService can't return a WSDL with custom namespace and definitions name in it ==
118 +
119 +**Authors:** Francis Labrie
120 + **Affected products:** //WebObjects// 5.2.x, 5.3.x
121 + **Bug reference:**
122 +
123 +=== Problem: ===
124 +
105 105  A //DirectToWebService// defined Web Services can't return a WSDL with custom values for properties like namespaces and definitions name. Worse, the generated namespace can even contains WebObjects application instance number or the wrong hostname.
106 106  
107 -==== Solution: ====
127 +=== Solution: ===
108 108  
109 -Base on a tips from Darel Lee, I've found in the com.webobjects.webservices.generation.//private.WOWSDLTemplate class some extras key definitions read from the user.d2wmodel DirectToWebService rule file. For instance~://
129 +Base on a tips from Darel Lee, I've found in the {{code language="none"}}com.webobjects.webservices.generation._private.WOWSDLTemplate{{/code}} class some extras key definitions read from the {{code language="none"}}user.d2wmodel{{/code}} //DirectToWebService// rule file. For instance:
110 110  
111 111  * **serviceLocationURL:** a key that allow the setting of the location URL for an operation. This is usefull if you need your WebServices to be reached using a secure HTTPS reference;
112 112  * **WSDLDefinitionName:** a key that allow the definitions name change. So instead of having "ServiceNameDefinition", you can set this value;
113 -* **WSDLTargetNamespace:** a key that allow the namespace change. This is the most usefull: you can avoid dynamic generation depending on WebObjects HTTP Adaptor? with this.
133 +* **WSDLTargetNamespace:** a key that allow the namespace change. This is the most usefull: you can avoid dynamic generation depending on WebObjects HTTP Adaptor with this.
114 114  
115 115  Here is an example of rule definition changing the above values:
116 116  
... ... @@ -125,50 +125,50 @@
125 125  
126 126  {{/code}}
127 127  
128 -=== WOWebServiceClient class can't connect to a server that requires an authentication (WO 5.2.x, Bug ID 3568441) ===
148 +== WOWebServiceClient class can't connect to a server that requires an authentication ==
129 129  
130 -Authors:Francis Labrie
131 -Affected products:WebObjects5.2.x, 5.3.x
132 -Bug reference:rdar:~/~/3568441
150 +**Authors:** Francis Labrie
151 + **Affected products:** //WebObjects// 5.2.x, 5.3.x
152 + **Bug reference:** [[rdar:~~/~~/3568441>>url:rdar://3568441||shape="rect"]]
133 133  
134 -==== Problem: ====
154 +=== Problem: ===
135 135  
136 -The com.webobjects.webservices.client.WOWebServiceClientclass can't connect to a server that requires a Basic HTTP Authentication despite the fact this class offers a way to register a security delegate (see setSecurityDelegateForServiceNamed(Object, String) instance method).
156 +The {{code language="none"}}com.webobjects.webservices.client.WOWebServiceClient{{/code}} class can't connect to a server that requires a Basic HTTP Authentication despite the fact this class offers a way to register a security delegate (see {{code language="none"}}setSecurityDelegateForServiceNamed(Object, String){{/code}} instance method).
137 137  
138 -Normally, the processClientRequest(MessageContext) delegate method (see com.webobjects.webservices.support.WOSecurityDelegateinterface documentation) would allow an easy way to set a username and a password to the message context. But there is a problem related to the design of the class: to register a security delegate, the WOWebServiceClientclass has to fetch the Web Services Definition Language (WSDL) XML document. But to get access to this WSDL, an authentication header must be set. This is the classic chicken and egg problem...
158 +Normally, the {{code language="none"}}processClientRequest(MessageContext){{/code}} delegate method (see {{code language="none"}}com.webobjects.webservices.support.WOSecurityDelegateinterface{{/code}} documentation) would allow an easy way to set a username and a password to the message context. But there is a problem related to the design of the class: to register a security delegate, the {{code language="none"}}WOWebServiceClient{{/code}} class has to fetch the Web Services Definition Language (WSDL) XML document. But to get access to this WSDL, an authentication header must be set. This is the classic chicken and egg problem...
139 139  
140 -==== Solution: ====
160 +=== Solution: ===
141 141  
142 -The best would be to add a default method to WOWebServiceClientclass to register a default security delegate that is not related to a service name before the class fetch the WSDL. But unfortunately, all key methods that would allow this kind of behavior change are privates, so subclassing is not a solution...
162 +The best would be to add a default method to {{code language="none"}}WOWebServiceClient{{/code}} class to register a default security delegate that is not related to a service name before the class fetch the WSDL. But unfortunately, all key methods that would allow this kind of behavior change are privates, so subclassing is not a solution...
143 143  
144 144  But a workaround is still possible:
145 145  
146 -1. Fetch the WSDL document yourself and store it to the local filesystem, using the java.net.URL instance and setting up the Basic HTTP Authentication header field of the java.net.URLConnection yourself;
147 -1. Instanciate another java.net.URL class that refer to the local WSDL document file;
148 -1. Instanciate the com.webobjects.webservices.client.WOWebServiceClient<>code> class using the file URL;
166 +1. Fetch the WSDL document yourself and store it to the local filesystem, using the java.net.URL instance and setting up the Basic HTTP Authentication header field of the {{code language="none"}}java.net.URLConnection{{/code}} yourself;
167 +1. Instanciate another {{code language="none"}}java.net.URL{{/code}} class that refer to the local WSDL document file;
168 +1. Instanciate the {{code language="none"}}com.webobjects.webservices.client.WOWebServiceClient{{/code}} class using the file URL;
149 149  1. Set for each service a security delegate that will add the proper credential information for the Basic HTTP Authentication.
150 150  
151 151  That's it. It looks like a big hack, but it works...
152 152  
153 -=== Web Services can't return a WSDL with secure HTTPS references specifying port other than the default 443 ===
173 +== Web Services can't return a WSDL with secure HTTPS references specifying port other than the default 443 ==
154 154  
155 -Authors:Francis Labrie
156 -Affected products:WebObjects5.2.x, 5.3.x
157 -Bug reference:rdar:~/~/4196417
175 +**Authors:** Francis Labrie
176 + **Affected products:** //WebObjects// 5.2.x, 5.3.x
177 + **Bug reference:** [[rdar:~~/~~/4196417>>url:rdar://4196417||shape="rect"]]
158 158  
159 -==== Problem: ====
179 +=== Problem: ===
160 160  
161 161  HTTPS protocol references can be published in Web Services WSDL. But unfortunately, WebObjects seems to ignore ports other than the default 443.
162 162  
163 -This problem is related to the bad waycom.webobjects.appserver.WORequestbuild the URL prefix: if the protocol is secure and no port (i.e. 0) is set when calling the//completeURLPrefix(StringBuffer,boolean,int)method, the port will always be 443. Unfortunately, Web Servicescom.webobjects.appserver.//private.WOWebServiceclass seems to call this method without setting the port number.
183 +This problem is related to the bad way {{code language="none"}}com.webobjects.appserver.WORequest{{/code}} builds the URL prefix: if the protocol is secure and no port (i.e. 0) is set when calling the {{code language="none"}}_completeURLPrefix(StringBuffer, boolean, int){{/code}} method, the port will always be 443. Unfortunately, Web Services {{code language="none"}}com.webobjects.appserver._private.WOWebService{{/code}} class seems to call this method without setting the port number.
164 164  
165 -==== Solution: ====
185 +=== Solution: ===
166 166  
167 -To work around this bug, you can subclass the com.webobjects.appserver.WORequest class like this:
187 +To work around this bug, you can subclass the {{code language="none"}}com.webobjects.appserver.WORequest{{/code}} class like this:
168 168  
169 169  {{code}}
170 170  
171 - package com.smoguli.appserver;
191 +package com.smoguli.appserver;
172 172  
173 173  import com.webobjects.appserver.WORequest;
174 174  import com.webobjects.foundation.NSData;