GCP - Cloud endpoints service_name and configuration - google-app-engine

I am studying Google Cloud Endpoints and I have some doubts about configuration.
I already work with appengine, but endpoints it is a little confuse for me.
I did this example:
https://cloud.google.com/endpoints/docs/frameworks/java/get-started-frameworks-java
I did some changes for test other possibilities:
appengine-web.xml
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java8</runtime>
<threadsafe>true</threadsafe>
<module>endpointsmodule</module>
<basic-scaling>
<max-instances>1</max-instances>
</basic-scaling>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
<!-- [START env_variables] -->
<env-variables>
<env-var name="ENDPOINTS_SERVICE_NAME" value="${endpoints.service.prefix}.endpoints.${endpoints.project.id}.appspot.com" />
<env-var name="ENDPOINTS_SERVICE_VERSION" value="1.0.0" />
</env-variables>
<!-- [END env_variables] -->
</appengine-web-app>
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- Wrap the backend with Endpoints Frameworks v2. -->
<servlet>
<servlet-name>EndpointsServlet</servlet-name>
<servlet-class>com.google.api.server.spi.EndpointsServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>com.example.echo.Echo,com.example.echo.Echo2</param-value>
</init-param>
</servlet>
<!-- Route API method requests to the backend. -->
<servlet-mapping>
<servlet-name>EndpointsServlet</servlet-name>
<url-pattern>/endpointsmodule/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- Add a filter that fetches the service config from service management. -->
<filter>
<filter-name>endpoints-api-configuration</filter-name>
<filter-class>com.google.api.control.ServiceManagementConfigFilter</filter-class>
</filter>
<!-- Add a filter that performs Endpoints logging and monitoring. -->
<!-- [START api_management] -->
<filter>
<filter-name>endpoints-api-controller</filter-name>
<filter-class>com.google.api.control.extensions.appengine.GoogleAppEngineControlFilter</filter-class>
<init-param>
<param-name>endpoints.projectId</param-name>
<param-value>${endpoints.project.id}</param-value>
</init-param>
<init-param>
<param-name>endpoints.serviceName</param-name>
<param-value>${endpoints.service.prefix}.endpoints.${endpoints.project.id}.appspot.com</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>endpoints-api-configuration</filter-name>
<servlet-name>EndpointsServlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>endpoints-api-controller</filter-name>
<servlet-name>EndpointsServlet</servlet-name>
</filter-mapping>
<!-- [END api_management] -->
</web-app>
pom.xml
<endpoints.project.id>myprojectid</endpoints.project.id>
<endpoints.service.prefix>mymodule</endpoints.service.prefix>
openapi.json
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "xxx"
},
"host": "myprojectid.appspot.com",
"basePath": "/endpointsmodule",
"schemes": [
"https"
],
The doubts are:
Whats is the purpose of service_name? I did deploy of openapi.json and appengine module but in my Google Console still appear the name of my project in "service name".
this configuration: ENDPOINTS_CONFIG_ID, I can not see anywhere in my Google Console.
I would like that my endpoints receive requets in "enpoints-module"(appengine) that is appengine, not a default module.
All requests to endpoints happen through _ah/api ?
I am trying to do a request for this path:
https://myprojectid.appspot.com/endpointsmodule/echo/v1/echo
What is the correct value to ENDPOINTS_CONFIG_ID and ENDPOINTS_SERVICE_VERSION?
The exception when appengine starts:
repackaged.com.google.api.config.ServiceConfigException: Failed to fetch default config version for service 'myserviceprefix.endpoints.myprojectid.appspot.com'. No versions exist!

The Endpoints service name is host field set in the OpenAPI specification. This has to match both the environment variable ENDPOINTS_SERVICE_NAME and the endpoints.serviceName filter parameter.

Related

Map a servlet to a cron url?

How do I map a servlet to a cron url? This question results from the comment to the answer in the following post: Use Cron jobs with Appengine Endpoints API
In my project the cron job is called as shown in the log in Google App Engine and the url https://[url-commented-out].appspot.com/_ah/api/stocksApi/v1/stocks executes properly when tested in the web browser and returns the proper value.
But I am getting the error 405: HTTP method GET not supported by this URL, when I try to run it in GAE. I've read https://cloud.google.com/appengine/docs/java/config/cron My code in cron.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/_ah/api/stocksApi/v1/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>
</cronentries>
My web.xml is:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>
[package].StocksEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/api/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>cron</web-resource-name>
<url-pattern>/_ah/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I am using Android Studio and have added a backend module by following HelloEndpoints and I have a StocksEndpoint.java
file with a getStocks(); method that returns stocks.
First add a servlet mapping for your cron to web.xml:
<!-- stock servlet -->
<servlet>
<servlet-name>StockServlet</servlet-name>
<servlet-class>YOUR.PACKAGE.HERE.StockServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StockServlet</servlet-name>
<url-pattern>/cron/stocks</url-pattern>
</servlet-mapping>
make sure to update the servlet class for your servlet!
Then finally put the new cron url in your cron.xml:
<cron>
<url>/cron/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>
Unfortunately urls under /_ah/api are restricted and cannot be called from within your App.
There are a couple of ways to go around this but the most accepted option is usually to use a regular servlet to serve Cron requests rather connecting to the endpoint.

