Flow Vars getting lost after Facebook Authorize in MuleStudio - facebook

I have a simple Flow to authorize to Facebook and then to post a Message.
<flow name="drupal-esbFlow2" doc:name="drupal-esbFlow2">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" doc:name="HTTP"/>
<set-variable variableName="facebookMSG" value="#[message.inboundProperties['msg']]" doc:name="Variable"/>
<facebook:authorize config-ref="Facebook" doc:name="Authorize"/>
<set-session-variable variableName="accessTokenId" value="#[flowVars['OAuthAccessTokenId']]" doc:name="Get OAuthAccessTokenId"/>
<facebook:publish-message config-ref="Facebook" msg="#[flowVars['facebookMSG']]" profile_id="100001574667695" accessTokenId="#[sessionVars['accessTokenId']]" doc:name="Publish Message"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
The Idea is that i want to hit the endpoint localhost:8082?msg=myMessage. Then i want to safe the inboundProperties['msg'] in a Flow Variable and use this in the Facebook Connector. But it seems that the Variables gets lost in the Transport...
I have read that this is an known issue (mule facebook - flow variable), but is there no walk around or something?

Well as the answer sort of alludes to, it seems the authorize mp is intended to be called in complete isolation of any other logic and simply return the access token id via an http:response-builder. The client is then responsible for sending the access token id to another flow for any other processing:
<flow name="authorizationAndAuthenticationFlow">
<http:inbound-endpoint host="localhost" port="8080" path="oauth-authorize"/>
<facebook:authorize/>
<http:response-builder status="200">
<http:set-cookie name="accessTokenId" value="#[flowVars['OAuthAccessTokenId']]"/>
<set-payload value="You have successfully authorized the connector. You access token id is #[flowVars['OAuthAccessTokenId']]"/>
</http:response-builder>
</flow>
I can sort of see why, but makes you architect your app in a very specific way.
The other options is to use the "state" parameter. But this depends on on what types of data you're in your flow vars. Example:
<facebook:authorize state="#[flowVars.myvalue]"/>
This will then get returned in the callback as an inbound property that can be retrieved via:
#[message.inboundProperties['state']]
etc.
Alternatively you could look at persisting certain values, possibly in the mule object-store.

Related

How to get MAM message ID of sent messages?

I am using eJabberd server (MAM enabled) with client library Strophe.js. Client app is storing fixed amount of the messages in local storage.
All the messages, that I receive from the server include elements <archived/> and <stanza-id/>, which provide server-side generated IDs:
<message
xmlns="jabber:client" to="aaa#example.net/8667085700924567016834" from="aaa#example.net">
<result
xmlns="urn:xmpp:mam:2" id="1520510373346685">
<forwarded
xmlns="urn:xmpp:forward:0">
<message
xmlns="jabber:client" xml:lang="en" to="bbb#example.net" from="aaa#example.net/60965696931000870402419" type="chat">
<archived
xmlns="urn:xmpp:mam:tmp" by="aaa#example.net" id="1520510373346685"/>
<stanza-id
xmlns="urn:xmpp:sid:0" by="aaa#example.net" id="1520510373346685"/>
<body>asdf</body>
</message>
<delay
xmlns="urn:xmpp:delay" from="example.net" stamp="2018-03-08T11:59:33.346685Z"/>
</forwarded>
</result>
</message>
I use these IDs to get fixed amount of messages on each MAM call (using RSM paging - before/after/max attributes). For example:
params = {
"before": "1520510373346685",
"max": 10,
onMessage: <some handler>,
onComplete: <some handler>,
}
this.connection.mam.query(Strophe.getBareJidFromJid(this.myJid), params);
This gets me 10 messages before the message with stanza-id 1520510373346685.
However, the messages I send inherently do not have this ID, until I send them and retrieve from MAM.
I did not find any examples on getting the currently sent message ID from the server, and the Strophe does not provide any callbacks after the message was sent from the client and received by the server.
So, the question - is there any way to get the server-generated message ID (stanza-id/archived) for the currently sent message?
Maybe my own approach is wrong - should I generate my own IDs and add it to each message from the client?
There is currently no mechanism specified besides querying the archive. One prominent idea within the XMPP community to solve this in the future is to reflect the send carbon back to the original sender, which would include a stanza-id element with the ID assigned by the archive.

Mule REST APIKit- My flow isn't returning a messge body

