How to control key generation in Mule Cache - caching

My requirement is to authenticate the user (with an external ws) as part of my Mule Flow and use the result of the authentication in a cache. however, if the user credentials change, then the cache should be automatically invalidated and user auth must be done with the external ws. Basically the cache key should be based on the user credentials. Is this possible ?
Here's my mule flow and i see that Mule is caching the results after the first request and irrespective of whether or not the payload changes in subsequent requests ( which is where the credentials are sent ) mule always returns the results from the cache. So when the first request has incorrect credentials, user auth fails and mule caches the response. From this point onwards, irrespective of sending correct credentials in subsequent requests, it always refers to the cache and returns user auth failure. How do I achieve what I wanted to achieve ?
Here's my mule flow:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" 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.0"
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/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
<http:listener-config name="HTTP-Inbound-Endpoint" host="0.0.0.0" port="8888" doc:name="HTTP Listener Configuration"/>
<http:request-config name="HTTP_Request_Configuration" host="10.10.10.10" port="8080" doc:name="HTTP Request Configuration"/>
<ee:object-store-caching-strategy name="Auth-Cache-Strategy" doc:name="Caching Strategy">
<in-memory-store name="UserAuthCache" maxEntries="100" entryTTL="3600" expirationInterval="3600"/>
</ee:object-store-caching-strategy>
<flow name="cacheauthenticationFlow">
<http:listener config-ref="HTTP-Inbound-Endpoint" path="*" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<ee:cache cachingStrategy-ref="Auth-Cache-Strategy" doc:name="Cache">
<logger message="Incoming: #[message.payload]" level="INFO" doc:name="Logger"/>
<scripting:transformer doc:name="Python">
<scripting:script engine="jython"><![CDATA[import base64
authorization = message.getInboundProperty("authorization")
#print "Authorization is: \"" + authorization + "\""
authstring = authorization.split()
#print authstring
credentials = authstring[-1]
#print "Credentials => " + credentials
decodedAuth = credentials.decode('base64')
#print decodedAuth
if (decodedAuth.find("#") > 0):
(id, password) = decodedAuth.split(":")
(username, project) = id.split("#")
print username + ":" + password + ", Project: " + project
else:
(username, password) = decodedAuth.split(":")
print username + ":" + password
message.payload = { "username" : username + "#" + project , "password" : password }
result = message]]></scripting:script>
</scripting:transformer>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="Incoming payload: #[message.payload]" level="INFO" doc:name="Logger"/>
<http:request config-ref="HTTP_Request_Configuration" path="/wservices/authenticate/user" method="POST" doc:name="HTTP-Dev-Box-Authentication"/>
<object-to-string-transformer doc:name="Object to String"/>
</ee:cache>
<logger message="Response From Cache: #[message.payload]" level="INFO" doc:name="Logger"/>
<set-payload value="#[message.payload.'status']" doc:name="Response"/>
</flow>
</mule>

Since the default key generation strategy for the cache scope is based on the message payload an option in your particular case would be to simply move the scripting:transformer to be executed before the ee:cache scope.
For a more general solution, where you do not want to overwrite your request payload, you can define the keyGenerationExpression or keyGenerator-refattribute on the ee:cache element to control how the cache key i generated.
For example to use the complete HTTP authorization header as key you could use:
<ee:cache cachingStrategy-ref="Auth-Cache-Strategy" doc:name="Cache"
keyGenerationExpression="#[message.inboundProperties.authorization]">
<!-- Your flow here -->
</ee:cache>
See the cache scope documentation for more information.
If you want to use this approach you could do is move parts of your jython code outside the cache scope, change it so that it sets the user and password as separate flow variables on the message and then use them in the keyGenerationExpression and then again later inside the cache scope in a simple set-payload transformer.

You can define a global configuration "Caching_Strategy":
<ee:object-store-caching-strategy name="Caching_Strategy" keyGenerationExpression="#[flowVars.userID]" doc:name="Caching Strategy"/>
and refer the global configuration in cache flow:
<ee:cache doc:name="Cache" cachingStrategy-ref="Caching_Strategy">
<!-- flow -->
</ee:cache>
You can control your keyGenerationExpression by the flow variable #[flowVars.userID]
For complete detail with example refer
http://www.tutorialsatoz.com/caching-in-mule-cache-scope/

