Sugar CRM Integration Using Java and Apache Axis - sugarcrm

I'm trying to integrate Sugar CRM with one of my projects. I'm using Apache Axis as my SOAP client.
I got the initial setup from this blog. Using this tutorial I'm able to login, fetch and insert data into my Sugar CRM installation.
I'm trying to fetch Leads using the following code
Get_entry_list_result_version2 entryList = port.get_entry_list(
sessionID, "Leads", "", "", 0, new String[] { "first_name",
"phone_work" }, null, 2, 0);
This portion is working fine, but when I try to add a query criteria as the 3rd parameter, system is throwing an error
Exception in thread "main" AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.xml.sax.SAXParseException: Content is not allowed in prolog.
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXParseException: Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1411)
Thank you
here is my new fetch using the query
Get_entry_list_result_version2 entryList = port.get_entry_list(
sessionID, "Leads", "first_name='arun'", "", 0, new String[] { "first_name",
"phone_work" }, null, 2, 0);
What am I doing wrong?
I've already compiled my axis-1.4 library to fix this bug

Arun P Johny's answer was correct and very helpful. I am using Talend Open Studio w/ tSugarCRMInput component. Even though there is a field for Module, the query does need to be fully qualified.

I figured it out, need to have a query qualified by the module name:
Sorry for my ignorance.
My further searches took me to here.
After fixing my code looks like
Get_entry_list_result_version2 entryList = port.get_entry_list(
sessionID, "Leads", " leads.last_name ='LastName' ", "", 0, new String[] { "first_name",
"phone_work", "sic_code" }, null, 10, 0);
Thanks

Related

How to send a POST request to OData v4 ActionImport with SAPUI5

I would like to send a POST request to an OData v4 ActionImport. How can I achieve this in an SAPUI5 environment? I had a look at the v4 ODataModel and ODataContextBinding. There are methods for execute an ActionImport but i dont know how to set the body then.
Generally asking: How should I submit OData requests that should not necessarily be bound to the UI? For example, if I just want to query a value from the backend or send a file to the backend. Right now, I create an ODataContextBinding and call the execute/requestObject method but i think that this might not be the best approach (Also i cant set the request body this way). Maybe it might be better to make a direct ajax request?
Thanks in advance!
I stumbled on your question because I had the exact same problem. I'm providing my solution in case it helps someone else.
onValidate: function(oEvent) {
var oModel = this.getModel("reportService");
var oActivityCreateContext = this.getCreateContext();
var oActionODataContextBinding = oModel.bindContext("/validateActivity(...)");
oActionODataContextBinding.setParameter("activity", oActivityCreateContext.getObject())
oActionODataContextBinding.execute().then(
function() {
var oActionContext = oActionODataContextBinding.getBoundContext();
console.table(oActionContext.getObject().value);
}.bind(this)
);
}
The model "reportService" is a sap.ui.model.odata.v4.ODataModel. The function call is unbound and is declared this way in my service.cds file:
action validateActivity(activity : Activities) returns many rm.ValidationMessage;
The oActionContext.getObject().value contains the response to my function call.
The key here is the setParameter that sets the activity on the payload. Here's what the resulting request could look like:
POST http://localhost:8080/api/ReportService/validateActivity
Content-Type: application/json
{"activity": {
"activityNumber": 1,
"report_ID": "a3558fce-76bc-49a9-ae23-bd5566fb3bc6",
"job_code": "160",
"learningPeriod": 1,
"salaryAnnex": "D3",
"workingRegion_code": "08",
"unionName": "CSD",
"local": "Local 123",
"nbWeeksWorked": 8,
"nbHourSimple": 110,
"nbHourTimeAndHalf": 5,
"nbHourDouble": 0,
"sin": "111222333",
}}
I hope this will help others who are struggling to do this.
Regards

Testing Cloud Function - Cannot read property 'data' of undefined

