2014-11-24 13 views
5

Il codice seguente funziona perfettamente nell'ambiente dev. GET a "/ _ah/api/worker/v1/tasks" chiama il metodo refresh() che aggiunge un'attività alla coda delle attività di default che i POST di "/ _ah/api/worker/v1/tasks" che viene gestito dal handle() metodo.La coda attività di Google App Engine riceve un 404 quando richiama l'API di Google Cloud Endpoint

@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. 
    } 
} 

Purtroppo, quando schierato alle effettive Google App Engine, il metodo di impugnatura non viene mai chiamato dalla coda Task.

È interessante notare che, posso chiamare con successo il gestore manualmente utilizzando l'Explorer API che produce il seguente registro in consolle GAE:

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 

Ma quando viene chiamato dalla coda Task, una 404 viene sempre restituito producendo la seguente accedere alla console GAE:

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 

Ancora, tutto funziona come previsto nell'ambiente di sviluppo. Rotto quando distribuito su GAE. Che cosa sto facendo di sbagliato?

Confrontando le voci di registro, ho pensato che ho trovato il problema e modificare il codice a:

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

Nope. Questo non funziona. Ora è rotto nell'ambiente di sviluppo e nella distribuzione di GAE.

Log dall'ambiente dev:

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

log dal console GAE:

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, sto usando GAE SDK 1.9.16.

+0

abbiamo lo stesso problema - stupito questo lo ha reso in produzione ... – DaBeeeenster

+0

@DaBeeeenster Abbiamo lo stesso problema ... Hai trovato una soluzione diversa dalla creazione di un altro servlet? – bogumil

risposta

5

Ho lo stesso problema. Nel PC locale, questo funziona bene.

Forse il server GAE non ha trovato l'url (endpoint) che non è scritto in web.xml esplicitamente.

Per risolvere questo problema, creare un altro servlet per un worker.

Ad esempio, il metodo endpoint è

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

guerra/WEB-INF/web.xml è

<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> 

e creare file di WorkerServlet.java come

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 In questo caso, l'URL/lavoro può essere trovato dal server GAE e la coda funziona bene.

+1

Alla fine questo è quello che ho finito per fare. Quindi sì, la soluzione sembra essere: creare un servlet separato. –

+0

Sono sicuro che un Endpoint avrebbe dovuto funzionare in qualche modo! Suppongo che la mia Guice Config si sia intromessa. In ogni caso ha finito per creare anche un servlet. – Manu

+0

@Manu non lo farà :(. Sfortunatamente non c'è modo di chiamare gli endpoint direttamente in questo momento. Fa davvero schifo, speriamo di ottenere buone notizie sull'I/O di quest'anno – jirungaray

0

solo per aggiungere alla risposta KNaito

RequestDispatcher dispatcher = req.getRequestDispatcher(target); 
dispatcher.forward(req, resp); 

Per reindirizzare, infine, la richiesta di posizione desiderata con entrambi i parametri.

Problemi correlati