Monday, December 12, 2016

JEE CDI annotations in Spring

JSR-330: javax.inject (@Inject). Already supported in Spring.

JSR-299 is only supported in JEE.

JSR-299 annotations recognizing by Spring: https://github.com/matzew/spring-cdi-bridge

Wednesday, October 5, 2016

Angular 2 forms


Saturday, October 1, 2016

Step-by-step building an Angular Material 2 application with Angular CLI

Look no further for up to date but complex Angular 2 seeds and start using Angular CLI.

Angular CLI is now based on Webpack but is simpler.

Versions

  • Angular 2.0.0 / 2.0.1
  • Material 2.0.0-apha9-3

Project creation

From the command line console (elevated on Windows):
  • Upgrade the Node version.
  • Install Angular CLI globally: 
npm install -g angular-cli
  • Create the project with SCSS support: 
ng new myapp --style=sass

If you are using WebStorm the project creation could also be done with the Angular CLI based.

From here you can always test the application launching it with:

ng serve

Project properties

  • Edit package.json and ...
    • Set the version.
    • Change the license property (or remove it and set private to true).
  • Edit index.hmtl and change the title as required.

From CSS to SASS

This is usually automatically done with --style=sass flag on the project creation but reviewing it is suggested.
  • Edit angular-cli.json and ...
    • Change "styles": ["styles.css"]  to "styles": ["styles.scss"] 
    • Change "styleExt": "css" to "styleExt": "scss"
  • Rename styles.css to styles.scss
  • Rename app.component.css to app.component.scss

Angular 2 version upgrade (Optional)

You can upgrade Angular 2.0.0 to the last stable 2.0.1 version editing package.json and changing the following versions:

"@angular/common": "2.0.1",
"@angular/compiler": "2.0.1",
"@angular/core": "2.0.1",
"@angular/forms": "2.0.1",
"@angular/http": "2.0.1",
"@angular/platform-browser": "2.0.1",
"@angular/platform-browser-dynamic": "2.0.1",
"@angular/router": "3.0.1",    

Material installation

  • Install the material module:
npm install --save @angular/material
  • Install the HammerJS dependency and its types:
npm install --save hammerjs
npm install --save-dev @types/hammerjs

  • Edit app.module.ts and add:
import { MaterialModule } from '@angular/material';

imports: [
  ...
  MaterialModule.forRoot()
]

Material icons linking (Optional)

  • Add the Material Icons link on index.html:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

Material theme customization (Optional)

Favico setup (Optional)

  • Remove favico.ico from src (it's a CLI bug, that's not its location)
  • Add your own favico.ico to the assets folder
  • Edit index.html and change favico.ico to assets/favico.ico  

Backend proxy setup (Optional)

Useful during development to route certain URL requests to a real server (usually REST calls).
  • Add a proxy.conf.json file on the project root folder with the following contents:
{
  "/api": {
    "target": "http://localhost:8080/myapp",
    "secure": false
  }
}

You can start using it with: 

ng serve --proxy-config proxy.conf.json

However it could be simplified by editing the package.json and adding a script:

"scripts": {
  "start": "ng serve --proxy-config proxy.conf.json",
}

So you can now launch it easily with:

npm start

Bundling for production 

You can always generate the production bundles on the dist folder with:

ng build --prod --bh /myapp/

However it could be simplified by edidting the package.json and adding a script:

"scripts": {
    ...
    "build": "ng build --prod --bh /myapp/"
},

So you can now launch it easily with:

npm run build

Internet resources



Tuesday, August 30, 2016

PaaS


"Application infrastructure functionality, enriched with cloud characteristics and offered as a service,
is platform as a service (PaaS). Gartner refers to it more precisely as cloud application infrastructure services."

"Application platform as a service (aPaaS) is a form of PaaS that provides a platform to
support application development, deployment and execution in the cloud."

Pure PaaS players
  • Pivotal Cloud Foundry.
  • Red Hat OpenShift.
  • Aprendaa.
  • Heroku.
  • Engine Yard.
IaaS hybrid players
  • Google?
  • Microsoft Azure Cloud Services?
  • Amazon AWS
  • ...
SaaS hybrids players
  • Salesforce
  • ...

PaaS frameworks
  • Pivotal Cloud Foundry.
  • Red Hat OpenShift.
  • Apache Stratos.
Related software
  • OpenStack
  • Docker
  • Kubernetes
  • Chef

References


Friday, August 26, 2016

