Sunday, December 31, 2017

Happy 2018 to everyone!

This year will be an extraordinary year of further devastation of this planet, more fires and floods, more US military expansion and control, more lies and propaganda, more military spending, more fiscal oppression and abolition of civil rights, more unemployment and less welfare. But who cares, we have smartphones and faster internet and an endless supply of US-manufactured circenses (games and entertainment). Planet is screwed anyway, so just enjoy while it lasts!




Rules to make good training material

In the last 10 months I have been stuffing myself night and days, weekend and holidays, with training. Most of that training was decent, some excellent, some really appalling. What makes a material "excellent"?

a) the trainee must be able to reproduce the exercise on his own. So training material must start with detailed instructions on how to setup an environment. Preferably on Linux, please avoid Windows as a testing platform. No blablabla, just installation scripts and links to pre-built VMs or Docker images.

b) all code used in example must be available on Github, under the form of a complete, buildable, working example. Avoid by all means incomplete snippets of code. Instructions on how to setup the environment should be provided in a complete A-Z form, if possible with most common troubleshooting scenarios available.

c) theory and practice must go hand-in-hand. Avoid lengthy all-encompassing introductions teaching the history of humanity from Adam and Eve. Must of us are just interested on getting some technology to work and play a little with it. Every new concept should IMMEDIATELY exemplified with a simple experiment.

d) avoid complex examples with lot of business logic. Keep it simply, carve your examples in order to highlight the single concept you are talking about.

e) videos are great, but please avoid slides, unless each slide is accompanied by a real-life example. Don't talk more than 3 minutes, you should just show examples and illustrate code, clearly pointing out the new stuff. It's also great when one is shown the relevant official documentation together with the example. Evidencing code and documentation with a mouse selection also helps, so as the viewer can easily focus on the sensitive stuff.

f) by all means, avoid telling us about yourself, how good you are and how you spend your leisure time - unless you do something really valuable like protecting nature, but most NERDS don't care about nature, life or anything which is not IT-related. You are just a NERD, we don't care about your nerdy life, spent serving the interests of corporations. If you want to help humanity, just deliver clear, crisp, focused training. Be humble, be focused, talk less, show more.

g) avoid writing complex code during the tutorial. Watching someone typing code is painfully boring and big waste of time when things go wrong and time is wasted fixing the issue. Write your code in advance, put it in github and during the presentation just quickly illustrate it.

h) avoid making long bullet list like this one hahaha





Saturday, December 30, 2017

maven wildfly archetype push to github

To get started with a basic webapp for wildfly:

mvn archetype:generate -DarchetypeArtifactId=wildfly-javaee7-webapp-archetype -DarchetypeGroupId=org.wildfly.archetype -DarchetypeVersion=8.2.0.Final


https://mvnrepository.com/artifact/org.wildfly.archetype/wildfly-javaee7-webapp-archetype/8.2.0.Final


once you have created the project (groupid=org.pierre, artifactid=aostapictures)
you do the following:

create a repository in gthub, named aostapictures (not sure if you can do it with git command line...I did with github web ui)

cd aostapictures/
git init
echo "/target/" > .gitignore
git add *
git add .cheatsheet.xml
git add .gitignore
git add .classpath
git add .factorypath
git add .project
git add .settings/
git commit -am "first commit"
git remote add origin https://github.com/vernetto/aostapictures.git
git push --set-upstream origin master
git push -u origin master


see also https://help.github.com/articles/adding-a-remote/

Thursday, December 28, 2017

Openshift "Could not resolve host: github.com; Unknown error"

if you get the error

"Could not resolve host: github.com; Unknown error"

when building your POD, the solution is simply:

sudo oc cluster down
sudo iptables -F
sudo oc cluster up

https://github.com/openshift/origin/issues/12110

https://github.com/openshift/origin/issues/10139

Pathetic

Wednesday, December 27, 2017

install kubectl and gcloud on CentOS

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

python -V

