Axisfault 302 when calling wso2 web services - wso2

I am using the below code to register a user in wso2 IS 5.1:
public static void main (String args[]){
try {
UserInformationRecoveryServiceStub stub = new UserInformationRecoveryServiceStub("https://localhost:9443/UserInformationRecoveryService");
RegisterUser user=new RegisterUser();
UserIdentityClaimDTO claim=new UserIdentityClaimDTO();
claim.setClaimUri("https://wso2.org/claims/emailaddress");
claim.setClaimValue("althaf.ashraf#gmail.com");
UserIdentityClaimDTO[] claims=new UserIdentityClaimDTO[2];
claims[0]=claim;
user.setUserName("user10");
user.setPassword("123456");
user.setProfile("default");
user.setTenantDomain("carbon.super");
user.setUserIdentityClaimDTOs(claims);
util.registerUser(user);
} catch (AxisFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UserInformationRecoveryServiceIdentityMgtServiceExceptionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And I am getting the below AXIS error
org.apache.axis2.AxisFault: Transport error: 302 Error: Found
When I use it through a SOAP client like SOAPUI I am able to access the web service successfully.
When I looked into this have seen that this might happen if the WSDL internally uses HTTP and then redirect to HTTPS.
Is there a way to figure out what I am missing here?

Please find the following example code I wrote to register a user using UserInformationRecoveryService.
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.transport.http.HttpTransportProperties;
import org.wso2.carbon.identity.mgt.stub.UserInformationRecoveryServiceIdentityMgtServiceExceptionException;
import org.wso2.carbon.identity.mgt.stub.UserInformationRecoveryServiceStub;
import org.apache.axis2.transport.http.HTTPConstants;
import java.io.File;
import java.rmi.RemoteException;
public class RegisterUserTest {
/**
* User Name to access WSO2 Carbon Server
*/
private static String USER_NAME = "admin";
/**
* Password of the User who access the WSO2 Carbon Server
*/
private static String PASSWORD = "admin";
/**
* Server url of the WSO2 Carbon Server
*/
private static String SEVER_URL = "https://localhost:9443/services/";
public static void main(String args[]) {
/**
* trust store path. this must contains server's certificate or Server's CA chain
*/
String trustStore = System.getProperty("user.dir") + File.separator +
"src" + File.separator + "main" + File.separator +
"resources" + File.separator + "wso2carbon.jks";
/**
* Call to https://localhost:9443/services/ uses HTTPS protocol.
* Therefore we to validate the server certificate or CA chain. The server certificate is looked up in the
* trust store.
* Following code sets what trust-store to look for and its JKs password.
*/
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
/**
* Axis2 configuration context
*/
ConfigurationContext configContext;
try {
configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem( null, null);
String serviceEndPoint = SEVER_URL + "UserInformationRecoveryService";
UserInformationRecoveryServiceStub stub = new UserInformationRecoveryServiceStub(configContext, serviceEndPoint);
ServiceClient client = stub._getServiceClient();
Options option = client.getOptions();
option.setProperty(HTTPConstants.COOKIE_STRING, null);
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername(USER_NAME);
auth.setPassword(PASSWORD);
auth.setPreemptiveAuthentication(true);
option.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth);
option.setManageSession(true);
stub.registerUser("fazlan", "Abcd123#", null, null, "carbon.super");
} catch (AxisFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (UserInformationRecoveryServiceIdentityMgtServiceExceptionException e) {
e.printStackTrace();
}
}
}
You need to copy the Identity server keystore into the resources directory for SSL handshake purpose.
Following is the pom.xml I used.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>stack.overflow.is</groupId>
<artifactId>adminservice</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>wso2-nexus</id>
<name>WSO2 internal Repository</name>
<url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
<releases>
<enabled>true</enabled>
<!--<updatePolicy>daily</updatePolicy> -->
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>
<repository>
<id>wso2.releases</id>
<name>WSO2 internal Repository</name>
<url>http://maven.wso2.org/nexus/content/repositories/releases/</url>
<releases>
<enabled>true</enabled>
<!--<updatePolicy>daily</updatePolicy> -->
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.mgt.stub</artifactId>
<version>5.0.7</version>
</dependency>
</dependencies>
</project>

Encounter this kind of message too.
Try to access webservice but shows:
org.apache.axis2.AxisFault: Transport error: 302 Error: Found.
Turns out that the reason is that I access wrong domain name of webservice URL.So I can not get right SSL certificate.So I guess it is something about SSL.

Related

Trying to use arrow-dataset java library but got missing arrow_dataset_jni.dll error

I followed the maven instructions to include the arrow-dataset in pom.xml
However, when running the code, it complained arrow-dataset-jni.dll not found
How to create or install dll ?
Thank you
J
Base on the master branch DLL is already supported and implemented. This will be available on the next release.
If you like to work with DLL support at this moment, you have 02 options:
Build the master Java branch project locally (java/dataset module)
Use current nightly packages repository
Then, steps could be:
1.- Download new jar Dataset / C Data locally from nightly packages mention
2.- Install new jar Dataset / C Data locally:
# intall dataset manually
mvn install:install-file -Dfile="C:\Users\dsusanibar\IdeaProjects\win-cookbooks\src\main\resources\files\arrow-dataset-10.0.0-SNAPSHOT.pom" -DgroupId="org.apache.arrow" -DartifactId="arrow-dataset" -Dversion="10.0.0-SNAPSHOT" -Dpackaging="pom"
mvn install:install-file -Dfile="C:\Users\dsusanibar\IdeaProjects\win-cookbooks\src\main\resources\files\arrow-dataset-10.0.0-SNAPSHOT.jar" -DgroupId="org.apache.arrow" -DartifactId="arrow-dataset" -Dversion="10.0.0-SNAPSHOT" -Dpackaging="jar"
# install c data interface manually
mvn install:install-file -Dfile="C:\Users\dsusanibar\IdeaProjects\win-cookbooks\src\main\resources\files\arrow-c-data-10.0.0-SNAPSHOT.pom" -DgroupId="org.apache.arrow" -DartifactId="arrow-c-data" -Dversion="10.0.0-SNAPSHOT" -Dpackaging="pom"
mvn install:install-file -Dfile="C:\Users\dsusanibar\IdeaProjects\win-cookbooks\src\main\resources\files\arrow-c-data-10.0.0-SNAPSHOT.jar" -DgroupId="org.apache.arrow" -DartifactId="arrow-c-data" -Dversion="10.0.0-SNAPSHOT" -Dpackaging="jar"
3.- Add new Dataset / C Data Interface dependencies into your project (Maven/Gradle)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>win-cookbooks</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<arrow.version>9.0.0</arrow.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-dataset</artifactId>
<version>10.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-memory-netty</artifactId>
<version>${arrow.version}</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-c-data</artifactId>
<version>10.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-memory-core</artifactId>
<version>${arrow.version}</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-format</artifactId>
<version>${arrow.version}</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-vector</artifactId>
<version>${arrow.version}</version>
</dependency>
</dependencies>
</project>
4.- Create Dataset with mew Dataset jar that contains DLL arrow_dataset_jni.dll + Read RecordBatches with new C Data Interface that contains DLL arrow_cdata_jni.dll:
import org.apache.arrow.dataset.file.FileFormat;
import org.apache.arrow.dataset.file.FileSystemDatasetFactory;
import org.apache.arrow.dataset.jni.NativeMemoryPool;
import org.apache.arrow.dataset.scanner.ScanOptions;
import org.apache.arrow.dataset.scanner.Scanner;
import org.apache.arrow.dataset.source.Dataset;
import org.apache.arrow.dataset.source.DatasetFactory;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.VectorSchemaRoot;
import org.apache.arrow.vector.ipc.ArrowReader;
import java.io.IOException;
import java.net.URISyntaxException;
public class Recipe {
public static void main(String[] args) throws URISyntaxException {
// File at: https://github.com/apache/arrow-cookbook/blob/main/java/thirdpartydeps/parquetfiles/data1.parquet
String uri = "file:///C:\\Users\\dsusanibar\\IdeaProjects\\win-cookbooks\\src\\main\\resources\\files\\data1.parquet";
ScanOptions options = new ScanOptions(/*batchSize*/ 5);
try (
BufferAllocator allocator = new RootAllocator();
DatasetFactory datasetFactory = new FileSystemDatasetFactory(allocator, NativeMemoryPool.getDefault(), FileFormat.PARQUET, uri);
Dataset dataset = datasetFactory.finish();
Scanner scanner = dataset.newScan(options)
) {
scanner.scan().forEach(scanTask -> {
try (ArrowReader reader = scanTask.execute()) {
while (reader.loadNextBatch()) {
final int[] count = {1};
try (VectorSchemaRoot root = reader.getVectorSchemaRoot()) {
System.out.println("Number of rows per batch["+ count[0]++ +"]: " + root.getRowCount());
System.out.println(root.contentToTSVString());
}
}
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Result:
Number of rows per batch[1]: 3
id name
1 David
2 Gladis
3 Juan
Please let us know if this work on your side.

Calling Web Service error "The remote server returned an unexpected response: (502) Connection refused."

Dears,
I have the following web service from client to call:
http://ajec.proxym-it.net/Ajec_sso_api/authenticate.wsdl
When I try to consume it, I got the this error :
The remote server returned an unexpected response: (502) Connection refused.
The inner exception is: {"The remote server returned an error: (502) Bad Gateway."}
Here is my code:
AuthenticateService.AuthenticatePortClient oAuthenticatePortClient = new AuthenticateService.AuthenticatePortClient();
AuthenticateService.authenticateRequest oauthenticateRequest = new AuthenticateService.authenticateRequest();
oauthenticateRequest.serviceId = "MobileTeam";
oauthenticateRequest.serviceKey = "AJEC1";
oauthenticateRequest.userName = "MMelhem";
oauthenticateRequest.password = "P#$$w0rd";
AuthenticateService.authenticateResponse oregisterUserResponse = oAuthenticatePortClient.authenticate(oauthenticateRequest);
and the web.config is:
<configuration>
<system.net>
<defaultProxy>
<proxy usesystemdefault="False" bypassonlocal="False" />
</defaultProxy>
</system.net>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="AuthenticatePortSoap11" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://172.16.0.82:80/Ajec_sso_api/authenticate"
binding="basicHttpBinding" bindingConfiguration="AuthenticatePortSoap11"
contract="AuthenticateService.AuthenticatePort" name="AuthenticatePortSoap11" />
</client>
</system.serviceModel>
</configuration>
What tool did you use to generate your client code (or hand-coded it)?
I used wsimport and I got slightly different code than yours. Since the IP seems to be in local domain (172.16.0.82), I couldn't test it. If you are interested, you could try it.
I used wsimport to generate/compile client class files:
wsimport -keep http://ajec.proxym-it.net/Ajec_sso_api/authenticate.wsdl
Then coded the client like this:
import com.ajec_sso.authenticate.*;
public class TClient {
static AuthenticatePortService service = new AuthenticatePortService();
public static void main(String[] args) {
try {
AuthenticatePort port = service.getAuthenticatePortSoap11();
AuthenticateRequest req = new AuthenticateRequest();
AuthenticateResponse res = new AuthenticateResponse();
req.setServiceId("MobileTeam");
req.setServiceKey("AJEC1");
req.setUserName("MMelhem");
req.setPassword("P#$$w0rd");
res = port.authenticate(req);
} catch(Exception e) {
e.printStackTrace();
}
}
}
Compiled like this (the generated com directory is in current directory).
javac TClient.java
I solved the problem by replace the endpoint address from
http://172.16.0.82:80/Ajec_sso_api/authenticate
to
http://ajec.proxym-it.net/Ajec_sso_api/authenticate

External DataSources not working with secured WSO2 DSS 3.2.2

Following is a sample dbs file which is deployed as dataservice in WSO2_DSS_3.2.2
<data name="login" serviceNamespace="www.abc.com/services/security" transports="http https">
<description>security service</description>
<config id="a_security">
<property name="carbon_datasource_name">sample-ds</property>
</config>
<query id="login" useConfig="a_security">
...
</query>
<operation name="login">
<call-query href="login">
...
</call-query>
</operation>
<resource method="POST" path="login">
...
</resource>
</data>
And sample-ds is setup from management console (its saved in registry). And this worked fine in a fresh DSS but when I applied a certificate with the DSS, it gives the following error. I tried this with several fresh DSS copies but same happens when applying the certificate.
ERROR {org.wso2.carbon.ndatasource.core.DataSourceRepository} - Error in updating data source [remove:false] at path '/repository/components/org.wso2.carbon.ndatasource/mdl-psm-ds': Error in updating data source 'mdl-psm-ds' from registry [remove:false]: Error in secure load of data source meta info: errorDuringDecryption
org.wso2.carbon.ndatasource.common.DataSourceException: Error in updating data source 'mdl-psm-ds' from registry [remove:false]: Error in secure load of data source meta info: errorDuringDecryption
at org.wso2.carbon.ndatasource.core.DataSourceRepository.updateDataSource(DataSourceRepository.java:186)
at org.wso2.carbon.ndatasource.core.DataSourceRepository.updateAllUserDataSource(DataSourceRepository.java:135)
at org.wso2.carbon.ndatasource.core.DataSourceRepository.refreshAllUserDataSources(DataSourceRepository.java:115)
at org.wso2.carbon.ndatasource.core.DataSourceRepository.initRepository(DataSourceRepository.java:92)
at org.wso2.carbon.ndatasource.core.DataSourceManager.initTenant(DataSourceManager.java:92)
at org.wso2.carbon.ndatasource.core.internal.DataSourceServiceComponent.initSuperTenantUserDataSources(DataSourceServiceComponent.java:189)
at org.wso2.carbon.ndatasource.core.internal.DataSourceServiceComponent.checkInitTenantUserDataSources(DataSourceServiceComponent.java:180)
at org.wso2.carbon.ndatasource.core.internal.DataSourceServiceComponent.setRegistryService(DataSourceServiceComponent.java:131)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
The reason is registry data related to data source has been encrypted from previous key and try to decrypt using the new key.To overcome this issue, you can reconfigure datasource with the same name after the server is started up. Then datasouce passwords will be encrypted again with the new certificate.
If the main error is Caused by: org.wso2.carbon.core.util.CryptoException: A crypto service implementation has not been registered., add below component class to org.wso2.carbon.core project:
package org.wso2.carbon.core.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.crypto.api.CryptoService;
/**
* #scr.component name="carbon.core.dshcomponent" immediate="true"
* #scr.reference name="carbonCryptoService" interface="org.wso2.carbon.crypto.api.CryptoService"
* cardinality="0..1" policy="dynamic" bind="setCarbonCryptoService" unbind="unsetCarbonCryptoService"
*/
public class CarbonCoreDataHolderHelperComponent {
private static Log log = LogFactory.getLog(CarbonCoreDataHolderHelperComponent.class);
private CarbonCoreDataHolder dataHolder = CarbonCoreDataHolder.getInstance();
protected void activate(ComponentContext ctxt) {
}
protected void deactivate(ComponentContext ctxt) {
}
protected void setCarbonCryptoService(CryptoService cryptoService){
if (log.isDebugEnabled()) {
log.debug("crypto service loaded..");
}
dataHolder.setCryptoService(cryptoService);
}
protected void unsetCarbonCryptoService(CryptoService cryptoService){
dataHolder.setCryptoService(null);
if (log.isDebugEnabled()) {
log.debug("crypto service unloaded..");
}
}
}
This Component will bind crypto service prior to user datasource initilization.

How to create standalone WSDL based web service using Spring WS?

Please, help me to run standalone web service on local machine using Spring WS and existing wsdl.
I am new in Spring WS. There is my code:
package com.mayacomp.ws;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
web service end point:
package com.mayacomp.endpoint;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import com.mayacomp.pack.intRequest;
import com.mayacomp.pack.IntResponse;
#Endpoint
public class WsEndpoint {
private static final String NAMESPACE_URI = "http://new.webservice.namespace";
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "intRequest")
#ResponsePayload
public IntResponse getIntHist(#RequestPayload intRequest request) {
try {
com.mayacomp.pack.IntResponse _return = new com.mayacomp.pack.IntResponse();
/*a lot of setters for _return object*/
return _return;
} catch (java.lang.Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
}
and webservie config:
package com.mayacomp.ws;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition;
import org.springframework.ws.wsdl.wsdl11.Wsdl11Definition;
#EnableWs
#Configuration
#EnableAutoConfiguration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean dispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "MayaService")
public Wsdl11Definition defaultWsdl11Definition() {
SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
wsdl11Definition.setWsdl(new ClassPathResource("MayaService.wsdl"));
return wsdl11Definition;
}
}
my pom file looks like:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>maya-ws</artifactId>
<dependencies>
<!-- tag::springws[] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-ws</artifactId>
<version>1.2.3.RELEASE</version>
</dependency>
<!-- end::springws[] -->
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I need to run application (I can run) and get web service via link like localhost:8080/ws/MayaService?wsdl
I will be glad for any advices.

How to handle exception strategy in SOAP Web Service in Mule

I have a question regarding Web Service in Mule 3.3.1 CE. I have a Web Service which exposes three operation and a class that implements these operations. These operation can return a result (positive) or an Exception (AuthExeception, ValidateExeception, etc).
Thanks to SOAP Mule Component when I raise a Java Exception, the framework is able to marshall the java exception in a SOAP Fault, but if I wanted to both return a SOAP Fault to the client and handle the exception with an exception strategy in Mule (i.e sending an email), the Mule behavior it is not how can I expect.
In other word when I raise, for example, an AuthException, the flow control pass to the Exception Strategy defined and I'am not anymore able to send back to the client the SOAP Fault (AuthException).
The question is: How can I both send back the SOAP Response and handle the Exception Strategy?
Here below there is a snippet of mule xml file where the exception strategy is implemented simply with a Logger component:
<flow name="esb_consignmentFlow1" doc:name="esb_consignmentFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="${conn.host}" port="8081" doc:name="HTTP" path="sgb/consignment" />
<cxf:jaxws-service doc:name="Process SOAP Request" serviceClass="com.suzuki.sales.webservice.ProcessTriggerPortType"/>
<component class="it.aizoon.suzuki.service.implementation.TriggerConsignmentOperationsImplementation" doc:name="triggerConsignmentOperationsImpl"/>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<flow-ref name="ErrorHandling" doc:name="Flow Reference"/>
</catch-exception-strategy>
</flow>
<flow name="ErrorHandling" doc:name="ErrorHandling" >
<logger level="INFO" doc:name="Logger"/>
</flow>
I've read something about Processing Strategy, but I don't know if it's the correct way.
Thank you very much for your help.
Here below there's my flow.xml
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:smtp="http://www.mulesoft.org/schema/mule/smtp" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf" xmlns:context="http://www.springframework.org/schema/context"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
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="CE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd
http://www.mulesoft.org/schema/mule/smtp http://www.mulesoft.org/schema/mule/smtp/current/mule-smtp.xsd
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 ">
<spring:beans>
<spring:bean id="consignmentProperty" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- In questo modo riesco a definire un file di property esterno che non è in una locazione hard-coded -->
<spring:property name="ignoreUnresolvablePlaceholders" value="true"/>
<spring:property name="locations">
<spring:list>
<spring:value>classpath:esb_consignment.properties</spring:value>
<spring:value>classpath:connections.properties</spring:value>
<spring:value>classpath:email.properties</spring:value>
<!-- L'ultimo nella lista è il più generico perché sovrascrive le properties -->
</spring:list>
</spring:property>
</spring:bean>
<spring:bean id="outfaultInterceptor" class="it.aizoon.suzuki.service.interceptors.CustomSoapFaultOutInterceptor">
<spring:property name="outputQueue" value="ErrorHandler"/>
</spring:bean>
</spring:beans>
<flow name="TriggerConsignmentInterceptorService" doc:name="TriggerConsignmentInterceptorService">
<http:inbound-endpoint exchange-pattern="request-response" host="${conn.host}" port="${conn.port}" doc:name="HTTP" path="sgb/consignment" />
<cxf:jaxws-service doc:name="Process SOAP Request" serviceClass="com.suzuki.sales.webservice.ProcessTriggerPortType">
<cxf:outFaultInterceptors>
<spring:ref bean="outfaultInterceptor"/>
</cxf:outFaultInterceptors>
</cxf:jaxws-service>
<component class="it.aizoon.suzuki.service.implementation.TriggerConsignmentOperationsImplementation" doc:name="triggerConsignmentOperationsImpl"/>
</flow>
<flow name="ErrorHandler" doc:name="ErrorHandler">
<vm:inbound-endpoint exchange-pattern="one-way" path="ErrorHandler" doc:name="Error Handler"/>
<logger message="PAYLOAD: #[message.payload]" level="INFO" doc:name="Payload"/>
<set-payload value="Tipo di Eccezione: #[message.payload]" doc:name="Set Payload"/>
<smtp:outbound-endpoint host="${smtp.host}"
from="${email.fromAddress}"
to="${email.toAddress}"
subject="${email.subject}"
responseTimeout="10000"
doc:name="Email Notification"/>
<logger message="EMAIL SENT" level="INFO" doc:name="Result"/>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger message="ERRORE INVIO EMAIL" level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
</flow>
</mule>
Here below there's the interceptor which handle the SOAP response and the exception strategy
package it.aizoon.suzuki.service.interceptors;
import javax.xml.bind.UnmarshalException;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.mule.DefaultMuleMessage;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.client.MuleClient;
import org.mule.api.context.MuleContextAware;
import org.mule.module.cxf.CxfConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.suzuki.sales.webservice.AuthenticationFailedException;
import com.suzuki.sales.webservice.ValidationFailedException;
public class CustomSoapFaultOutInterceptor extends AbstractPhaseInterceptor implements MuleContextAware{
private static final Logger logger = LoggerFactory.getLogger(CustomSoapFaultOutInterceptor.class);
private String outputQueue;
private MuleContext context;
public CustomSoapFaultOutInterceptor() {
// TODO Auto-generated constructor stub
super(Phase.MARSHAL);
}
#Override
public void setMuleContext(MuleContext context) {
// TODO Auto-generated method stub
this.context = context;
}
#Override
public void handleMessage(Message message) throws Fault {
// TODO Auto-generated method stub
MuleClient client = context.getClient();
MuleEvent event = (MuleEvent) message.getExchange().get(CxfConstants.MULE_EVENT);
DefaultMuleMessage muleMessage = (DefaultMuleMessage) event.getMessage();
Throwable genericExec = message.getContent(Exception.class).getCause();
Throwable exception = null;
if(genericExec instanceof ValidationFailedException){
exception = (ValidationFailedException) genericExec;
}else if(genericExec instanceof AuthenticationFailedException){
exception = (AuthenticationFailedException) genericExec;
}else if(genericExec instanceof UnmarshalException){
exception = (UnmarshalException) genericExec;
}
try {
muleMessage.setPayload(exception);
client.send("vm://" + getOutputQueue(), muleMessage);
} catch (MuleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getOutputQueue() {
return outputQueue;
}
public void setOutputQueue(String outputQueue) {
this.outputQueue = outputQueue;
}
public MuleContext getContext() {
return context;
}
public void setContext(MuleContext context) {
this.context = context;
}
}
Mule suppresses the exception beyond the exception strategy.
For this scenario where you want to handle the exception as well as send it as reply, a custom transformer is to be provided to prepare the soap fault with the exception and then set it as payload in the exception strategy flow.
<flow name="ErrorHandling" doc:name="ErrorHandling" >
<logger level="INFO" doc:name="Logger"/>
<custom-transformer class="com.example.service.ErrorTransformer"></custom-transformer>
</flow>
And a transformer to prepare the error message.
#Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
String exceptionMessage = message.getExceptionPayload().getException().getCause().getMessage() ;
String outputMessage = "<soap:Fault xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> " +
" <faultcode>soap:Server</faultcode> " +
"<faultstring>" + exceptionMessage + "</faultstring> " +
"</soap:Fault>";
return outputMessage;
}
Note: This is a sample transformer. Customize it for your scenario.