Functional programming

  • Why:
    • General sateless tendency: cloud & scaling
    • No locks (multi-thread)
    • Easy reading
    • Easy testing
    • JavaScript boom?
  • How: 
    • Pure functions (no side-effects)
    • Immutability
    • Composition (not inheritance)
    • Deferred execution
    • Currying
    •  ...
  • Related: funcional reactive programming.

Why functional programming matters:
https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf

FP Languages
Hybrid Languages
  • Scala (JVM)
  • F#

Monday, August 22, 2016

Nginx reverse proxy

proxy_pas without path:

location /some/path/ {
   proxy_pass http://new.domain;
}
http://orig.domain/some/path/x --> http://new.domain/some/path/x

proxy_pas case insensitive:

location ~* /some/path/ {
   proxy_pass http://new.domain;
}

Wednesday, August 3, 2016

Multiple browser windows applications

Basic Techniques:
  • HTML5 postMessage: provides inter-windows message based communication.
  • HTML5 local storage: provides a shared storage for all the windows. Windows can be notified of local storage updates through events so this technique can also be used as a postMessage replacement.
  • Direct JS: to be tested. ¿limitations?.
childWin = openWindow();
childWin.anyFunction();

Auxiliary techniques
  • HTML5 Webworkers.
  • Angular app bootstraping tweaks.
Referenes:

Immutables on JavaScript & TypeScript


Monday, July 25, 2016

Spring batch


Configuration
Parameters and context
Transactions
Scaling


Examples
Job database schema

Spring boot properties

# Don't create the tables
spring.batch.initializer.enabled=false

# Don't launch all the jobs on app start
spring.batch.job.enabled=fasle

Oracle



Sunday, July 24, 2016

Vaadin containers

  • BeanItemContainer: the properties of the container are determined automatically by introspecting the used JavaBean class. Uses the beans themselves as identifiers.
  • BeanContainer: unlike BeanItemContainer, the item IDs do not have to be the beans themselves.  Uses explicit IDs or implicit IDs with setBeanIdResolver or setBeanIdProperty.

Friday, July 15, 2016

RapidClipse

https://www.rapidclipse.com/
Eclipse, Hibernate and Vaadin based rapid development environment.

  • Complete project setup wizard.
  • Good IDE layout: entities, DAOs, UI, etc.
  • Nice UI preview.
  • Diferent UIs in the same project: desktop, tablet and mobile.
  • Database/entity diagram.
  • Desktop (SWT) or client-server (HTML) apps.
  • Uses Vaadin component subclases (propietary).
  • Theme and per component SCSS support.
  • Includes authentication and authroization support (DB or LDAP).
  • No text documentation available (only screencasts).
  • No SQL (no Hibernate) DAO support.
  • Maven and Java 8.

Thursday, July 14, 2016

Angular 2 change detection

Default behaviour

Change detection is fired on each event loop chance (events, http requets, timers, ...).

Components are allways explored form the root to the leafs of the component tree.

By default, A2 is conservative and explores the complete tree and evaluates all the expressions in each component or directive template. Then compares the output of each expression to its previous output. If the result of an expression has changed, A2 updates the DOM accordingly.

This is as fast as posible; A2 generates change detectors with Javascript VM-friendly code (monomorphic). As the application grows, things may start to lag.

This is the default CD strategy and is called ChangeDetectionStrategy.CheckAllways.

OnPush mode

In order to reduce the performance impact the CD strategy of components can be set to ChangeDetectionStrategy.OnPush.

OnPush means that the change detector will only run on a component or directive if one of the following occurs:
  • An input property has changed to a new value (new primitive value or new object reference).
  • An event handler fired in the component or directive (???).
  • You manually tell the change detector to look for changes.
  • The change detector of a child component or directive runs.
OnPush should be implemented starting on leafs, otherwise child components or directives on them with CheckAllways strategy won't be allways executed.


References

Wednesday, June 8, 2016

STOMP over WebSockets with JSR 356

Atmosphere supports STOMP but subscriptions must be hardcoded on annotations.

Alternative:
Other Java impl.
JavaScript
  • STOMP over WebSockets  (original and discontinued): supports SocksJS and 1.0/1.1 protocol versions
  • Webstomp client: (fork of the previous) added 1.2 support. Used on HornetQ broker.

Sunday, May 29, 2016

Multiple non modal dialogs in Angular Material

