I would like to know whether it is possible to host a Google App Engine backend servlet using Sitebricks. I am trying to do so in my GAE Java app -- frontend gets the backend URL using GAE's BackendService interface and send an HTTP Request -- but the HTTP response always returns with a 404 Not Found).
I would love to post some source code / configuration files, but I fell that it may be best for me to explain what I am doing. Basically, my servlet has been configured using Sitebricks in the same exact manner as my frontend servlets that are working perfectly (ie, using the #Service, #At and #Get annotation in the servlet classes and methods, plus configuring SitebricksModule in my app's global Guice Injector instance). I am using a dynamic backend instance, configured properly in backends.xml.
Does anyone have any hints on pairing Sitebricks with GAE Backends?
Yes Sitebricks works on GAE. I recommend the 0.8.8-SNAPSHOT version from sonatype's OSS repo for latest functionality. Otherwise the latest tested release is 0.8.7 from Maven Central. The only bit that doesn't work is requesting other websites from GAE using the Sitebricks Web Client.
Are you using GuiceServletContextListener? This is the best way to create an Injector. Also make sure your web.xml points to it and sets up GuiceFilter correctly (as per sitebricks.org docs).
Dhanji.
(maintainer, sitebricks)
Related
I would like to have a web and an endpoint module.
I have this working in my dev environment largely following https://github.com/GoogleCloudPlatform/appengine-modules-sample-java .
However I can't get this working when hosted inside app engine. If I make the web module the default, I can't route to the endpoint module via dispatch.xml. This is because endpoints (apparently) need to live at /_ah/api and its not possible to route this away from the default module.
The other alternative is putting the endpoint module as the default module, however I don't then know how to route everything but /_ah/api/ to the web module. It seems that you can't route /* away from the default module.
EDIT: Note I want to have both modules running off of the same custom domain.
EDIT2: Note this is single page app. The front end module is purely html, css and js, which I want to talk to the endpoint module on the same domain.
Any way to solve this?
If the problem only resides in the routing, you can definitely have your default module with endpoints and a module 'website' for your frontend.
Then your dispatch file should look like that (python version, the Java one should be quite similar):
dispatch:
- url: "*/_ah/*"
module: default
- url: "*/*"
module: website
The dispatch file apparently sets the routing with a top to bottom priority so each request targeting the endpoints */_ah/* will be routed to the default module and the rest will go on the website module.
However if you have CORS issues, you can check in the handler configuration for static files or had the proper headers directly in your page handler code.
If the issue you have is splitting the traffic you should probably intercept all requests and look for the destination URL and divert accordingly. But i think your issue is actually accesing the endpoint deployed on a non default version.
You can deploy specific endpoints to specific (non default) versions of your app.
As stated in the official docs:
To access backend API versions that are deployed to non-default App Engine versions of your app, you must include the version specifier in the URL, like this: https://version-dot-your_app_id.appspot.com. For example, suppose your default app version is 1, but you want to access a backend API version deployed to App Engine app version 2; you would use this URL: https://2-dot-your_app_id.appspot.com.
The answer suggested by #Anhuin is good for your simpler purposes. But if you want to have totally independent modules, i suggest you to use subdomain mapping
Create a sub domain like api.domain.com for endpoints and web.domain.com for your regular frontend modules.
Map these in the dipatch.xml
<url>api.domain.com/*</url>
<module>endpointmod</module>
<url>web.domain.com/*</url>
<module>webmod</module>
I prefer this because '_ah' is used by appengine in multiple places like appstats, remote api and so on. This will be clearer to the people working in frontend also by calling the sub domains.
At work I have to regularly work on a site that uses Tomcat, Hybris and (I think?) Spring. Although I'm slowly learning, I'm quite unfamiliar with all of these technologies.
Is there a simple way to handle 301 redirects through Hybris? Perhaps through the Hybris administration console or Hybris management console?
Currently, we are using http://www.tuckey.org/urlrewrite/ and functionally, it works great. But adding a vanity URL or a URL redirect to the website involves editing / testing on localhost, then pushing urlrewrite.xml to stage and testing, then finally pushing urlrewrite.xml to the production environment.
Is there a better way to handle 301's with the technology we're using?
Hybris is built almost entirely upon the Spring framework. I'm not sure if the site you are maintaining uses the Accelerator template for the storefront, but if it is, then you'll want to look into Spring MVC. Look for methods that are annotated with #Controller. You can do just about anything you want with Spring MVC including 301 redirects.
There is no simple way to do this immediately in a nice configurable way in hybris. And frankly you would not want to. You should handle this in your web server.
But if you really want to, you should add a filter to the Accelerator storefront to check incoming requests against a list of items (perhaps RedirectURL Items) and redirect as required.
Could you explain exactly what you are trying to achieve ? I think like it has been said, in most cases redirection at the web server level would be more appropriate.
We have an AppEngine app with that we would like to use with Google Endpoints. We need to support a web client as well as mobile clients which is what makes Endpoints attractive to us since we can easily generate Android and iOS client APIs.
The problem is that cloud endpoints currently don't support custom domains, so our web client cannot directly communicate with the endpoints (the mobile clients do not have this issue).
Here is what we've tried already:
CORS requests from the client to the appspot.com domain. The problem with this is since our request do not meet the requirements for simple CORS (custom headers, cookies, etc.), a preflight request must be sent with every request, which slows everything down
Client makes request to our custom domain which in turn makes a request to the appspot endpoint. Again, the extra request is not good for performance
We've also tried setting up a duplicate Jersey REST API just for the web client. We double annotate all our methods (once for Cloud Endpoints and once for Jersey) and the web client accesses the Jersey API and the mobile clients access the Endpoints API. This works pretty well except that Jersey and Endpoints use different exceptions. So if we want to throw a 404 Endpoints exception that will mess up the Jersey response and vice versa.
Are there any other options? We want to use the power of Endpoints for generating mobile clients but also get around the custom domain limitation for the web client.
We ended up ditching Cloud Endpoints entirely and went with a pure Jersey REST API instead.
To deal with our need to generate mobile clients for the API, we annotated our API with Swagger. As an added bonus, Swagger seems to support more client generation than Cloud Endpoints and also makes it relatively easy to setup your own client generation from a template if your target language isn't directly supported.
Jersey + Swagger was not as easy to setup as Cloud Endpoints, but it is more customizable and allowed us to get around the custom domain restriction imposed by Cloud Endpoints.
Google Cloud Endpoints 2.0 now supports custom domains. If you are using Google Cloud Endpoints 1.0 you can migrate by doing the following:
Update your dependency to use the new artifact. In Maven, this looks
something like below:
com.google.endpoints endpoints-framework 2.0.0-beta.8
Remove the legacy dependency, which is the appengine-endpoints artifact.
Update the API entry point in your project web.xml file:
Rename all occurrences of SystemServiceServlet to EndpointsServlet.
Replace all occurences of the path /_ah/spi/* to the new required path /_ah/api/*
See:
https://cloud.google.com/appengine/docs/java/endpoints/migrating
https://code.google.com/p/googleappengine/issues/detail?id=9384
Easiest solution is to use reverse proxy.
For example if your application is http://myapp.appspot.com, create simple html page on http://myapp.com and redirect to http://myapp.appspot.com using javascript.
Index.html on http://myapp.com.
<html>
<head>
<script>
windows.location = http://myapp.appspot.com;
</script>
</head>
<body></body>
</html>
It has one more advantage: if you put your proxy page on another hosting (not appspot.com) your application ( http://myapp.appspot.com ) will be accessible from China.
I'm starting to study GWT now, and have a very general question, I could maybe teach myself with a little more experience, but I don't want to start it wrong, so I decided to ask you.
I always develop using JSF, having separate packages for beans, controllers and managedbeans.
However, as the GWT uses RPC, I will not have managedbeans, right?
So, GWT automatically handles user session for me, or do I have to do it myself?
What is the best package structure for the project?
It is best to use RPC, or create a webservice and access the webservice in GWT?
It's hard to host the application on a tomcat server?
Is there a test saying which server is faster for GWT?
Thank you.
However, as the GWT uses RPC, I will not have managedbeans, right?
True, GWT RPC uses POJOs.
So, GWT automatically handles user session for me, or do I have to do it myself?
GWT is pure AJAX APP - client code (normally) runs in one browser window (similar to gmail) and does not reload the web page. This means that the application state is always there - no need for sessions (as a means of saving state). You still might need sessions for user authentication, but this is usually handled by servlet container.
What is the best package structure for the project?
Three packages: client, server and shared. Client for GWT client code, server for server (also RPC) code and shared for POJOs that are used by both client and server.
It is best to use RPC, or create a webservice and access the webservice in GWT?
Go with GWT-RPC or (better, newer) with RequestFactory.
It's hard to host the application on a tomcat server?
It's straightforward: GWT client code is compiled to JS/html and is hosted as any static content. RPC server code is just Servlets - normal web.xml registration.
Is there a test saying which server is faster for GWT?
No clue, but IMHO does not matter, because most of the latency will come from database and network.
Also have a look at http://code.google.com/p/gwt-platform/
This framework is really great and follow all suggested best practices(e.g. MVP) by google and give you as well great support for gin, gwt dispatcher, website crawling, history with tokens, code splitting via gwt async etc.
If you want to set up a good project structure try to use the maven gwt plugin(http://mojo.codehaus.org/gwt-maven-plugin/) it helps you a lot with setting up an initial structure and manage your build process.
I have a GWT application, with a Native Java backend, and a compiled Javascript front-end (as usual).
My GWT service should also be accessible from other clients, including a java applet. Initially my idea was to double the GWT service as a SOAP service, and use a soap client from the applet to access the GWT service, but I am wondering if it might be possible to use the built-in GWT client infrastructure to call the server from Java.
The problem with this approach is serializing the request and deserialize the response so as to be compatible with the GWT service.
One solution is to use GWT SyncProxy:
http://code.google.com/p/gwt-syncproxy/
which is explained here:
(dead) http://www.gdevelop.com/blog/2010/01/testing-gwt-rpc-services/
(Wayback Archive) http://wayback.archive.org/web/20130107141210/http://www.gdevelop.com/blog/2010/01/testing-gwt-rpc-services/
You can use it directly or, since they provide the source, you take a peek to see how they serialize the request and deserialize the response.
Another approach is to use Restlet to provide the services and then convert your GWT client to make REST calls. The Restlet people provide a GWT library to facilitate this.
http://wiki.restlet.org/docs_2.0/13-restlet/275-restlet/144-restlet.html
They provide an example of calling the REST service via Restlet from different clients, including GWT client, Java SE, and Android:
http://wiki.restlet.org/docs_2.0/13-restlet/21-restlet/318-restlet/303-restlet.html
Edit:
I only know RESTlet from evaluating it last year for my GWT project. I'm no expert and I didn't end up using it, but this is no reflection, good or bad, on RESTlet.
OP asks:
What would be the advantage of using the Restlet framework over JAX-RS ?
Essentially, JAX-RS is an just API (like JDBC) - you still need to pick an implementation or use the reference implementation Jersey. RESTLet has an extension for supporting JAX-RS API.
http://www.restlet.org/about/faq#07
7. What is the link between Restlet and JAX-RS (JSR-311)?
...
To summarize, both APIs have very different designs but are potentially complementary. The good news is that Jérôme Louvel (Restlet's creator) is an active member of the JSR-311 Expert Group and that an implementation of the JAX-RS API was made on top of the Restlet API. This "JAX-RS extension for Restlet" was developed by Stephan Koops in the context of his Master thesis and is one of the most advanced implementations available. For more documentation on this extension, please refer to this page.
OP asks:
Is it possible to use Tomcat / web.xml infrastructure instead of org.reslet.server
http://wiki.restlet.org/docs_2.0/13-restlet/275-restlet/312-restlet.html
This edition is aimed for development and deployment of Restlet applications inside Java EE application server, or more precisely inside Servlet containers such as Apache Tomcat.