In GAE Java 11, how do I enqueue a task to run in the same subdomain of current code? - google-app-engine

My logs show a 404 error when I run this code:
String queuePath = QueueName.of( PROJECT_ID, LOCATION, QUEUE_NAME ).toString( );
Task.Builder taskBuilder = Task.newBuilder( )
.setAppEngineHttpRequest(
AppEngineHttpRequest.newBuilder( )
.setRelativeUri( relativeUri )
.setHttpMethod( HttpMethod.GET )
.build( )
);
Task task = client.createTask( queuePath, taskBuilder.build( ) );
The logs seem to show the request is going to my main domain, not my subdomain that this code is running in.
What am I missing?
2023-01-05 Update:
I had to resort to the generic approach as seen here.
Task.Builder taskBuilder = Task.newBuilder( )
.setHttpRequest(
HttpRequest.newBuilder( )
.setUrl( fullUri )
.setHttpMethod( HttpMethod.GET )
.build( )
);

I think you missed giving the subdomain to the cloud run Task queues.
Lets say, if your subdomain is subdomain.example.com and you want to enqueue a task to run at /task, you will set the relative URI to /task.
To resolve your problem I have modified your code with giving you /subdomain as subdomain:
String hostname = "api.mydomain.com";
String relativeUri = "/servlet-path";
String queuePath = QueueName.of( PROJECT_ID, LOCATION, QUEUE_NAME ).toString( );
Task.Builder taskBuilder = Task.newBuilder()
.setAppEngineHttpRequest(
AppEngineHttpRequest.newBuilder()
.setRelativeUri(relativeUri)
.setHttpMethod(HttpMethod.GET)
.setHost(hostname)
.build()
);
Task task = client.createTask( queuePath, taskBuilder.build());
Alternatively you can add subdomain in google cloud console by following this
Console -> App Engine -> Settings -> Custom Domains -> Add a Custom Domain
as shown in this thread
For Information about this topic you can go through this documentations and for official reference you can go to here

Related

Google PubSub not working to create a new topic

i'm using the v1-master branch of the PHP API Client library from here:
https://github.com/google/google-api-php-client/blob/v1-master/src/Google/Service/Pubsub.php
i'm sure i have all the OAuth stuff right, so assume the $client is already created correctly... also {my-app-id} is replaced with my real application id
$pubsub = new Google_Service_Pubsub($client);
$new_topic = new Google_Service_Pubsub_Topic();
$new_topic->setName('projects/{my-app-id}/topics/mytopic');
$topic = $pubsub->topics->create($new_topic);
this throws an exception:
exception: Google_Service_Exception Object
(
[errors:protected] => Array
(
[0] => Array
(
[domain] => global
[reason] => invalidArgument
[message] => Invalid resource name given (name=projects/{my-app-id}/topics/mytopic). Refer to https://cloud.google.com/pubsub/overview#names for more information.
)
)
{my-app-id} is just letters a-z, so it is valid and meets all the criteria on the pubsub overview, and i do have rights to the project because if i change the {my-app-id} value, i get a permission denied message.
i've also gone through the API Explorer and got similar broken results:
REQUEST:
PUT https://pubsub.googleapis.com/v1/projects/{my-app-id}/topics/mytopic?key={YOUR_API_KEY}
{
}
RESPONSE:
404 OK
- Show headers -
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND"
}
}
i've also tried using the master branch of the API client and changing the endpoints to the pubsub.googleapis.com/v1 endpoints rather than www.googleapis.com/pubsub/v1beta1... i even tried v1beta2. nothing is working.
the PubSub API is enabled for my project, but i can't get any topics created.
does anyone have any PHP sample code of a working app to use the PubSub service? any ideas what i'm doing wrong?
If the API Explorer is also not working, that would indicate that the project id you are specifying in place of {my-app-id} is not correct. It should be a project that has already been created. Visit https://console.developers.google.com/home/dashboard?project={my-app-id} and ensure that you get a dashboard for your project. If not, then that would confirm that the project id is incorrect.

Set up configuration to Access amazon order from seller account

