Warm up requests not working in Cloud Endpoints Objectify - google-app-engine

I've been trying to get warm up requests to work in my Endpoints project using Objectify but nothing seems to be working. Is there something I missed? I tried two methods:
servlet:
public class WarmUpServ extends HttpServlet {
static {
ObjectifyService.factory().register(CounterEnt.class);
ObjectifyService.factory().register(CounterShard.class);
}
#Override
public void init() throws ServletException {
super.init();
}
#Override
public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException,IOException {
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>warm-up</servlet-name>
<servlet-class>com.myapp.backend.WarmUpServ</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>warm-up</servlet-name>
<url-pattern>/war-up</url-pattern>
</servlet-mapping>
And I also tried a listener:
public class WarmUpServListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
ObjectifyService.factory().register(CounterEnt.class);
ObjectifyService.factory().register(CounterShard.class);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
web.xml
<listener>
<listener-class>com.myapp.backend.WarmUpServListener</listener-class>
</listener>
Note: I need to register my entities this way because I have a dependency where it uses ObjectifyService directly.

Warmup requests are not guaranteed to be made.
https://cloud.google.com/appengine/docs/standard/java/warmup-requests/
If warmup requests are enabled for your application, App Engine
attempts to detect when your application needs a new instance and
initiates a warmup request to initialize a new instance. However,
these detection attempts do not work in every case. As a result, you
might encounter loading requests, even if warmup requests are enabled
in your app. For example, if your app is serving no traffic, the first
request to the app will always be a loading request, not a warmup
request.
Use a ServletContextListener instead; that will always be called once at each instance start.

Related

Configure http4 certificate in application.yml

I'm trying to move my http4 certificate configuration away from RouteBuilder class and to application.yml file. My code is exactly like the Java example on this page under the "Setting up SSL for HTTP Client - Programmatic Configuration of the Component": (https://camel.apache.org/http4.html#HTTP4-UsingtheJSSEConfigurationUtility). However, on the website there is no yml example, only the Java solution that I currently have and Spring DSL solution. Does anybody know how to translate the Java code to yml?
#Configuration
public class configureHttps4Certificate extends RouteBuilder {
#Override
public void configure() throws Exception {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("pathToResource");
ksp.setPassword("password");
TrustManagersParameters tmp = new TrustManagersParameters();
tmp.setKeyStore(ksp);
SSLContextParameters scp = new SSLContextParameters();
scp.setTrustManagers(tmp);
HttpComponent httpComponent = getContext().getComponent("https4", HttpComponent.class);
httpComponent.setSslContextParameters(scp);
}
}
If you use SpringBoot you can easily create Java configuration classes that automatically import values from property or YAML files just by using one annotation.
#ConfigurationProperties("app.config")
public class MyConfiguration
Check out this section of the SpringBoot documentation that describes this mechanism.

App Engine: Empty referrer error from cron Job when calling Endpoint with restricted API key

I have an App engine app + Cloud endpoints. I have configured a cron task in the task queue to call one of the endpoints. The cron has an auth-constraint to admin.
All of this is working, however when I restrict the api key to certain domains, I get the following error when the cron is run:
Failed
check_errors {
code: REFERER_BLOCKED
detail: "Requests from referer <empty> are blocked."
}
It doesn't seem like I can add a referee header to the cron.yaml
apparently Google App Engine issues cron requests from the IP address 0.1.0.1.
so I could potentially allow that ip, but I want to restrict api key by domain not i.p. and it doesn't seem like I can do both
Does anyone know a workaround to allow the cron job access to an api key restricted by domain?
I found a work around for this:
Note: I see people referencing this in the docs:
"Calling Google Cloud Endpoints
You cannot call a Google Cloud Endpoint from a cron job. Instead, you should issue a request to a target that is served by a handler that's specified in your app's configuration file or in a dispatch file. That handler then calls the appropriate endpoint class and method."
https://cloud.google.com/appengine/docs/standard/java/config/cron#
Without further explanation or example that I could see.
I am however able to call my endpoints from a cron job, and it was working fine, other than the api key restraint issue.
I read several comments on other posts that mention doing a servlet mapping, but without providing an example, so here is the workaround I found and example code for the servlet mapping.
Java Class
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
// call your Endpoint Method here, or whatever you want
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
}
web.xml
<servlet>
<servlet-name>cronServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cronServlet</servlet-name>
<url-pattern>/cronServlet</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>cronServletConstraint</web-resource-name>
<url-pattern>/cronServlet</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
cron.yaml
cron:
- description: myCron
url: /cronServlet
schedule: every 12 hours
https://cloud.google.com/appengine/docs/flexible/java/how-requests-are-handled

resolving views in angularjs spring boot application with spring security

I am trying to build an application with AngularJS 1.x, Spring Boot REST with Spring Security. Though I have intermediate knowledge on Spring REST itself, I am quite new to AngularJS and Spring Security.
I have given the github link of the application I have developed so far. Its in skeletal form still, and nothing is working:
https://github.com/imrnk/touchinghand
I will list down the problems and confusion I am having below:
1) I am using ui-router states to navigate from one state to another. So far I have identified two states: the "login" page and a link from there to "registration" page. Once the user will logged in, she will land to a dashboard. But this dashboard is yet to be created.
Now this login.html could be said as the entry point to the application. And when I type localhost:8080/ it should redirect to localhost:8080/login. Now I can see the page is redirecting correctly to the login.html but the templates I am using (login.template.html or register.template.html) inside login.html is not loading... However, when I am running through node js using browsersync, I see the page is loading with all the contents in it.
2) I tried disabling the spring security and then I see the login page is loaded correctly. So I guessed it could be a spring security issue, but what exactly is the issue I couldn't figure out.
My HttpSecurity configuration inside the implementation of WebSecurityConfigurerAdapter looks like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/login", "/register", "/**/*.css",
"/**/*.js", "/**/**/*.css", "/**/**/*.js",
"/**/**/**/*.css", "/**/**/**/*.js",
"/**/**/**/**/*.css", "/**/**/**/**/*.js", "/**/home.html", "**/login.html",
"**/**/login.template.html", "**/**/registration.template.html")
.permitAll().
regexMatchers("/registration*")
.permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
And my MvcConfig looks like this:
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("classpath:/resources/static/css/**")
.addResourceLocations("classpath:/resources/static/css/");
registry.addResourceHandler("classpath:/resources/js/**").addResourceLocations("classpath:/resources/js/");
registry.addResourceHandler("classpath:/resources/static/**")
.addResourceLocations("classpath:/resources/static/");
registry.addResourceHandler("classpath:/resources/static/templates/**")
.addResourceLocations("classpath:/resources/static/templates/");
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/").setViewName("forward:/login");
//registry.addViewController("/login").setViewName("forward:/login");
registry.addViewController("login.html");
//registry.addViewController("register").setViewName("registration");
// registry.addViewController("/registration.html");
//registry.addViewController("/dashboard").setViewName("dashboard");
//registry.addViewController("/dashboard.html");
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("static/");
resolver.setSuffix(".html");
registry.viewResolver(resolver);
}
}
My LoginController class which anotated as #Controller has this:
#RequestMapping(value={"/"}, method = RequestMethod.GET)
public String showLogin(Model model){
model.addAttribute("user", new UserDTO());
return "/login";
}
3) I am quite confused between what should be the name of the resolved views and how that could map with the angular templates html.
I suspect, probably I am following a pure REST approach, and hanging in the middle with some aspect of Spring MVC and Spring REST. Introducing Spring Security also increased the problem for now.
I am also attaching the firefox developer network screenshot if that could help
enter image description here
Kindly help me out. Thanks.

