Saving GWT form data into different application - google-app-engine

I have a GWT application which has form. If user enters data and submit i have to store the data into google datastore and also an JSP application which is running on tomcat server. I found this is done through Task in GAE GAE Push Task from this i am calling a servlet in my gwt application and in that servlet URL fetch There i have to code to send data to another application and call the servlet to insert data. Can anyone give me how to do it(By a simple example). Is this a correct approach or any other way to do this correctly?

I have done it successfully added a push queue task in server side and called a servlet from there which is registered in guice. then in that servlet i called the fallowing lines
Task queue code
Queue queue = QueueFactory.getDefaultQueue();
queue.addAsync(TaskOptions.Builder.withUrl("/userServlet").method(Method.GET).param("userName", userName).param("pwd", pwd).param("mail",mail));
and userservlet has fallowing code to connect to theother application
final String url_Name = "http://xxxxxxxx.com/AddUserServlet";
//final String url_Name = "http://localhost:8181/jos-webapp-1.2.1/AddUserServlet";
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
HTTPRequest request = null;
HTTPResponse response= null;
try{
URL url = new URL(url_Name);
request = new HTTPRequest(url, HTTPMethod.POST);
String body = "userName="+uName+"&pwd="+pwd+"email"+email;
request.setPayload(body.getBytes());
response = fetcher.fetch(request);
}catch(Exception ex){
ex.printStackTrace();
}
In my JOIDS(second application) I wrote a servlet(AdduserServlet) and used someget the data. Any better solution than this will be accepted

Related

Using a managed service identity to call into SharePoint Online. Possible?

I have been playing around with Managed Service Identity in Azure Logic Apps and Azure Function Apps. I think it is the best thing since sliced bread and am trying to enable various scenarios, one of which is using the MSI to get an app-only token and call into SharePoint Online.
Using Logic Apps, I generated a managed service identity for my app, and granted it Sites.readwrite.All on the SharePoint application. When then using the HTTP action I was able to call REST endpoints while using Managed Service Identity as Authentication and using https://.sharepoint.com as the audience.
I then though I'd take it a step further and create a function app and follow the same pattern. I created the app, generated the MSI, added it the Sites.readwrite.All role same way I did with the Logic App.
I then used the code below to retrieve an access token and try and generate a clientcontext:
#r "Newtonsoft.Json"
using Newtonsoft.Json;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.SharePoint.Client;
public static void Run(string input, TraceWriter log)
{
string resource = "https://<tenant>.sharepoint.com";
string apiversion = "2017-09-01";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Secret", Environment.GetEnvironmentVariable("MSI_SECRET"));
var response = client.GetAsync(String.Format("{0}/?resource={1}&api-version={2}", Environment.GetEnvironmentVariable("MSI_ENDPOINT"), resource, apiversion)).Result;
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result.ToString();
var json = JsonConvert.DeserializeObject<dynamic>(responseString);
string accesstoken = json.access_token.ToString()
ClientContext ctx = new ClientContext("<siteurl>");
ctx.AuthenticationMode = ClientAuthenticationMode.Anonymous;
ctx.FormDigestHandlingEnabled = false;
ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e){
e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accesstoken;
};
Web web = ctx.Web;
ctx.Load(web);
ctx.ExecuteQuery();
log.Info(web.Id.ToString());
}
}
The bearer token is generated, but requests fail with a 401 access denied (reason="There has been an error authenticating the request.";category="invalid_client")
I have tried to change the audience to 00000003-0000-0ff1-ce00-000000000000/.sharepoint.com#" but that gives a different 401 error, basically stating it cannot validate the audience uri. ("error_description":"Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown.). I have also replace the CSOM call with a REST call mimicking the same call I did using the Logic App.
My understanding of oauth 2 is not good enough to understand why I'm running into an issue and where to look next.
Why is the Logic App call using the HTTP action working, and why is the Function App not working??
Anyone?
Pretty basic question: Have you tried putting an '/' at the end of the resource string e.g. https://[tenant].sharepoint.com/ ?
This issue is also present in other endpoints so it may be that its interfering here as well.

Slack & Salesforce - Rest API - Outgoing webhook

I am trying to connect to Salesforce Apex using POST. Slack has this pluggin, Outgoing Webhook which sends to a URL a POST request.
I have already created an APEX class to handle the request,
#RestResource(urlMapping='/test/accounts/*')
global with sharing class REST_slackAccount {
#HttpGet
global static void doGet() {
System.debug('Connected');
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
//accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
System.debug('Connected');
}
}
I am getting nothing from Salesforce when i trigger the request from Slack. What am i doing wrong.
I have already created a remote site settings.
The URL i used in Slack to make the POST request is:
https://test.salesforce.com/services//test/accounts/
Thank you.
It looks like that controller is only handling GET requests but Slack is doing a POST.

Signpost Oauth and post parameters

