Visar inlägg med etikett google. Visa alla inlägg
Visar inlägg med etikett google. Visa alla inlägg

2016-09-01

Scala Stack with Google Flexible Environment

Scala Stack with Google Flexible Environment

(this article is not yet completed)
(updated 2016-11-11)

I've created a few Maven projects based on Google Flexible Environment and Scala backend which produces HTML, CSS and JavaScript without any files (.html, .css, .sass, .less, .js) and without any frontend builder like Gulp or Grunt.

Goal

To produce all frontend from Scala backend utilizing shared code and to be fully tested.

Infographic

Scala servlets creates HTML with CSS and JavaScript.
This is a graphic representation of how it works.
  • All code is written in Scala
  • Code may share
    • Resources
    • Validation
    • Routes
    • Logic
    • Translations and other data
    • Structure of
      • HTML
      • CSS
  • A servlet can read Scala JS source code and compile a JavaScript
    • This includes the shared code
  • A servlet can build HTML with CSS 
  • Other servlets can provide REST API and also use the shared code
  • All code can be unit tested and all code can be tested in the same test
This means that the Scala stack covers both frontend and backend.

Code

There is a repository called Scala Stack at Github. There is one branch for jQuery in development and one branch for Angular which is only started:
*Unfortunately I can't afford Google Compute Engine running 24/7 and was forced to shut them down. If Google Compute Engine would scale from 0 to minimize expense I could start them again.

Examples

I'm currently working on a example using jQuery (in progress) and one using Angular (started).
Note that Scala JS source is placed in webapp, an alternative could be resources



2016-07-12

Google Flexible Environment with Virtual Scala JS Compiler

Google Flexible Environment with Virtual Scala JS Compiler

After several months I managed to translate Scala JS Fiddle to Google Java Flexible Environment 

Goal

To create a project with Scala backend which generates JavaScript in a virtual compiler.

Live Demo

The live demo uses a Scala Servlet to generate HTML (Scala Tags) with a JavaScript. A second Scala Servlet is responding to "/javascript.js" and is using a virtual compiler to compile a String with simple Scala JS code to a JavaScript

Environment

It's a Maven project using Google Flexible "Compat" Environment which includes some App Engine features (not used) and Java 8 with Servlet API 3.1.

Source

Check out my Github

2016-06-21

Logging with Flexible Environment and Jetty

Logging with Flexible Environment and Jetty

Problem

Logging was not available for Google Flexible Environment with Java 8 and Jetty 9. But after reading Jetty documentation all needed was added SLF4J as dependency and use it's Logger.

Solution

Add SL4FJ as dependencies in pom:

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.21</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.21</version>
    </dependency>

Use org.slf4j.LoggerFactory and org.slf4j.Logger to log:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static Logger logger = LoggerFactory.getLogger(JavaServlet.class);
logger.info("Info logging!");

Deployed

When deployed, the logging is shown in STDERR

2015-12-06

Infographic of Google Endpoints in both Scala and Scala JS

I'm no expert in infographics, but I'd tried to show how Google Endpoints is implemented in Scala and Scala JS.

Map

So there are three different languages:
  1. Scala
  2. Javascript
  3. HTML

Google Endpoints

When this is implemented in Scala on backend, it will generate Javascript. HTML needs to load the script and call a Javascript function when loaded.

Scala JS

Written in Scala, Scala JS will generate Javascript. When the Google Endpoints script is loaded, it will callback to Scala JS's script which will created either dynamic or facade representations of it.

Shared

Since Google Endpoints is implemented in Scala and frontend Javascripts in Scala JS, it's easy to share common logic with Scala code.

Code Example

A simple implementation can be found here:

2015-12-05

Dynamic and facade implementation of Google Endpoints with Scala JS

Google Endpoints generates Javascript that mirrors all REST calls to backend. With Scala JS, these scripts can be used in two different ways: dynamic or facade.

Dynamic

This is the easiest solution. If you know the names and the parameters to backend I would recomend this approch. All you need to do is to type vars and defs to js.Dynamic and then use them just as Javascript. Example of loading your API:
And to use a method with csv as parameter:
"literal(csv = validatedText)" is like Javascript "{csv : validatedText}"

Facade

This is approch needs more work since you need to mirror the Javascript generated by Google Endpoints, but will give you types and the structure of the Javascript.
Example of loading your API:
This works since you have defined the API in a facade like in this example:
You know which functions are available since you have made a complete facade. Example:
And therefore it's easy make a call with types:

2015-12-04

Scala JS with Angular and Google Endpoints

Finally done with a simple implementation with Scala JS of Angular and Google Endpoints.

Scala

All backend and frontend is done in Scala with shared logic. Made a simple validation of input which is used in frontend when trying to post, and in backend when it receives.

Google Endpoints

A Javascript is generated which mirrors all exposed methods. This is then used by Scala JS to make all requests to backend.

2015-11-09

Google App Engine + Scala + ScalaJS + Objectify

Created a single Maven project combining Google App Engine, Scala, ScalaJS and Objectify.

Description

A Scala implementation of Filter using Objectify, a separate source directory for ScalaJS which is generating JavaScript with SBT.

2015-11-08

Google Endpoints + Objectify

Created a small project combining Google Endpoints with Objectify. Added page with a simple JavaScript introduction.

Fabric

There is a small sample for creating some data and getting it.

Creating

