User Guide
  • Introduction
  • Overview
    • About 4WS.Platform
      • Architecture
      • Enterprise Edition
      • Tech specs and requirements
      • Warp SDK
    • Creating a web application
  • Core features
    • Tables
    • SqlTool
    • Definition of Data models and Relations
      • Relations
      • Reverse Engineering
      • Custom Fields
    • Defining business components
      • What are business components
      • Business components to fill-in panels
      • Creating business components
        • By a datastore entity
        • By a MongoDB collection
      • Defining Custom Java Business component
    • Defining the UI
      • App Designer
        • App Designer Menu
        • Definition of additional data sources
        • Panel containers and layouts
          • Tab panel
          • Alternative panel
          • Accordion panel
          • Vertical orientation panel
          • Horizontal orientation panel
          • Columns panel
          • Table panel
          • Generic panel
          • Responsive panel
        • Window content
          • Grid Panel
          • Form Panel
          • Filter Panel
          • Tree Panel
          • Google Map Panel
          • Preview Panel (old Image panel)
          • Tree + Grid Panel
          • Image Gallery
        • Windows list
        • Panel definition
          • Columns properties
          • Controls properties
          • Filter properties
          • Supported components
        • Variables
        • Code selectors
          • When not to use a dynamic combo-box
        • Smart Filter and Advanced Filter
        • Multi Value Combobox Filter
        • Multi Value Tree Filter
        • Buttons
        • Translations
          • Translations about GUI components and internationalization settings
          • Data coming from database
          • Custom code and translations
        • Application Menu
        • Bulk import binded to a grid
        • Range Date Filter
      • Web Interpreter
        • Grid components
        • Detail forms
        • Other components
        • Other features
          • Chat
        • Global variables
          • Client-side global variables
          • Server global variables
        • Forgot Password
    • Working with users and roles
      • Rule for roles
      • Permissions Administrator
    • Wizard
      • How to add a checkbox grid to select one or more rows
      • How to load a second grid when clicking on a row from the first grid
      • How to load a form when clicking on a row of the grid
      • How to open a window when double clicking on a row of the grid
      • How to open a window with right click on the popup menu
      • How to open a window when pressing a button on the grid toolbar
      • How to load a grid after loading a form
      • How to open a window when pressing a button on the form toolbar
      • How to load a grid when clicking on a tree node
      • How to load a form when clicking on a tree node
    • Defining events
      • Panel events
      • Column events
      • Control events
      • Filter events
      • Timer events
      • Start-End event
    • Server-side Javascript & Web Service
      • Server-side Javascript
      • Grid component filled by a server-side JS
      • Detail component filled by a server-side JS
      • How to define a server-side JavaScript action
      • Web service
  • Setting up the environment
    • How to install
    • Application parameters
    • Global parameters
  • Modules
    • Reports & Charts
      • Jasper Report + iReport
      • Online report
      • Docx templating
      • Charts
      • Pivot Grid
      • Multidimensional pivot grid
      • Data Export from SQL query
    • SSO
      • Identity management in Platform
        • Identity management on the internal Platform database
        • Identity management based on Google SSO
      • LDAP
        • LDAP support
        • Identity management based on LDAP and database
        • Identity management based on an embedded LDAP server used by Alfresco and or Activiti
        • Identity management based on a remote LDAP server to connect to Platform on the cloud
        • Connecting an LDAP server to Activiti BPM
        • Connecting an LDAP server to Alfresco ECM
      • Google SSO
        • Google SSO
        • Google OAuth2
        • Identity management based on Google SSO
      • Custom SSO
      • Firebase
    • Mobile
      • Mobile introduction
      • Offline vs Online
        • Server side features
        • Server side functionalities
        • Server side Platform features
        • Mobile app features
      • Mobile side specifics
        • Customizations
          • Custom theme editor
        • App Menu
        • Window content
          • Detail scrollable form
          • Scrollable paginated grid
          • Constraint layout
          • Constraint panel
          • Collection grid view
          • Preview panel (mobile)
        • Form Controls
      • Reference guide
      • Cleaning up data
      • How to
      • App deployment
        • App deployment for the iOS platform
        • App deployment for the Android platform
      • Style properties
      • Appendix : Synchronization flow
      • Translations
    • GSuite
      • Introduction
      • Client-side integration
      • GMail
      • Calendar
      • Drive
      • Contacts
    • Google Cloud Platform
      • Datastore
        • Google Datastore Introduction
        • How to create Datastore entities
      • Google Cloud Storage
    • Scheduler
      • Scheduler Introduction
      • Process settings
        • How to define a sequence of consecutive processes
        • How to define a Custom Java Business component
        • How to define a Grid Data Import
        • How to define a server-side Javascript action
      • Email notifications
      • Process executions
      • Manually start a scheduled process
      • Process input parameters
    • Queue Manager
    • Log & Analysis
      • Application Log
      • Log statistics
      • App analyzer
      • Table log
      • Threads
      • Sessions and heap memory
      • Heap memory analysis
      • Access Log
      • Datastore statistics
      • Total monthly costs with Google Datastore
      • Service Monitoring
        • Introduction
        • Defining a service to monitor
        • Notifications setup
        • Events automatically managed by Platform
        • Remote Platform servers
        • Knowledge base
        • Adding log programatically
        • Searching for logged data
        • Use cases
    • File Management
    • Export and Import of Metadata
      • Application Metadata Management
    • Trigger writing operations
    • Audit
    • BPM
      • BPMN Introduction
      • BPMN main parts
      • Activiti Setup
      • Platform integration
        • Processes
        • Models
        • Process instances
        • To-do list
        • Process history
      • Process Web Modeler
        • Model Creation
          • Start-End Event
          • Gateways
        • Supported objects
        • Start tasks and user tasks
        • Form properties
          • Important notes
          • Property types
        • Service tasks
          • Web service
          • SQL Query
          • SQL statement
        • Mail task
        • Script task
          • Example : how to get a value previously read from a SQL query
          • Example : how to get the current process instance id
        • Timer events
        • Subprocess and Call Activiti
      • Utility methods available in Platform
        • How to start a process from a JavaScript action
        • How to complete a user task from a JavaScript action
      • An example
        • Processes
        • Instances
        • Activities
        • History
    • Embedded CMS
    • ECM
      • Alfresco
        • Alfresco Introduction
        • Integration between 4WS.Platform and Alfresco
          • Integration at GUI level
          • Integration at model level
          • Integration at authentication and authorizations level
          • Additional features
        • How to use 4WS.Platform and Alfresco together
          • Set the same Identity Management system
          • Define document types and aspects in Alfresco
          • Import the document types and aspects definitions in 4WS.Platform
          • Define document types and aspects in 4WS.Platform
          • Reverse engineering of document types or aspects
          • Definition of business components to fill-in panels
          • Definition of the GUI
          • Additional server-side services
        • Requirements
        • Current limits in 4WS.Platform - Alfresco integration
      • Archiflow
        • Setup
        • Archiflow artifacts
        • How to
    • Lotus Notes Migration Tool
    • NoSQL databases
      • MongoDB
        • MongoDB Introduction
        • Setting up the environment
        • How to create collections
        • How to create business components
        • How to create windows filled with data coming from MongoDB collections
        • Design rules
      • Google Datastore
        • Google Datastore Introduction
        • Setting up the environment
        • How to create entities
        • How to create business components
        • How to create windows filled with data coming from Datastore entities
        • Design rules
    • TensorFlow
    • Web Page Development
      • Pure Web Page Development
      • Google Material Design development
      • Appendix A - a complete example without any lib
      • Appendix B - a complete example with Google MD
    • Jira Integration
    • Platform for GAE
    • SQL errors management
    • Multidimensional pivot grid
    • Quality
      • Automated Web Service Testing
      • Automated unit testing
      • Source code static analysis using ESlint
      • Source code static analysis using SonarQube
  • Troubleshootings
  • Best practises
    • Database design
    • Database maintenance
    • Creating a Web app : common use cases
    • Creating a mobile app : common use cases
