Salesforce to Mule Soft - salesforce

I have a requirement like, need to pass the Account and contact information from Salesforce to Mule Soft.
It needs to be done by SOAP (WSDL File).
How to get WSDL file from Mulesoft? Anyone have done this is salesforce?
Please guide me how to do this one?

Using Mule Anypoint Studio you can use the Salesforce Connector and a Salesforce flow element that will get Contact information from Salesforce. The Salesforce Connector in Mule uses the SOAP interface from Salesforce.
Inside your Mule Flow you can simply use
<sfdc:query config-ref="SalesforceConfig" query="dsql:SELECT * FROM Contact" doc:name="Salesforce"/>
The above code will return you a streaming object. One of the best things to do at that point is implement a Java transformer afterwards to soak up the results and turn it to whatever you want.
<custom-transformer class="org.stackoverflow.transformers.QueryResultsToWhatever" doc:name="Java"/>
The class would then be written in java:
public class QueryResultsToWhatever extends AbstractMessageTransformer {
public Object transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
// get the Streaming list of maps that is the payload
org.mule.streaming.ConsumerIterator<Map<Object, Object>> CI = message
.getPayload(org.mule.streaming.ConsumerIterator.class);
if (CI.hasNext()) {
Object _obj = CI.next();
//Each Iterator represents a row returned from the query
if (_obj instanceof Map) {
Map<Object, Object> sfmap = (Map<Object, Object>) _obj;
// cast it
// Now you have a Map to access each field inside each row
Since this is a pretty simple use case for the Salesforce connector, the tutorials available on https://developer.mulesoft.com/docs/display/current/Salesforce+Connector
Can help greatly.

Related

Apache Camel CXF difficulty calling an RPC/Encoded WSDL when updating list of elements

While not officially supported, with a few minor modifications to the WSDL I was able to successfully generate CXF Objects for the WSDL and get Camel CXF to talk to an RPC/Encoded WSDL endpoint. The code is incredibly simple and most request/responses work without issue except for attempting to send updates of a list of elements. Here is what the service expects:
<elements arrayType="UpdateElement">
VS here is what is being sent:
<elements>
I need to add the arrayType into the outgoing message. I looked into a number of ways of doing this:
1) An interceptor right before the SOAP message is sent by CXF then use XPath to add the element but I was not clear how to accomplish this using Apache Camel + Camel CXF. How to retrieve the CXF client from the Camel Context?
MyService client = ???
2) Fix it via WSDL? Is it possible to add this element to the WSDL so it is generated as a part of the CXF Objects? It is defined like this presently:
<message name="wsdlElementRequest">
<part name="elements" type="tns:UpdateElements" /></message>
'message' and 'part' come from http://schemas.xmlsoap.org/wsdl/.
Any ideas or suggestions would be appreciated. Thanks!
In case anyone ever stumbles on this with a similar issue, I figured it out myself. I was able to retrieve the CxfEndpoint via CamelContext:
camelContext.getEndpoint(endpointUrl, CxfEndpoint.class);
Then I was able to add the interceptor I created:
public class MyCxfInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
...
Using the CxfEndpoint methods:
cxfEndpoint.getOutInterceptors().add(new MyCxfInterceptor());
In my interceptor I also incorporated another interceptor, SAAJOutInterceptor, that converts the SOAP into an easy to work with object:
private List<PhaseInterceptor<? extends Message>> extras = new ArrayList<>(1);
public MyCxfInterceptor() {
super(Phase.USER_PROTOCOL);
extras.add(new SAAJOutInterceptor());
}
public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
return extras;
}
The easy to work with SOAP message:
#Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
SOAPMessage msg = soapMessage.getContent(SOAPMessage.class);
try {
SOAPBody soapBody = msg.getSOAPBody();
Then it was a simple matter of using XPATH to make the correction to the outgoing SOAP message.
private XPath xpath = XPathFactory.newInstance().newXPath();
...
NodeList nodeList = soapBody.getElementsByTagName("tagName");
for (int x = 0; x < nodeList.getLength(); x++) {
Node node = nodeList.item(x);
((Element) node).setAttribute("missingAttributeName", "missingAttributeValue");
}
I hope this helps anyone working with challenging SOAP services!
Credit to the blog which played a big part in enabling me to implement this solution: https://xceptionale.wordpress.com/2016/06/26/message-interceptor-to-modify-outbound-soap-request/

get custom gauge metric from WebMonitorEndpoint (Rest Monitoring API) in Flink

I've got custom metric ->
public class TestMetric implements Gauge<MyType> {
#Override
public MyType getValue() {
final MyType myObject = new MyType();
return myObject;
}
}
And I'm using them as suggested in the documentation ->
getRuntimeContext().getMetricGroup().gauge("MyCustomMetric", new TestMetric());
I want to get this metric with GET method, but so far I tried almost everything in the API documentation (https://ci.apache.org/projects/flink/flink-docs-release-1.8/monitoring/rest_api.html ) but didn't find that metric.
Do you know how (or even could I) get that custom metric via API?
In order to query the metric via Flink's REST interface you need to first figure some ids out:
flink_cluster: Address of your flink cluster
port: Port of REST endpoint
jobId: Id of your job which can be figured out via http://flink_cluster:port/jobs
vertexId: Id of the vertex to query. This can be figured out via http://flink_cluster:port/jobs/:jobId which gives you the job information with all vertexIds
subtaskindex: Index of the parallel subtask to query
http://flink_cluster:port/jobs/:jobId/vertices/:vertexId/subtasks/:subtaskindex/metrics?get=MyCustomMetric

MS Botframework - Access to intent and message

Is it possible to create a plugin that has access to both intent and message at the same time in botframework? I'm specifically interested in creating a plugin that can send the message that was received as well as the intent that was registered and used to outside analytics.
Yes, you can intercept and log messages via custom middleware.
The following code sample shows how to intercept messages that are exchanged between user and bot using the concept of middleware in the Bot Builder SDK for .NET.
First, create a DebugActivityLogger class and define a LogAsync method to specify what action is taken for each intercepted message. This example just prints some information about each message.
public class DebugActivityLogger : IActivityLogger
{
public async Task LogAsync(IActivity activity)
{
Debug.WriteLine($"From:{activity.From.Id} - To:{activity.Recipient.Id} - Message:{activity.AsMessageActivity()?.Text}");
}
}
Then, add the following code to Global.asax.cs. Every message that is exchanged between user and bot (in either direction) will now trigger the LogAsync method in the DebugActivityLogger class.
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterType<DebugActivityLogger>().AsImplementedInterfaces().InstancePerDependency();
builder.Update(Conversation.Container);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
For a complete middleware code example, see: https://github.com/Microsoft/BotBuilder-Samples/tree/master/CSharp/core-Middleware

How to retrieve images from database in an enterprise java bean? (using JPAs and JSP)

My problem is the following: so I have a database that has some customers stored in it. For every customer I added a picture like this:
INSERT INTO ITSO.CUSTOMER (TITLE,FIRST_NAME,LAST_NAME,SSN,IMAGE) VALUES ('Mr','Henry','Cui','111-11-1111', LOAD_FILE('D:/Workspace8/Images/11.jpg'));
How can I retrieve these pictures in an Enterprise java bean? ( I have to mention I am using JPAs). Are the queries a solution?
#NamedQuery(name="getImageForCustomer", query="select image from Customer c where c.ssn=?1")
Do I need to store my picture in a different way?
In the EJB I have this method getCustomer(). Can I add another argument, something like Byte[] image??
public Customer getCustomer(String ssn) throws ITSOBankException {
System.out.println("getCustomer: " + ssn);
try {
return entityMgr.find(Customer.class, ssn);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
throw new ITSOBankException(ssn);
}
My plan is to display the image in a JSP afterwards, using a servlet and an EJB injection.
I would be so grateful if someone can help me!!!
(It's for learning purpose)
First of all, storing image in database is not very good practice. Though it is sufficient for learning purposes, in real application consider storing images in file system or cloud service of your choice and store only path or link to image.
But back to your question.
In your Customer JPA class, you can define field for image annotated with javax.persistence.Lob annotation:
#Lob
private byte[] image;
...and your image data will be loaded into image byte array field by JPA.
To display image on JSP page you have to implement servlet, which will provide image data based on customer id (for example /image?customerId=10). Here is a good example how to implement such a servlet: How to convert byte array to image

Storing the Cursor for App Engine Pagination

I'm trying to implement pagination using App Engine's RPC and GWT (it's an app engine connected project).
How can I pass both the query results and the web-safe cursor object to the GWT client from the RPC?
I've seen examples using a servlet but I want to know how to do it without a servelt.
I've considered caching the cursor on the server using memcache but I'm not sure if that's appropriate or what should be used as the key (session identifier I would assume, but I'm not sure how those are handled on App Engine).
Links to example projects would be fantastic, I've been unable to find any.
OK, so the best way to do this is to store the cursor as a string on the client.
To do this you have to create a wrapper class that is transportable so you can pass back it to the client via RequestFactory that can hold the results list and the cursor string. To do that you create a normal POJO and then a proxy for it.
here's what the code looks like for the POJO:
public class OrganizationResultsWrapper {
public List<Organization> list;
public String webSafeCursorString;
public List<Organization> getList() {
return list;
}
public void setList(List<Organization> list) {
this.list = list;
}
public String getWebSafeCursorString() {
return this.webSafeCursorString;
}
public void setWebSafeCursorString(String webSafeCursorString) {
this.webSafeCursorString = webSafeCursorString;
}
}
for the proxy:
#ProxyFor(OrganizationResultsWrapper.class)
public interface OrganizationResultsWrapperProxy extends ValueProxy{
List<OrganizationProxy> getList();
void setList(List<OrganizationProxy> list);
String getWebSafeCursorString();
void setWebSafeCursorString(String webSafeCursorString);
}
set up your service and requestFactory to use the POJO and proxy respectively
// service class method
#ServiceMethod
public OrganizationResultsWrapper getOrganizations(String webSafeCursorString) {
return dao.getOrganizations(webSafeCursorString);
}
// request factory method
Request<OrganizationResultsWrapperProxy> getOrganizations(String webSafeCursorString);
Then make sure and run the RPC wizard so that your validation process runs otherwise you'll get a request context error on the server.
Here's the implementation in my data access class:
public OrganizationResultsWrapper getOrganizations(String webSafeCursorString) {
List<Organization> list = new ArrayList<Organization>();
OrganizationResultsWrapper resultsWrapper = new OrganizationResultsWrapper();
Query<Organization> query = ofy().load().type(Organization.class).limit(50);
if (webSafeCursorString != null) {
query = query.startAt(Cursor.fromWebSafeString(webSafeCursorString));
}
QueryResultIterator<Organization> iterator = query.iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
resultsWrapper.setList(list);
resultsWrapper.setWebSafeCursorString(iterator.getCursor().toWebSafeString());
return resultsWrapper;
}
a second option would be to save the webSafeCursorString in the memcache, as you already mentioned.
my idea looks like this:
the client sends always request like this "getMyObjects(Object... myParams, int maxResults, String clientPaginationString)". the clientPaginationString is uniquely created like shown below
server receives request and looks into the memcache if there is a webSafeCursorString for the key clientPaginationString
if the server finds nothing, he creates the query and save the webSafeCursorString into memcache with the clientPaginationString as the key. -> returns the results
if the server finds the webSafeCursorString he restarts the query with it and returns the results
the problems are how to clean the memcache and how to find a unique clientPaginationString:
a unique clientPaginationString should be the current UserId + the params of the current query + timestemp. this should work just fine!
i really can't think of a easy way how to clean the memcache, however i think we do not have to clean it at all.
we could store all the webSafeCursorStrings and timestemps+params+userid in a WebSafeCursor-Class that contains a map and store all this in the memcache... and clean this Class ones in a while (timestamp older then...).
one improvement i can think of is to save the webSafeCursorString in the memcache with a key that is created on the server (userSessionId + servicename + servicemethodname + params). however, important is that the client sends an information if he is interested in a new query (memcache is overriden) or wants the next pagination results (gets webSafeCursorString from memcache). a reload of the page should work. a second tap in the browser would be a problem i think...
what would you say?

Resources