I want to set .config.inc.php of MarketplaceWebServiceOrders library that I used to access order of amazon seller account.
Here is my config.inc.php file setting
/************************************************************************
* REQUIRED
*
* All MWS requests must contain a User-Agent header. The application
* name and version defined below are used in creating this value.
***********************************************************************/
define('APPLICATION_NAME', 'MarketplaceWebServiceOrders');
define('APPLICATION_VERSION', '2013-09-01');
After figure out these setting I got error
Caught Exception: Resource / is not found on this server. API Section is missing or you have provided an invalid operation name. Response Status Code: 404 Error Code: InvalidAddress Error Type: Sender Request ID: 47e5f613-5913-48bb-ac9e-cb00871b36af XML: Sender InvalidAddress Resource / is not found on this server. API Section is missing or you have provided an invalid operation name. 47e5f613-5913-48bb-ac9e-cb00871b36af ResponseHeaderMetadata: RequestId: 47e5f613-5913-48bb-ac9e-cb00871b36af, ResponseContext: 6qut/Q5rGI/7Wa0eutUnNK1+b/1rvHSojYBvlGThEd1wAGdfEtnpP2vbs28T0GNpF9uG82O0/9kq 93XeUIb9Tw==, Timestamp: 2015-09-15T12:47:19.924Z, Quota Max: , Quota Remaining: , Quota Resets At:
Here GetOrderSample.php file code for service url. Which I have done already.
// More endpoints are listed in the MWS Developer Guide
// North America:
$serviceUrl = "https://mws.amazonservices.com/Orders/2013-09-01";
// Europe
//$serviceUrl = "https://mws-eu.amazonservices.com/Orders/2013-09-01";
// Japan
//$serviceUrl = "https://mws.amazonservices.jp/Orders/2013-09-01";
// China
//$serviceUrl = "https://mws.amazonservices.com.cn/Orders/2013-09-01";
$config = array (
'ServiceURL' => $serviceUrl,
'ProxyHost' => null,
'ProxyPort' => -1,
'ProxyUsername' => null,
'ProxyPassword' => null,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebServiceOrders_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
APPLICATION_NAME,
APPLICATION_VERSION,
$config);
Caught Exception: Resource / is not found on this server.
This is telling you that the problem is with the path. It's not being able to find that.
Are you sure that the class you're trying to use is in the right path? Most classes that you need to run the samples are in the "Model" folder.
I mean to say, if you take the sample out of the sample folder and put it elsewhere, it won't be able to find classes in the "Model" folder.
An easy fix to test it is to put everything you downloaded from the MWS site into your web directory and just edit the config file. It should work that way.
I'm not a php guy, but I don't see where you're setting up the access keys, merchant id, marketplace id, and most importantly the serviceURL. The 404 error is the first clue meaning it can't find the service. Download the PHP client library which has everything you need to get started.

How do I test Cloud Endpoints with Oauth on devserver

