Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google App Engine Task Queue gets a 404 when invoking Google Cloud Endpoints API

The following code works perfectly in the dev environment. A GET to "/_ah/api/worker/v1/tasks" calls the refresh() method which adds a task to the default task queue that POSTs to "/_ah/api/worker/v1/tasks" which is handled by the handle() method.

@Api(name = "worker", version = "v1", scopes = { Constants.EMAIL_SCOPE }, clientIds = { Constants.API_EXPLORER_CLIENT_ID, Constants.WEB_CLIENT_ID })
public class WorkerApi
{
    @ApiMethod( name="refresh", path = "tasks", httpMethod = HttpMethod.GET)
    public void refresh()
    {
        MyObject myObject = new MyObject()
        Queue queue = QueueFactory.getDefaultQueue();
        TaskOptions o = TaskOptions.Builder.withUrl("/_ah/api/worker/v1/tasks");
        o.payload(ApiHelper.ObjectToJson(myObject ));               
        queue.add(o);                           
    }

    @ApiMethod( name="handle", path = "tasks", httpMethod = HttpMethod.POST)
    public void handle(HttpServletRequest req, MyObject myObject) 
    {
        // This handler is called if running in dev in environment

        // If running on GAE this handler is never called.
    }
}

Sadly, when deployed to actual Google App Engine, the handle method is never called by the Task Queue.

Interestingly, I can successfully call the handler manually using the API Explorer which produces the following log in GAE console:

2014-11-24 12:01:30.914 /_ah/spi/my.test.application.WorkerApi.handle 200 1394ms 0kb Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36 module=default version=1
198.66.21.14 - - [24/Nov/2014:12:01:30 -0800] "POST /_ah/spi/my.test.application.WorkerApi.handle HTTP/1.1" 200 116 - "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36" "my-test-application.appspot.com" ms=1394 cpu_ms=1003 cpm_usd=0.000013 app_engine_release=1.9.16 instance=00c61b117c39338c333cff447edea78fa0f90d

But when called by the Task Queue, a 404 is always returned producing the following log in the GAE console:

2014-11-24 12:07:54.727 /_ah/api/worker/v1/tasks 404 147ms 0kb AppEngine-Google; (+http://code.google.com/appengine) module=default version=1
0.1.0.2 - - [24/Nov/2014:12:07:54 -0800] "POST /_ah/api/worker/v1/tasks HTTP/1.1" 404 234 "https://my-test-application.appspot.com/_ah/spi/my.test.application.WorkerApi.refresh" "AppEngine-Google; (+http://code.google.com/appengine)" "my-test-application.appspot.com" ms=148 cpu_ms=23 cpm_usd=0.000026 queue_name=default task_name=9271899958322278984 pending_ms=61 app_engine_release=1.9.16 instance=00c61b117c7544e23aeb8d8b0c996da6d286d539

Again, everything works as expected in the dev environment. Broken when deployed to GAE. What am I doing wrong?

Comparing the log entries, I thought that I found the problem and change the code to:

TaskOptions o = TaskOptions.Builder.withUrl("/_ah/spi/my.test.application.WorkerApi.handle");

Nope. This doesn't work. Now it's broken in the dev environment and in the GAE deployment.

Log from dev environment:

[INFO] INFO: Web hook at http://127.0.0.1:8080/_ah/spi/my.test.application.WorkerApi.handle returned status code 404.  Rescheduling..

Log from GAE console:

2014-11-24 12:24:10.872 /_ah/spi/my.test.application.WorkerApi.handle 404 396ms 0kb AppEngine-Google; (+http://code.google.com/appengine) module=default version=1
0.1.0.2 - - [24/Nov/2014:12:24:10 -0800] "POST /_ah/spi/my.test.application.WorkerApi.handle HTTP/1.1" 404 96 "https://my-test-application.appspot.com/_ah/spi/my.test.application.WorkerApi.refresh" "AppEngine-Google; (+http://code.google.com/appengine)" "my-test-application.appspot.com" ms=397 cpu_ms=23 cpm_usd=0.000011 queue_name=default task_name=7132899958322278984 app_engine_release=1.9.16 instance=00c61b117c565c0a8aa81e1b86e50d78f0346330

BTW, I'm using GAE SDK 1.9.16.

like image 673
matt peterson Avatar asked Nov 24 '14 20:11

matt peterson


1 Answers

I have a same problem. In the local PC, this works well.

Maybe, the GAE server can not found the url (endpoint) which is not written in web.xml explicitly.

To fix this problem, create another servlet for a worker.

For example, the endpoint method is

    Queue queue = QueueFactory.getDefaultQueue();
    TaskOptions o = TaskOptions.Builder.withUrl("/work");
    o.param( "target" , target) ; // target is String in this case
    queue.add(o);

war/WEB-INF/web.xml is

<web-app ...>
 ... default servet (SystemServiceServlet) ...
 <servlet>
  <servlet-name>WorkerServlet</servlet-name>
  <servlet-class>com.example.your.package.WorkerServlet</servlet-class>
 </servlet>
 .... default mapping file ...
 <servlet-mapping>
   <servlet-name>WorkerServlet</servlet-name>
   <url-pattern>/work</url-pattern>
 </servlet-mapping>

and create WorkerServlet.java file as

public class WorkerServlet extends HttpServlet {

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    String target = req.getParameter("target");

    // do something

    resp.setStatus( resp.SC_OK );

  }

}

In this case, the url /work can be found by GAE server and Queue works well.

like image 198
KNaito Avatar answered Oct 31 '22 14:10

KNaito