Powered by GitBook
On this page
  • Platform for GAE
  • Limitations
  • Setup
  • Every-day activities

Was this helpful?

  1. Modules

Platform for GAE

PreviousJira IntegrationNextSQL errors management

Last updated 5 years ago

Was this helpful?

Google App Engine (GAE) is a cloud computing platform for developing and hosting web services in Google-managed data centers. Web services can run across multiple servers, with automatic scaling: when the number of requests increases for an application, App Engine automatically allocates more resources to handle the additional demand.

Google App Engine is free up to a certain level of consumed resources. Fees are charged for additional storage, bandwidth, or instance hours required by the application (web services).

Google App Engine's integrated Google Cloud Datastore database has a SQL-like syntax called "GQL". GQL does not support the Join statement. Anyway, Datastore is a powerful NoSQL database, able to manage a very high amount of data, in a scalable way, so it represents the perfect choice for some parts of an application, requiring working with big data and do not have the need for analysis of aggregated data, where a relational database or a BI solution can better fit the scenario.

Platform for GAE

Starting from this brief introduction, Platform can be deployed in a GAE standard environment, in order to scale in seconds, when needed.

The Platform suite is composed of different software layers:

  • App Designer - a web application running on ComputeEngine and using a CloudSQL relational database to manage application configuration

  • Web Interpreter - a web application running on ComputeEngine and using a CloudSQL relational database or other data sources, representing the configured application running and accessible by the end users; there is one web interpreter instance for each configured application

  • Mobile Interpreter - a native mobile app, built for Android and iOS platforms, used to run mobile apps, configured starting form the App Designer