Related

Custom validation in Mule ESB

I am trying to add custom validation against a generated request object for incoming JSON payload using the javax.validation framework and openapi-generator-maven-plugin in Mule ESB.
I am following the below mulesoft documentation :
https://docs.mulesoft.com/mule-runtime/3.9/building-a-custom-validator
I have added the below custom validation :
<validation:custom-validator doc:name="Validation" class="com.poltu.validation.CustomValidator" />
But when I amtrying to run the application ,it fails with the below message :
Invalid content was found starting with element 'validation:custom-validator'. One of '{"http://www.mulesoft.org/schema/mule/core":abstract-message-processor, "http://www.mulesoft.org/schema/mule/core":abstract-mixed-content-message-processor}' is expected.
Edit :
below is the xml configuration that I am now using :
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:validation="http://www.mulesoft.org/schema/mule/validation"
xmlns:xml-module="http://www.mulesoft.org/schema/mule/xml-module"
xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:java="http://www.mulesoft.org/schema/mule/java"
xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
xmlns:db="http://www.mulesoft.org/schema/mule/db"
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:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/json
http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/core
http://www.mulesoft.org/schema/mule/core/current/mule.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/db
http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/ee/core
http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/java
http://www.mulesoft.org/schema/mule/java/current/mule-java.xsd
http://www.mulesoft.org/schema/mule/xml-module
http://www.mulesoft.org/schema/mule/xml-module/current/mule-xml-module.xsd
http://www.mulesoft.org/schema/mule/validation
http://www.mulesoft.org/schema/mule/validation/current/mule-validation.xsd">
<db:config name="Database_Config" doc:name="Database Config"
doc:id="d31ea473-7b58-4d28-83b3-bed7e0bebf2c" >
<db:oracle-connection host="localhost" user="system" password="system"
instance="xe" />
</db:config>
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener
config" doc:id="78fddb86-0942-4ccf-a300-2d721291c964" basePath="/emp_service"
>
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<flow name="mule1Flow" doc:id="246fb555-ea4b-4b9f-bf2c-a332dc3a0ea1" >
<http:listener doc:name="Add_emp_Listener" doc:id="a9d8ff2a-00a7-4759-
8c0f-c53b9211e0e9" config-ref="HTTP_Listener_config" path="add_emp"
allowedMethods="POST"/>
<validation:custom-validator doc:name="validation"
class="com.poltu.validation.CustomValidator" />
<db:insert doc:name="Insert" doc:id="d44b5680-ae0a-4e97-8c91-
9baba4039e7e" config-ref="Database_Config">
<db:sql ><![CDATA[insert into emp_details
values(:emp_id,:emp_name,:emp_status)]]></db:sql>
<db:input-parameters ><![CDATA[#[{
"emp_id": payload.emp_id,
"emp_name" : payload.emp_name,
"emp_status" : payload.emp_status
}]]]></db:input-parameters>
</db:insert>
<ee:transform doc:name="Transform Message" doc:id="7e7be7f4-c2fc-43f9-
8b76-bf63bf8ac51b" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
"status":"OK",
"response":"Created re bhaii...."
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<logger level="INFO" doc:name="Logger" doc:id="647043ee-5a28-414e-898e-
dce291114c2c" message="response payload is -- #[payload.response]"/>
</flow>
</mule>
The documentation that you are using is for Mule 3.9. That method is not compatible with Mule 4. To create a custom validator in Mule 4 you need to create a Mule Extension with the Mule SDK for Java. Follow the instructions to create the module. Once your module builds, add a validator operation as described at https://docs.mulesoft.com/mule-runtime/4.3/migration-module-validation#custom_validator

camel-http4 post not working I get no response