I've got a Raspberry Pi and setup a weather (and soil moisture) rig.
I found this guide: https://codelabs.developers.google.com/codelabs/iot-data-pipeline which I followed and got stuck around Step 6-7.
From what I understand - when I send data to PubSub - nothing happens. On the Raspberry End I sort of get the idea that data is being sent but it doesn't get passed into BigQuery. I did some print statements at various points to try and see where it got stuck.
As I was trying to find the error I slowly backtracked to Step 5 (Create a Cloud Function).
Step 5 along with associated code I copied can be seen here: https://codelabs.developers.google.com/codelabs/iot-data-pipeline/#4
In GCP - I click into Cloud Function -> function-weatherPubSubToBQ -> Testing (tab)
Under the heading - Trigger event - I filled out the JSON below:
{
"sensorID":"Raspberry",
"timecollected":"2020-09-11 06:45:19",
"zipcode":"00000",
"latitude":"0.0",
"longitude":"0.0",
"temperature":"-273",
"humidity":"-1",
"dewpoint":"-273",
"pressure":"0"
}
When I click on - Test the function - the output is as below
**Error: function execution failed. Details:
Cannot read property 'data' of undefined**
Screen capture of JSON and error message
I am guessing one of these two things are causing the problem.
event.data or PubSubMessage.data
I tried to make some changes to the code but I am just shooting in the dark.
I was wondering if:
I did something wrong which means there might be some other
issues somewhere else.
This guide is slightly old and there have
been some updates which make the older code in the guide not
function as desired. (not step/image in the guide matches with what
I saw online, as of Sep 2020)
If someone knows what is wrong in
the code and is able to let me know how to solve it that would be
much appreciated.
Thanks in advance.
TLDR: The tutorial is outdated, don't use it, unless you want to face multiple problems and want to learn in the hard way
I went through the tutorial and I was able to replicate the issue.. and many more. As you already mentioned it, the tutorial is outdated and many things have changed, you can infer that by looking at the images and noticing that the UI is even different, so I wouldn't recommend this tutorial to anyone who is new to GCP.
The first issue:
**Error: function execution failed. Details: Cannot read property 'data' of undefined**
Can be easily resolved by looking at the structure of what it's expected from a pub/sub message:
{
"data": string,
"attributes": {
string: string,
...
},
"messageId": string,
"publishTime": string,
"orderingKey": string
}
So easy right? However once you mimic the structure of the message with your own variables as I did:
{
"data": "",
"attributes": {
"sensorID":"Raspberry",
"timecollected":"2020-09-11 06:45:19",
"zipcode":"00000",
"latitude":"0.0",
"longitude":"0.0",
"temperature":"-273",
"humidity":"-1",
"dewpoint":"-273",
"pressure":"0"
},
"messageId": "id_1",
"publishTime": "2014-10-02T15:01:23Z",
"orderingKey": ""
}
You will get an error regarding the JSON:
SyntaxError: Unexpected token ' in JSON at position 1
This error is due to the use of ' on the construction of the JSON inside the variable incomingData so you have to change the first variable declaration, I did it by using template literals:
const incomingData = PubSubMessage.data ? Buffer.from(PubSubMessage.data, 'base64').toString() : `{"sensorID": "na","timecollected":"01/01/1970 00:00:00","zipcode":"00000","latitude":"0.0","longitude":"0.0","temperature":"-273","humidity":"-1","dewpoint":"-273","pressure":"0"}`;
But this is not the end of the issues, after doing some tests while trying to insert into BigQuery, I got an error regarding the insertion, but didn't get a clue of what was really happening, so I isolated the consult in an external script and found that the error handling was wrong, the first thing I recommend you to change is the BigQuery version in the package.json from:
"#google-cloud/bigquery": "^0.9.6"
Into
"#google-cloud/bigquery": "5.2.0"
Which is the last version at the time of writing this answer. The next part is to redefine the way you're using BigQuery constructor into:
const bigquery = new BigQuery({
projectId: projectId
});
Then after many tests I found that the catch wasn't doing it's job as expected, so have to rewrite that part into:
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then((foundErrors) => {
rows.forEach((row) => console.log('Inserted: ', row));
if (foundErrors && foundErrors.insertErrors != undefined) {
foundErrors.forEach((err) => {
console.log('Error: ', err);
})
}
})
.catch((err) => {
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then((foundErrors) => {
rows.forEach((row) => console.log('Inserted: ', row));
if (foundErrors && foundErrors.insertErrors != undefined) {
foundErrors.forEach((err) => {
console.log('Error: ', err);
})
}
})
.catch((err) => {
if(err.name=='PartialFailureError'){
if (err && err.response.insertErrors != undefined) {
err.response.insertErrors.forEach((errors) => {
console.log(errors);
})
}
}else{
console.log("GENERIC ERROR:",err)
}
});
});
After this you will finally notice that the error is due to (again) the incomingData variable:
Could not parse \'01/01/1970 00:00:00\' as a timestamp. Required format is YYYY-MM-DD HH:MM[:SS[.SSSSSS]]'
You have to change the date from 01/01/1970 00:00:00 into 1970-01-01 00:00:00.
Still here with me? Well there's another error coming from the usage of callback at the end of the CF:
This is due to the fact that Cloud Functions now require three parameters and callback is the last one, so change the function declaration into:
exports.subscribe = function (event, context, callback)
After all of this you have been able to insert data into BigQuery, however we're using the local variable and not the data coming from pub/sub, at this point I gave up, since I will need to practically rewrite the full function in order to make it work by using Attributes instead of the data.
So as mentioned it before don't follow this tutorial if you're beginning in the GCP world.