**Issue solved, thanks to neildo. Here's what it took to get a response from a POST
RAML file must have a response body definition
HTTP Endpoint must be set to request-response
All Flows using the synchronous Processing Strategy
Accept and Content-Type HTTP headers set to application/json on the request
**
The implementation of my REST Flow calls a Java API that returns a Java object. I then convert the object to a JSON document and return it to the client. My Logger step is logging the correct data, however the client just gets a 200 OK with an empty body.
I have set all my Flows to synchronous and my HTTP Endpoint to request-response. What am I missing?
Thank you!
Nathan
Here is my XML file
<apikit:config name="IAMPerson-config" raml="IAMPerson.raml" consoleEnabled="true" consolePath="console" doc:name="Router"/>
<apikit:mapping-exception-strategy name="IAMPerson-apiKitGlobalExceptionMapping">
<apikit:mapping statusCode="404">
<apikit:exception value="org.mule.module.apikit.exception.NotFoundException" />
<set-property propertyName="Content-Type" value="application/json" />
<set-payload value="{ "message": "Resource not found" }" />
</apikit:mapping>
...
</apikit:mapping-exception-strategy>
<flow name="IAMPerson-main" doc:name="IAMPerson-main" processingStrategy="synchronous">
<http:inbound-endpoint address="http://localhost:8081/api" doc:name="HTTP" exchange-pattern="request-response" password="admin" user="admin" contentType="application/json"/>
<apikit:router config-ref="IAMPerson-config" doc:name="APIkit Router"/>
<exception-strategy ref="IAMPerson-apiKitGlobalExceptionMapping" doc:name="Reference Exception Strategy"/>
</flow>
<flow name="post:/person:IAMPerson-config" doc:name="post:/person:IAMPerson-config" processingStrategy="synchronous">
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="PersonDTO"/>
<invoke name="invokeCreate" object-ref="personService" method="create" methodArguments="#[payload]"></invoke>
<json:object-to-json-transformer sourceClass="Person" doc:name="Person Object to JSON"/>
<logger level="INFO" doc:name="Logger" message="#[payload]"/>
</flow>
<flow name="put:/person:IAMPerson-config" doc:name="put:/person:IAMPerson-config" processingStrategy="synchronous">
<logger level="INFO" doc:name="Logger" message="#[payload]"/>
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="PersonDTO"/>
<invoke name="invokeUpdate" object-ref="personService" method="update" methodArguments="#[payload]"/>
<json:object-to-json-transformer sourceClass="Person" doc:name="Person Object to JSON"/>
<logger level="INFO" doc:name="Logger" message="#[payload]"/>
</flow>
Here is part of my RAML file where I define a request and response body. When I posted a message to Mule, I got this error with nothing logged to the Mule console.
null (java.lang.NullPointerException). Message payload is of type: ContentLengthInputStream
post:
body:
application/json:
responses:
200:
body:
application/json:
In your raml file, make sure your resource method is mapping the response 200 body with application/json. For example...
/person:
post:
responses:
200:
body:
application/json:
I had the same problem (using version 3.5.0), but with a GET request. None of the proposed solutions (neither items 1 through 4 at the top of the edited question, nor the checked answer) solved the problem for me. (Most of them were already true in my case.)
What did work for me was adding the following at the bottom of the problematic GET flow's XML:
<response>
<set-property propertyName="Content-Type" value="application/json"/>
</response>
Unfortunately, there seems to be no way to do this using the visual editor (in the "Message Flow" tab). I had to do this manually in the "Configuration XML" tab instead.
Also, inserting the above element in the main flow (the one that invokes the APIKit Router) -- which has to be done BEFORE the <exception-strategy> element for some reason -- does not solve the problem. However, in this case, the response element DOES show up in the visual editor.
I looked at this page on SO 15 times before I realized how I'd caused this. I'd added a Transformer to do some authentication. I'd customized my onCall method, but left transformMessage as the default which sets a 200 and returns null.
Lo and behold, changing return null to return message made everything work again.
Use this format of response for 200 status code in your RAML file.
responses:
200:
body:
application/json:

Mule Rest Post call to SFDC to create a lead

I need to post a Rest call to SFDC with the respective credentials and create the SalesLead in SFDC. The response should come inthe form of Acknowledgment JSON response.
I am not sure how to use http:rest-service-component to post the data for creating lead.
Any help or sample is appreciated...
It is resolved now by using the "https:outbound-endpoint". All this code need is a JSON object as input.
Below is the snippnet:
<https:outbound-endpoint
method="POST" exchange-pattern="request-response"
address="url"
contentType="application/json" doc:name="HTTP" >
<message-properties-transformer scope="outbound">
<add-message-property key="Authorization" value="OAuth ****"/>
</message-properties-transformer>
</https:outbound-endpoint>
<echo-component doc:name="Echo"/>

Debugging 500 Response for Create Sales Receipt Through API Explorer