this is my first camel HTTP4 implementation and having trouble. I get no response as if the route to URI is wrong and message goes ??? it doesn't make the HTTP4 call it appears?
using camel-version 2.17.0.redhat-630310, java 8
my pom has dependency
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http4</artifactId>
</dependency>
my route
<route
id="core.getToken.route"
autoStartup="true" >
<from id="getToken" ref="getToken" />
<process ref="uAARequestTokenProcessor" />
<log message="Message after uAARequestTokenProcessor: ${body}" loggingLevel="INFO"/>
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<to uri="http4://dummyhost" />
<log message="After HTTP4 POST: ${body}" loggingLevel="INFO"/>
<to uri="{{accessToken}}" />
</route>
I call the uAARequestTokenProcessor to condition the outbound message.
public class UAARequestTokenProcessor implements Processor {
private static final Logger LOG = LoggerFactory.getLogger(UAARequestTokenProcessor.class);
#Override
public void process(Exchange exchange) throws Exception {
LOG.info("Entering UAA Request Token Processor: start " );
final String clientId = (String)exchange.getIn().getHeader("CLIENTID");
final byte[] ClientId = clientId.getBytes("UTF-8");
final String userName = (String)exchange.getIn().getHeader("USERNAME");
final String password = (String)exchange.getIn().getHeader("PASSWORD");
final String tokenUrl = (String)exchange.getIn().getHeader("TOKENURL");
LOG.info("ClientId: " + new String(ClientId));
LOG.info("userName: " + userName);
LOG.info("password: " + password);
LOG.info("tokenUrl: " + tokenUrl);
LOG.info("Processing UAA token request for Client ID: " + clientId + " and User Name: " + userName);
LOG.info("Before Base64 encryption of Client ID: " + new String(ClientId));
StringBuilder authHeader = new StringBuilder("Basic ");
authHeader.append(Base64.getEncoder().encodeToString(ClientId));
LOG.info("after Base64 encryption of Client ID: " + authHeader.toString());
String body = String.format("grant_type=password&username=%s&password=%s",
URLEncoder.encode(userName, "UTF-8"), //Translates a string into x-www-form-urlencoded format
URLEncoder.encode(password, "UTF-8"));
LOG.info("HTTP BODY: " + body);
exchange.getIn().setHeader(Exchange.HTTP_URI, tokenUrl);
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "MediaType.APPLICATION_FORM_URLENCODE");
exchange.getIn().setHeader("Authorization", authHeader.toString());
exchange.getIn().setBody(body);
LOG.info("Exchange.HTTP_URI: " + exchange.getIn().getHeader("Exchange.HTTP_URI"));
LOG.info("Exchange.CONTENT_TYPE: " + exchange.getIn().getHeader("Exchange.CONTENT_TYPE"));
LOG.info("Authorization: " + exchange.getIn().getHeader("Authorization"));
LOG.info("Exiting UAA Request Token Processor: Finish " );
}
}
it looks like to me that the Exchange.HTTP_URI or HTTP headers are not getting set unless the headers for HTTP4 are different? but I'm following the HTTP4 doc, https://github.com/apache/camel/blob/master/components/camel-http4/src/main/docs/http4-component.adoc
what happens is inside the processor I try to read the HTTP headers and it shows they are null, after being set.
Entering UAA Request Token Processor: start
ClientId: ingestor.57e72dd3-6f9e-4931-b4bc-cd04eaaff3e3.1f7dbe12-2372-439e-8104-06a5f4098ec9
userName: 5c0642fe-a495-44db-93f7-67056fa2c061_ingestor
password: 154f0252d166f27b5e21ef171b02a79f41a0daf3
tokenUrl: http4://d1e53858-2903-4c21-86c0-95edc7a5cef2.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token
Processing UAA token request for Client ID: ingestor.57e72dd3-6f9e-4931-b4bc-cd04eaaff3e3.1f7dbe12-2372-439e-8104-06a5f4098eff9 and User Name: 5c0232fe-a495-44db-94f7-67156fa2c061_ingestor
Before Base64 encryption of Client ID: ingestor.57e72dd3-6f9e-4931-b4bc-cd04eaaff3e3.1f7dbe12-2372-439e-8104-06a5f4098eff9
after Base64 encryption of Client ID: Basic aW5nZXN0b3IuNTdlNzJkZDMtNmY5ZS00OTMxLWI0YmMtY2QwNGVhYWZmM2UzLjFmN2RiZTEyLTIzNzItNDM5ZS04MTA0LTA2YTVmNDA5OGVjOQ==
HTTP BODY: grant_type=password&username=5c0232fe-a495-44db-94f7-67156fa2c061_ingestor&password=154f0252d166f27b5e21ef171b02beebop
Exchange.HTTP_URI: null
Exchange.CONTENT_TYPE: null
Authorization: Basic aW5nZXN0b3IuNTdlNzJkZDMtNmY5ZS00OTMxLWI0YmMtY2QwNGVhYWZmM2UzLjFmN2RiZTEyLTIzNzItNDM5ZS04MTA0LTA2YTVmNDA5OGVjOQ==
Exiting UAA Request Token Processor: Finish
The stack trace shows headers but not as EXCHANGE.HTTP_URI
2018-04-23 13:17:29,203 | INFO | ile://ge-ip/core | Tracer | 231 - org.apache.camel.camel-core - 2.17.0.redhat-630310 | ID-alphprdfuse2i-44477-1524503724804-3-52 >>>
(core.getToken.route) setHeader[CamelHttpMethod, POST] --> http4://predhost <<< Pattern:InOnly,
Headers:{Authorization=Basic aW5nZXN0b3IuNTdlNzJkZDMtNmY5ZS00OTMxLWI0YmMtY2QwNGVhYWZmM2UzLjFmN2RiZTEyLTIzNzItNDM5ZS04MTA0LTA2YTVmNDA5OGVjOQ==,
breadcrumbId=ID-alphprdfuse2i-44477-1524503724804-3-50,
CamelFileAbsolute=false,
CamelFileAbsolutePath=/app/iprctest/jboss-fuse-6.3.0.redhat-310/ge-ip/core/Noble/nst_dge-1_2018-04-10_19-55-10.CSV, CamelFileLastModified=1524503800000,
CamelFileLength=3706, CamelFileName=Noble/nst_dge-1_2018-04-10_19-55-10.CSV, CamelFileNameConsumed=Noble/nst_dge-1_2018-04-10_19-55-10.CSV, CamelFileNameOnly=nst_dge-1_2018-04-10_19-55-10.CSV,
CamelFileNameProduced=ge-ip/upload/Noble/nst_dge-1_2018-04-10_19-55-10.CSV, CamelFileParent=ge-ip/core/Noble,
CamelFilePath=ge-ip/core/Noble/nst_dge-1_2018-04-10_19-55-10.CSV, CamelFileRelativePath=Noble/nst_dge-1_2018-04-10_19-55-10.CSV, CamelHttpMethod=POST,
CamelHttpUri=http4://d1e53858-2903-4c21-86c0-95edc7a5cef2.pred-uaa.run.aws-usw02-pr.ice.pred.io/oauth/token,
CLIENTID=ingestor.57e72dd3-6f9e-4931-b4bc-cd04eaaff3e3.1f7dbe12-2372-439e-8104-06a5f4098ec9,
Content-Type=MediaType.APPLICATION_FORM_URLENCODE,
CUSTKEY=Noble, PASSWORD=154f0252d166f27b5e21a79f41a0daf3,
TENANTUUID=c0642fe-a495-44db-93f7-67056fa2c061,
TOKENURL=http4://d1e53858-2903-4c21-86c0-95edc7f2.pred-uaa.run.aws-usw02-pr.ice.pred.io/oauth/token,
UPLOADURL=http4://apm-times-query-svc-prod.app-api.aws-usw02-pr.pred.io/v2/time_series/upload,
USERNAME=5c0642fe-a495-44db-93f7-67056fa2c061_ingestor},
BodyType:String, Body:grant_type=password&username=5c0642fe-a495-44db-93f7-2c061_ingestor&password=154f0252d166f2ef171b02a79f41a0daf3
THE http4://predhost is a dummy URI in the spring XML and should be over ridden by the exchange.getIn().setHeader(Exchange.HTTP_URI, tokenUrl);
I never reach the URL endpoint and never reach the log message after making the to HTTP4://
<to uri="http4://predixhost" />
<log message="After HTTP4 POST: ${body}" loggingLevel="INFO"/>
I have tried the following but still get no response, no exceptions, nothing. setting the header CamelHttpUri to overirde the default dummy uri, and a dynamic toD, ???
<route
id="core.getToken.route"
autoStartup="true" >
<from id="getToken" ref="getToken" />
<process ref="uAARequestTokenProcessor" />
<!-- <log message="Message after uAARequestTokenProcessor: ${body}" loggingLevel="INFO"/> -->
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<!-- <setHeader headerName="CamelHttpUri">
<simple>${header.TOKENURL}</simple>
</setHeader> -->
<toD uri="${header.TOKENURL}" />
<log message="After HTTP4 POST: ${body}" loggingLevel="INFO"/>
<to uri="{{accessToken}}" />
</route>
I don't know what is wrong? I can't get a response, an exception, it looks like I cannot send to the HTTP4 endpoint. I am reaching now, verified my proxy settings in the environment, and also tried in the camel context, I don't know what is going on or what to do, I get no logging info to go on, ...
<camelContext
id="com.passthru.coreCamelContext"
trace="true"
xmlns="http://camel.apache.org/schema/blueprint"
allowUseOriginalMessage="false"
streamCache="true"
errorHandlerRef="deadLetterErrorHandler" >
<properties>
<property key="http.proxyHost" value="PITC-Zscaler-Americas-Cin.proxy.corporate.comp.com"/>
<property key="http.proxyPort" value="80"/>
</properties>
<streamCaching id="CacheConfig"
spoolUsedHeapMemoryThreshold="70"
anySpoolRules="true"/>
I've tried with CURL and it works from command line, I've tried with Postman and it works. thanks for your help.
What this is to do, simply POST a message to an UAA(https) service with a body of:
grant_type=password&username=myUserName&password=myPassword
and headers:
Content-Type=application/x-www-form-urlencoded
Authorization=Basic aW5nZXN0b3IuNTdlNzJkZDMt==
and the server will issue an access token.
like this postman example:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "username=93f7c061_ingestor&password=15a79f41a0daf3&grant_type=password");
Request request = new Request.Builder()
.url("https://d1e53858-2903-4c21-86c0-95edc7a5cef2.uaa.run.aws-usw02-pr.ice.io/oauth/token")
.post(body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Authorization", "Basic aW5nZXN0b3IuNTdlNzJkZDMtNmY5ZS00OTMxLWI0YmMtY2QwNGVhYWZmM2UzLjFmN2RiZTEyLTIzNzItNDM5ZS04MTA0LTA2YTVmNDA5OGVjOTo=")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "ad8ba9b0-6215-4c53-a6ef-b3a5bf7901f6")
.build();
Response response = client.newCall(request).execute();
Hello I hope there is someone out there that can help, I'm stuck.
I have confirmed, I believe that the HTTP4 endpoint is not working. I have a deadletter queue
<bean id="deadLetterErrorHandler" class="org.apache.camel.builder.DeadLetterChannelBuilder">
<property name="deadLetterUri" value="${deadLetterQueue}"/>
<property name="redeliveryPolicy" ref="redeliveryPolicyConfig"/>
</bean>
<bean id="redeliveryPolicyConfig" class="org.apache.camel.processor.RedeliveryPolicy">
<property name="maximumRedeliveries" value="3"/>
</bean>
and each exchange sent to this endpoint is tried 3x and then sent to the deadletter queue. the content of the message in the deadletter queue is what should be sent to the HTTP4 endpoint and thus the UAA service.
├── deadletterqueue
│   ├── ID-alphprdfuse2i-36326-1524606956414-3-65
grant_type=password&username=5c0642fe_ingestor&password=02a79f41a0daf3
the message headers leading in to this look good too.
core.getToken.route) log[HTTP4 POST body: ${body}] --> http4://d1e53858-2903-4c21-86c0-95edc7a5cef2.uaa.run.aws-usw02.io:443/oauth/token?throwExceptionOnFailure=false <<< Pattern:InOnly, Headers:{Authorization=Basic aW5nZXN0b3IuNTdlNzJkZDMtNmY5ZS00OTMxLWI0YmMtY2QwNGVhYWZmM2UzLjFmN2RiZTEyLTIzNzItNDM5ZS04MTA0LTA2YTVmNDA5OGVjOQ==, CamelHttpCharacterEncoding=UTF-8, CamelHttpMethod=POST, CamelHttpUri=http4://d1e53858-2903-4c21-86c0-95edc7a5cef2.uaa.run.aws.io:443/oauth/token, Content-Type=MediaType.APPLICATION_FORM_URLENCODE, TOKENURL=http4://d95edc7a5cef2.uaa.run.aws-usw02-pr.ice.io:443/oauth/token}, BodyType:String, Body:grant_type=password&username=5c06-a495-44db-93f7-67056fa2c061_ingestor&password=7b5e21ef171b02a79f41a0daf3
I'm convinced it must be something wrong with the way I'm implementing HTTP4. I do not need to expose a web service I only need to push to it. I can't get this to work. please help.
ok, this was a multi faceted problem.
1st my proxy setting was incorrect. I found it has to be set with either the IP or the name, cononical name without the protocol http://.
I had it like:
<camelContext
id="com.ge.digital.passthru.coreCamelContext"
trace="true"
xmlns="http://camel.apache.org/schema/blueprint"
allowUseOriginalMessage="false"
streamCache="true"
errorHandlerRef="deadLetterErrorHandler" >
<properties>
<property key="http.proxyHost" value="http://PITC-Zscaler-Americas.proxy.corporate.com"/>
<property key="http.proxyPort" value="80"/>
</properties>
but as mentioned this apparently is incorrect and do not use the protocol in the def. like:
<properties>
<property key="http.proxyHost" value="PITC-Zscaler-Americas.proxy.corporate.com"/>
<property key="http.proxyPort" value="80"/>
</properties>
or
<properties>
<property key="http.proxyHost" value="123.123.123.123"/>
<property key="http.proxyPort" value="80"/>
</properties>
this gave me a response, not the one I was hoping for but one that gave me hope.
this gave me a 504 gateway timeout, wow, i was getting something back. :)
2nd, The endpoint over ride wasn't working...
m.setHeader(Exchange.HTTP_URI, tokenUrl);
using
<toD uri="${header.TOKENURL}?throwExceptionOnFailure=false" />
<toD uri="${header.TOKENURL}" />
so I just tried a simple to in the route
<to uri="http4://d1e53858-uaa.run.aws-usw02-pr.ice.io:443/oauth/token?throwExceptionOnFailure=false" />
with the over ride
m.setHeader(Exchange.HTTP_URI, tokenUrl);
where the tokenUrl was defined as
http4://d1e53858-uaa.run.aws-usw02-pr.ice.io:443/oauth/token
this gives me a 504, I was hoping this was something I could take care of on my side, usually isn't but sometimes... so I kept trying things... until... I used the actual address in the HTTP_URI like...
https://d1e53858-uaa.run.aws-usw02-pr.ice.io/oauth/token
and now I am getting a CamelHttpResponseCode=401, CamelHttpResponseText=Unauthorized
I'm one happy camper, this is something I can work with... I then tested the same substitution setting the URI in the route in xml. and this worked also.
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<log message="HTTP4 POST headers: ${headers}" loggingLevel="DEBUG"/>
<setHeader headerName="CamelHttpUri">
<simple>${header.TOKENURL}?throwExceptionOnFailure=false</simple>
</setHeader>
<to uri="http4://d1e53858-uaa.run.aws-usw02-pr.ice.io/oauth/token?throwExceptionOnFailure=false" />
I am still trying to get the dynamic route working, but I'm satisfied with what I have and will focus more on that later.
<toD uri="${header.TOKENURL}?throwExceptionOnFailure=false" />
<toD uri="${header.TOKENURL}" /> -->
thank you everyone, I hope my struggles as a newbie help others, I can't be the only one with these silly happenings. anyway, cheers all.