When talking about the server-side computation, a weak point is the scalability of a web solution, typically composed of a set of web services. The more requests the web application receives, the more difficult is for the backend to respond with an acceptable timing.

The backend is composed of the web service layer running on Compute Engine (GCE) and the relational database, running on CloudSQL, a managed database.

A common production environment is composed of a Google Load Balancer able to forward requests to a number of GCE instances, using the auto-scaling feature provided by Google.

However, this solution can scale in a minute (the latency time required to startup a new GCE instance), not so perfect for a peak of requests requiring a more responsive solution.

GAE+Datastore represents a better solution when the auto-scaling needs the creation of new instances in a second or so.

On the other hand, using a NoSQL database means a lower speed when executing queries and a very simple enquiring language, when compared with the standard SQL.

Starting from these constraints, Platform for GAE represents a subset of the Web Interpreter described above, running on GAE and connected to Datastore (and other Google Cloud Platform services). You cannot use it to run a web application, but you can create your high-scalable set of web services.

You have still to use a standard Platform installation, running on GCE+CloudSQL and configure a Datastore and objects and business components.

Using the App Designer, you can define web services to run into GAE (i.e. "Javascript for GAE" actions).

Once deployed these set of web services on GAE, you can access to them as usual.

Supported features are:

  • metadata export towards GAE

  • object definition on Datastore

  • javascript for GAE actions (your stateless web services), including read/write operations on Datastore

  • a set of request alias, that you can use to call web services

  • authentication based on a fixed token (defined once per GAE instance) or on Platform users

  • Mem-Cache support, i.e. a cross-instance data cache, where you can store/read values needed across multiple requests or for a long time, in order to avoid costly and slow Datastore queries

  • Task Queue support, i.e. javascript for GAE actions enqueued into an internal queue, processed one at a time, so that there is a limit to the required computational process and it can also provide a better response to HTTP sync calls.

Limitations