curl -LO https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-183.0.0-linux-x86_64.tar.gz
kubectl
ls -ltra
mkdir gcloud
mv google-cloud-sdk-183.0.0-linux-x86_64.tar.gz gcloud/
cd gcloud
tar xvzf google-cloud-sdk-183.0.0-linux-x86_64.tar.gz
./google-cloud-sdk/install.sh
sudo reboot now


gcloud


see https://kubernetes.io/docs/tasks/tools/install-kubectl/
see https://cloud.google.com/sdk/docs/quickstart-linux



openshift create project

oc login
oc new-project pippo
oc new-app centos/ruby-22-centos7~https://github.com/openshift/ruby-ex.git

https://hub.docker.com/r/centos/ruby-22-centos7/ "This container image includes Ruby 2.2 as a S2I base image for your Ruby 2.2 applications."


https://github.com/openshift/ruby-ex "This is a basic ruby application for OpenShift v3 that you can use as a starting point to develop your own application and deploy it on an OpenShift cluster."








Monday, December 25, 2017

docker enabling remote daemon administration

one can use the -H option

https://docs.docker.com/engine/reference/commandline/dockerd/#examples
https://docs.docker.com/engine/admin/systemd/#start-automatically-at-system-boot
https://docs.docker.com/engine/reference/commandline/dockerd//#daemon-configuration-file

don't try to use /etc/docker/daemon.json , it's not supported for this option

Do this:

sudo less /usr/lib/systemd/system/docker.service

change
ExecStart=/usr/bin/dockerd
into
ExecStart=/usr/bin/dockerd -D -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
(if this fails, remove the -D)

sudo systemctl daemon-reload
sudo systemctl restart docker

sudo systemctl stop firewalld

sudo less /var/log/messages

sudo journalctl -xe

netstat -an | grep 2375


Now you can connect remotely (in this case I am using localhost, but you can use an IP or a hostname if remotely connecting):

docker -H localhost:2375 info


I have tried with
export DOCKER_HOST="tcp://0.0.0.0:2375"
systemctl daemon-reload
systemctl restart docker


but it didn't work for me...


This allows to do cool stuff like:

curl http://localhost:2375/images/json | python -mjson.tool



One can use also the HTTP REST Api https://docs.docker.com/develop/sdk/examples/

Sunday, December 24, 2017

redis

https://hub.docker.com/r/_/redis/

"Redis is the most popular key-value store. The name Redis means REmote DIctionary Server."


previous post http://www.javamonamour.org/2014/01/redis.html


Friday, December 22, 2017

etcd

What is etcd ? https://en.wikipedia.org/wiki/Container_Linux_by_CoreOS#ETCD

Who is CoreOS ? https://en.wikipedia.org/wiki/Container_Linux_by_CoreOS#CoreOS and https://coreos.com/



sudo yum install etcd

etcdctl

etcdctl get pippo
Error: client: etcd cluster is unavailable or misconfigured; error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused
; error #1: malformed HTTP response "\x15\x03\x01\x00\x02\x02"

error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused
error #1: malformed HTTP response "\x15\x03\x01\x00\x02\x02"


systemctl start etcd

etcdctl get pippo
Error: 100: Key not found (/pippo) [3]

etcdctl set /example/key pippo
pippo
etcdctl get /example/key
pippo
etcdctl ls /
/example
etcdctl ls /example
/example/key
etcdctl ls /example/key
/example/key

netstat -an | grep 4001
you will see 143 entries (!!!) (use | wc -l to count)

netstat -an | grep 2379
here the HTTP service is running

curl -LsS http://127.0.0.1:2379/v2/keys
{"action":"get","node":{"dir":true,"nodes":[{"key":"/example","dir":true,"modifiedIndex":4,"createdIndex":4}]}}


#to get help
etcd -h

for instance:
etcd --version
etcd Version: 3.2.9
Git SHA: f1d7dd8
Go Version: go1.8.3
Go OS/Arch: linux/amd64


More basic examples here https://coreos.com/etcd/docs/latest/getting-started-with-etcd.html