How to upload & download files using mule in Anypoint Studio using FTP connector?

I tried using FTP connector and FileZilla FTP server (xampp).
Here is my flow code and output. In case when I'm using SFTP I'm getting output as "connection is closed by foreign host".
Configuration XML:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:sftp="http://www.mulesoft.org/schema/mule/sftp" xmlns:ftp="http://www.mulesoft.org/schema/mule/ee/ftp" 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"
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/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/ee/ftp http://www.mulesoft.org/schema/mule/ee/ftp/current/mule-ftp-ee.xsd
http://www.mulesoft.org/schema/mule/sftp http://www.mulesoft.org/schema/mule/sftp/current/mule-sftp.xsd">
<file:connector name="FileRead" readFromDirectory="D:\Data\input" autoDelete="false" streaming="true" validateConnections="true" doc:name="File"/>
<ftp:connector name="FTP" pollingFrequency="1000" validateConnections="true" outputPattern="output.json" doc:name="FTP"/>
<flow name="ftpFlow">
<file:inbound-endpoint path="D:\Data\input" connector-ref="FileRead" pollingFrequency="100000" responseTimeout="10000" doc:name="File"/>
<ftp:outbound-endpoint host="127.0.0.1" port="14147" passive="true" responseTimeout="10000" doc:name="FTP" connector-ref="FTP" outputPattern="output.json" password="kamal" path="/" user="kamal"/>
</flow>
</mule>
Console Output:
INFO 2018-03-01 13:00:07,218 [[ftp].FileRead.receiver.01] org.mule.transport.file.FileMessageReceiver: Lock obtained on file: D:\Data\input\example.json
INFO 2018-03-01 13:00:07,300 [[ftp].FTP.dispatcher.01] org.mule.lifecycle.AbstractLifecycleManager: Initialising: 'FTP.dispatcher.145993108'. Object is: FtpMessageDispatcher
INFO 2018-03-01 13:00:07,305 [[ftp].FTP.dispatcher.01] org.mule.lifecycle.AbstractLifecycleManager: Starting: 'FTP.dispatcher.145993108'. Object is: FtpMessageDispatcher
ERROR 2018-03-01 13:01:12,866 [[ftp].FTP.dispatcher.01] org.mule.retry.notifiers.ConnectNotifier: Failed to connect/reconnect: EEFtpConnector
{
name=FTP
lifecycle=start
this=608b1fd2
numberOfConcurrentTransactedReceivers=4
createMultipleTransactedReceivers=true
connected=true
supportedProtocols=[ftp]
serviceOverrides=<none>
}
. Root Exception was: Could not parse response code.
Server Reply: FZS
Listening port of File Zilla was 21. Port 14147 is administration port.
Use the little small groovy script provided in that.This should work .I just tested this and working as expected .Deleting can be done by autoDelete attribute or fileAge .Please let me know if this helps
<flow name="ftptestFlow">
<ftp:inbound-endpoint host="hostname" port="port" path="path/filename" user="userid" password="password" responseTimeout="10000" doc:name="FTP"/>
<set-variable variableName="fileName" value="fileName" doc:name="fileName"/>
<scripting:component doc:name="getFile">
<scripting:script engine="Groovy"><![CDATA[new File(flowVars.fileName).getText('UTF-8')]]></scripting:script>
</scripting:component>
<file:outbound-endpoint path="path" outputPattern="filename" responseTimeout="10000" doc:name="File"/>
</flow>

