I would like to create a WADL-File from which Java Interfaces can be created using Apache CXF wadl2java Maven plugin.
In the WADL I would like to use the Datatypes defined in a XSD-File.
These are my REST Services:
#Path("/v1/order")
public interface OrderResource {
#PUT
#Consumes(MediaType.APPLICATION_XML)
public Response createOrder(Order order);
#GET
#Produces(MediaType.APPLICATION_XML)
public List<Order> getOrders(#QueryParam("orderId") List<Long> orderIds);
}
My WADL:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02" >
<grammars>
<include href="RestService_schema1.xsd" />
</grammars>
<resources base="http://localhost:9080/rest/">
<resource path="v1/order/" id="OrderResource">
<resource>
<method name="PUT" id="createOrder">
<request>
<representation mediaType="application/xml" />
</request>
<response status="200">
</response>
</method>
</resource>
</resource>
<resource>
<method name="GET" id="getOrders">
<request>
<param name="orderId" style="query" type="xs:long" />
</request>
<response status="200">
<representation mediaType="application/xml" />
</response>
</method>
</resource>
</resources>
</application>
My RestService_schema1.xsd:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Order" type="Order" />
<xs:complexType name="Order">
<xs:attribute name="OrderId" type="orderid">
<xs:annotation>
<xs:documentation>...
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:sequence>
.
.
.
.
</xs:sequence>
</xs:complexType>
<xs:simpleType name="orderid">
<xs:annotation>
<xs:documentation> ....
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:long" />
</xs:simpleType>
</xs:schema>
What I want to do:
I would like to specify in my WADL the input type Order for the createOrder Service. I know this can be done with the element-attribute, but how can I link it? Maybe element="Order" within the <representation>-Tag??
The Query Param of the getOrders()-Service should be List<Long> (in the WADL a List with orderid's) and the Response Type List<Order>. How can I specify this in the WADL?
Related
Is there a way to not tell the service about the settings at all and just provide them at the application level?
I am still unhappy with how servicefabric configuration seems to work.
Near as I can tell I have to specify in the service’s settings.xml all of the possible configuration values. Then I can override those in the application’s ApplicationParameters. Per documentation this looks like it holds true for environment variables also.
The complication that creates is that our configuration is used to hydrate options in many cases with arrays.
For example consider the json:
{
"AuthorizationOptions": {
"Policies": [
{
"Name": "User",
"Groups": [ "Domain Users" ]
}
]
}
}
There are 2 arrays; that are necessary and useful. To express this in the service fabric configuration it translates to:
<Section Name="AuthorizationOptions">
<Parameter Name="Policies:0:Name" Value="User"/>
<Parameter Name="Policies:0:Groups:0" Value="Domain Users"/>
</Section>
While the translation is not pleasant in comparison to the structured object it is completely usable.
However, If I don’t specify the section and parameters in the service, I can’t seem to override them in the application. So in this case I would have to define the exact number of policies and groups per policy in the service and the application could modify the policy name, or the group values, but not the number of policies total or number of groups total.
Is there a way to not tell the service about the settings at all and just provide them at the application level?
If not what alternatives exist to make the service reusable across applications that I may want to use to provide this type of dynamic configuration differently?
The last part of the puzzle that may assist in answering this question is I am using some pre-release code to translate the service fabric settings into Microsoft.Extensions.Configuration.IConfiguration. However, that is just taking the settings it finds; it isn't the cause of the override issue I am running into.
Example Service Settings.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Section Name="AuthorizationOptions">
<!-- I should not have to provide these at the application level!
However, it fails to deploy if I don't. -->
<Parameter Name="Policies:0:Name" Value="User"/>
<Parameter Name="Policies:0:Groups:0" Value="Domain Users"/>
</Section>
</Settings>
Example Application ApplicationManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ServiceFabric.ExampleType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" DefaultValue="" />
<Parameter Name="Service.Example_InstanceCount" DefaultValue="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Name" DefaultValue="Users" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Groups_0" DefaultValue="Domain Users" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Service.ExamplePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="AuthorizationOptions">
<Parameter Name="Policies:0:Name" Value="[Service.Example_AuthorizationOptions_Policies_0_Name]" />
<Parameter Name="Policies:0:Groups:0" Value="[Service.Example_AuthorizationOptions_Policies_0_Groups_0]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
<EnvironmentOverrides CodePackageRef="code">
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[Service.Example_ASPNETCORE_ENVIRONMENT]" />
</EnvironmentOverrides>
</ServiceManifestImport>
<DefaultServices>
<Service Name="Service.Example" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="Service.ExampleType" InstanceCount="[Service.Example_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
Example Application ApplicationParameters (Local.1Node.xml):
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/ServiceFabric.Example" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" Value="Development" />
<Parameter Name="Service.Example_InstanceCount" Value="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Name" Value="Users" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Groups_0" Value="Domain Users" />
</Parameters>
</Application>
Example Application PublishProfiles (Local.1Node.xml):
<?xml version="1.0" encoding="utf-8"?>
<PublishProfile xmlns="http://schemas.microsoft.com/2015/05/fabrictools">
<ClusterConnectionParameters />
<ApplicationParameterFile Path="..\ApplicationParameters\Local.1Node.xml" />
</PublishProfile>
Should be unrelated, but example consumption of the settings:
internal sealed class Example : StatelessService
{
public Example(StatelessServiceContext context)
: base(context)
{ }
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting HttpSys on {url}");
return new WebHostBuilder()
.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.Negotiate; // Microsoft.AspNetCore.Server.HttpSys
options.Authentication.AllowAnonymous = false;
}).ConfigureServices(services => services.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddServiceFabricConfiguration(FabricRuntime.GetActivationContext(), options => {
options.IncludePackageName=false;
});
})
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
}
From that point forward everything is in the IConfiguration object as expected.
There are many ways to configure a service fabric application, and each approach will bring you to a different challenges.
SF team recommend the approach in the docs, because you can have a better version control of configurations, and makes harder to commit mistakes, as it is explicitly declared in a file, I've used a few different approaches because of limitations like yours, the follwoing approach might solve your problem:
Configure like the original approach, but with complex types stored as JSON values: it is the closest solution to the recommended design and you still can keep control of the configuration versions on source control.
It would be something like:
Settings.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns... namespaces here...>
<Section Name="AuthorizationOptions">
<Parameter Name="Policies"/>
</Section>
</Settings>
ApplicationManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="ServiceFabric.ExampleType" ApplicationTypeVersion="1.0.0" xmlns:...namespaces....>
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" DefaultValue="" />
<Parameter Name="Service.Example_InstanceCount" DefaultValue="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies" DefaultValue="[]" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Service.ExamplePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="AuthorizationOptions">
<Parameter Name="Policies" Value="[Service.Example_AuthorizationOptions_Policies]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
<EnvironmentOverrides CodePackageRef="code">
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[Service.Example_ASPNETCORE_ENVIRONMENT]" />
</EnvironmentOverrides>
</ServiceManifestImport>
<DefaultServices>
<Service Name="Service.Example" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="Service.ExampleType" InstanceCount="[Service.Example_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
ApplicationParameters.xml
<?xml version="1.0" encoding="utf-8"?>
<Application Name="fabric:/ServiceFabric.Example" xmlns:...namespaces....>
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" Value="Development" />
<Parameter Name="Service.Example_InstanceCount" Value="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies" Value="[{'Name': 'User','Groups': ['Domain Users']}, {'Name': 'Admin','Groups': ['Administrators']}]" />
</Parameters>
</Application>
In your service code:
public class Policy
{
public string Name { get; set; }
public string[] Groups { get; set; }
}
var settings = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config").Settings;
var authOptions = settings.Sections["AuthorizationOptions"].Parameters["Policies"].Value;
var obj = JsonConvert.DeserializeObject<Policy[]>(authOptions);
You could go a level further and store the entire
AuthorizationOptions as a JSON, but like said previously, more
generic it become, easier will be to commit mistakes and harder to find
configuration issues.
I'm trying to deploy an ASP.net 5 website to my local service fabric dev cluster but get an Access Denied exception on every deploy. I know that the problem is with the web service because when I remove it from the deployment my other service is deployed without any error
This exception looks like it is trying to delete a file, but which one and why wouldn't it have access?
6>. 'E:\Github\Flow.Server\Flow.Server.Fabric\Scripts\Deploy-FabricApplication.ps1' -ApplicationPackagePath 'E:\Github\Flow.Server\Flow.Server.Fabric\pkg\Debug' -PublishProfileFile 'E:\Github\Flow.Server\Flow.Server.Fabric\PublishProfiles\Local.xml' -DeployOnly:$true -UnregisterUnusedApplicationVersionsAfterUpgrade $false -OverrideUpgradeBehavior 'None' -OverwriteBehavior 'Always' -ErrorAction Stop
6>Message : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
6>Data : {}
6>InnerException :
6>TargetSite : Void RunInMTA(System.Action)
6>StackTrace : at System.Fabric.Interop.Utility.RunInMTA(Action action)
6> at System.Fabric.Common.FabricDirectory.Delete(String path, Boolean recursive, Boolean
6> deleteReadOnlyFiles)
6> at Microsoft.ServiceFabric.Powershell.ApplicationCmdletBase.TestApplicationPackage(String
6> applicationPackagePath, Hashtable applicationParameters, String imageStoreConnectionString)
6> at System.Management.Automation.CommandProcessor.ProcessRecord()
6>HelpLink :
6>Source : System.Fabric
6>HResult : -2147024891
Here is my ApplicationManifest
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="Flow.Server.FabricType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Silo_InstanceCount" DefaultValue="-1" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Flow.Server.Fabric.WebApi" ServiceManifestVersion="1.0.0" />
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Flow.Server.Fabric.SiloPkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
</ServiceManifestImport>
<DefaultServices>
<Service Name="Flow.Server.Fabric.WebApiService">
<StatelessService ServiceTypeName="Flow.Server.Fabric.WebApiType">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Flow.Server.Fabric.Silo">
<StatelessService ServiceTypeName="Flow.Server.Fabric.SiloType" InstanceCount="[Silo_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
And here is the ServiceManifest
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="Flow.Server.Fabric.WebApi" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<ServiceTypes>
<StatelessServiceType ServiceTypeName="Flow.Server.Fabric.WebApiType">
<Extensions>
<Extension Name="__GeneratedServiceType__">
<GeneratedNames xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<DefaultService Name="Flow.Server.Fabric.WebApiService" />
<ServiceEndpoint Name="Flow.Server.Fabric.WebApiTypeEndpoint" />
</GeneratedNames>
</Extension>
</Extensions>
</StatelessServiceType>
</ServiceTypes>
<CodePackage Name="C" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>approot\runtimes\dnx-clr-win-x64.1.0.0-rc1-update1\bin\dnx.exe</Program>
<Arguments>--appbase approot\src\Flow.Server.Fabric.WebApi Microsoft.Dnx.ApplicationHost Microsoft.ServiceFabric.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener</Arguments>
<WorkingFolder>CodePackage</WorkingFolder>
<ConsoleRedirection FileRetentionCount="5" FileMaxSizeInKb="2048" />
</ExeHost>
</EntryPoint>
</CodePackage>
<Resources>
<Endpoints>
<Endpoint Name="Flow.Server.Fabric.WebApiTypeEndpoint" Protocol="http" Type="Input" />
</Endpoints>
</Resources>
</ServiceManifest>
I have a SOAP::Lite client using the service method to grab a wsdl. This needs to call a webservice with a single operation and method with no parameters. It's resulting in a nested method call that the provider tells me is wrong. And I'm not very knowledgeable about SOAP::Lite or webservices. Advice appreciated!
my $lookup = SOAP::Lite->service('http://hostname.com/path/SpringVerifierWebServicePort?wsdl')
-> proxy("$theURL") ;
$response = $lookup->verifySpring('');
And that is generating this stub on the call.
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://webservice.springverifier.toolslang.fedins.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body>
<tns:verifySpring>
<verifySpring xsi:nil="true" xsi:type="tns:verifySpring" />
</tns:verifySpring> </soap:Body></soap:Envelope>
SOAP::Transport::HTTP::Client::send_receive: HTTP::Response=HASH(0x167bee8)
SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 500 Internal Server Error
The provider of that webservice tells me the 500 error is due to the nested verifySpring on the call. Do I need to call this differently than I am, or is the WSDL invalid and screwing up SOAP::Lite? I don't know enough about SOAP and webservices to say if the problem is the WSDL, or if I need to call this differently in SOAP::LITE. Could anyone give me some direction please?
The provider WSDL is this:
<?xml version="1.0" encoding="UTF-8" ?>
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://webservice.springverifier.toolslang.fedins.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="SpringVerifierWebServiceService" targetNamespace="http://webservice.springverifier.toolslang.fedins.com">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://webservice.springverifier.toolslang.fedins.com" targetNamespace="http://webservice.springverifier.toolslang.fedins.com" version="1.0">
<xs:element name="verifySpring" type="tns:verifySpring" />
<xs:element name="verifySpringResponse" type="tns:verifySpringResponse" />
<xs:complexType name="verifySpring">
<xs:sequence />
</xs:complexType>
<xs:complexType name="verifySpringResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:environmentInfo" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="environmentInfo">
<xs:sequence>
<xs:element minOccurs="0" name="dbRegion" type="xs:string" />
<xs:element minOccurs="0" name="jndi" type="xs:string" />
<xs:element minOccurs="0" name="springProfile" type="xs:string" />
<xs:element minOccurs="0" name="systemDate" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="verifySpringResponse">
<wsdl:part element="tns:verifySpringResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="verifySpring">
<wsdl:part element="tns:verifySpring" name="parameters" />
</wsdl:message>
<wsdl:portType name="SpringVerifierWebService">
<wsdl:operation name="verifySpring">
<wsdl:input message="tns:verifySpring" name="verifySpring" />
<wsdl:output message="tns:verifySpringResponse" name="verifySpringResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SpringVerifierWebServiceServiceSoapBinding" type="tns:SpringVerifierWebService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="verifySpring">
<soap:operation soapAction="" style="document" />
<wsdl:input name="verifySpring">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="verifySpringResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SpringVerifierWebServiceService">
<wsdl:port binding="tns:SpringVerifierWebServiceServiceSoapBinding" name="SpringVerifierWebServicePort">
<soap:address location="http://dev1.spring.service.fedins.com/fedservice/toolslang/springverifier/webservice/services/SpringVerifierWebServicePort" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
'' is an actual value (empty string), use verifySpring(); and not verifySpring('');
Example
#!/usr/bin/perl --
use strict;
use warnings;
use SOAP::Lite;
my $soap = SOAP::Lite
-> uri('http://127.0.0.1/MyModule')
-> proxy('http://127.0.0.1:1203')
;;;;;;;;;
$soap->readable(1);
$soap->transport->add_handler("request_send", sub { print $_[0]->as_string,"\n"; return } );
eval { $soap->verifySpring(''); 1 } or print "$#\n";
eval { $soap->verifySpring(); 1 } or print "$#\n";
__END__
POST http://127.0.0.1:1203 HTTP/1.1
Accept: text/xml
Accept: multipart/*
Accept: application/soap
User-Agent: SOAP::Lite/Perl/1.11
Content-Length: 522
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://127.0.0.1/MyModule#verifySpring"
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<verifySpring xmlns="http://127.0.0.1/MyModule">
<c-gensym3 xsi:type="xsd:string" />
</verifySpring>
</soap:Body>
</soap:Envelope>
500 Can't connect to 127.0.0.1:1203 at - line 11.
POST http://127.0.0.1:1203 HTTP/1.1
Accept: text/xml
Accept: multipart/*
Accept: application/soap
User-Agent: SOAP::Lite/Perl/1.11
Content-Length: 475
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://127.0.0.1/MyModule#verifySpring"
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<verifySpring xmlns="http://127.0.0.1/MyModule" xsi:nil="true" />
</soap:Body>
</soap:Envelope>
500 Can't connect to 127.0.0.1:1203 at - line 12.
It should be simple but I can't set it working. My XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ws="http://www.mulesoft.org/schema/mule/ws" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:data-mapper="http://www.mulesoft.org/schema/mule/ee/data-mapper" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.6.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ws http://www.mulesoft.org/schema/mule/ws/current/mule-ws.xsd
http://www.mulesoft.org/schema/mule/ee/data-mapper http://www.mulesoft.org/schema/mule/ee/data-mapper/current/mule-data-mapper.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<ws:consumer-config name="Web_Service_Consumer" wsdlLocation="http://procese/sysworkflow/en/classic/services/wsdl2" service="ProcessMakerService" port="ProcessMakerServiceSoap" serviceAddress="http://procese:80/sysworkflow/en/classic/services/soap2" doc:name="Web Service Consumer"/>
<data-mapper:config name="JSON_To_XML" transformationGraphPath="json_to_xml.grf" doc:name="JSON_To_XML"/>
<flow name="ws_pm_login3Flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<set-payload value="#[{"userid":"xyz.qwe", "password":"12345"}]" doc:name="Set Payload"/>
<data-mapper:transform config-ref="JSON_To_XML" doc:name="JSON To XML"/>
<ws:consumer config-ref="Web_Service_Consumer" operation="login" doc:name="Web Service Consumer"/>
</flow>
</mule>
The WS is working fine.
The mapper file json_to_xml.grf looks like:
<?xml version="1.0" encoding="UTF-8"?><Graph __version="3.5.0" author="abc" created="Tue Apr 21 13:27:56 EEST 2015" description="JSON To XML" guiVersion="3.4.4.P" id="1429614596881" licenseCode="Unlicensed" licenseType="Unknown" modified="Tue Apr 21 13:27:56 EEST 2015" modifiedBy="abc" name="JSON_To_XML" revision="1.0" showComponentDetails="false">
<Global>
<Metadata __index="0" __referenceCounter="1" __sourcePath="{}/login" _dataStructure="OBJECT" _id="__id" _type="Input" id="e941872a-c0e5-4148-ac8c-6010c4dad903">
<Record fieldDelimiter="," name="login" recordDelimiter="\n\\|\r\n\\|\r" type="delimited">
<Field __artificialType="_id" __systemManaged="true" name="__id" type="string"/>
<Field __index="1" __sourcePath="{}/login/password" containerType="SINGLE" label="password" name="password" type="string"/>
<Field __index="0" __sourcePath="{}/login/userid" containerType="SINGLE" label="userid" name="userid" type="string"/>
</Record>
</Metadata>
<Metadata __index="0" __referenceCounter="1" __sourcePath="{}/login" _dataStructure="OBJECT" _id="__id" _type="Output" id="d9e5b0f6-b757-46cb-89bf-a7662be5c77f">
<Record fieldDelimiter="," name="login" recordDelimiter="\n\\|\r\n\\|\r" type="delimited">
<Field __artificialType="_id" __systemManaged="true" name="__id" type="string"/>
<Field __index="0" __sourcePath="{}/login/password" containerType="SINGLE" label="password" name="password" type="string"/>
<Field __index="1" __sourcePath="{}/login/userid" containerType="SINGLE" label="userid" name="userid" type="string"/>
</Record>
</Metadata>
<Dictionary>
<Entry id="DictionaryEntry0" input="true" name="inputPayload" output="false" type="object"/>
<Entry id="DictionaryEntry1" input="false" name="outputPayload" output="true" type="object"/>
</Dictionary>
</Global>
<Phase number="0">
<Node cacheInMemory="true" charset="UTF-8" enabled="enabled" fileURL="dict:outputPayload" guiName="XML WRITER" guiX="900" guiY="20" id="EXT_XML_WRITER0" type="EXT_XML_WRITER">
<attr name="mapping"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<login xmlns:clover="http://www.cloveretl.com/ns/xmlmapping" clover:inPort="0">
<password>$0.password</password>
<userid>$0.userid</userid>
</login>]]></attr>
<attr name="_data_format"><![CDATA[XML]]></attr>
</Node>
<Node enabled="enabled" guiName="Foreach 'login' -> 'login'" guiX="460" guiY="20" id="FOREACH_LOGIN_LOGIN" transformClass="com.mulesoft.datamapper.transform.MelRecordTransform" type="REFORMAT">
<attr name="melScript"><![CDATA[//MEL
//START -> DO NOT REMOVE
output.__id = input.__id;
//END -> DO NOT REMOVE
output.password = input.password;
output.userid = input.userid;
]]></attr>
</Node>
<Node charset="UTF-8" enabled="enabled" fileURL="dict:inputPayload" guiName="JSON READER" guiX="20" guiY="20" id="JSON_READER0" type="JSON_READER">
<attr name="mapping"><![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Context xpath="/root">
<Context outPort="0" sequenceField="__id" xpath="object">
<Mapping cloverField="password" trim="true" xpath="password"/>
<Mapping cloverField="userid" trim="true" xpath="userid"/>
</Context>
</Context>
]]></attr>
<attr name="_data_format"><![CDATA[JSON]]></attr>
</Node>
<Edge debugMode="true" fromNode="FOREACH_LOGIN_LOGIN:0" guiBendpoints="" id="Edge1" inPort="Port 0 (in)" metadata="d9e5b0f6-b757-46cb-89bf-a7662be5c77f" outPort="Port 0 (out)" toNode="EXT_XML_WRITER0:0"/>
<Edge debugMode="true" fromNode="JSON_READER0:0" guiBendpoints="" id="Edge0" inPort="Port 0 (in)" metadata="e941872a-c0e5-4148-ac8c-6010c4dad903" outPort="Port 0 (out)" toNode="FOREACH_LOGIN_LOGIN:0"/>
</Phase>
</Graph>
When I start the process I get:
Error executing graph: ERROR (com.mulesoft.mule.module.datamapper.api.exception.DataMapperExecutionException). Message payload is of type: HashMap
I am using 3.6.1 EE
What am I missing?
Turns out it is a problem in mule to use the double quotes in JSON. I swithced to XML and now it is working fine.
I have an issue with SOAPAction that contains accents.
From a third-party WSDL, I have generated Java Classes using CXF wsdl2java plugin. Using the generated classes, I have developed a CXF-based client and server. The problem is that the server fail to get the client's request with the following error :
2014-06-19 11:45:08,423 [qtp1051344475-17] WARN - Interceptor for {http://simulator.be.connectors.cam/}RIBSOAPSoapImplService#{http://tempuri.org/}Opération_1 has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: The given SOAPAction http://tempuri.org/RIB_SOAP/Opération_1 does not match an operation.
at org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor$SoapActionInAttemptTwoInterceptor.handleMessage(SoapActionInInterceptor.java:188)
at org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor$SoapActionInAttemptTwoInterceptor.handleMessage(SoapActionInInterceptor.java:163)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at ...
The log of the request at the client side shows the correct value of the SOAPAction while the request at the server side shows the wrong value.
The request at the client side is :
2014-06-19 11:45:08,349 [main] INFO - Outbound Message
---------------------------
ID: 1
Address: http://localhost:17081/SIMULATOR/RIB/WS
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], Connection=[Keep-Alive], SOAPAction=["http://tempuri.org/RIB_SOAP/Opération_1"]}
Payload: <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:Opération_1 xmlns:ns2="http://Rib_InSchema" xmlns:ns3="http://tempuri.org/" xmlns:ns4="http://Rib_OutSchema">
<ns2:Root>
<RIB>1234567890</RIB>
</ns2:Root>
</ns3:Opération_1>
</soap:Body>
</soap:Envelope>
--------------------------------------
The request at the server side is :
2014-06-19 11:45:08,408 [qtp1051344475-17] INFO - Inbound Message
----------------------------
ID: 2
Address: http://localhost:17081/SIMULATOR/RIB/WS
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[339], content-type=[text/xml; charset=UTF-8], Host=[localhost:17081], Pragma=[no-cache], SOAPAction=["http://tempuri.org/RIB_SOAP/Opération_1"], User-Agent=[Apache CXF 2.7.10]}
Payload: <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:Opération_1 xmlns:ns2="http://Rib_InSchema" xmlns:ns3="http://tempuri.org/" xmlns:ns4="http://Rib_OutSchema">
<ns2:Root>
<RIB>1234567890</RIB>
</ns2:Root>
</ns3:Opération_1>
</soap:Body>
</soap:Envelope>
--------------------------------------
As you can see from the logs, the UTF-8 is the used encoding at all levels. However, for some reason, at the server side, the SOAPAction has been decoded using ISO-8859-1.
The used WSDL is :
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/"
xmlns:s1="http://Rib_InSchema" xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:s2="http://Rib_OutSchema"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">BizTalk assembly
"BTS, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=dab3109d17486051" published web service.
</wsdl:documentation>
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:import namespace="http://Rib_InSchema" />
<s:import namespace="http://Rib_OutSchema" />
<s:element name="Opération_1">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" ref="s1:Root" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Opération_1Response">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" ref="s2:Root" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
<s:schema elementFormDefault="qualified"
targetNamespace="http://Rib_InSchema">
<s:element name="Root">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" form="unqualified"
name="RIB" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
<s:schema elementFormDefault="qualified"
targetNamespace="http://Rib_OutSchema">
<s:element name="Root">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" form="unqualified"
name="NumCompte" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" form="unqualified"
name="Nom" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" form="unqualified"
name="Prenom" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" form="unqualified"
name="Agence" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" form="unqualified"
name="AgenceAdresse" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" form="unqualified"
name="RIB" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="Opération_1SoapIn">
<wsdl:part name="parameters" element="tns:Opération_1" />
</wsdl:message>
<wsdl:message name="Opération_1SoapOut">
<wsdl:part name="parameters" element="tns:Opération_1Response" />
</wsdl:message>
<wsdl:portType name="RIB_SOAPSoap">
<wsdl:operation name="Opération_1">
<wsdl:input message="tns:Opération_1SoapIn" />
<wsdl:output message="tns:Opération_1SoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="RIB_SOAPSoap"
type="tns:RIB_SOAPSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Opération_1">
<soap:operation
soapAction="http://tempuri.org/RIB_SOAP/Opération_1"
style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="RIB_SOAPSoap12"
type="tns:RIB_SOAPSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Opération_1">
<soap12:operation
soapAction="http://tempuri.org/RIB_SOAP/Opération_1"
style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="RIB_SOAP">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">BizTalk assembly
"BTS, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=dab3109d17486051" published web service.
</wsdl:documentation>
<wsdl:port name="RIB_SOAPSoap"
binding="tns:RIB_SOAPSoap">
<soap:address
location="http://localhost/BTS_Proxy/RIB_SOAP.asmx" />
</wsdl:port>
<wsdl:port name="RIB_SOAPSoap12"
binding="tns:RIB_SOAPSoap12">
<soap12:address
location="http://localhost/BTS_Proxy/RIB_SOAP.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Spring conf for the client:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
"
>
<!--.~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~-->
<!--.~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~-->
<http-conf:conduit name=".*">
<http-conf:client ConnectionTimeout="30000" ReceiveTimeout="30000" />
</http-conf:conduit>
<jaxws:client
id="ribWebServiceClient"
serviceClass="org.tempuri.RIBSOAPSoap"
address="${ws.rib.url}"
>
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" >
<property name="prettyLogging" value="true" />
</bean>
</jaxws:features>
<jaxws:properties>
<entry key="exceptionMessageCauseEnabled" value="true" />
<entry key="faultStackTraceEnabled" value="true" />
</jaxws:properties>
</jaxws:client>
<!--.~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~-->
</beans>
Spring conf for the server:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
"
>
<!--.~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~-->
<!--.~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~-->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!--.~~~~~~~~..~~~~~~~~..~~~~~~~~-->
<jaxws:endpoint
id="ribWebServiceEndPoint"
implementor="#ribWebService"
address="${ws.rib.url}"
>
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" >
<property name="prettyLogging" value="true" />
</bean>
</jaxws:features>
<jaxws:properties>
<entry key="exceptionMessageCauseEnabled" value="true" />
<entry key="faultStackTraceEnabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
<!--.~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~..~~~~~~~~-->
</beans>
According to the HTTP spec, all the HTTP headers are supposed to be ISO-8859-1. There is an separate spec for how to encode non-ISO-8859-1 characters into the header (https://www.rfc-editor.org/rfc/rfc2047) but I'm not sure if the HTTPUrlConnection object in the JDK supports that or not. I'm also not sure if other soap client would support it either.
I would strongly suggest making sure the SOAPAction values would be ISO-8859-1 compatible.
Please refer to this discussion in CXF Users Mainling List. As mentioned by Aki, HTTP Specs requires that HTTP Headers use only US-ASCII characters (see rfc2822). And as mentioned by Daniel and Aki, the spec rfc2047 should be used in case there is a need to use a none US-ASCII character.
The solution for this issue is to avoid using characters that are not US-ASCII characters (include accented characters of course).