My app uses Oauthed Cloud Endpoints and is working fine in production.
My problem is that on the local devserver, my User user is always set to example#example.com, even though I've gone through the usual auth, access code, etc etc etc and have a valid authed user.
I get that example#example.com is useful to test oauth endpoints before I have oauth working properly, but since my app is working I'd rather see the actual user there.
To be specific, my endpoint method is
#ApiMethod(name = "insertEmp"), etc
public Emp insertEmp(User user, Emp emp) {
System.out.println(user.getEmail()); // (A) log "appengine" email
System.out.println(OAuthServiceFactory.getOAuthService().getCurrentUser().getEmail(); // (B) log authed email
...
When deployed, everything is fine, and both (A) and (B) log the authenticated user (my.email#gmail.com).
When testing on my local devserver, (A) always logs "example#example.com", even though I have gone through the Oauth sequence and have a valid, authenticated user, and (B) logs my.email#gmail.com. So I can do hi-fidelity testing, I need the User to be the real authenticated user.
So in simple terms, how do I get (A) and (B) to be the same?
It seems it can't be done. I've ended up coding around it by putting the following code at the top of my Endpoint methods.
if ("example#example.com".equalsIgnoreCase(user.getEmail()) {
user = new User(OAuthServiceFactory.getOAuthService().getCurrentUser().getEmail(),"foo");
}
So now, even on devserver, the User email matches the Oauth email.
This is not so easy. You'll have to make your settings in the APIs Console. Here you will be able to add "localhost" (http://localhost/) Then you can authenticate, through Google, even though you are running you application on your localhost for development.
I have used it extensively, and it works OK
Links: https://code.google.com/apis/console/
Just remember the ID's you use here is completely independent of you appengine ID.
Took me a few hours to figure that one out.
The thing is that when you are doing the authentication in local, you are not doing it through the Google servers so authenticating your user is something that actually is not happening in local.
Google always provides the example#example.com user when you try to simulate the log in, it happens basically in all the services, like when you provide a log in through your Google Account in any web site (for instance using GWT and App Engine).
What can be different in your site if you test with your real user or you consider example#example.com user as your user?
In your endpoint API you need this
ApiMethod ( name="YourEndPointName", path="yourPath",
clientIds={"YourId.apps.googleusercontent.com"},
scopes = { "https://www.googleapis.com/auth/userinfo.profile" })
Then in the called method, you will have a User object from the GAPI.
Use this to get the actual email from the google User object like this
public myEndPointMethod( Foo foo, User user ){
email = user.getEmail();
}
I replaced the Oauth2 user (example#example.com) with user from UserFactory and it works fine. I use this method to validate user for all API authenticated API requests.
public static User isAuthenticated(User user) throws OAuthRequestException{
if(user == null){
throw new OAuthRequestException("Please login before making requests");
}
if(SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Development && "example#example.com".equalsIgnoreCase(user.getEmail()) ) {
//Replace the user from the user factory here.
user = UserServiceFactory.getUserService().getCurrentUser();
}
return user;
}
Using the go runtime I have resorted to this function to obtain a User that is functional on both the dev server and production:
func currentUser(c context.Context) *user.User {
const scope = "https://www.googleapis.com/auth/userinfo.email"
const devClient = "123456789.apps.googleusercontent.com"
allowedClients := map[string]bool{
"client-id-here.apps.googleusercontent.com": true,
devClient: true, // dev server
}
usr, err := user.CurrentOAuth(c, scope)
if err != nil {
log.Printf("Warning: Could not get current user: %s", err)
return nil
}
if !allowedClients[usr.ClientID] {
log.Printf("Warning: Unauthorized client connecting with the server: %s", usr.ClientID)
return nil
}
if (usr.ClientID == devClient) {
usr = user.Current(c) // replace with a more interesting user for dev server
}
return usr
}
This will use the dev server login information entered using http://localhost:8080/_ah/login
It's not possible.
I use another endpoint to replace user_id in current session.

Get auth token in Gatling

I'm trying to use Gatling to test my API but I've got a problem. I'm testing for now the login/logout. At the login, the user got a token, that is used for logout.
When I use the recorder, it keep a fix token, and of course, it doesn't work when I run the test. But I don't find in the doc or google how I can get dynamically the token.
Does anyone know ?
Thanks !
EDIT:
after recording here what I got
val headers_13 = Map(
"Accept" -> """*/*""",
"Origin" -> """http://site.com""",
"token" -> """token"""
)
val scn = scenario("Scenario Name")
.exec(http("request_1")
.post("http://site.com/login")
.headers(headers_1)
.param("""player[email]""", """email#address.com""")
.param("""player[password]""", """password""")
)
.pause(757 milliseconds)
…
.exec(http("request_13")
.get("http://site.com/logout")
.headers(headers_13)
)
.pause(202 milliseconds)
I try to put the two pieces of code after .post("http://site.com/login") and .get("http://site.com/logout") but that didn't works
Where is your token? Is it a HTTP header?
Generally speaking, the way to save data from responses in order to reuse it for further requests is the Check API.
.check(header("tokenName").saveAs("token")
...
.header("tokenName", "${token}")

gaeutilities' session works on SDK, but not on Google app engine?

I encountered a strange problem: The gaeutilities' session worked on the GAE SDK, but not on the actual Google App Engine platform. The followings are session creation and existence checking using Python, respectively.
Session creation:
self.session = sessions.Session()
self.session.delete_item('account')
self.session.delete_item('accountKey')
...
query = db.Query(model.Member)
query = query.filter('account =', account) # 'account' is the user account
results = query.fetch(limit=1)
if results: # Account exists
member = results[0]
self.session['account'] = account
self.session['accountKey'] = member.key()
...
Session existence checking:
self.session = sessions.Session()
if 'accountKey' in self.session: # Session exists
account = self.session['account'] # Could this be the problem?
...
The above program runs OK on the GAE SDK. But I uploaded the program to Google App Engine, and it didn't work. What might be the problem?
I am not familiair with gaeutilities. But with self.session = sessions.Session() you create a new session. This will be empty. So your check if 'accountKey' in ... will not work. There must be another way to get the existing session.
I have found another approach to solve the problem using gae-sessions. Check here.

Resources