As usual, great tutorial on "clustering nodes with etcd" by DigitalOcean:
https://www.digitalocean.com/community/tutorials/how-to-use-etcdctl-and-etcd-coreos-s-distributed-key-value-store and https://discovery.etcd.io
and https://coreos.com/etcd/docs/latest/op-guide/clustering.html



Thursday, December 21, 2017

docker insecure registry

I have been tortured for a long time by this:

sudo oc cluster up

[sudo] password for centos:
Starting OpenShift using openshift/origin:v3.7.0 ...
-- Checking OpenShift client ... OK
-- Checking Docker client ... OK
-- Checking Docker version ... OK
-- Checking for existing OpenShift container ... OK
-- Checking for openshift/origin:v3.7.0 image ... OK
-- Checking Docker daemon configuration ... FAIL
Error: did not detect an --insecure-registry argument on the Docker daemon
Solution:

Ensure that the Docker daemon is running with the following argument:
--insecure-registry 172.30.0.0/16





"docker info" will output you a wealth of information, including this:

Insecure Registries:
127.0.0.0/8


( you can use docker info | grep -A 4 -i insecure )

So the only way to start Openshift Cluster was

sudo oc cluster up --skip-registry-check=true


It turned out that https://stackoverflow.com/questions/42211380/add-insecure-registry-to-docker to add the extra entry for insecure-registry one should

sudo vi /etc/docker/daemon.json

and enter this:

{
"insecure-registries" : [ "172.30.0.0/16" ]
}


sudo systemctl daemon-reload
sudo systemctl restart docker
sudo oc cluster down
sudo oc cluster up



and no more errors! Great!

To the Openshift lazy developers: in future please provide also a hint how to troubleshoot the issue... it would save a LOT of time to us frustrated users.

The more I use Openshift the more it feels like a huge Goldberg machine, a Zeppelin.






Tuesday, December 19, 2017

docker create vs docker run

This exercise takes a base image jboss/wildfly, spins a container, add a ping.war in the deployments folder and commits a new image named wildflywithping. You can easily reproduce yourself, all you need is docker and a pair of hands (one is enough... also no hands but a pen in your mouth can be enough)


#this pulls a new image from docker hub to local registry
docker pull jboss/wildfly
docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
jboss/wildfly latest ec52433b28ee 2 weeks ago 622MB


#this creates a container from imageid
docker create ec52433b28ee
docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
177bdb401283 ec52433b28ee "/opt/jboss/wildfly/…" 4 minutes ago Created dreamy_lamarr


but the container is not running:

docker exec -ti 177bdb401283 /bin/bash

Error response from daemon: Container 177bdb4012832d42a386ad24c92588d4d245b27249fb95e146d98f5266a74706 is not running


docker start 177bdb401283
docker exec -ti 177bdb401283 /bin/bash

[jboss@177bdb401283 ~]$


in another terminal, run this

docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
177bdb401283 ec52433b28ee "/opt/jboss/wildfly/…" 8 minutes ago Up About a minute 8080/tcp dreamy_lamarr




#rename container
docker rename 177bdb401283 con_pvwildfly
docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
177bdb401283 ec52433b28ee "/opt/jboss/wildfly/…" 22 minutes ago Up 15 minutes 8080/tcp con_pvwildfly


#now you can use container name instead of containerid
docker exec -ti con_pvwildfly /bin/bash


One could have reached the same result in a single command:

docker run --name con_pvwildfly -ti jboss/wildfly /bin/bash


Now, in the container, go to the wildfly deployment folder, we shall copy here a ping.war from outside:

cd /opt/jboss/wildfly/standalone/deployments
ls -ltra

Open a new terminal on the host (not in the container!):