Spring MVC AngularJS No mapping found

I've been following the tutorial for integrating Spring Security with AngularJS, but it uses Spring Boot. I can get the tutorial examples working, but I need my app to run as a regular MVC application under Tomcat.
The problem is getting the application to route to the index.html page for the initial view. The only mappings I have in the controllers are the REST calls I want to receive from Angular, but I can't seem to get the application to go to the index page. Spring Boot does this automatically, but I'm going to run this as a web app under Tomcat. Trying to go there directly causes a 'No mapping found' error.
I'm using Java configuration and have the antMatchers, etc as described in the tutorial.
Here are a few entries in my config classes to make this happen.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/index.html", "/home.html", "/login.html", "/").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers(HttpMethod.POST, "/user").permitAll().anyRequest()
.authenticated().and()
.csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
if ("true".equals(System.getProperty("httpsOnly"))) {
LOGGER.info("launching the application in HTTPS-only mode");
http.requiresChannel().anyRequest().requiresSecure();
}
}
#Configuration
#EnableWebMvc
#ComponentScan("com.mygroupnotifier.controller")
public class ServletContextConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/resources/static/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/resources/static/js/");
registry.addResourceHandler("/*.html").addResourceLocations("/resources/static/");
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
}
As usual the most difficult part of this is getting the leading and ending / on the classes and the html files.

UriMatcher equivalent helper for web apps?

I have coded a lot of Android App and many times, I have used the UriMatcher class to match both conetent uris and http urls.
Now I am working on a little web app using Java and Gae. I have little servlet that need to match calls agains DYNAMIC info. Not static url patterns, but runtime parse data.
In Android, UriMatcher would have been my chioce, but what is available in the Java Se World?
You can simply use Java Servlet API on GAE and register it to receive a wildcard Uris, then resolve and map Uris:
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
String uri = req.getRequestURI();
// do something with the uri here
// generate a response
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
}
and register it:
<servlet>
<servlet-name>My servlet</servlet-name>
<servlet-class>com.package.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>My servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

Resources