Useful while panel not released (https://material.angularjs.org/HEAD/api/service/$mdPanel)

CSS to prevent modality:

.md-dialog-container {
    pointer-events: none;
}
md-dialog {
    pointer-events: all;
}

Dialog options:

{
/* Don't close this dialog when opening a new one */
    skipHide: true, 
/* Don't do the darkening of the whole screen */
    hasBackdrop: false 
}

References

Wednesday, May 25, 2016

CORS

Under certain request characteristics an additional request is automatically issued by the browser. This "preflight" request gathers CORS information form the server that is checked before making the real request.

References

Thursday, May 5, 2016

Custom authentication in QlikView Server (NTLM)

It's all about externalizing the user validation.

  • Some kind of username mapping (other system --> QlikView) is required.
  • Works on any Server edition (Small Business Edition and EE).
  • Document access is based on NTFS rights.
  • Every user must be given rights for every document. 
  • It should be easier and more flexible on Enterprise Edition by activating DMS.
  • Also easier with per session licensing (7x more expensive).
  • IIS required (it doesn't work with QVS).
Installation
  • Install IIS.
  • Install QlikView server with IIS-QV Tunneling.
  • Set anonymous authentication on the IIS administrator for QlikView and QvAjaxZfc.
  • On QMC System -> Setup -> QVW -> Authentication set:
    • Authentication: Always
    • Type: Ntlm
    • Login Address: Default login page
  • Edit C:\Program Files\QlikView\Server\QlikViewClients\QlikViewAjax\Authenticathe.aspx
Authenticate.aspx content

<%@ Import Namespace="QlikView.AccessPoint" %>
<%@ Import Namespace="QlikView.AccessPoint.HttpInterfaces" %>
<%@ Import Namespace="QvIISWebServer" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Collections.Generic"%>
<%@ Page Language="C#" AutoEventWireup="true" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e) {
        Response.Clear();
        Context context = this.GetContext();
        
        // Saving the Basic authentication header to a string ("Basic UserName:Password")
        string auth = Request.Headers["Authorization"];
        
        bool valid = false;
        string userName = "";            
        if (auth != null && auth.IndexOf("Basic ") == 0)
        {
            // Removing "Basic " from the string and decoding the username and password
            string unameColonPwd = System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(auth.Substring(6)));
            int colonPos = unameColonPwd.IndexOf(':');
            if (colonPos >= 0)
            {
                // Splitting username:password into two seperate strings
                userName = unameColonPwd.Substring(0, colonPos);
                string pwd = unameColonPwd.Substring(colonPos + 1);
                
                // *** IMPLEMENT THIS FUNCTION WITH YOUR OWN USER VALIDATION 
                valid = checkCredentials(userName, pwd);
            }
        }            
        
        if(valid)
        {

            // *** IMPLEMENT THIS FUNCTION WITH YOUR OWN USER MAPPING
            userName = "DOMAIN\\" + mapUserName(userName);

            // *** IMPLEMENT THIS FUNCTION TO SET THE USER GROUPS
            // You can also return null on NTFS 
            List<string> groups = getUserGroups(userName);

            // Creating an user object with groups
            IUser user = new NamedUser(userName, groups, true);
            // Associate the IUser with the session cookie and either redirect or sent back a status code
            QlikView.AccessPoint.User.GenericAuthentication(context, user);
            //Stop now so we don't issue a new BASIC challenge                                
            
            /*
            YOU CAN USE THIS HELPER FUNCTION INSTEAD GenericAuthentication WHEN THE NT USER PASSWORD IS KNOWN
            IUser user = QlikView.AccessPoint.User.TryLogon("DOMAIN\\user", "pwd"); 
            */
        }
        else
        {
            Context.Response.StatusCode=401;
            Context.Response.AppendHeader("WWW-Authenticate","Basic realm=\"QlikView\"");
        }

        return;
    }
</script>

Internet references

Thursday, April 28, 2016

Browser normalization tools: transpilers, polyfills and shims

Transpiler
  • It's a source-to-source compiler.
  • Converts and older ES syntax to the new one. 
  • Additionally, it's a must when using TypeScript or Coffe-Script to generate the corresponding ES code.
  • Executed before deployment, it's a development tool not needed at run-time.
Example: Babel
Polyfills
  • A polyfill is code that detects if a certain “expected” API is missing and manually implements it.
  • Polyfills often have to use multiple language platforms because sometimes a particular JS API doesn’t exist in that browser at all.
  • A JS library and eventually other native artifacts are required at run-time.
Example: core-js

Shim
  • A shim is code that intercepts existing API calls and implements different behavior (the API already exists but it must be normalized/patched).
  • Usually they are smaller pieces of code than polyfills.
  • Usually they are entirely written in JS.
  • A JS library it's required at run-time.
Example: es6-shim

References

ES7 async/await

Let you program in a synchronous thinking way.
It's a step forward (after Promises) in the direction of removing the JavaScript "callback hell".
References

Thursday, March 31, 2016

Hystrix