HttpClient append parameter object to GET request

I'm quite the noob using Ionic or Angular for that matter. So as a cheat sheet I'm using the ionic-super-starter template (link below).
I am trying to make a get request to my API and it works just find if I'm doing it like this:
this.api.get('user/'+this.user.userId+'/entries?include=stuff&access_token=TOKEN');
but when I put the url params into an object it stops working:
let options = {
'include':'stuff',
'access_token':'TOKEN'
}
this.api.get('user/'+this.user.userId+'/entries', options);
The only error I get is "Unauthorized Request" since the options object including the access token was not appended to the url.
In the ionic-super-starter template the providers/api/api.ts calls .set() for each key in my params object:
if (params) {
reqOpts.params = new HttpParams();
for (let k in params) {
reqOpts.params.set(k, params[k]);
}
}
but according to Angular University this is not possible since "HTTPParams is immutable".
If it really was wrong to do this, I don't believe it would be in the ionic template. Nor would I believe that I would be the first person to come across this issue.
However, I am stuck here so any help would be appreciated.
Link to Angular University:
https://blog.angular-university.io/angular-http/#httprequestparameters
Link to ionic-super-starter:
https://github.com/ionic-team/starters/tree/master/ionic-angular/official/super
I think I figured it out myself:
if I write (in my src/providers/api/api.ts)
reqOpts.params = reqOpts.params.append(k, params[k]);
instead of
reqOpts.params.set(k, params[k]);
it works.
if you are using a loopback API as I am you might have nested objects like:
let options = {
"filter": {
"order": "date DESC"
},
"access_token":this.user._accessToken
};
this won’t work. try instead:
let options = {
"filter": '{"order":"date DESC"}',
"access_token":this.user._accessToken
};

Can't send a link to my own wall