curl -O https://github.com/AdamBien/ping/releases/download/ping-0.0.1/ping.war
(see https://github.com/AdamBien/ping)
docker cp ping.war con_pvwildfly:/opt/jboss/wildfly/standalone/deployments

and check in the container that the file was copied: ls -ltra

docker stop con_pvwildfly

docker commit con_pvwildfly wildflywithping
sha256:99d6ae628596f0fa658f4927bfab1823d654d81bf4afd6b004edfede39ce34cd

docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
wildflywithping latest 99d6ae628596 33 seconds ago 622MB






Primefaces PushEndpoint for WebSockets

https://www.primefaces.org/docs/api/6.1/org/primefaces/push/annotation/PushEndpoint.html


"An Endpoint for Push operation executed from by RemoteEndpoint or using an EventBus. A class annotated with this annotation must at least have one method annotated with OnOpen, OnClose or OnMessage."


https://www.primefaces.org/primefaces-push-2-0/


https://github.com/Atmosphere/atmosphere



https://www.primefaces.org/showcase/push/notify.xhtml



systemd

Really interesting reading https://en.wikipedia.org/wiki/Systemd


For instance, I didn't know that systemd has PID = 1

ps -ef | grep systemd
root 1 0 0 Dec16 ? 00:10:38 /usr/lib/systemd/systemd --switched-root --system --deserialize 2

and that other daemons like journald, logind and networkd (if running), have parent PID = 1

ps -ef | grep journald
root 499 1 0 Dec16 ? 00:02:41 /usr/lib/systemd/systemd-journald


ps -ef | grep logind
root 727 1 0 Dec16 ? 00:01:00 /usr/lib/systemd/systemd-logind



Saturday, December 16, 2017

Getting started with Ansible in Docker

Since OpenShift uses Ansible, and also since I hate Puppet, I love Python, Ansible is based on Python and I always wanted to learn a Provisioning tool other from Puppet to prove that Puppet folks are losers...
and since Ansible can nuke your environment if used incorrectly....

I am installing Ansible in a docker Centos machine, so I can nuke it at my will!

docker pull centos
#here nothing happens
docker run centos
docker container ls
docker run -i -t centos
yum install man
yum install ansible
exit
#note down the container id, it's displayed after the root@ prompt , like in root@61d50a06c86c
docker commit 61d50a06c86c centosansible

at this point I can easily run:
docker run -i -t centosansible

and if I do
docker images | grep centos
centosansible latest 2766690643c3 9 minutes ago 353MB
centos latest 3fa822599e10 2 weeks ago 204MB

I see that my image is there (the 353MB size include all the layers from centos image, which are NOT duplicated, so the real additional space is only 353-204=149 MB


http://docs.ansible.com/ansible/latest/intro_installation.html


ansible --version
ansible 2.4.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]


ansible localhost -a /bin/date

ansible localhost -m ping



This is a nice tutorial - skip first 13 minutes, then you have 20 minutes of theory, then some interesting Ansible examples








quick nfs mount on CentOS

#find your ip
ifconfig
#create folder to share
sudo mkdir -p /drbd/main/shared
#who cares about security
sudo chmod -R 777 /drbd/
#create folder where local files should appear
mkdir -p /home/centos/ocpnfs
sudo vi /etc/exports
#enter this in /etc/exports
/drbd/main/shared/ 10.0.2.15(rw)
#end of /etc/exports
sudo systemctl restart nfs
sudo exportfs -v
sudo mount -t nfs 10.0.2.15:/drbd/main/shared/ /home/centos/ocpnfs
touch /home/centos/ocpnfs/pippo.txt



oc cluster up : how to enable admin privileges

Once you install OpenShift with "oc cluster up", you are confronted with a frustrating situation: you are told to login as

oc login -u system -p admin

to be a cluster administrator, but in reality you are just a regular user.

If you try to do

oc adm policy add-cluster-role-to-user cluster-admin system

you get a

Error from server (Forbidden): User "system" cannot list clusterrolebindings.authorization.openshift.io at the cluster scope: User "system" cannot list all clusterrolebindings.authorization.openshift.io in the cluster (get clusterrolebindings.authorization.openshift.io)


After zillion of desperate attempts (including reinstalling everything a few times) I have found a way:

#become root
sudo su -
#login as admin, not as system
oc login -u admin -p admin
#grant yourself superhuman rights
oc adm policy add-cluster-role-to-user cluster-admin admin --config=/var/lib/origin/openshift.local.config/master/admin.kubeconfig
cluster role "cluster-admin" added: "admin"
#login again
oc login -u admin -p admin
Login successful.

You have access to the following projects and can switch between them with 'oc project ':

* default
kube-public
kube-system
myproject
openshift
openshift-infra
openshift-node

Using project "default".




and when I log into https://127.0.0.1:8443/console/ as admin/admin I can see all the Openshift internal projects.




Thursday, December 14, 2017

Openshift REST Client API written in Java

https://github.com/openshift/openshift-restclient-java/

immensely more usable than the CLI...

I ask myself who wants to learn by heart the hyper-complicated Openshift command line interface, when you can easily wrap all that crap in a nice fluent Java API....

Life is short, I am too busy, no time to learn all the freaking CLIs of the planet... please give me simple and powerful programming tools... I don't want to type any commands...

To get started, create a Maven Java Project, add this in pom.xml:


  <dependencies>
   <dependency>
    <groupId>com.openshift</groupId>
    <artifactId>openshift-restclient-java</artifactId>
    <version>5.9.3.Final</version>
   </dependency>
 </dependencies>


then run this:

package org.pierre.ocpclient;

import com.openshift.restclient.ClientBuilder;
import com.openshift.restclient.IClient;
import com.openshift.restclient.ResourceKind;
import com.openshift.restclient.model.IProject;
import com.openshift.restclient.model.IResource;

public class CreateProject {
 public static void main(String[] args) {
  IClient client = new ClientBuilder("https://localhost:8443")
    .withUserName("admin")
    .withPassword("admin")
    .build();
  
  IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, "myfirstproject");
  IProject project =  (IProject)client.create(request);
  
 }

}