Mule inserting empty payload in JMS queue in catch-exception strategy block

I am simulating a time-out exception (or any other for that sake) when calling external vendor web service. I store the original payload at the start of flow and in catch-exception-strategy, replace the payload with original payload. Payload gets replaced fine, apply XSLT transformer fine, copy the transformed payload to file outbound fine but the strange thing is JMS gets empty message (though message properties are intact). Using Mule 3.3.1 and ActiveMQ. Result is same if Active MQ is replaced by Sonic
<flow name="orderRequirementsToVendor">
<jms:inbound-endpoint queue="order.vendor" />
<set-variable variableName="originalPayload" value="#[message.payload]" />
<outbound-endpoint address="${vendor.ws.url}" mimeType="text/xml" connector-ref="https.connector" responseTimeout="100">
<cxf:proxy-client payload="body" enableMuleSoapHeaders="false">
<cxf:inInterceptors>
<spring:bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<spring:bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</cxf:outInterceptors>
</cxf:proxy-client>
</outbound-endpoint>
.
.
.
<choice-exception-strategy>
<catch-exception-strategy>
<logger message="In catch exception strategy. Unknown Exception" level="ERROR" />
<logger message="#[exception.causeException]" level="ERROR" />
<set-payload value="#[flowVars.originalPayload]"/>
<set-property propertyName="exception" value="#[exception.summaryMessage]"/>
<transformer ref="generalErrorTransformer" />
<file:outbound-endpoint path="/outbound/vendor/error/ack-before" outputPattern="out_vendor_transformed_ack_error_beforeStatusQueue[function:dateStamp].xml" />
<jms:outbound-endpoint queue="order.status" />
<file:outbound-endpoint path="/outbound/vendor/error/ack-after" outputPattern="out_vendor_transformed_ack_error_afterStatusQueue[function:dateStamp].xml" />
</catch-exception-strategy>
</choice-exception-strategy>
</flow>
Both ack-before and ack-after has files with correct payload in them but message received in order.status is empty
EDIT:
This is the exception in my logs
2013-05-29 09:12:33,864 ERROR [orderRequirementsToVendor.stage1.02] exception.AbstractExceptionListener (AbstractExceptionListener.java:299) -
********************************************************************************
Message : COULD_NOT_READ_XML_STREAM. Failed to route event via endpoint: org.mule.module.cxf.CxfOutboundMessageProcessor. Message payload is of type: PostMethod
Code : MULE_ERROR-42999
--------------------------------------------------------------------------------
Exception stack is:
1. Read timed out (java.net.SocketTimeoutException)
java.net.SocketInputStream:-2 (null)
2. Read timed out (com.ctc.wstx.exc.WstxIOException)
com.ctc.wstx.sw.BaseNsStreamWriter:617 (null)
3. COULD_NOT_READ_XML_STREAM (org.apache.cxf.interceptor.Fault)
org.apache.cxf.databinding.stax.StaxDataBinding$XMLStreamDataWriter:133 (null)
4. COULD_NOT_READ_XML_STREAM. Failed to route event via endpoint: org.mule.module.cxf.CxfOutboundMessageProcessor. Message payload is of type: PostMethod (org.mule.api.transport.DispatchException)
org.mule.module.cxf.CxfOutboundMessageProcessor:144 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