I am developing a multi protocol client (currently Twitter, Facebook and Google Reader) for Windows using C# and wanted to extend its functions to send links to Facebook (currently I "only" have text status messages, comments and likes).
So I wrote this quite small method here:
public void PostLink(string text, string url)
{
if (string.IsNullOrEmpty(url))
{
PostTextStatus(text);
return;
}
dynamic parameters = new ExpandoObject();
parameters.message = text;
parameters.link = System.Web.HttpUtility.UrlEncode(url);
dynamic result = facebookClient.Post("me/links", parameters);
UpdateNewsFeed();
}
But I get the following error message back from Facebook: "(OAuthException) (#1500) The url you supplied is invalid"
But at least as I read the API docs this should be the right url and I tried it also with my user ID instead of "me" and without the UrlEncode - no luck so far.
Any help appreciated :)
(Using latest stable version für Facebook C# SDK)
The used client is initiated by
facebookClient = new FacebookClient(AccessToken);
dynamic result = (IDictionary<string, object>)facebookClient.Get("me");
if (result != null)
{
LoginSuccessfull = true;
}
}
and the AccesToken and its permissions were retrieved using
IDictionary<string, object> loginParameters = new Dictionary<string, object>
{
{ "response_type", "token" },
{ "appId", appId},
{ "secret", appSecret }
};
Uri redirectUri = new Uri("http://www.li-ghun.de/Nymphicus/");
loginUri = FacebookOAuthClient.GetLoginUrl(appId, null, _extendedPermissions, loginParameters);
with I think quite more than enough permissons:
private string[] _extendedPermissions = new[] {
"user_activities",
"user_birthday",
"user_checkins",
"user_education_history",
"user_events",
"user_games_activity",
"user_groups",
"user_hometown",
"user_interests",
"user_likes",
"user_location",
"user_notes",
"user_online_presence",
"user_photo_video_tags",
"user_photos",
"user_questions",
"user_relationship_details",
"user_relationships",
"user_religion_politics",
"user_status",
"user_subscriptions",
"user_videos",
"user_website",
"user_work_history",
"friends_about_me",
"friends_activities",
"friends_birthday",
"friends_checkins",
"friends_education_history",
"friends_events",
"friends_games_activity",
"friends_groups",
"friends_hometown",
"friends_interests",
"friends_likes",
"friends_location",
"friends_notes",
"friends_online_presence",
"friends_photo_video_tags",
"friends_photos",
"friends_questions",
"friends_relationship_details",
"friends_relationships",
"friends_religion_politics",
"friends_status",
"friends_subscriptions",
"friends_videos",
"friends_website",
"friends_work_history",
"create_event",
"create_note",
"email",
"export_stream",
"manage_friendlists",
"manage_notifications",
"manage_pages",
"offline_access",
"photo_upload",
"publish_actions",
"publish_checkins",
"publish_stream",
"read_friendlists",
"read_insights",
"read_mailbox",
"read_requests",
"read_stream",
"rsvp_event",
"share_item",
"status_update",
"video_upload",
};
Problem has been all the time at myself being stupid - I accidently exchanged the parameters when calling my method so the text of the entry was in the link property and vica versa.
Stupid me :(
I think your issue lies in the URL being posted as the link. Be sure that URL is visible to the linter (https://developers.facebook.com/tools/lint).
Another thing is to try playing with the Graph API Explorer tool and see if you can use it to post a link. If so, then try changing the application drop down to the app you're having issues with and try posting the link again.
In my case i was posting "http://localhost:3000" and facebook reject it. I tried with "www.google.com" and it works
The error I was getting was, even though the URL itself was valid, the og:image was being set to //example.com/example.jpg and missing http: or https:. I blame Facebook for this one, for not accepting a valid URL that any browser will accept, but the Debugger definitely helped identify this and solved the issue.
https://developers.facebook.com/tools/lint

How can I read SOAP-Headers and add FaultHeaders to a response sent by an AXIS 2 Web Service

I have a WSDL that defines a custom SOAP-header that the client needs to send and a SOAP-Fault header that the server could send as a response.
Now I have a problem. I cannot for the life of me fathom how to set SOAP-Fault-headers on a response generated with AXIS 2 (Version 1.6.1) or read SOAP-Headers that come with a request.
Can anyone point me in the right direction?
Thank you very much in advance.
If is security related you should look to Rampart.
If not, try looking into
ClientSide:
From your stub, retrieve the ServiceClient via _getServiceClient().
enter link description here
ServerSide:
If I recall correctly is done via MessageContext, so from axiscontext opbtain current message context.
Add custom fault to soap response. This can be done in one of two ways.
1) Simply throwing a Java exception with a message will generate a simple Axis2 fault
Example:
throw new java.lang.UnsupportedOperationException("Please implement " +
this.getClass().getName() + "#SomeOperationName");
Also please note: If you generated your service using the Axis2 WSDL2JAVA utility, the line above will be added to the MyServiceName_Skeleton source for each defined WSDL Operation.
Once the .aar is deployed, connectivity to each operation can be verified using a web browser, e.g. https://server:port/axis2/services/MyServiceName?SomeOperationName.
2) Ensure that the WSDL defines an optional (occurs:0) custom Fault structure. This can be sent to client with any other required (and empty) elements.
Example:
com.some.service.operation.SomeOperationNameResponse_Type OPRT = new com.some.service.operation.SomeOperationNameResponse_Type();
com.some.service.SomeOperationNameResponse OPR = new com.some.service.SomeOperationNameResponse();
.
.
.
if ((rcStatusString.equals("Succeeded")) || (rcStatusString.equals("Warning"))) {
<build happy path response>
} else if (rcStatusString.equals("Failed")) {
final MYFault fault = new MYFault();
final MYFault_Type faultType = new MYFault_Type();
final MYFaultList faultList = new MYFaultList();
final MYFaultList_Type faultListType = new MYFaultList_Type();
faultType.setFaultCode("10100");
faultType.setFaultSubcode("9999");
faultType.setFaultType(FaultType_Enum.SYSTEM);
faultType.setFaultReasonText("Some Operation Failed");
faultType.setSeverity(FaultSeverity_Enum.CRITICAL_ERROR);
//fault.setMYFault(faultType);
faultListType.addMYFault(faultType);
OTHRTYPE.setAValue("");
OPRT.setAValueType(OTHRTYPE);
OPRT.setMYFaultList(faultListType);
} else {
throw new java.lang.UnsupportedOperationException(
"MYSERVICE: [Some Operation] Session: "+sessVal+" Request ID: "+rcRequestId+" Unrecognized Completion Status ["+rcStatusString+"]");
}
OPR.setSomeOperationResponse(OPRT);
return OPR;
}