I am using signpost with google appengine (java) to send a status update to twitter.
OAuthConsumer consumer = new DefaultOAuthConsumer("AAA",
"BBB");
consumer.setTokenWithSecret("CCC", "DDD");
URL url = new URL("http://api.twitter.com/1.1/statuses/update.json?status=abc");
HttpURLConnection request;
request = (HttpURLConnection) url.openConnection();
consumer.sign(request);
request.setRequestMethod("POST");
request.connect();
InputStream response = request.getInputStream();
int a = response.read();
while (a!=-1){
resp.getOutputStream().write(a);
a = response.read();
}
You can see hear I am putting the post parameters in the url like a get request, someone else mentioned this worked for them, I have also tried to put them in the body of the message like you are supposed to do. But I always get {"errors":[{"message":"Could not authenticate you","code":32}]}. My tokens and secret tokens are all correct, but if they weren't I would get a different error of {"errors":[{"message":"Invalid or expired token","code":89}]}.
I think signpost isn't doing the oauth process on the whole body (including the parameters) so it is giving the error.
Any ideas?
Turns out signpost is not a great library for app-engine. A few bugs in it prevent it from working without certin errors. Scribe is a better Oauth tool to be used with Appengine Java.

Can Google Cloud Endpoints Be Hit Using Task Queues?

I have an app engine task queue that tries to call a cloud endpoint, but when I see the task queue fire off it gets a 404. I verified the endpoint is configured for post:
#ApiMethod(name = "sendemail", path = "sendemail", httpMethod = HttpMethod.POST)
and I am queueing like this:
TaskOptions lOptions = TaskOptions.Builder.withUrl("/_ah/api/email/v1/sendemail");
I can hit the endpoint using the endpoint explorer, what am I missing? Thanks!
It's probably defaulting to get method try adding method POST or making endspoints method get.
withUrl("....").method(Method.POST)

Request to App Engine Backend Timing Out

I created an App Engine backend to serve http requests for a long running process. The backend process works as expected when the query references an input of small size, but times out when the input size is large. The query parameter is the url of an App Engine BlobStore blob, which is the input data for the backend process. I thought the whole point of using App Engine backends was to avoid the timeout restricts that App Engine frontends possess. How can I avoid getting a timeout?
I call the backend like this, setting the connection timeout length to infinite:
HttpURLConnection connection = (HttpURLConnection)(new URL(url + "?" + query).openConnection());
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestMethod("GET");
connection.setConnectTimeout(0);
connection.connect();
InputStream in = connection.getInputStream();
int ch;
while ((ch = in.read()) != -1)
json = json + String.valueOf((char) ch);
System.out.println("Response Message is: " + json);
connection.disconnect();
The traceback (edited for anonymity) is:
Uncaught exception from servlet
java.net.SocketTimeoutException: Timeout while fetching URL: http://my-backend.myapp.appspot.com/somemethod?someparameter=AMIfv97IBE43y1pFaLNSKO1hAH1U4cpB45dc756FzVAyifPner8_TCJbg1pPMwMulsGnObJTgiC2I6G6CdWpSrH8TrRBO9x8BG_No26AM9LmGSkcbQZiilhC_-KGLx17mrS6QOLsUm3JFY88h8TnFNer5N6-cl0iKA
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.convertApplicationException(URLFetchServiceImpl.java:142)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:43)
at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:417)
at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getInputStream(URLFetchServiceStreamHandler.java:296)
at org.someorg.server.HUDXML3UploadService.doPost(SomeService.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
As you can see, I'm not getting the DeadlineExceededException, so I think something other than Google's limits is causing the timeout, and also making this a different issue from similar stackoverflow posts on the topic.
I humbly thank you for any insights.
Update 2/19/2012: I see what's going on, I think. I should be able to have the client wait indefinitely using GWT [or any other type of client-side async framework] async handler for an any client request to complete, so I don't think that is the problem. The problem is that the file upload is calling the _ah/upload App Engine system endpoint which then, once the blob is stored in the Blobstore) calls the upload service's doPost backend to process the blob. The client request to _ah/upload is what is timing out, because the backend doesn't return in a timely fashion. To make this timeout problem go away, I attempted to make the _ah_upload service itself a public backend accessible via http://backend_name.project_name.appspot.com/_ah/upload, but I don't think that google allows a system service (like _ah/upload) to be run as a backend. Now my next approach is to just have ah_upload immediately return after triggering the backend processing, and then call another service to get the original response I wanted, after processing is finished.
The solution was to start a backend process as a tasks and add that to the task queue, then returning a response to client before it waits to process the backend task (which can take a long time). If I could have assigned ah_upload to a backend, this would have also solved the problem, since the clien't async handler could wait forever for the backend to finish, but I do not think Google permits assigning System Servlets to backends. The client will now have to poll persisted backend process response data, as Paul C mentioned, since tasks can not respond like a normal servlet.

Resources