Wednesday, December 13, 2017

Excellent Docker presentation by Preethi Kasireddy

https://medium.freecodecamp.org/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b

Where you learn:

- difference between a Container and a VM

- what is an Hypervisor (hosted or bare-metal)

- Docker Engine
- Docker client
- Docker daemon
- Dockerfile
- Docker image
- Union File Systems
- Volumes
- Containers

- Namespaces (NET, PID, MNT, UTS, IPC, USER)
- Cgroups (Control groups)
- Isolated union file systems



Great OpenShift presentation : OpenShift 3 Walkthrough




Here the code https://github.com/gshipley/openshift3mlbparks


In case you want to take the DO280 certification.... https://www.redhat.com/en/services/training/do280-red-hat-openshift-administration-i

I was able to deploy the project on Openshift Online and run it.... impressive, but the configuration effort is really huge, when compared to docker-compose....


this is older video repeating more or less same concepts




and the famous "instant gratification with Openshift"



Grant Shipley is a great guy. Here another great talk by him - more philosophical than technical





Tuesday, December 12, 2017

keycloak wikipedia

As usual, the fascist side of Wikipedia attracts swarms of wikilosers, in search of a victim to club down to death.

My article on Keycloak has been marked for deletion, so I am saving it here for the benefit of future generations (I know, there is no future, but let's pretend there is)

Keycloak Developer(s) JBoss, a division of Red Hat
Stable release
3.3.0 / October 26, 2017
Written in Java
Type Single sign-on system
License LGPL
Website keycloak.org


Keycloak is a software product from JBoss to allow single sign-on and Identity Management.

Contents

1 Features
2 Components
3 See also
4 References

Features

Among the many features of Keycloak include :

User Registration
Social login
Single Sign-On/Sign-Off across all applications belonging to the same Realm
2-factor authentication
LDAP integration
Kerberos broker
multitenancy with per-realm customizeable skin


Components

There are 2 main components of Keycloak:

Keycloak server
Keycloak application adapter

See also

Single sign-on
OpenSSO
Kerberos (protocol)
Identity management
List of single sign-on implementations

References
Official web site http://www.keycloak.org/
Sébastien Blanc (June 16, 2017). "Easily Secure Your Spring Boot Applications With Keycloak". dzone.com. https://dzone.com/articles/easily-secure-your-spring-boot-applications-with-k



I swear I will never touch Wikipedia again.








Monday, December 11, 2017

Adam Bien memorable quote about maintainability

https://youtu.be/O1VTx0psUgo?t=569

For me how I see the JAX-RS movement is the following

no one cares of my clients about JAX-RS Rest or whatever.

What we would to have is to build the application quickly and maintainable

So when is the application maintainable?

In my eyes it’s maintainable in this case if you understand the domain concepts

and you forget the app for 2 years

and after 2 years you return to the project

and you still remember the concepts

you should quickly be able to understand the app, introduce new features, and fix bugs.

When is it possible?

This is only possible in case the domain concepts and the business logic immediately becomes visible to you.

The more it’s obfuscated with strange patterns, the less maintainable your application becomes.


So regardless whether you use Spring Boot, Java EE or whatever, what you should get at the end of the day,

If you know the domain concepts and you look at the URIs, you should be immediately identify what is going on there.

So this is the only quality for which I am interested in implementing JAX RS or Business Services.



WebSockets and JSONDecoder in Wildfly 11


import java.io.Serializable;
import java.net.URI;

import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

import com.pierre.inst.model.Member;

@ClientEndpoint(decoders={JSONDecoder.class})
public class MemberClientEndpoint implements Serializable{

    @Inject
    private Event<Member> memberEvent;

    @OnMessage
    public void onMessage(Member member) {
        memberEvent.fire(member);
    }
}




java.lang.RuntimeException: javax.websocket.DeploymentException: UT003029: Could not find message parameter on method public void com.pierre.inst.websockets.MemberClientEndpoint.onMessage(com.pierre.inst.model.Member)

where JSONDecoder is

import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;

import com.google.gson.Gson;
import com.pierre.inst.model.Member;

public class JSONDecoder implements Decoder.Text<Object> {

 private Gson gson;

 @Override
 public void init(EndpointConfig config) {
  gson = new Gson();
 }

 @Override
 public void destroy() {
  // do nothing
 }

 @Override
 public Object decode(String s) throws DecodeException {
  return gson.fromJson(s, Member.class);
 }

 @Override
 public boolean willDecode(String s) {
  return true;
 }

}


see also
https://docs.oracle.com/javaee/7/tutorial/websocket007.htm
and
https://issues.jboss.org/browse/UNDERTOW-287

The issue is that JSONDecoder is too generic, parameter class is Object, it should be Member:


import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;

import com.google.gson.Gson;
import com.pierre.inst.model.Member;

public class JSONDecoder implements Decoder.Text<Member> {

 private Gson gson;

 @Override
 public void init(EndpointConfig config) {
  gson = new Gson();
 }

 @Override
 public void destroy() {
  // do nothing
 }

 @Override
 public Member decode(String s) throws DecodeException {
  return gson.fromJson(s, Member.class);
 }

 @Override
 public boolean willDecode(String s) {
  return true;
 }

}







Sunday, December 10, 2017

docker-machine

On CentOS:

curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine



Saturday, December 9, 2017

docker-compose

Install docker-compose on CentOS. Digital Ocean tutorials are very good:

https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-centos-7


sudo yum install epel-release
sudo yum install -y python-pip


if you get

"Another app is currently holding the yum lock; waiting for it to exit...
The other application is: PackageKit
"

just do "ps -ef | grep PackageKit", find the PID and do "sudo kill -9 PID"


sudo pip install --upgrade pip

sudo pip install docker-compose
sudo yum upgrade python*


docker-compose



Awesome quick hands-on php tutorial on docker-compose



first do:
sudo pip3.6 install flask
sudo pip3.6 install flask_restful


cd
mkdir jakewright; cd jakewright
mkdir product; cd product

you should have this tree:
~
~/jakewright
~/jakewright/product

make sure you are in ~/jakewright/product :

cat api.py
from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class Product(Resource):
    def get(self):
        return {
            'products' : ['Ice Cream', 'Chocolate', 'Fruit']
        }

api.add_resource(Product, '/')

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=9080, debug=True)