Deploy vaadin app to Google App Engine - Error NOT_FOUND

I successfully deployed a Vaadin application, but when calling it I see ERROR : NOT_FOUND
I suppose that my default page is not found,because the default page is selected wrong.
Question:
How can I point (I suppose in my web.xml) to my default page?
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>GoogleAppVaadin701Project</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Vaadin eclipse plugin does not create web.xml which works for vaadin application. In the book of vaadin you can find section about web.xml - https://vaadin.com/book/vaadin7/-/page/application.environment.html
following is basic servlet definition and mapping based on the book which works fine. Just change the UI parameter to point to your UI implementation
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>
com.vaadin.server.GAEVaadinServlet
</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>com.example.higoogle.HigoogleUI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

Works locally but throws java.lang.IncompatibleClassChangeError when deployed to GAE

I am attempting to use Jersey coupled with GAE to produce a RestFul endpoint. The guide that I have attempted to follow can be found here. The service works properly when run locally. When deployed to GAE I receive a 500 error with the stack trace shown below.
I am using Eclipse Juno Service Release 1, AppEngine - 1.7.3, jersey-archive-1.1.5-ea-SNAPSHOT
Here is my Web.xml
<?xml version="1.0" encoding="utf-8" standalone="no"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.senseme.server</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value/>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
</web-app>
Here is my appengine-web.xml:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>sensemeweb</application>
<version>1</version>
<!--
Allows App Engine to send multiple requests to one instance in parallel:
-->
<threadsafe>true</threadsafe>
<!-- Configure serving/caching of GWT files -->
<static-files>
<include path="**" />
<!-- The following line requires App Engine 1.3.2 SDK -->
<include path="**.nocache.*" expiration="0s" />
<include path="**.cache.*" expiration="365d" />
<exclude path="**.gwt.rpc" />
</static-files>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
<!--
HTTP Sessions are disabled by default. To enable HTTP sessions specify:
<sessions-enabled>true</sessions-enabled>
It's possible to reduce request latency by configuring your application to
asynchronously write HTTP session data to the datastore:
<async-session-persistence enabled="true" />
With this feature enabled, there is a very small chance your app will see
stale session data. For details, see
http://code.google.com/appengine/docs/java/config/appconfig.html#Enabling_Sessions
-->
</appengine-web-app>
Works locally but when deployed to GAE the following exception is thrown:
Uncaught exception from servlet
java.lang.IncompatibleClassChangeError: Implementing class
at com.google.appengine.runtime.Request.process-eef9dd80521e7794(Request.java)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:68)
at com.sun.jersey.api.core.PackagesResourceConfig.init(PackagesResourceConfig.java:110)
at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:76)
at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:87)
at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:641)
at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:619)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:199)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:307)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:470)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440)
at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:454)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:461)
at com.google.tracing.TraceContext.runInContext(TraceContext.java:703)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:338)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:330)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:458)
at java.lang.Thread.run(Thread.java:679)
I have tried just about everything to no avail, How do I fix this?
After trying every solution I encountered this is the one that I found to resolve the issue:
https://stackoverflow.com/a/13552626/778331

Google App Engine - JSF - Facelets - Why not *.xhtml as a url-pattern?

I'm migrating an existing app from Tomcat to GAE. When testing locally, the xhtml pages are loaded as static pages. All processing is bypassed including my filter. However, if I reference a page that doesn't exist, my security filter forwards the request to the login.xhtml and the JSF/facelet renders fine.
Any idea why the xhtml pages are getting processed?
Other integrations: eclipse Helios, gae 1.6.5, maven (eclipse/m2), moharra 2.0.9, richfaces 4.2.0, spring 3.1.1
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- https://community.jboss.org/wiki/HowToUseRichFaces40WithGoogleAppEngine -->
<context-param>
<param-name>com.sun.faces.enableThreading</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>com.xyz.web.filter.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.richfaces.webapp.ResourceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/org.richfaces.resources/*</url-pattern>
</servlet-mapping>
</web-app>
Update:
It works if I add the following mapping and refer to the page with .jsf extension. Referring to the .xhtml directly, still loads the source. Is it typical configuration to refer to .jsf extension for a .xhtml? If so, how do you configure the app so the source isn't available when accessed via .xhtml?
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
If I correctly understand your needs, you should add
<static-files>
<exclude path="/**.xhtml" />
</static-files>
in appengine-web.xml
If you skip this, your web browser will get reply from "static file server", not from JSF.

Development Console in Google App Engine with Struts 2

I tried Struts 2 in Google App Engine following example from http://www.mkyong.com/google-app-engine/google-app-engine-struts-2-example
It works perfectly but I can't accessed Development Console which is supposed to be accessed in http://localhost:8888/_ah/admin
Is it about the filter? How to fixed it?
Below is the content of web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.mkyong.listener.Struts2ListenerOnGAE</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Yes, the <url-pattern>/*</url-pattern> maps everything to Struts filter.
I solved it by appending the code below to struts.xml
<constant name="struts.action.excludePattern" value="/_ah/admin"/>

Resources