Latency tolerance, fault tolerance and monitoring for distributed systems.
https://github.com/Netflix/Hystrix/wiki

JSON Web Token (JWT)


Other links:

LMAX Disruptor - High performance parallel event processing in Java

  • Multicast.
  • Event pre-allocation.

  • https://github.com/LMAX-Exchange/disruptor

    Tuesday, March 29, 2016

    OpenLayers 3



    Review
    Pros
    • Map rotation.
    • Large SRS support.
    • Reprojection.
    • Accurate (pixel-perfect) hit test.
    • RTree-indexed features.
    • Drawing optimizations (geometry simplification and clipping).
    • Wider support of map sources including OGC protocols.
    • Styling/symbolizers.
    • API compatible WebGL renderer (lines not supported).
    • No plugins required: built-in clustering, edition, heatmap and many other features.
    • Async rendering with "Beforeoperations”, “postcompose” y “postrender” hooks.
    Cons
    • Large API.
    • Still changing.
    • Code size.
    Resources
    Books

    Minimal Angular 2 seed

    SystemJS, TypeScript and NPM:
    https://github.com/jhades/ng2-minimal

    SystemJS, TypeScript, NPM and Gulp:
    https://github.com/angular/angular2-seed/tree/systemjs

    According to this article it should be a good starting point while angular-cli gets matured.

    Tuesday, March 15, 2016

    QlikView extensions

    Definition.xml

    <ExtensionObject PageHeight="" PageWidth=""/>
    • PageWidth: maximum number of columns to retrieve.
    • PageHeight: maximum number of  rows to retrieve.
    Data Object

    • PageSize.x:  current page column count (maximum is PageWidth).
    • PageSize.y: current page row count (maximum is PageHeight).
    • TotalSize.x: total number of columns on the data set.
    • TotalSize.y: total number of rows on the data set.
    Selection
    You can use the SearchColumn, SelectValuesInColumn or SelectTextsInColumn API methods.

    this.Data.SelectTextsInColumn(0, true, value);

    You can only make selections in the dimensions that are exposed to the extension.
    The extension functions like any chart in QlikView meaning that it can only select in the underlying hypercube

    References

    Thursday, March 10, 2016

    Vert.x



    • Asynchronous programming model.
    • Multi-reactor (one ore more event loops).
    • Polyglot: Java, JavaScript, Groovy, JRuby, Scala, ...
    • Verticles: processing units. Akka/Actor similarities.
    • Worker Verticles: blocking code.
    • Modules: reusable Verticle set with isolated classloader.
    • Local/clustered Shared Map.
    • Local/clustered Event Bus.
    • HA (auto-deploy of failed Verticles on other nodes).
    • Hot deployment (auto-reload on development).
    • Light with minimum dependencies: Netty, Jackson & Hazelcast.
    • Deployment: fat JAR or minimal Vert.x container.
    • Fast: https://www.techempower.com/benchmarks/#section=data-r12&hw=peak&test=json.

    Wednesday, January 6, 2016

    CompletableFuture

    Basic usage

    // Use runAsync instead when the Task is a Runnable
    final CompletableFuture<String> f1 = 

        CompletableFuture.supplyAsync(() -> longRunningTask1(params), executor);
    final CompletableFuture<String> f2 = ...

    final CompletableFuture<String> f3 = ...

    // Wait for all to complete

    CompletableFuture.allOf(f1, f2, f3).join();

    References:

    Java 8 parallel stream gotchas

    When using parallel streams in Java you are using the ForkJoinPool.commonPool() singleton and therefore sharing a single thread pool across the entire program. It, by default, has one less threads as you have processors, as returned by Runtime.availableProcessors() (can be overriden with -Djava.util.concurrent.ForkJoinPool.common.parallelism).

    As a consequence:

    • You have no control over the pool properties/size.
    • There is no isolation between pools so long running tasks or IO locking calls may cause performance problems.
    References:


    The solution is executing the stream in a specific ForkJoinPool:

    ForkJoinPool forkJoinPool = new ForkJoinPool(2);
    forkJoinPool.submit(() ->
        IntStream.range(1, 1_000_000)
          .parallel()
          .filter(PrimesPrint::isPrime)
          .collect(toList())
    ).get();

    References:

    Other solution using CompletableFuture:

    ForkJoinPool forkJoinPool = new ForkJoinPool(2);
    CompletableFuture<List<Integer>> primes = CompletableFuture.supplyAsync(() ->
      range(1, 1_000_000)
        .parallel()
        .filter(PrimesPrint::isPrime)
        .collect(toList()), 
      forkJoinPool
    );

    See next blog entry on  CompletableFuture.