python3.6 api.py

http://localhost:9080/


cat Dockerfile
FROM python:3-onbuild
COPY . /usr/src/app
CMD ["python", "api.py"]



cat requirements.txt
flask
flask_restful


docker build . -t jakewright
-> Successfully tagged jakewright:latest
docker images
docker run -p 9080:9080 jakewright


now in ~/jakewright folder:
cat docker-compose.yml

version: '3'

services:
product-service:
build: ./product
volumes:
- ./product:/usr/src/app
ports:
- 9080:9080


(leaving the second part for now....)

docker-compose up -d
docker-compose stop

your service should now be equally available, in an image called jakewright_product-service


User Manual for Dockerfile https://docs.docker.com/engine/reference/builder/#usage



PS another GREAT video by Jake Wright is Learning CSS https://www.youtube.com/watch?v=0afZj1G0BIE , and don't forget Learning Docker https://www.youtube.com/watch?v=YFl2mCHdv24





Friday, December 8, 2017

Kubernetes

great introduction








Wednesday, December 6, 2017

WebSockets client-server example

Server-side:

annotate a POJO with javax.websocket.server.ServerEndpoint

A method annotated with javax.websocket.OnOpen will handle the creation of a javax.websocket.Session

Another method handles the reception of a message, it's annotated with javax.websocket.OnMessage