GAE + Platform cannot be used in a flexible way as for GCE. These are the main limitations:

  • only stateless web services are supported. It means you have to design your javascript for GAE actions so that they can work without internal state linked to a user, but everything needed must be passed forward

  • up to 10 queues can be defined

  • a single queue execution cannot run for more than 10 minutes

  • no access to file system is allowed, so reading/writing files should not be carried out using GAE

Setup

In order to use Platform for GAE, a few steps must be followed:

  • create a GAE instance in an already existing Google Cloud Project, the same where GCE and CloudSQL have been configured and where a standard installation of Platform is available; here it is essential to pay attention to the region when the GAE will be installed: it cannot be changed later, so it is important to set it correctly

  • deploy Platform for GAE into the just configured GAE instance

  • through the App Designer, some Global parameters must be defined, in the GOOGLE folder, in order to correctly setup the connection with the right Google Cloud project and Datastore:

    • Google Service Account Email

    • Google Service Account Key

    • Google Datastore Id

  • through the App Designer, the Application parameter named "Password Platform for GAE" must be defined, in the GOOGLE folder, in order to correctly setup the connection with the Google App Engine, used to communicate with it and send application metadata or other operations

At this point, it is possible to start creating objects for the Datastore and define Javascript for GAE actions, which will be later executed inside a GAE instance.

Optionally, it is possible to define request alias for the actions just created.

Once the configuration process for your application has been completed, you can export metadata to GAE:

  • select Application -> Import/Export Application

  • go to "Metadata Application Management" folder

  • press the Export metadata to Platform for GAE

That's all!

Now it is possible to invoke your web services into GAE and enjoy the high-scalability offered by this layer.

Every-day activities

Uploading a single action

Once you have deployed your actions to GAE, you can change any of them multiple times.

You can edit the action definition in the App Designer and send these change to GAE, without exporting the whole application (Import/Export Application).

You can send a single action by pressing the "Sync action with GAE" button available on the right fo the window related to the action definition.

Once done that, the changes for your action are already available and up.

Enqueuing operations into GAE from your web application

A very common integration scenario between your web application running on GCE and web services available in GAE is related to the execution of computations within GAE, using the Task Queue feature, i.e. by enqueuing these operations into GAE, instead of running them in the standard Platfom queues.

Forwarding these operations outside of a standard Platform environment has the big advantage of reducing the computation effort required by GCE and use GAE for whay it is designed for: high scalability with multiple requests.

For this reason, you can use a new js method available in a server-side js action:

var uuid = utils.enqueueGaeAction(String queueName,Long actionId,Map params)

This method will forward the execution of the action identified by actionId to GAE, so actionId myst be a "Javascript for GAE" action; in GAE the execution will be enqueued in the queue identified by "queueName".

The method will get back a UUID value representing the unique identifier for the enqueued element, in case it would be helpful to trace it in your web application.

A few limitations:

  • up to 10 queues are available in GAE; this value could be changed when deploying Platform for GAE, but it is not recommended, since it could be pretty expensive to increase it, in terms of billing

  • up to 5 tasks per seconds are allowed to be executed in a single queue in GAE

  • no postponed actions can be enqueued (as for server-side javascript enqueueAction method)

  • queue execution is not reported inside the App Designer: it can be monitored only by using the GCP console, in the section App Engine -> Task Queues

Javascript for GAE

You can define your js actions to run into GAE in a very similar way you already do it when creating server-side js actions: the syntax is the same, i.e. utils.method(...)

The difference here is that only a subset of all server-side js methods is available.

You can check out which methods are available by simply pressing CTRL+space inside the js editor when editing a "Javascript for GAE" action.

Basically, the available methods are the ones compatible with GAE, i.e. there are NOT methods involving read/write operations on files or report generations.

Logging operations are supported, as for Server-side Javascript, but it can be accessed only by using GCP console (see next section for more details).

Enqueuing operations into GAE from a GAE web service