As a sample, it's possible to create three different entities
  • EntityId, with POST, creates a new id
  • EntityData, with POST
  • EntityPrimitives, with POST
When posting an EntityId, the response will be its new id.
When posting an EntityData or EntityPrimitives, use the same id as EntityId.

Fetching

To get each type, there's a GET path like
/entityid/123
/entitydata/123
To get the EntityId and all children with the same id, it's possible to use
/entityid/123/entitydata+entityprimitives/

2015-09-12

App Engine + Scala + Java + SBT + Eclipse

Combining Java App Engine with Scala and SBT, and Import to Eclipse

Forked and added Eclipse plugin, to in a easy way run a App Engine project in Eclipse and with Scala.

2015-06-20

Google App Engine + Scala with Jersey + ScalaJs

Have been interested in ScalaJs for a while and wanted to use it and Scala with Jersey in Google App Engine. This is a first try to combine them.

GitHub Repository


2015-02-05

Auth0 + Google App Engine (Java) = "Running on GAE? Fine. No cookie support for you!"

Had some troubles implementing Auth0 Java example code to Google App Engine since ...


  1. W2015-02-05 20:25:28.236
    [s~workaround-town/1.382027755131049112].<stderr>: No CookieHandler. Running on GAE? Fine. No cookie support for you!
    
    
  2. W2015-02-05 20:25:28.239
    Error for /auth0-callback/
    java.lang.ExceptionInInitializerError
     at com.auth0.Auth0ServletCallback.createResty(Auth0ServletCallback.java:168)
     at com.auth0.Auth0ServletCallback.fetchTokens(Auth0ServletCallback.java:109)
     at com.auth0.Auth0ServletCallback.doGet(Auth0ServletCallback.java:73)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
     at se.ce.workaround.WorkaroundFilter.doHttpFilter(WorkaroundFilter.java:145)
     at se.ce.util.web.singlepage.DefaultFilter.doFilter(DefaultFilter.java:38)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58)
     at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
     at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
     at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
     at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
     at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
     at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
     at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
     at org.mortbay.jetty.Server.handle(Server.java:326)
     at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
     at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
     at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
     at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
     at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
     at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:484)
     at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
     at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
     at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
     at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
     at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
     at java.lang.Thread.run(Thread.java:724)
    Caused by: java.security.AccessControlException: access denied ("java.net.NetPermission" "setDefaultAuthenticator")
     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
     at java.security.AccessController.checkPermission(AccessController.java:565)
     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
     at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
     at java.net.Authenticator.setDefault(Authenticator.java:127)
     at us.monoid.web.Resty.<clinit>(Resty.java:94)
     ... 43 more
    
  3. W2015-02-05 20:25:28.241
    Nested in java.lang.ExceptionInInitializerError:
    java.security.AccessControlException: access denied ("java.net.NetPermission" "setDefaultAuthenticator")
     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
     at java.security.AccessController.checkPermission(AccessController.java:565)
     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
     at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
     at java.net.Authenticator.setDefault(Authenticator.java:127)
     at us.monoid.web.Resty.<clinit>(Resty.java:94)
     at com.auth0.Auth0ServletCallback.createResty(Auth0ServletCallback.java:168)
     at com.auth0.Auth0ServletCallback.fetchTokens(Auth0ServletCallback.java:109)
     at com.auth0.Auth0ServletCallback.doGet(Auth0ServletCallback.java:73)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
     at se.ce.workaround.WorkaroundFilter.doHttpFilter(WorkaroundFilter.java:145)
     at se.ce.util.web.singlepage.DefaultFilter.doFilter(DefaultFilter.java:38)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58)
     at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
     at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
     at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
     at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
     at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
     at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
     at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
     at org.mortbay.jetty.Server.handle(Server.java:326)
     at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
     at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
     at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
     at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
     at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
     at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:484)
     at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
     at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
     at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
     at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
     at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
     at java.lang.Thread.run(Thread.java:724)
    
  4. C2015-02-05 20:25:28.244
    Uncaught exception from servlet
    java.lang.ExceptionInInitializerError
     at com.auth0.Auth0ServletCallback.createResty(Auth0ServletCallback.java:168)
     at com.auth0.Auth0ServletCallback.fetchTokens(Auth0ServletCallback.java:109)
     at com.auth0.Auth0ServletCallback.doGet(Auth0ServletCallback.java:73)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
     at se.ce.workaround.WorkaroundFilter.doHttpFilter(WorkaroundFilter.java:145)
     at se.ce.util.web.singlepage.DefaultFilter.doFilter(DefaultFilter.java:38)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58)
     at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
     at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
     at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
     at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
     at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
     at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
     at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
     at org.mortbay.jetty.Server.handle(Server.java:326)
     at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
     at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
     at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
     at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
     at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
     at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:484)
     at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
     at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
     at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
     at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
     at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
     at java.lang.Thread.run(Thread.java:724)
    Caused by: java.security.AccessControlException: access denied ("java.net.NetPermission" "setDefaultAuthenticator")
     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
     at java.security.AccessController.checkPermission(AccessController.java:565)
     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
     at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
     at java.net.Authenticator.setDefault(Authenticator.java:127)
     at us.monoid.web.Resty.<clinit>(Resty.java:94)
     ... 43 more
Will create a Auth0Callback suited for Google App Engine. Take a look at my Github:
https://github.com/AIMMOTH/GAEAuth0Callback