Client-side:

You have to extend javax.websocket.Endpoint
and override the method onOpen(Session session, EndpointConfig config), where you add to the Session a MessageHandler.Whole to implement a onMessage() . This Endpoint just handles the Message but not the session.

To create a session, connect to the Server: ContainerProvider.getWebSocketContainer().connectToServer(this.endpoint, new URI("ws://server:port/contextroot/serviceuri"))


Client and server are here

https://github.com/vernetto/JavaMonAmour/tree/master/pvabwebsocketsserver

https://github.com/vernetto/JavaMonAmour/tree/master/pvabwebsocketsclient


Here the explanation by the Great Adam Bien





Primefaces themes

see https://stackoverflow.com/questions/30253826/how-to-do-themeswitcher-using-primefaces

see https://www.primefaces.org/showcase/ui/misc/themeSwitcher.xhtml


add this to your pom.xml


<dependency>
<groupId>org.primefaces.themes</groupId>
<artifactId>all-themes</artifactId>
<version>1.0.10</version>
</dependency>


in the web.xml the primefaces.THEME should be dynamically assigned:

<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>#{guestPreferences.theme}</param-value>
</context-param>

use this themeSwitcher in a page

<h:form>
<p:outputLabel for="basic" value="Basic:" />
<p:themeSwitcher id="basic" style="width:165px">
<f:selectItem itemLabel="Choose Theme" itemValue="" />
<f:selectItems value="[afterdark, afternoon, afterwork, aristo, black-tie, blitzer, bluesky, bootstrap, casablanca, cupertino, cruze, dark-hive, delta, dot-luv, eggplant, excite-bike, flick, glass-x, home, hot-sneaks, humanity, le-frog, midnight, mint-choc, omega, overcast, pepper-grinder, redmond, rocket, sam, smoothness, south-street, start, sunny, swanky-purse, trontastic, ui-darkness, ui-lightness, vader]" var="theme" itemLabel="" itemValue=""/>
</p:themeSwitcher>
</h:form>




Sunday, December 3, 2017

Mojarra 2.2.13.SP4 in Wildfly 11 debugging

I get a message "The form component needs to have a UIForm in its ancestry. Suggestion: enclose the necessary components within <h:form> ". After some mucking (basically, exclude stuff and see if it still breaks) I discovered the fix: enclose a p:menubar in a h:form <h:form><p:menubar>