You can use the utils.enqueueAction method from within a "Javascript for GAE" action in order to forward and postpone heavy operations from the main web service to the Task Queue: this design choice is highly recommended, since GAE will interrupt HTTP requests longer than 60 seconds, so in case of complex logic, it would be always a good idea to use queues for managing the real work.

For an example, see the section below.

Executing public web services on GAE

It is strongly recommended to design web services in GAE (i.e. actions having type "javascript for GAE") so that they are asynchronous, that is to say, they should always be coupled to a second "javascript for GAE" action to enqueue the elaboration internally, so that the real elaboration is executed in the queue and the web service can terminate immediately.

Bear in mind that a single HTTP request never can last for a long time: App Engine interrupt with error an HTTP request every time it lasts more than 60 seconds.

You can do it, by following these steps:

1.create your internal action "javascript for GAE" which will elaborate your request; let's say that it has xxx id

2.create your public web service, i.e. another action "javascript for GAE" which will be invoked by any external client and (i) enqueue the input data to the first action and (ii) will provide a response to the client; let's say that it has yyy id

var uuid = utils.enqueueAction(
      "MY_QUEUE_NAME", // queueName
      xxx, // actionId
      vo, // // my input data, expressed in JSON format
      null, // priority is ignored
      null, // processWaitTime is ignored
      false // logExecution is ignored
);
utils.setReturnValue(JSON.stringify({ success: true, uuid: uuid }));
// in this way, you can trace your enqueued action, starting from the uuid, if needed

3.define a request alias for your public web service, where you have to internally provide the appId, the action id and either the token or the standard credentials appId+companyId+siteId+username.

/executeJs?actionId=yyy&appId=MYAPPID&token=MYAUTHTOKEN
/executeJs?actionId=yyy&appId=MYAPPID&companyId=...&siteId=...&username=...&password=...

It is strongly recommended to pass sensitive information in the request header rather than as request parameters, in this way they will be encrypted by HTTPS when executing the request.

Your auth token is set as default value like the Google Project Name; in any case, it is the same specified as "GAE Password" value for the app parameter in the App Designer.

As an alternative, you can specify user credentials:

/executeJs?actionId=yyy&appId=MYAPPID&companyId=...&siteId=...&username=...&password=...
  1. You are now ready to invoke your public web service:

https://yourgoogleprojectname.appspot.com/alias?cmd=MY_ALIAS&appId=...

You can use both GET and POST HTTP methods.

Executing queries on Datastore

Platform for GAE was born to provide high scalability. This goal can be reached only if a few constraints are fulfilled:

  • use only stateless web services

  • use the MemCache as much as possible, to minimize the access to a database

  • connect only to a high scalable database, that is to say, the NoSQL Google Datastore

If you need to read or write instructions on Google Datastore, you can use the same javascript instructions available in the standard installation of Platform, described below.

First, you have to declare your objects, one of each "entity" (e.g. table...) you want to manage in Datastore:

  • select the "Data Model" menu and choose "Objects and relationships"

  • press the Add button and then "Add Object to Datastore"

  • Here you have to assign a name to the object, in camel-case and with the first letter in uppercase (e.g. OrderRows)

  • Add as many fields as you need and choose a field as primary key; it is strongly recommended to choose a string type (or directly an UUID type) field for the primary key and assign to it an UUID value, which does not require additional queries to be reckoned. That means you should always avoid to choose a counter for the primary key: it is not the faster choice

Once you have created your objects, you can start using them in actions having type "Javascript for GAE" and create your web services to read or write data in the corresponding entities.

Reading data (using GQL - Google query language for Datastore)

var json = utils.executeQueryOnGoogleDatastore("select * from Intro",9,true,[]);
//utils.log(json,"DEBUG");
utils.setReturnValue(json);

Important note: DO NOT use the previous method to execute a query whose purpose is reading a single record, starting from the primary key: the "executeQueryOnGoogleDatastore" operation is "expensive" and should not be used when it is not needed, i.e. when you need to read a single record by primary key.

Bear in mind that all reading/writing operations (except for reading an entity by primary key) are pay-per-use operations: the more you call them, the more you pay.