I've been developing an IPP application using the PHP devkit. I've been using the XML returned from the $object->asIDSXML() method to debug my objects through the API Explorer. Within the API Explorer I have been recieving a very ambiguous error when trying to create a Sales Receipt and I'm hoping I can learn more about the scheme requirements. Is there a validation xsd file somewhere? I'm currently unable to understand why I receive the following 500 code.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <FaultInfo
xmlns="http://www.intuit.com/sb/cdm/baseexceptionmodel/xsd">
<Message>Internal Server Error</Message>
<ErrorCode>500</ErrorCode>
<Cause>SERVER</Cause> </FaultInfo>
The documentation regarding a 500 states something along the lines of :
Possible Causes:
Illegal permissions.
Illegal values that are not verified in the validation process.
Invalid data that the business logic verified.
I know that I have proper permissions, I have authenticated with an OAuth Token that has all privileges. The later two possibilities I believe are the issue, but I don't know how to get any additional information regarding the potentially invalid or missing data. I have literally tried creating a duplicate by using the API explorer to retrieve the SalesReceipt XML and then removing the DocumentID and sending to a create POST through the API explorer at which point I receive the same error shown above.
The following is the XML post data provided to the API. As far as I can tell the xml contains all the required fields fore creating a Sales Receipt. Thanks in advance for any help.
<SalesReceipt>
<Header>
<TxnDate>2013-04-16-07:00</TxnDate>
<CustomerId idDomain="QBO">78</CustomerId>
<TotalAmt>4.00</TotalAmt>
<ShipAddr>
<Line1>123 Fake Ave</Line1>
<City>Fake City</City>
<CountrySubDivisionCode>ID</CountrySubDivisionCode>
<PostalCode>83854</PostalCode>
</ShipAddr>
</Header>
<Line>
<Id>1</Id>
<Desc>Face to face IT Consulting Services, providing solutions to client's IT issues.</Desc>
<Amount>4.00</Amount>
<Taxable>false</Taxable>
<ItemId>17</ItemId>
<UnitPrice>4.00</UnitPrice>
<Qty>1</Qty>
</Line>
</SalesReceipt>
Can you please try the following
<SalesReceipt xmlns='http://www.intuit.com/sb/cdm/v2'>
<Header xmlns:ns3='http://www.intuit.com/sb/cdm/v2'>
<ns3:TxnDate>2013-04-16-07:00</ns3:TxnDate>
<ns3:CustomerId>78</ns3:CustomerId>
<ns3:TotalAmt>4.00</ns3:TotalAmt>
<ShipAddr>
<Line1>123 Fake Ave</Line1>
<City>Fake City</City>
<CountrySubDivisionCode>ID</CountrySubDivisionCode>
<PostalCode>83854</PostalCode>
</ShipAddr>
</Header>
<Line xmlns:ns11='http://www.intuit.com/sb/cdm/v2'>
<ns11:Id>101</ns11:Id>
<ns11:Desc>Face to face IT Consulting Services, providing solutions to client's IT issues.</ns11:Desc>
<ns11:Amount>4.00</ns11:Amount>
<ns11:Taxable>false</ns11:Taxable>
<ns11:ItemId>17</ns11:ItemId>
<ns11:UnitPrice>4.00</ns11:UnitPrice>
<ns11:Qty>1</ns11:Qty>
</Line>
</SalesReceipt>

Quartz Generator and exception handling

i have a flow that works as follows:
<flow name="ChatListener">
<quartz:inbound-endpoint jobName="eventTimer"
repeatInterval="${chatListener.pollingInterval}">
<quartz:event-generator-job />
</quartz:inbound-endpoint>
<filter ref="ActiveTrainingFilter" />
<component>
<singleton-object class="com.ChatListener.ChatListener" />
</component>
<not-filter>
<payload-type-filter expectedType="org.mule.transport.NullPayload" />
</not-filter>
<collection-splitter />
<vm:outbound-endpoint path="ChatMsgs"
exchange-pattern="one-way" />
<default-exception-strategy>
<vm:outbound-endpoint path="ErrorMsgs"/>
</default-exception-strategy>
</flow>
Now, what is actually hapenning is that the generator calls the singleton compnent which does some DB retrieval and returns a collection of a java bean class which i later split (the null filter is in case i want to stop the flow).
My problem is - suppose i have an error connecting to the db and the component's oninitialise fails. What would keep the generator from trying to call the component over and over again? (and producing an error every time).
It looks to me as if i've handling something not quite right, So what would be the good to implement it to deal with exceptions?
Any ideas? thanks in advance!
I would try the following:
Declare the quartz endpoint in a global manner,
Use it in the flow.
Create a custom exception strategy and use it in the flow too.
Inject the global quartz endpoint in this custom exception strategy.
In this strategy, if the exception caught is one you deem characteristic to unrecoverable failure, call endpoint.stop().
You would need to go through JMX to restart the endpoint after clearing the error condition.