A few things leave me really disappointed: this warning should be issued by Eclipse editor, not runtime... and the warning message should be accompanied by the exact location and identity of the offending element.

And in Mojarra 2.2.13.SP4 (Wildfly 11) there doesn't seem to be any debugging flag to get more information.

RANT ON once more, ui development has made huge steps BACKWARDS in the last 20 years RANT OFF Using Delphi in 1995 I was able to put together a very decent and complex UI in MINUTES - with JSF/HTML/Mojarra/CSS/Bootstrap it takes MONTHS and it's no fun. That's why whenever I have to do a UI I keep it MINIMALISTIC, I hate wasting my time in such poorly engineered products.





Saturday, December 2, 2017

JSF facelets, composition, layouts, templates

https://docs.oracle.com/javaee/7/javaserver-faces-2-2/vdldocs-facelets/toc.htm this is the Facelets documentation

and this https://docs.oracle.com/javaee/7/javaserver-faces-2-2/vdldocs-facelets/ui/composition.html is the ui:composition documentation



RANT ON

Let's admit it, HTML UI development is sheer mess.
In OOP you learn about nice encapsulation, separation of concerns, tidy APIs, design-time validation, convention over configuration... in HTML it's exactly the other way round, everything mixed up and it's just a verbose visually incomprehensible jungle, tons of implicit stuff has to be explicitly stated over and over, tons of useless boilerplate fluff make the code unreadable. It makes me really sick. With some better designed standard, the size of this crap could be reduced by a factor of 10 without any loss, actually gaining a lot in readability and maintainability. It's so evident.


RANT OFF

Here a decent tutorial (a bit too complicated) on templates:



code is here:

https://github.com/discospiff/JavaFullStackEnterpriseWeb


in a JSF application you use a template, in which you insert contents defined in pages.

In a template, to insert the content, you use div+insert (=insertContent) ,

In a page, to use a template, you use composition (=useTemplate)

In a page, to define the content, you use define (=defineContent).

Again: a template inserts stuff; a page defines stuff and uses a template to arrange it on a layout.


for a page, look here https://github.com/discospiff/JavaFullStackEnterpriseWeb/blob/master/PlantPlaces/WebContent/index.xhtml

and the corresponding template is https://github.com/discospiff/JavaFullStackEnterpriseWeb/blob/master/PlantPlaces/WebContent/template.xhtml





Netbeans rocks, Eclipse sucks

With Eclipse, setting up a simple Web Application with JSF and deploying it to Wildfly is a long, frustrating struggle.

With Netbeans, it takes 10 seconds.

File / New Project, Java Web / Web Application, project name "WebApplication1", server : select Wildfly server, Java EE Version: Java EE 7 Web, context path: /WebApplication1, Frameworks: select JavaServer Faces, in the components tab select Primefaces (the first time iyou haveto wait 10 seconds while it fetches the dependencies "JSF library Primefaces not setup correctly..." )

Right click on the Project, Run... it will open http://localhost:8080/WebApplication1/ and you are ready to go.


What Netbeans generates is:







BEWARE: to run on Wildfly 11, you should change the version of primefaces in pom.xml from 5.0 to 6.0, otherwise you get an error "wildfly This page calls for XML namespace http://primefaces.org/ui declared with prefix p but no taglibrary exists for that namespace"

The only issue I had with Netbeans 8.2 is that it's not compatible with Java 9, I had to edit netbeans.conf and change netbeans_jdkhome to point to JDK 8.

Incidentally, check out this AWESOME video on how to generate a Primefaces crud application from Entities with Netbeans

https://netbeans.org/kb/docs/javaee/maven-primefaces-screencast.html

You can simply forget that with Eclipse. A Total Eclipse of the Heart



"every now and then I fall apart
I don't know what to do and I am always in the dark
There is nothing I can do, a total Eclipse of the heart
Once upon a time there was light in my life"

hahaha