Is there a way to connect to https server by specifying only the url in Mule 2?

When I run this:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://www.mulesource.org/schema/mule/http/2.2"
xmlns:https="http://www.mulesource.org/schema/mule/https/2.2"
xsi:schemaLocation="
http://www.mulesource.org/schema/mule/http/2.2 http://www.mulesource.org/schema/mule/http/2.2/mule-http.xsd
http://www.mulesource.org/schema/mule/https/2.2 http://www.mulesource.org/schema/mule/https/2.2/mule-https.xsd
http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd">
<model>
<service name="ConnectToHTTPS">
<inbound>
<http:inbound-endpoint host="localhost"
port="9000"
synchronous="true"/>
</inbound>
<outbound>
<chaining-router>
<outbound-endpoint address="https://localhost"
synchronous="true"/>
</chaining-router>
</outbound>
</service>
</model>
</mule>
I get this:
...
ERROR 2011-07-05 13:06:28,826 [main] org.mule.MuleServer:
********************************************************************************
Message : Failed to invoke lifecycle phase "initialise" on object: HttpsConnector{this=1efe475, started=false, initialised=false, name='connector.https.0', disposed=false, numberOfConcurrentTransactedReceivers=4, createMultipleTransactedReceivers=true, connected=false, supportedProtocols=[https], serviceOverrides=null}
Type : org.mule.api.lifecycle.LifecycleException
Code : MULE_ERROR-70228
JavaDoc : http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/lifecycle/LifecycleException.html
********************************************************************************
Exception stack is:
1. The Key password cannot be null (java.lang.IllegalArgumentException)
org.mule.api.security.tls.TlsConfiguration:290 (null)
2. Failed to invoke lifecycle phase "initialise" on object: HttpsConnector{this=1efe475, started=false, initialised=false, name='connector.https.0', disposed=false, numberOfConcurrentTransactedReceivers=4, createMultipleTransactedReceivers=true, connected=false, supportedProtocols=[https], serviceOverrides=null} (org.mule.api.lifecycle.LifecycleException)
org.mule.lifecycle.DefaultLifecyclePhase:277 (http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/lifecycle/LifecycleException.html)
********************************************************************************
...
You need to explicitly configure the HTTPS connector with a client keystore so you can make outbound HTTPS calls. This is explained here (free registration required to read this doc).
In essence, it boils down to this:
<https:connector name="httpConnector">
<https:tls-client path="clientKeystore" storePassword="mulepassword"/>
</https:connector>

Resources