In case of reading an entity by primary key use the next method

Reading a single entity by primary key:

var vo = getEntity(
  entityName, // name of the entity, in camel-case (e.g. "OrderHeaders")
  key, // the primary key, typically a String type
  maxCachedEntities // max number of entities read from this method which will be stored in cached, 
  // instead of being retrieved from datastore; the cache can be cleared up, by using "clearDatastoreEntities" method
); // vo is a javascript object, the entity

Insert data:

var outcome = utils.insertObjectOnGoogleDatastore
  vo, // the js object to insert, having attributes compatible with the ones defined in the entity
  xxx, // dataModelId corresponding to the entity where writing data
  true // interruptExecution
);

Update data:

var outcome = utils.updateObjectOnGoogleDatastore(
  vo, // the js object to insert, having attributes compatible with the ones defined in the entity
  xxx, // dataModelId corresponding to the entity where writing data
  true // interruptExecution
);

Delete data:

var outcome = utils.deleteObjectOnGoogleDatastore(
  vo, // the js object to insert, having attributes compatible with the ones defined in the entity
  xxx, // dataModelId corresponding to the entity where writing data
  true // interruptExecution
);

Executing queries on CloudSQL

Platform for GAE was born to provide high scalability. This goal can be reached only if a few constraints are fulfilled:

  • use only stateless web services

  • use the MemCache as much as possible, to minimize the access to a database

  • connect only to a high scalable database, that is to say, the NoSQL Google Datastore

Consequently, you should avoid reading or writing data to external systems, including a relational database.

Optionally, you could connect App Engine to CloudSQL, the managed relational database provided by Google, having a MySQL implementation.

Consequently, you have the chance to directly access this database instance, if correctly set up in the Google Console for the same Google Cloud Project.

Since the CloudSQL instance cannot provide the same scalability of Datastore, it should be used carefully.

Please have a look at this section to get more details about that:

If you decide to directly connect App Engine to a CloudSQL, please respect the following steps:

  • try to use the MemCache as much as possible, instead of reading data from CloudSQL

  • check if data you need from CloudSQL is already available in cache, only in case it is not, then read it through a query

This hint can ensure as much scalability as you need, if queries are always the same.

Once you have created your objects linked to CloudSQL, you can start using them in actions having type "Javascript for GAE" and create your web services to read data in the corresponding tables.

Reading data

var list = []; // please do not do it for long result sets!
var readRow = function(vo) {
    //utils.log(JSON.stringify(vo),"DEBUG");
    list.push(vo);
}

utils.executeQueryWithCallback("readRow","SELECT * FROM PRM01_USERS",null,false,true,[]);
utils.setReturnValue(JSON.stringify(list));

As you can see from the example above, you can only read a single row at a time, in order to reduce the amount of memory needed to read a long result set; you should avoid accumulating records as in the example, but simply process each record when available in the callback function.

Writing data

var numberOfProcessedRecords = utils.executeSqlNoLog(
  sql,
  null,  // dataStore id
  false, // separatedTransaction
  true,  // interruptExecution
  []     // parameters
);

Logging on GAE

As for Server-side Javascript, you can still use the utils.log(...) method to log messages within your actions runed into GAE.

Please pay attention to the number of log operations you include in your actions: if they have beed included for debugging purpose, they should also be removed at some point.

It is highly recommended to remove useless logging operations, since they could increase the total billing for your web services running on GAE.

In order to see the logged messages, you have to access the GCP console and

  • go to StackDriver -> Logging

  • choose the right GCP project and select "GAE Application, Default server"

Messages will be shown automatically, according to these selections and other optional filters, from the least recent to the most recent (on the bottom).

Each line reports a single HTTP request, request time, outcome, etc.

When expanding a single line, related to a specific HTTP request, you can see all logged messages related to that request.

https://cloud.google.com/sql/docs/mysql/connect-app-engine