Sunday, April 29, 2018

Cool Java library to handle github

Especially useful is the Authentication API, it's really very simple.

http://github.jcabi.com/index.html

package pvgithubclient;

import com.jcabi.github.Coordinates;
import com.jcabi.github.Github;
import com.jcabi.github.Issue;
import com.jcabi.github.Repo;
import com.jcabi.github.RtGithub;

/**
 * http://github.jcabi.com/index.html
 * http://github.jcabi.com/apidocs-0.38/index.html
 *
 */
public class GitClient {
 public static void main(String[] args) throws Exception {
  Github github = new RtGithub("myusername", "mypassword");
  Repo repo = github.repos().get(new Coordinates.Simple("myusername", "myrepository"));
  Issue issue = repo.issues().create("How are you?", "Please tell me...");
     issue.comments().post("My first comment!");
 }
}



Farewall to all those horrible REST calls with hand-made JSON or even worse XML.
Yes, "FareWALL" in the sense that I hope that whoever invented REST and XML and JSON can hit a WALL with his bicycle. Proper APIs is the only way to handle everything.

Ah, beware that you cannot DELETE an issue in github, once created.... this because some MORONIC FASCIST decided so, despite public outrage. So use this example with care.





Gitlab on Docker

you can install directly https://about.gitlab.com/installation/#centos-7 (to uninstall: sudo gitlab-ctl stop && sudo gitlab-ctl uninstall && sudo systemctl stop gitlab-runsvdir.service && sudo systemctl disable gitlab-runsvdir.service )


but it's wiser to simply run a docker image:

https://docs.gitlab.com/omnibus/docker/


sudo docker run --detach --hostname gitlab.example.com --publish 7443:443 --publish 7080:80 --publish 7022:22 --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab --volume /srv/gitlab/logs:/var/log/gitlab --volume /srv/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:latest

(I had to change 22 to 2222, since it was already used)

for SELinux (you can disable by sudo vi /etc/selinux/config, then set disabled and reboot... check with sestatus):
sudo docker run --detach --hostname gitlab.example.com --publish 443:443 --publish 80:80 --publish 22:22 --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab:Z --volume /srv/gitlab/logs:/var/log/gitlab:Z --volume /srv/gitlab/data:/var/opt/gitlab:Z gitlab/gitlab-ce:latest



then http://127.0.0.1:7080 , give your admin password and register for a new user vernetto

create project vernetto, make it public, create repository pippo, then clone it from bash terminal
git clone http://localhost:7080/vernetto/pippo.git
cd pippo/
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
git remote -v
origin http://localhost:7080/vernetto/pippo.git (fetch)
origin http://localhost:7080/vernetto/pippo.git (push)



Friday, April 27, 2018

Nexus 3.10 Docker hosted repository on HTTPS

https://support.sonatype.com/hc/en-us/articles/213465098-How-to-Configure-HTTPS-Protocols-Used-By-Nexus

https://support.sonatype.com/hc/en-us/articles/213465768-SSL-Certificate-Guide

https://hub.docker.com/r/bradbeck/nexus-https/


https://hub.docker.com/r/bradbeck/nexus-https/~/dockerfile/

FROM sonatype/nexus3 
MAINTAINER Brad Beck <bradley.beck+docker@gmail.com> 
ENV NEXUS_SSL=${NEXUS_HOME}/etc/ssl 
ENV PUBLIC_CERT=${NEXUS_SSL}/cacert.pem \ 
    PUBLIC_CERT_SUBJ=/CN=localhost \ 
    PRIVATE_KEY=${NEXUS_SSL}/cakey.pem \ 
    PRIVATE_KEY_PASSWORD=password ARG GOSU_VERSION=1.10 

USER root 
RUN yum -y update && yum install -y openssl libxml2 libxslt && yum clean all
RUN gpg --keyserver pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
 && curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-amd64" \
 && curl -o /usr/local/bin/gosu.asc -SL "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-amd64.asc" \
 && gpg --verify /usr/local/bin/gosu.asc \
 && rm /usr/local/bin/gosu.asc \
 && rm -r /root/.gnupg/ \
 && chmod +x /usr/local/bin/gosu

RUN sed \
    -e '/^nexus-args/ s:$:,${jetty.etc}/jetty-https.xml:' \
    -e '/^application-port/a \
application-port-ssl=8443\
' \
    -i ${NEXUS_HOME}/etc/nexus-default.properties
COPY entrypoint.sh ${NEXUS_HOME}/entrypoint.sh
RUN chown nexus:nexus ${NEXUS_HOME}/entrypoint.sh && chmod a+x ${NEXUS_HOME}/entrypoint.sh
VOLUME [ "${NEXUS_SSL}" ]
EXPOSE 8443 WORKDIR ${NEXUS_HOME}
ENTRYPOINT [ "./entrypoint.sh" ]
CMD [ "bin/nexus", "run"]




[root@9118f1784d46 ssl]# more /opt/sonatype/nexus/entrypoint.sh
#!/usr/bin/env bash

set -x
set -eo pipefail

if [ "$1" == 'bin/nexus' ]; then
  if [ ! -f "$NEXUS_SSL/keystore.jks" ]; then
    mkdir -p $NEXUS_SSL
    if [ ! -f $PUBLIC_CERT ] && [ ! -f $PRIVATE_KEY ]; then
      openssl req -nodes -new -x509 -keyout $PRIVATE_KEY -out $PUBLIC_CERT -subj
 "${PUBLIC_CERT_SUBJ}"
    fi
    if [ ! -f $NEXUS_SSL/jetty.key ]; then
      openssl pkcs12 -export -in $PUBLIC_CERT -inkey $PRIVATE_KEY -out $NEXUS_SS
L/jetty.key -passout pass:$PRIVATE_KEY_PASSWORD
    fi
    $JAVA_HOME/bin/keytool -importkeystore -noprompt -deststorepass $PRIVATE_KEY
_PASSWORD -destkeypass $PRIVATE_KEY_PASSWORD -destkeystore $NEXUS_SSL/keystore.j
ks -srckeystore $NEXUS_SSL/jetty.key -srcstoretype PKCS12 -srcstorepass $PRIVATE
_KEY_PASSWORD
    sed -r '/<Set name="(KeyStore|KeyManager|TrustStore)Password">/ s:>.*$:>'$PR
IVATE_KEY_PASSWORD'</Set>:' -i $NEXUS_HOME/etc/jetty/jetty-https.xml
  fi

  mkdir -p "$NEXUS_DATA"
  chown -R nexus:nexus "$NEXUS_DATA"

  exec gosu nexus "$@"
fi

exec "$@"








create a Docker hosted repo on HTTPS port 8282

no need for insecure registry:

[centos@localhost ~]$ docker run -d -p 127.0.0.1:8081:8081 -p 127.0.0.1:8443:8443 -p 127.0.0.1:8482:8482 -v ~/nexus-data:/nexus-data -v ~/nexus-ssl:/opt/sonatype/nexus/etc/ssl --name nexus bradbeck/nexus-https
4b4e525ee28d5f10a26c4667065f15a7e9f308412bbcc6ebab18e2a030c042dd
[centos@localhost ~]$ netstat -an | grep 8482
tcp 0 0 127.0.0.1:8482 0.0.0.0:* LISTEN
[centos@localhost ~]$ docker login https://localhost:8482
Username: admin
Password:
Login Succeeded

this is the image https://hub.docker.com/r/bradbeck/nexus-https/~/dockerfile/




How to create the .cer, .key and jks files....

this will create a wildfly.keystore:
keytool -genkeypair -keystore wildfly.keystore -storepass mypassword -keypass mypassword -keyalg RSA -validity 180 -alias wildfly -dname "cn=packtpub,o=PackPub,c=GB"






Wildfly FORM based authentication with DB realm

https://dzone.com/articles/jdbc-realm-and-form-based-0

https://github.com/myfear/SimpleJDBCRealmWildFly


CREATE TABLE Users(username VARCHAR(255) PRIMARY KEY, passwd VARCHAR(255));

CREATE TABLE UserRoles(username VARCHAR(255), role VARCHAR(32));

the jar file is in:
D:\apps\wildfly12\modules\system\layers\base\org\picketbox\main\picketbox-5.0.2.Final.jar


java -classpath modules/system/layers/base/org/picketbox/main/picketbox-5.0.2.Final.jar org.jboss.security.Base64Encoder admin SHA-256
[jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg=]

INSERT INTO users (username, passwd) VALUES ('myfear', 'jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg=');
INSERT INTO userroles (username, role) VALUES ('myfear', 'ADMIN');

<security-domain name="secureDomain" cache-type="default">
                    <authentication>
                        <login-module code="Database" flag="required">
                            <module-option name="dsJndiName" value="java:jboss/datasources/UserDS"/>
                            <module-option name="principalsQuery" value="select passwd from Users where username=?"/>
                            <module-option name="rolesQuery" value="select role, 'Roles' from UserRoles where username=?"/>
                            <module-option name="hashAlgorithm" value="SHA-256"/>
                            <module-option name="hashEncoding" value="base64"/>
                        </login-module>
                    </authentication>
                </security-domain>




To debug security, make sure you enable logging:

    <profile>
        <subsystem xmlns="urn:jboss:domain:logging:4.0">
            <console-handler name="CONSOLE">
                <level name="ALL"/>
                <formatter>
                    <named-formatter name="COLOR-PATTERN"/>
                </formatter>
            </console-handler>
   
   
   
           <logger category="org.jboss.security" use-parent-handlers="false">
                <level name="TRACE"/>
                <handlers>
                    <handler name="CONSOLE"/>
                </handlers>
            </logger>



you get this:


08:37:33,815 TRACE [org.jboss.security] (MSC service thread 1-7) PBOX00227: removeAppConfig(jboss-web-policy)
08:37:33,815 TRACE [org.jboss.security] (MSC service thread 1-6) PBOX00227: removeAppConfig(jaspitest)
08:37:33,815 TRACE [org.jboss.security] (MSC service thread 1-8) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:33,818 TRACE [org.jboss.security] (MSC service thread 1-8) PBOX00315: delete, contextID: simpeljdbcrealm-1.0-SNAPSHOT.war
08:37:33,818 TRACE [org.jboss.security] (MSC service thread 1-8) PBOX00337: nextState for action delete: deleted
08:37:33,819 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:33,822 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00315: delete, contextID: simpeljdbcrealm-1.0-SNAPSHOT.war
08:37:33,823 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00337: nextState for action delete: deleted
08:37:33,824 TRACE [org.jboss.security] (MSC service thread 1-5) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:33,825 TRACE [org.jboss.security] (MSC service thread 1-5) PBOX00315: delete, contextID: kitchensink.war
08:37:33,825 TRACE [org.jboss.security] (MSC service thread 1-5) PBOX00337: nextState for action delete: deleted
08:37:33,827 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:33,827 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00315: delete, contextID: kitchensink.war
08:37:33,828 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action delete: deleted
08:37:33,842 TRACE [org.jboss.security] (ServerService Thread Pool -- 74) PBOX00354: Setting security roles ThreadLocal: null
08:37:33,851 TRACE [org.jboss.security] (ServerService Thread Pool -- 76) PBOX00354: Setting security roles ThreadLocal: null
08:37:33,856 TRACE [org.jboss.security] (ServerService Thread Pool -- 76) PBOX00354: Setting security roles ThreadLocal: null
08:37:33,867 TRACE [org.jboss.security] (MSC service thread 1-2) PBOX00227: removeAppConfig(secureDomain)
08:37:33,869 TRACE [org.jboss.security] (ServerService Thread Pool -- 74) PBOX00354: Setting security roles ThreadLocal: null
08:37:33,908 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00227: removeAppConfig(other)
08:37:33,908 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00227: removeAppConfig(jboss-ejb-policy)
08:37:47,423 TRACE [org.jboss.security] (MSC service thread 1-6) PBOX00226: addAppConfig(dummy), AuthInfo: AppConfigurationEntry[]:
08:37:52,909 TRACE [org.jboss.security] (MSC service thread 1-4) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:52,909 DEBUG [org.jboss.security] (MSC service thread 1-4) PBOX00307: Constructing JBossPolicyConfiguration with contextID simpeljdbcrealm-1.0-SNAPSHOT.war
08:37:52,911 TRACE [org.jboss.security] (MSC service thread 1-4) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:52,918 TRACE [org.jboss.security] (MSC service thread 1-4) PBOX00314: commit, contextID: simpeljdbcrealm-1.0-SNAPSHOT.war
08:37:52,918 TRACE [org.jboss.security] (MSC service thread 1-4) PBOX00337: nextState for action commit: inService
08:37:53,703 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:53,703 DEBUG [org.jboss.security] (MSC service thread 1-1) PBOX00307: Constructing JBossPolicyConfiguration with contextID kitchensink.war
08:37:53,712 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:53,714 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00310: addToRole, permission: [MemberRegistration,role-ref=**]
08:37:53,716 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00337: nextState for action addToRole: open
08:37:53,717 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00314: commit, contextID: kitchensink.war
08:37:53,721 TRACE [org.jboss.security] (MSC service thread 1-1) PBOX00337: nextState for action commit: inService
08:37:58,946 TRACE [org.jboss.security] (ServerService Thread Pool -- 66) PBOX00354: Setting security roles ThreadLocal: null
08:37:58,952 TRACE [org.jboss.security] (ServerService Thread Pool -- 66) PBOX00354: Setting security roles ThreadLocal: null
08:37:58,960 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action getPolicyConfiguration: open
08:37:58,968 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebResourcePermission" "/faces/admin/*")
08:37:58,968 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:37:58,969 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/faces/admin/*")
08:37:58,976 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:58,980 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/faces/admin/*")
08:37:58,980 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:58,986 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/faces/users/*")
08:37:58,986 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:58,987 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/faces/users/*")
08:37:58,989 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:58,992 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/faces/users/*")
08:37:58,997 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:58,998 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/faces/users/*")
08:37:58,999 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:58,999 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/faces/users/*")
08:37:58,999 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:59,000 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/faces/users/*")
08:37:59,000 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:59,004 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/:/faces/admin/*:/faces/users/*")
08:37:59,010 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:59,011 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/:/faces/admin/*:/faces/users/*")
08:37:59,014 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:59,014 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/:/faces/admin/*:/faces/users/*")
08:37:59,020 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:59,021 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/:/faces/admin/*:/faces/users/*")
08:37:59,021 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:59,022 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/:/faces/admin/*:/faces/users/*")
08:37:59,022 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:37:59,027 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebRoleRefPermission" "Faces Servlet" "**")
08:37:59,033 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:37:59,034 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebRoleRefPermission" "Faces Servlet" "ADMIN")
08:37:59,036 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:37:59,046 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebRoleRefPermission" "" "**")
08:37:59,047 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:37:59,049 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebRoleRefPermission" "" "ADMIN")
08:37:59,051 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:37:59,056 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00314: commit, contextID: simpeljdbcrealm-1.0-SNAPSHOT.war
08:37:59,058 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action commit: inService
08:38:00,471 TRACE [org.jboss.security] (ServerService Thread Pool -- 64) PBOX00354: Setting security roles ThreadLocal: null
08:38:01,078 TRACE [org.jboss.security] (ServerService Thread Pool -- 64) PBOX00354: Setting security roles ThreadLocal: null
08:38:01,081 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action getPolicyConfiguration: open
08:38:01,086 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/")
08:38:01,087 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:38:01,088 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/")
08:38:01,088 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:38:01,089 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebResourcePermission" "/")
08:38:01,092 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:38:01,097 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/")
08:38:01,098 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:38:01,098 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00312: addToUncheckedPolicy, permission: ("javax.security.jacc.WebUserDataPermission" "/")
08:38:01,100 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToUncheckedPolicy: open
08:38:01,101 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebRoleRefPermission" "Faces Servlet" "**")
08:38:01,103 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:38:01,104 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebRoleRefPermission" "org.jboss.as.quickstarts.kitchensink.rest.JaxRsActivator" "**")
08:38:01,110 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:38:01,111 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00310: addToRole, permission: ("javax.security.jacc.WebRoleRefPermission" "" "**")
08:38:01,113 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action addToRole: open
08:38:01,119 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00314: commit, contextID: kitchensink.war
08:38:01,120 TRACE [org.jboss.security] (MSC service thread 1-3) PBOX00337: nextState for action commit: inService
08:39:10,718 TRACE [org.jboss.security] (default task-1) PBOX00354: Setting security roles ThreadLocal: null
08:39:10,964 TRACE [org.jboss.security] (default task-1) PBOX00354: Setting security roles ThreadLocal: null
08:39:13,160 TRACE [org.jboss.security] (default task-1) PBOX00354: Setting security roles ThreadLocal: null
08:39:13,260 TRACE [org.jboss.security] (default task-2) PBOX00354: Setting security roles ThreadLocal: null
08:39:13,261 TRACE [org.jboss.security] (default task-3) PBOX00354: Setting security roles ThreadLocal: null
08:39:13,284 TRACE [org.jboss.security] (default task-4) PBOX00354: Setting security roles ThreadLocal: null
08:39:13,331 TRACE [org.jboss.security] (default task-1) PBOX00354: Setting security roles ThreadLocal: null
08:39:13,375 TRACE [org.jboss.security] (default task-5) PBOX00354: Setting security roles ThreadLocal: null
08:39:17,603 TRACE [org.jboss.security] (default task-5) PBOX00200: Begin isValid, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@c0d93cdc, cache entry: null
08:39:17,605 TRACE [org.jboss.security] (default task-5) PBOX00209: defaultLogin, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@c0d93cdc
08:39:17,616 TRACE [org.jboss.security] (default task-5) PBOX00221: Begin getAppConfigurationEntry(secureDomain), size: 6
08:39:17,618 TRACE [org.jboss.security] (default task-5) PBOX00224: End getAppConfigurationEntry(secureDomain), AuthInfo: AppConfigurationEntry[]:
LoginModule Class: org.jboss.security.auth.spi.DatabaseServerLoginModule
08:39:17,629 TRACE [org.jboss.security] (default task-5) PBOX00236: Begin initialize method
08:39:17,636 DEBUG [org.jboss.security] (default task-5) PBOX00281: Password hashing activated, algorithm: SHA-256, encoding: base64, charset: null, callback: null, storeCallBack: null
08:39:17,638 TRACE [org.jboss.security] (default task-5) PBOX00262: Module options [dsJndiName: java:jboss/datasources/DOICHDS, principalsQuery: select passwd from Users where username=?, rolesQuery: select role, 'Roles' from UserRoles where username=?, suspendResume: true]
08:39:17,648 TRACE [org.jboss.security] (default task-5) PBOX00240: Begin login method
08:39:17,670 TRACE [org.jboss.security] (default task-5) PBOX00263: Executing query select passwd from Users where username=? with username myfear
08:39:17,724 TRACE [org.jboss.security] (default task-5) PBOX00241: End login method, isValid: true
08:39:17,725 TRACE [org.jboss.security] (default task-5) PBOX00242: Begin commit method, overall result: true
08:39:17,728 TRACE [org.jboss.security] (default task-5) PBOX00263: Executing query select role, 'Roles' from UserRoles where username=? with username myfear
08:39:17,735 TRACE [org.jboss.security] (default task-5) PBOX00263: Executing query select role, 'Roles' from UserRoles where username=? with username myfear
08:39:17,776 TRACE [org.jboss.security] (default task-5) PBOX00210: defaultLogin, login context: javax.security.auth.login.LoginContext@59f877d, subject: Subject(745690868).principals=org.jboss.security.SimplePrincipal@1437571176(myfear)org.jboss.security.SimpleGroup@1704402987(Roles(members:ADMIN))org.jboss.security.SimpleGroup@1704402987(CallerPrincipal(members:myfear))
08:39:17,777 TRACE [org.jboss.security] (default task-5) PBOX00207: updateCache, input subject: Subject(745690868).principals=org.jboss.security.SimplePrincipal@1437571176(myfear)org.jboss.security.SimpleGroup@1704402987(Roles(members:ADMIN))org.jboss.security.SimpleGroup@1704402987(CallerPrincipal(members:myfear)), cached subject: Subject(882771324).principals=org.jboss.security.SimplePrincipal@1437571176(myfear)org.jboss.security.SimpleGroup@1704402987(Roles(members:ADMIN))org.jboss.security.SimpleGroup@1704402987(CallerPrincipal(members:myfear))
08:39:17,780 TRACE [org.jboss.security] (default task-5) PBOX00208: Inserted cache info: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@4b02ffcf
08:39:17,785 TRACE [org.jboss.security] (default task-5) PBOX00201: End isValid, result = true
08:39:17,798 TRACE [org.jboss.security] (default task-5) PBOX00354: Setting security roles ThreadLocal: null
08:39:17,814 TRACE [org.jboss.security] (default task-5) PBOX00200: Begin isValid, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@c0d93cdc, cache entry: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@4b02ffcf
08:39:17,814 TRACE [org.jboss.security] (default task-5) PBOX00204: Begin validateCache, domainInfo: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@4b02ffcf, credential class: class [C
08:39:17,815 TRACE [org.jboss.security] (default task-5) PBOX00205: End validateCache, result = true
08:39:17,817 TRACE [org.jboss.security] (default task-5) PBOX00201: End isValid, result = true
08:39:17,832 TRACE [org.jboss.security] (default task-5) PBOX00354: Setting security roles ThreadLocal: null
08:39:17,906 TRACE [org.jboss.security] (default task-5) PBOX00200: Begin isValid, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@c0d93cdc, cache entry: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@4b02ffcf
08:39:17,906 TRACE [org.jboss.security] (default task-5) PBOX00204: Begin validateCache, domainInfo: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@4b02ffcf, credential class: class [C
08:39:17,910 TRACE [org.jboss.security] (default task-5) PBOX00205: End validateCache, result = true
08:39:17,916 TRACE [org.jboss.security] (default task-5) PBOX00201: End isValid, result = true
08:39:17,920 TRACE [org.jboss.security] (default task-5) PBOX00354: Setting security roles ThreadLocal: null








Tuesday, April 24, 2018

Useful Java EE patterns

If you need a self-refreshing cache - with a timer to fetch updates - visible to all users:

annotate a class ApplicationCache with:

@javax.enterprise.context.ApplicationScoped
@javax.ejb.Singleton
@javax.ejb.ConcurrencyManagement(ConcurrencyManagementType.BEAN)


initialize it with a method annotated with
@javax.annotation.PostConstruct
public void startup()

provide a scheduled method:

@javax.ejb.Schedule(dayOfWeek = "1-5", hour = "*", minute = "*/30", persistent = false)
public void refreshCache()


Wherever you want to invoke a service method on the above class, you acquire a reference with

@javax.inject.Inject
private ApplicationCache applicationCache;


=================



If you need a logger:

@javax.inject.Inject
private org.slf4j.Logger logger;


=================



if you need a thread-safe collection:

private final List employees = Collections.synchronizedList(new ArrayList());
private final Map employeesMap = Collections.synchronizedMap(new HashMap());

===================






Monday, April 23, 2018

Wildfly: deploy an application as a root context

http://www.mastertheboss.com/jboss-web/jbosswebserver/how-to-deploy-a-web-application-on-the-root-context-on-jboss-as-7


Schemas for the standalone.xml can be found in D:\apps\wildfly12\docs\schema

For the undertow (former web) subsystem, use wildfly-undertow_5_0.xsd



and the virtual-server is defined in jboss-as-web_2_2.xsd (which is JBoss AS, not Wildfly)


This CLI:
/subsystem=undertow:write-attribute(name=default-virtual-host, value=default-host)
adds default-virtual-host="default-host" to the line subsystem xmlns="urn:jboss:domain:undertow:5.0" in config.xml

subsystem xmlns="urn:jboss:domain:undertow:5.0"




Very helpful: https://docs.jboss.org/author/display/WFLY10/CLI+Recipes


By default, Wildfly 12 comes with this Undertow configuration

<subsystem xmlns="urn:jboss:domain:undertow:5.0">
 <buffer-cache name="default"/>
 <server name="default-server">
  <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
  <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
  <host name="default-host" alias="localhost">
   <location name="/" handler="welcome-content"/>
   <filter-ref name="server-header"/>
   <filter-ref name="x-powered-by-header"/>
   <http-invoker security-realm="ApplicationRealm"/>
  </host>
 </server>
 <servlet-container name="default">
  <jsp-config/>
  <websockets/>
 </servlet-container>
 <handlers>
  <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
 </handlers>
 <filters>
  <response-header name="server-header" header-name="Server" header-value="WildFly/11"/>
  <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
 </filters>
</subsystem>


According to the book "WildFly Configuration, Deployment, and Administration - Second Edition" , page 118, if you want to deploy a webapp to handle the / root context, you first have to run this CLI:


/subsystem=undertow/server=default-server/host=default-host/location=\/:remove()

After which the entry <location name="/" handler="welcome-content"/> will disappear from the standalone.xml

To build such CLI command, it's very useful to open the Administration console, then bottom right you have "Tools" "Management Model" , then you navigate in the tree matching the structure you can read in the XML.
Unfortunately CLI can't be generated directly from the console (as it was the case in WLST and WebLogic! One huge point in favor of WebLogic!)

<jboss-web>
<context-root>/</context-root>
</jboss-web>

git clone https://github.com/vernetto/primefaces-test.git
cd primefaces-test
mvn clean package

(in the CLI) deploy c:\pierre\gitclones\primefaces-test\target\primefaces-test-1.0-SNAPSHOT.war


enter localhost:8080 and your webapp is there instead of the ROOT.war application !

Enter http://localhost:9990/console/App.html#standalone-deployments;backButton=/deployments-details and you see the









Wildfly 12 virtual-server

http://www.mastertheboss.com/jboss-web/jbosswebserver/how-to-deploy-a-web-application-on-the-root-context-on-jboss-as-7


Schemas for the standalone.xml can be found in D:\apps\wildfly12\docs\schema

For the undertow (former web) subsystem, use wildfly-undertow_5_0.xsd



and the virtual-server is defined in jboss-as-web_2_2.xsd (which is JBoss AS, not Wildfly)


This CLI:
/subsystem=undertow:write-attribute(name=default-virtual-host, value=default-host)
adds default-virtual-host="default-host" to the line subsystem xmlns="urn:jboss:domain:undertow:5.0" in config.xml

subsystem xmlns="urn:jboss:domain:undertow:5.0"




Very helpful: https://docs.jboss.org/author/display/WFLY10/CLI+Recipes

Sunday, April 22, 2018

wildfly configuration, deployment and administration - second edition


This is a decent book, hands on and very practical. It wastes a bit too much time explaining stuff that everybody knows (what is TLS) rather than concentrating only on Wildfly stuff. Also big drawback is lack of github repository with examples (you can download then from the publisher). Also the style is a bit dry and boring.

Good for the beginner just getting started with Wildfly.



Friday, April 20, 2018

Google Kubernetes Engine getting started

Use only Google Chrome to access Google Kubernetes Engine.... with Firefox the Shell doesn't work properly (frustrating).

Log into https://console.cloud.google.com/kubernetes/

https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app


This is the hello-app https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/tree/master/hello-app


git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/hello-ap

export PROJECT_ID="$(gcloud config get-value project -q)"
docker build -t gcr.io/${PROJECT_ID}/hello-app:v1 .


the Dockerfile being built is:
FROM golang:1.8-alpine
ADD . /go/src/hello-app
RUN go install hello-app

FROM alpine:latest
COPY --from=0 /go/bin/hello-app .
ENV PORT 8080
CMD ["./hello-app"]

and this is the log



Sending build context to Docker daemon 9.216kB
Step 1/7 : FROM golang:1.8-alpine
1.8-alpine: Pulling from library/golang
550fe1bea624: Pull complete
cbc8da23026a: Pull complete
12508f45ab1b: Pull complete
f6a6c5429359: Pull complete
1c48badb8476: Pull complete
2866b24847ef: Pull complete
Digest: sha256:1b0930a92a5d478d3f93d8d3c06cb3c241262ccbf77de35eb617e202f58c9b76
Status: Downloaded newer image for golang:1.8-alpine
---> bbb7421a9337
Step 2/7 : ADD . /go/src/hello-app
---> ad8ee8aa671c
Removing intermediate container b8668e8cdedd
Step 3/7 : RUN go install hello-app
---> Running in c4b1bbf253a3
---> 9f8fb12fadc2
Removing intermediate container c4b1bbf253a3
Step 4/7 : FROM alpine:latest
latest: Pulling from library/alpine
ff3a5c916c92: Pull complete
Digest: sha256:8c03bb07a531c53ad7d0f6e7041b64d81f99c6e493cb39abba56d956b40eacbc
Status: Downloaded newer image for alpine:latest
---> 3fd9065eaf02
Step 5/7 : COPY --from=0 /go/bin/hello-app .
---> 490bb535a1a4
Removing intermediate container 617f13e84c40
Step 6/7 : ENV PORT 8080
---> Running in 828bf4c23c66
---> 4198dd25173f
Removing intermediate container 828bf4c23c66
Step 7/7 : CMD ./hello-app
---> Running in d009b6f24683
---> 0a8fed701a4d
Removing intermediate container d009b6f24683
Successfully built 0a8fed701a4d
Successfully tagged gcr.io/pippo-189911/hello-app:v1
>









h2 remote TCP client

telnet ip port

Remote connections to this server are not allowed, see -tcpAllowOthers
org.h2.jdbc.JdbcSQLException: Remote connections to this server are not allowed, see -tcpAllowOthers [90117-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.message.DbException.get(DbException.java:144)
at org.h2.server.TcpServerThread.run(TcpServerThread.java:89)
at java.lang.Thread.run(Thread.java:748)
Connection closed by foreign host.


You fix the issue by running h2 server as:

java -cp "/opt/h2/bin/h2-1.4.197.jar:$H2DRIVERS:$CLASSPATH" -Dh2.consoleTimeout=500000 org.h2.tools.Console -web -webAllowOthers -tcp -tcpAllowOthers


on the client side, in wildfly, you have

<datasource jndi-name="java:jboss/datasources/DOICHDS" pool-name="DOICHDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:tcp://yourserverip:9092/~/PIPPO;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>PIPPO</user-name>
<password>PIPPO</password>
</security>
</datasource>

See https://stackoverflow.com/a/9838282/651288



jboss-cli

https://docs.jboss.org/author/display/WFLY/Command+Line+Interface

$ ./jboss-cli.sh



Unable to read the logging configuration from 'file:/d/apps/wildfly12/bin/jboss-cli-logging.properties' (java.io.FileNotFoundException: \d\apps\wildfly12\bin\jboss-cli-logging.properties (The system cannot find the path specified))
INFO  [org.jboss.modules] JBoss Modules version 1.7.0.Final
INFO  [org.jboss.as.cli.CommandContext] You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect
connect
INFO  [org.xnio] XNIO version 3.6.2.Final
INFO  [org.xnio.nio] XNIO NIO Implementation Version 3.6.2.Final
INFO  [org.jboss.remoting] JBoss Remoting version 5.0.5.Final
INFO  [org.jboss.threads] JBoss Threads version 2.3.1.Final
INFO  [org.wildfly.security] ELY00001: WildFly Elytron version 1.2.2.Final
ERROR [org.jboss.as.cli.CommandContext] The controller is not available at localhost:9990: java.net.ConnectException: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: Connection refused: no further information
The controller is not available at localhost:9990: java.net.ConnectException: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: Connection refused: no further information



Instead of the normal ports 8080/9990 I have 8180/10090 , because in standalone.xml I have specified in socket-binding-group a jboss.socket.binding.port-offset:100

So I try with

./jboss-cli.sh --controller=localhost:10090

and I get a beautiful

INFO  [org.xnio] XNIO version 3.6.2.Final
INFO  [org.xnio.nio] XNIO NIO Implementation Version 3.6.2.Final
INFO  [org.jboss.remoting] JBoss Remoting version 5.0.5.Final
INFO  [org.jboss.threads] JBoss Threads version 2.3.1.Final
INFO  [org.wildfly.security] ELY00001: WildFly Elytron version 1.2.2.Final
[standalone@localhost:10090 /]



If you look in jboss-cli.xml you see that the default controller is configured in it:

<!-- The default controller to connect to when 'connect' command is executed w/o arguments -->
    <default-controller>
        <protocol>remote+http</protocol>
        <host>localhost</host>
        <port>9990</port>
    </default-controller>

If I change 9990 to 10090, I can seamlessly connect without having to specify the --controller=localhost:10090

Remarkable also the .jbossclirc file. "# WildFly (JBoss) CLI will execute commands from this file before
# the command line session (interactive or not) will start."


Regarding the message "Unable to read the logging configuration from 'file:/d/apps/wildfly12/bin/jboss-cli-logging.properties' ", I have it only when running the jboss-cli.sh in git bash.... if I run jboss-cli.bat I don't have the problem. Most likely it's due to the fact that in git bash the $JBOSS_HOME is rendered as file:/d/apps/wildfly12/ , and Java can't handle this... welcome to the messy world of Windows...


It seems also that the TAB autocomplete is not working under git bash.... I am switching permanently to a DOS console.... how sad..



Useful CLI:

#dump elytron configuration
/subsystem=elytron:read-resource(recursive=true)

#dump logger configuration
/subsystem=logging/console-handler=CONSOLE:read-resource

#add a filesystem-realm and add a user
#see https://docs.jboss.org/author/display/WFLY/WildFly+Elytron+Security#WildFlyElytronSecurity-ConfigureAuthenticationwithaFilesystemBasedIdentityStore

/subsystem=elytron/filesystem-realm=exampleFsRealm:add(path=fs-realm-users,relative-to=jboss.server.config.dir)
/subsystem=elytron/filesystem-realm=exampleFsRealm/:add-identity(identity=user1)
cd subsystem=elytron
cd filesystem-realm=exampleFsRealm
:set-password(identity=user1,clear={password="password123"})

#(this creates a file user1-OVZWK4RR.xml with inside 'identity xmlns="urn:elytron:1.0"' )




PRICELESS: ./jboss-cli.sh --gui opens a UI which really simplifies the discovery of CLI syntax

PRICELESS: https://wildscribe.github.io/WildFly/12.0/index.html Wildfly Reference model, all attributes and operations explained (very briefly, but better than nothing)







Wednesday, April 18, 2018

RHEL SELinux and docker search behind a company firewall

It seems you should add registry.access.redhat.com to the company open firewall rules / iptables...

docker search hello-world

Error response from daemon: invalid registry endpoint https://registry.access.redhat.com/v1/: Get https://registry.access.redhat.com/v1/_ping: dial tcp: lookup registry.access.redhat.com on 127.0.0.1:53: no such host. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry registry.access.redhat.com` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/registry.access.redhat.com/ca.crt

https://rhelblog.redhat.com/2015/04/15/understanding-the-changes-to-docker-search-and-docker-pull-in-red-hat-enterprise-linux-7-1/


"The Red Hat default config in ‘/etc/sysconfig/docker’ adds ‘registry.access.redhat.com’, which is the authoritative source for official Red Hat content. The default docker.io search path is hardcoded and remains enabled."


eg:

cat /etc/sysconfig/docker
# /etc/sysconfig/docker

# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false'
if [ -z "${DOCKER_CERT_PATH}" ]; then
    DOCKER_CERT_PATH=/etc/docker
fi

# Do not add registries in this file anymore. Use /etc/containers/registries.conf
# from the atomic-registries package.
#

# On an SELinux system, if you remove the --selinux-enabled option, you
# also need to turn on the docker_transition_unconfined boolean.
# setsebool -P docker_transition_unconfined 1

# Location used for temporary files, such as those created by
# docker load and build operations. Default is /var/lib/docker/tmp
# Can be overriden by setting the following environment variable.
# DOCKER_TMPDIR=/var/tmp

# Controls the /etc/cron.daily/docker-logrotate cron job status.
# To disable, uncomment the line below.
# LOGROTATE=false

# docker-latest daemon can be used by starting the docker-latest unitfile.
# To use docker-latest client, uncomment below lines
#DOCKERBINARY=/usr/bin/docker-latest
#DOCKERDBINARY=/usr/bin/dockerd-latest
#DOCKER_CONTAINERD_BINARY=/usr/bin/docker-containerd-latest
#DOCKER_CONTAINERD_SHIM_BINARY=/usr/bin/docker-containerd-shim-latest


and

cat /etc/containers/registries.conf
# This is a system-wide configuration file used to
# keep track of registries for various container backends.
# It adheres to TOML format and does not support recursive
# lists of registries.

# The default location for this configuration file is /etc/containers/registries.conf.

# The only valid categories are: 'registries.search', 'registries.insecure', 
# and 'registries.block'.

[registries.search]
registries = ['registry.access.redhat.com']

# If you need to access insecure registries, add the registry's fully-qualified name.
# An insecure registry is one that does not have a valid SSL certificate or only does HTTP.
[registries.insecure]
registries = []


# If you need to block pull access from a registry, uncomment the section below
# and add the registries fully-qualified name.
#
# Docker only
[registries.block]
registries = []




docker registry-mirrors

One can setup a registry mirror to intercept all "docker pull" and route them through a local cache registry..... however there seem to be issues when you use Nexus Docker Repo for this purpose...

setup Nexus Docker registry as here http://www.javamonamour.org/2018/03/using-nexus-3-as-docker-registry-proxy.html


cat /etc/docker/daemon.json
{
"debug" : true,
"experimental" : true,
"insecure-registries" : [ "localhost:8081", "localhost:8082" ],
"registry-mirrors" : [
"http://localhost:8082"
]
}

sudo systemctl daemon-reload
sudo systemctl restart docker


docker start nexus3
docker login localhost:8082 (admin/admin123)

docker info
Registry Mirrors:
http://localhost:8082/

docker pull hello-world

sudo cat /var/log/messages | grep docker

Apr 17 22:35:02 localhost dockerd: time="2018-04-17T22:35:02.139328745+02:00" level=debug msg="Calling GET /v1.37/images/json"
Apr 17 22:35:14 localhost dockerd: time="2018-04-17T22:35:14.623910991+02:00" level=debug msg="Calling GET /_ping"
Apr 17 22:35:14 localhost dockerd: time="2018-04-17T22:35:14.628661368+02:00" level=debug msg="Calling GET /v1.37/info"
Apr 17 22:35:14 localhost dockerd: time="2018-04-17T22:35:14.673297720+02:00" level=debug msg="Calling POST /v1.37/images/create?fromImage=hello-world&tag=latest"
Apr 17 22:35:14 localhost dockerd: time="2018-04-17T22:35:14.673784263+02:00" level=debug msg="Trying to pull hello-world from http://localhost:8082/ v2"
Apr 17 22:35:15 localhost dockerd: time="2018-04-17T22:35:15.137325587+02:00" level=info msg="Attempting next endpoint for pull after error: Get http://localhost:8082/v2/library/hello-world/manifests/latest: no basic auth credentials"
Apr 17 22:35:15 localhost dockerd: time="2018-04-17T22:35:15.137404591+02:00" level=debug msg="Trying to pull hello-world from https://registry-1.docker.io v2"
Apr 17 22:35:17 localhost dockerd: time="2018-04-17T22:35:17.637206822+02:00" level=debug msg="Pulling ref from V2 registry: hello-world:latest"
Apr 17 22:35:17 localhost dockerd: time="2018-04-17T22:35:17.640510754+02:00" level=debug msg="docker.io/library/hello-world:latest resolved to a manifestList object with 9 entries; looking for a linux/amd64 match"
Apr 17 22:35:17 localhost dockerd: time="2018-04-17T22:35:17.640582612+02:00" level=debug msg="found match for linux/amd64 with media type application/vnd.docker.distribution.manifest.v2+json, digest sha256:d5c74e6f8efc7bdf42a5e22bd764400692cf82360d86b8c587a7584b03f51520"
Apr 17 22:35:18 localhost dockerd: time="2018-04-17T22:35:18.504407966+02:00" level=debug msg="pulling blob \"sha256:9bb5a5d4561a5511fa7f80718617e67cf2ed2e6cdcd02e31be111a8d0ac4d6b7\""
Apr 17 22:35:19 localhost dockerd: time="2018-04-17T22:35:19.580697501+02:00" level=debug msg="Downloaded 9bb5a5d4561a to tempfile /var/lib/docker/tmp/GetImageBlob741769005"
Apr 17 22:35:19 localhost dockerd: time="2018-04-17T22:35:19.600499679+02:00" level=debug msg="Applying tar in /var/lib/docker/overlay2/6fd7cd727232306d47dbbd8835c85bab265bc3c51f1fd4e784d814556652d761/diff"
Apr 17 22:35:19 localhost dockerd: time="2018-04-17T22:35:19.759362924+02:00" level=debug msg="Applied tar sha256:2b8cbd0846c5aeaa7265323e7cf085779eaf244ccbdd982c4931aef9be0d2faf to 6fd7cd727232306d47dbbd8835c85bab265bc3c51f1fd4e784d814556652d761, size: 1848"


Interesting this message:

Apr 17 22:35:15 localhost dockerd: time="2018-04-17T22:35:15.137325587+02:00" level=info msg="Attempting next endpoint for pull after error: Get http://localhost:8082/v2/library/hello-world/manifests/latest: no basic auth credentials"




https://github.com/moby/moby/issues/20097
https://stackoverflow.com/questions/42143395/docker-registry-mirror-not-used no basic auth credentials -> solution with nginx
https://github.com/moby/moby/issues/30880 this is the main ticket


it seems that the only workaround is to setup a nginx proxy with basic authentication injected
Otherwise, https://github.com/moby/moby/issues/30880 "Nexus OSS 3.6.0-02 can finally transparently proxy docker images. It has a new feature called "Anonymous Read Access" for docker registry access (see
https://help.sonatype.com/display/NXRM3/Private+Registry+for+Docker) and disabling "Force basic authentication" and adding "Docker bearer token realm" in nexus/admin/security/realms seems to fixes this issue, no more "no basic auth credentials" in the logfile."



I have done the above, and I can now see after a "docker pull hello-world":

Apr 18 15:01:24 localhost dockerd: time="2018-04-18T15:01:24.245724948+02:00" level=debug msg="Calling GET /_ping"
Apr 18 15:01:24 localhost dockerd: time="2018-04-18T15:01:24.246891099+02:00" level=debug msg="Calling GET /v1.37/info"
Apr 18 15:01:24 localhost dockerd: time="2018-04-18T15:01:24.362426987+02:00" level=debug msg="Calling POST /v1.37/images/create?fromImage=hello-world&tag=latest"
Apr 18 15:01:24 localhost dockerd: time="2018-04-18T15:01:24.374842745+02:00" level=debug msg="Trying to pull hello-world from http://localhost:8082/ v2"
Apr 18 15:01:24 localhost dockerd: time="2018-04-18T15:01:24.439398678+02:00" level=debug msg="Increasing token expiration to: 60 seconds"
Apr 18 15:01:29 localhost dockerd: time="2018-04-18T15:01:29.026052252+02:00" level=debug msg="Pulling ref from V2 registry: hello-world:latest"





Tuesday, April 17, 2018

Docker run a command in an image

How many times you are baffled because you run

docker run myregistry/maven:3-alpine

and it simply exists without doing anything.

Then you do

docker run myregistry/maven:3-alpine /bin/bash

and the same thing happens

Then you inspect the image:

docker image inspect myregistry/maven:3-alpine


and you notice

           "Cmd": [
                "mvn"
            ],

          "Entrypoint": [
                "/usr/local/bin/mvn-entrypoint.sh"
            ],


and you wonder what is actually executed....

Luckily you can simply OVERRIDE the entrypoint (see https://gist.github.com/mitchwongho/11266726 ) :


docker run -it --entrypoint /bin/bash myregistry/maven:3-alpine

so you enter directly a bash shell, without executing the original Entrypoint of course.


The documentation of this precious Maven image is https://hub.docker.com/_/maven/ here

mvn settings are in /usr/share/maven/ref/settings-docker.xml and (maybe) in /usr/share/maven/conf/settings.xml
mvn binaries are in /usr/bin/mvn -> /usr/share/maven/bin/mvn


Ref: docker run https://docs.docker.com/engine/reference/commandline/run/#options


Priceless, to debug Maven: mvn -X help:effective-settings



Monday, April 16, 2018

Jenkins Blueocean and integration with JIRA

docker run -u root -d --rm -p 8090:8080 --name jenkins-blueocean -v jenkins-data:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean

http://localhost:8080 and finish configuring admin user and install all recommended plugins

docker ps (note the containerid)
docker commit $containerid myjenkinsblueocean

sudo docker run --detach --publish 8080:8080 cptactionhank/atlassian-jira:latest
(for some reason, jira in docker needs 8080:8080... I tried 8090:8080 and it tries internally to connect to 8080 which fails)



See also http://www.javamonamour.org/2017/11/jira-on-docker-and-integration-with.html



Jenkins sucks

Jenkins sucks. Ok it could suck more, but let me tell you what I find really frustrating from a begginner's perspective

a) documentation is pathetic. The Jenkins User Handbook until a few months ago was full of empty sections with only "work in progress".... now it's a bit better, but still....

b) plugins is a cosmic chaos... any basic installation would include at least some 100 common plugins, so why not include them in the Jenkins baseline and avoid all this chaos.... also, plugin documentation is most of the time really basic

c) no development IDE, no way to remote debug. Should I develop code in BlueOcean plugin in a browser??? are you serious??? When one is used to IntelliJ, having to code Jenkins Pipelines in Notepad++ is like going back to Stone Age. The Eclipse plugin is laughable, you can just remotely invoke the linter for validation.... no autocomplete, no inline javadoc, NOTHING

d) Groovy is good, but management of libraries is a bit shaky.... however this is not the weakest point, at least they don't make me code in XML like Maven or Ant do, or in a ridiculous DSL like Puppet does....

e) the UI was coded by children... you have to click for hours to find something... not even a search tool to point you quickly where a certain parameter is defined.... it's the typical click-o-drome of tools that are designed for non-programmers and end up being a nightmare of clicks and hidden corners.




Wednesday, April 11, 2018

debug hanging shell scripts

https://stackoverflow.com/questions/4640794/a-running-bash-script-is-hung-somewhere-can-i-find-out-what-line-it-is-on

set -x

lsof -p $pid

strace -p $pid -s 1024

/proc/$pid/environ

pstree -pl 21156 + cat /proc/15232/stack (15232 is the PID of the hanging process)

top

set -v or set -o verbose

http://bashdb.sourceforge.net/
https://www.shellcheck.net/
https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug



Hibernate validator dependencies for unit testing

http://hibernate.org/validator/ home page of validation


at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:271)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath


I have this in my pom.xml

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<scope>provided</scope>
</dependency>





Apparently I should add this implementation

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>


I do that, then I have :


java.lang.NoClassDefFoundError: javax/validation/ClockProvider
 at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:33)
 at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:276)
 at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)

Caused by: java.lang.ClassNotFoundException: javax.validation.ClockProvider
 at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:357)





Then I add

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
<scope>test</scope>
</dependency>




and I get

Caused by: java.lang.ClassNotFoundException: javax.validation.ParameterNameProvider


Here they say you should remove the validation-api : https://stackoverflow.com/questions/24652753/java-lang-noclassdeffounderror-javax-validation-parameternameprovider


I do this:


<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
<scope>test</scope>
</dependency>


now I get:



Caused by: javax.validation.ValidationException: HV000183: Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead
 at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.buildExpressionFactory(ResourceBundleMessageInterpolator.java:123)
 at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.(ResourceBundleMessageInterpolator.java:47)
 at org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultMessageInterpolator(ConfigurationImpl.java:461)
 at org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultMessageInterpolatorConfiguredWithClassLoader(ConfigurationImpl.java:637)
 at org.hibernate.validator.internal.engine.ConfigurationImpl.getMessageInterpolator(ConfigurationImpl.java:388)
 at org.hibernate.validator.internal.engine.ValidatorFactoryImpl.(ValidatorFactoryImpl.java:179)
 at org.hibernate.validator.HibernateValidator.buildValidatorFactory(HibernateValidator.java:38)
 at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:355)
 at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:103)




So I add ( https://stackoverflow.com/questions/24386771/javax-validation-validationexception-hv000183-unable-to-load-javax-el-express )



<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
<scope>test</scope>
</dependency>



and I get

java.lang.ClassNotFoundException: javax.el.ELManager


then I finally use

<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>


and it works!

once more, all you need is:

  <dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <scope>provided</scope>
  </dependency>

  <dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.7.Final</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
    <scope>test</scope>
  </dependency>

<dependency>
  <groupId>javax.el</groupId>
  <artifactId>javax.el-api</artifactId>
  <version>3.0.0</version>
    <scope>test</scope>
</dependency>

  <dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.el</artifactId>
    <version>2.2.4</version>
    <scope>test</scope>
  </dependency>
  















Saturday, April 7, 2018

H2 autogenerating unique IDs from Sequence

if you have annotated the ID with

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Entity;

@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = "ID"), name = "VOCABULARY")
public class Vocabulary implements Serializable {

@Id
@GeneratedValue
private Long id;

and declared the ID as
CREATE TABLE "VOCABULARY" (
    "ID" NUMBER(10,0) NOT NULL
...
)
CREATE UNIQUE INDEX "VOCABULARY_UNIQ_ID" ON "VOCABULARY" ("ID") ;
ALTER TABLE "VOCABULARY" ADD PRIMARY KEY ("ID");

this is not enough... you will get this when you try to insert a new record:

org.h2.jdbc.JdbcSQLException: Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-197]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
        at org.h2.message.DbException.get(DbException.java:179)
        at org.h2.message.DbException.get(DbException.java:155)
        at org.h2.command.Parser.readSequence(Parser.java:5970)
        at org.h2.command.Parser.readTerm(Parser.java:3131)
        at org.h2.command.Parser.readFactor(Parser.java:2587)
        at org.h2.command.Parser.readSum(Parser.java:2574)
        at org.h2.command.Parser.readConcat(Parser.java:2544)
        at org.h2.command.Parser.readCondition(Parser.java:2370)
        at org.h2.command.Parser.readAnd(Parser.java:2342)
        at org.h2.command.Parser.readExpression(Parser.java:2334)
        at org.h2.command.Parser.parseCall(Parser.java:4854)
        at org.h2.command.Parser.parsePrepared(Parser.java:382)
        at org.h2.command.Parser.parse(Parser.java:335)
        at org.h2.command.Parser.parse(Parser.java:307)
        at org.h2.command.Parser.prepareCommand(Parser.java:278)
        at org.h2.engine.Session.prepareLocal(Session.java:611)
        at org.h2.server.TcpServerThread.process(TcpServerThread.java:271)
        at org.h2.server.TcpServerThread.run(TcpServerThread.java:165)
        at java.lang.Thread.run(Thread.java:748)

        at org.h2.engine.SessionRemote.done(SessionRemote.java:624)
        at org.h2.command.CommandRemote.prepare(CommandRemote.java:68)
        at org.h2.command.CommandRemote.(CommandRemote.java:45)
        at org.h2.engine.SessionRemote.prepareCommand(SessionRemote.java:494)
        at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1203)
        at org.h2.jdbc.JdbcPreparedStatement.(JdbcPreparedStatement.java:73)
        at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:676)
        at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.doPrepareStatement(BaseWrapperManagedConnection.java:757)
        at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.prepareStatement(BaseWrapperManagedConnection.java:743)
        at org.jboss.jca.adapters.jdbc.WrappedConnection.prepareStatement(WrappedConnection.java:454)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$1.doPrepare(StatementPreparerImpl.java:87)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)



Solution is:

CREATE SEQUENCE VOCABULARY_SEQUENCE_ID START WITH (select max(ID) + 1 from VOCABULARY);

(this allows me to prepopulate the VOCABULARY with static values, and initialize the sequence accordingly)

and in Java

@Id
@SequenceGenerator(name= "VOCABULARY_SEQUENCE", sequenceName = "VOCABULARY_SEQUENCE_ID", initialValue=1, allocationSize = 1)
@GeneratedValue(strategy=GenerationType.AUTO, generator="VOCABULARY_SEQUENCE")
private Long id;



Why in 2018 such common things have to be still so complicated, no clue, something is really going wrong in the Java world... maybe using Spring it's only a matter of 1 annotation... no clue...





ANTLR

http://www.antlr.org/




Source code: https://pragprog.com/titles/tpantlr2/source_code

(I am using GIT bash)
on Windows:
export CLASSPATH=/d/pierre/downloads/antlr/antlr-4.0-complete.jar:.
alias antlr="java -jar /d/pierre/downloads/antlr/antlr-4.0-complete.jar"
alias grun='java org.antlr.v4.runtime.misc.TestRig'

on Linux
export CLASSPATH=/home/centos/antlr/antlr-4.0-complete.jar:.
alias grun='java -cp /home/centos/antlr/antlr-4.0-complete.jar:. org.antlr.v4.runtime.misc.TestRig'


grun Hello r -tokens

I could not find which EOF key to press on Windows (it's CTRL-D in Linux).



If more people knew how to write a grammar and a parser, we probably would not be wasting so much of our life manually sorting horrendous Maven pom.xml files, or hacking HTML pages embedded with all sort of obscure hocus-pocus additions, or even typing unreadable GIT commands to undo a commit.

But we don't want to be monkeys, we want to learn the fundamentals of our profession : elaborate languages to explain, in a clear concise and unambiguous way, what we expect from a computing machine.



Troubleshooting:


If you get
java.lang.NullPointerException
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:311)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.antlr.v4.runtime.misc.TestRig.process(TestRig.java:157)
at org.antlr.v4.runtime.misc.TestRig.main(TestRig.java:142)

check this:

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/misc/Launcher.java?av=f

public Class<?>  [More ...] loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
int i = name.lastIndexOf('.');
if (i != -1) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(name.substring(0, i));
}
}

and this http://grepcode.com/file/repo1.maven.org/maven2/org.antlr/antlr4/4.0/org/antlr/v4/runtime/misc/TestRig.java?av=f

try {
lexerClass = cl.loadClass(lexerName).asSubclass(Lexer.class);
}

At this point I am pretty hopeless.... just ignore this issue, when you run grun with parameters, it works.

See https://github.com/antlr/antlr4/issues/174


Friday, April 6, 2018

WebLogic on Kubernetes

https://blogs.oracle.com/weblogicserver/weblogic-server-certification-on-kubernetes

https://github.com/oracle/docker-images/tree/master/OracleWebLogic/dockerfiles/12.2.1.3

sample Dockerfile https://github.com/oracle/docker-images/blob/master/OracleWebLogic/samples/wls-k8s-domain/Dockerfile

WebLogic Dockerfiles are at https://github.com/oracle/docker-images/tree/master/OracleWebLogic



Katacoda docker interactive tutorial

Katacoda is the best thing I have seen this year. IT teachers and IT books are made obsolete by this tool.

https://www.katacoda.com/courses/docker/deploying-first-container

docker search redis

docker run -d redis

docker ps

docker inspect 654e238d3bef
docker logs 654e238d3bef

docker run -d --name redisHostPort -p 6379:6379 redis:latest

docker run -d --name redisDynamic -p 6379 redis:latest

docker port redisDynamic 6379

docker run -d --name redisMapped -v /opt/docker/data/redis:/data redis

docker run -d ubuntu ps
docker exec ubuntu bash

Dockerfile
FROM nginx:alpine
COPY . /usr/share/nginx/html

docker build -t webserver-image:v1 .

docker images

docker run -d -p 80:80 webserver-image:v1

curl docker
cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.0.1       registry.test.training.katacoda.com
172.17.0.51     host01 751a165ea438 st_4yzuip_d2d
172.17.0.51     docker 751a165ea438 st_4yzuip_d2d
172.17.0.36     e1c00230b89e

to create data container:
docker create -v /config --name dataContainer busybox

docker cp config.conf dataContainer:/config/
docker run --volumes-from dataContainer ubuntu ls /config

to move the data container to another machine:
docker export dataContainer > dataContainer.tar
docker import dataContainer.tar



Networks

docker network create backend-network
docker run -d --name=redis --net=backend-network redis
docker run --net=backend-network alpine env
docker run --net=backend-network alpine cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

docker run --net=backend-network alpine ping -c1 redis
docker network create frontend-network
docker network connect frontend-network redis
docker run -d -p 3000:3000 --net=frontend-network katacoda/redis-node-docker-example
curl docker:3000

docker network create frontend-network2
docker network connect --alias db frontend-network2 redis
docker run --net=frontend-network2 alpine ping -c1 db










The Kubernetes Book by Nigel Poulton

I have learned much more from "Kubernetes Webinar Series" freely available on youtube. Unless you are a really total beginner, you have already heard/read most of the stuff in this book.

https://en.wikipedia.org/wiki/Kubernetes


https://labs.play-with-k8s.com/

on node1:

kubeadm init --apiserver-advertise-address $(hostname -i)
kubectl version | base64 |tr -d '\n'
kubectl version
kubectl apply -n kube-system -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 |tr -d'\n')"
kubectl apply -f https://k8s.io/docs/user-guide//nginx-app.yaml
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
whoami
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
kubectl
id
cd
cd .kube
ls -ltra
vi config
kubectl get nodes

on node2:

hostname
kubeadm join --token 523042.dd2ec91db1bf45d0 192.168.112.2:6443 --discovery-token-ca-cert-hash sha256:c48cc070ad8759a57293a41598c197a48faba5deb3f1475fd127713b4fc32aeb



Eclipse generate JPA entities from DB

Unfortunately there doesn't seem to exist a tool to generate JPA Entities directly from SQL. Weird!
So you have to start by populating a real schema.

Create a Java project

Configure "Targeted Runtimes" with "Wildfly 11 Runtime"

Configure Project, Facets, and select JPA (ignore the "further configuration available")

Right-click on Project, you should see "JPA Tools", "Generate Entities from tables"



When I was young I was thinking of 2017 as the age of teletransportation and instant cure for all diseases. Instead it's the age of wasting hours for a Maven configuration. I bet the Cro-Magnon were more technologically savvy than the Maven folks.




Kubernetes up and running


https://github.com/kubernetes-up-and-running/examples

Velocity
Declarative, self-healing
Decoupled architectures (APIs and LB) (Pods, LB, namespaces, ingress)



more Docker in Action

docker run -d --volume /var/lib/cassandra/data --name cass-shared alpine echo Data Container

docker run -d --volumes-from cass-shared --name cass1 cassandra:2.2

docker run -it --rm --link cass1:cass cassandra:2.2 cqlsh cass

select * from system.schema_keyspaces where keyspace_name = 'docker_hello_world';

create keyspace docker_hello_world with replication = { 'class' : 'SimpleStrategy', 'replication_factor': 1 };

select * from system.schema_keyspaces where keyspace_name = 'docker_hello_world';

quit

docker stop cass1
docker rm -vf cass1

docker run -d --volumes-from cass-shared --name cass2 cassandra:2.2
docker run -it --rm --link cass2:cass cassandra:2.2 cqlsh cass
select * from system.schema_keyspaces where keyspace_name = 'docker_hello_world';

quit

docker rm -vf cass2 cass-shared

#bind-mount volumes point to a space on the host 


cd 
mkdir example-docs
echo "ciao" > example-docs/index.html

docker run -d --name bmweb -v ~/example-docs:/usr/local/app 80:80 httpd:latest

#enter localhost:80 in your browser, you should see "ciao"

#create a file on the guest system
docker run --rm -v ~/example-docs:/testspace alpine /bin/sh -c 'echo test > /testspace/test'

#this will fail - read only
docker run --rm -v ~/example-docs:/testspace:ro alpine /bin/sh -c 'echo test2 > /testspace/test'

#check how the volume is mounted
docker run --rm -v ~/example-docs/absent:/absent alpine:latest /bin/sh -c 'mount | grep absent'







Openshift Online getting started

Create yourself an Openshift Online account (account creation seems to me a bit buggish)

https://docs.openshift.com/online/getting_started/basic_walkthrough.html

I follow the instructions and create my first mongodb / nodejs Openshift project


I download the CLI https://console.starter-ca-central-1.openshift.com/console/command-line

oc login https://api.starter-ca-central-1.openshift.com --token=4zlxeYZvlO9FdfvcBEEVZpMca-JA5UftBzShxdkGITI

oc project vernetto-example


.\oc.exe status
In project vernetto-example on server https://api.starter-ca-central-1.openshift.com:443

svc/mongodb - 172.30.171.215:27017
  dc/mongodb deploys openshift/mongodb:3.2
    deployment #1 deployed 15 minutes ago - 1 pod

http://nodejs-mongo-persistent-vernetto-example.193b.starter-ca-central-1.openshiftapps.com (svc/nodejs-mongo-persistent)
  dc/nodejs-mongo-persistent deploys istag/nodejs-mongo-persistent:latest <-
    bc/nodejs-mongo-persistent source builds https://github.com/vernetto/nodejs-ex.git on openshift/nodejs:6
    deployment #1 deployed 13 minutes ago - 1 pod

View details with 'oc describe /' or list everything with 'oc get all'.



.\oc.exe config view
apiVersion: v1
clusters:
- cluster:
    api-version: v1
    server: https://api.starter-ca-central-1.openshift.com:443
  name: api-starter-ca-central-1-openshift-com:443
contexts:
- context:
    cluster: api-starter-ca-central-1-openshift-com:443
    namespace: vernetto-example
    user: publicpierre/api-starter-ca-central-1-openshift-com:443
  name: vernetto-example/api-starter-ca-central-1-openshift-com:443/publicpierre
current-context: vernetto-example/api-starter-ca-central-1-openshift-com:443/publicpierre
kind: Config
preferences: {}
users:
- name: publicpierre/api-starter-ca-central-1-openshift-com:443
  user:
    token: 4zlxeYZvlO9FdbvcBEEVZpMca-JA5UftBzShxdkGVTI



.\oc.exe project
Using project "vernetto-example" on server "https://api.starter-ca-central-1.openshift.com:443".




.\oc.exe get svc
NAME                      CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
mongodb                   172.30.171.215           27017/TCP   3h
nodejs-mongo-persistent   172.30.187.89            8080/TCP    3h




The file C:\Users\publi\.kube\config contains the authentication info:

apiVersion: v1
clusters:
- cluster:
    api-version: v1
    server: https://api.starter-ca-central-1.openshift.com:443
  name: api-starter-ca-central-1-openshift-com:443
contexts:
- context:
    cluster: api-starter-ca-central-1-openshift-com:443
    namespace: vernetto-example
    user: publicpierre/api-starter-ca-central-1-openshift-com:443
  name: vernetto-example/api-starter-ca-central-1-openshift-com:443/publicpierre
current-context: vernetto-example/api-starter-ca-central-1-openshift-com:443/publicpierre
kind: Config
preferences: {}
users:
- name: publicpierre/api-starter-ca-central-1-openshift-com:443
  user:
    token: 4zlxeYZvlO9FdbacBEEVqpMca-JA5UftBfShxdkGVTI


with the 4 sections clusters, contexts, current-context, users


.\oc.exe get quota
NAME                          AGE
compute-resources             5h
compute-resources-timebound   5h
object-counts                 5h


.\oc.exe describe quota compute-resources
Name:           compute-resources
Namespace:      vernetto-example
Scopes:         NotTerminating
 * Matches all pods that do not have an active deadline. 
These pods usually include long running pods whose container command is not expected to terminate.
Resource        Used    Hard
--------        ----    ----
limits.cpu      2       2
limits.memory   1Gi     1Gi


.\oc.exe export services
apiVersion: v1
items:
- apiVersion: v1
  kind: Service
  metadata:
    annotations:
      description: Exposes the database server
    creationTimestamp: null
    labels:
      app: nodejs-mongo-persistent
      template: nodejs-mongo-persistent
    name: mongodb
  spec:
    ports:
    - name: mongodb
      port: 27017
      protocol: TCP
      targetPort: 27017
    selector:
      name: mongodb
    sessionAffinity: None
    type: ClusterIP
  status:
    loadBalancer: {}
- apiVersion: v1
  kind: Service
  metadata:
    annotations:
      description: Exposes and load balances the application pods
      service.alpha.openshift.io/dependencies: '[{"name": "mongodb", "kind": "Service"}]'
    creationTimestamp: null
    labels:
      app: nodejs-mongo-persistent
      template: nodejs-mongo-persistent
    name: nodejs-mongo-persistent
  spec:
    ports:
    - name: web
      port: 8080
      protocol: TCP
      targetPort: 8080
    selector:
      name: nodejs-mongo-persistent
    sessionAffinity: None
    type: ClusterIP
  status:
    loadBalancer: {}
kind: List
metadata: {}



to manually start a build:

oc start-build nodejs-mongo-persistent -n vernetto-example






Xml Parsing, tools, strategies and alternatives

JAXB



If you have an xsd, you can generate the @javax.xml.bind.annotation.XmlRootElement annotated Java POJOs with xjc:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/xjc.html
example:
cd D:\pierre\wildfly-11.0.0.CR1\docs\schema

xjc .\wildfly-config_5_0.xsd -d D:\pierre\workspaceneon\PVXmlParser\src\


Here an example to PARSE an xml file https://www.javacodegeeks.com/2013/02/jaxb-tutorial-getting-started.html

Here the https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/Unmarshaller.html

To generate an XSD from existing XML, try http://www.thaiopensource.com/relaxng/trang-manual.html (a bit old tool...)

package org.pierre.jbossconf;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import jboss.domain._5.Server;


public class XmlParser {
 public static void main(String[] args) throws JAXBException {
  JAXBContext jaxbContext = JAXBContext.newInstance(Server.class);
  Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
  File standaloneXmlFile = new File("D:\\pierre\\wildfly-11.0.0.CR1\\standalone\\configuration\\standalone.xml");
  Server server = (Server)jaxbUnmarshaller.unmarshal(standaloneXmlFile);
  server.getProfile().getAny().forEach((item) -> {System.out.println(item);}); 
 }

}



in my case, parsing fails because of missing tokes substitution "Not a number: ${jboss.socket.binding.port-offset:0}"

these variables are present in thee standalone.xml file:
jboss.deployment.scanner.rollback.on.failure
prop.remoting-connector.read.timeout
jboss.home.dir
jboss.bind.address
jboss.bind.address.management
jboss.bind.address
jboss.socket.binding.port-offset
jboss.management.http.port
jboss.management.https.port
jboss.ajp.port
jboss.http.port
jboss.https.port


Spring core tutorial

Although a bit outdated, it goes over the main points https://www.tutorialspoint.com/spring/

I have put the code of each step in https://github.com/vernetto/springdemo , instructions in the readme.md, a separate tag for each step. The class to run is MainApp.



Spring testing

spring-test

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html

spring-boot-test

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

@ContextConfiguration(locations = "/test-db-context.xml")

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.pierre.sourcing.dao, com.pierre.xcoll.dao" />

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@pippo:1521:PLUTO" />
        <property name="username" value="pippouser" />
        <property name="password" value="pippopassword" />
    </bean>

    <bean id="transManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
        <property name="dataSource" ref="dataSource" />
    </bean>

    <context:component-scan base-package="com.pierre.sourcing.dao" />
</beans>



Important annotations

org.springframework.test.annotation.Rollback; indicates whether the transaction for a transactional test method should be rolled back after the test method has completed.

org.springframework.transaction.annotation.Transactional

org.springframework.test.context.ContextConfiguration @ContextConfiguration("/test-config.xml") declares the application context resource locations or the annotated classes that will be used to load the context.

org.springframework.test.context.jdbc.Sql at class level, like in @Sql(scripts = "/preparation-sqls/cleanup-test-data.sql") , to run SQL BEFORE the test execution

org.springframework.test.context.junit4.SpringRunner (@RunWith(SpringRunner.class) )

org.springframework.beans.factory.annotation.Autowired



Docker resource control

systemd-cgls
systemd-cgtop

ls -ltr /sys/fs/cgroup/

https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/


mkdir stress
cd stress/

cat <<EOT >> Dockerfile
FROM fedora:latest
RUN yum -y install stress && yum clean all
ENTRYPOINT ["stress"]
EOT

docker build . -t stress
docker run -d stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 30s
systemd-cgtop


To display the scope of a container:

docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c82c5d0e0a0dac72ce935fd10c49bb0c6f680f009cdce20995b1c731d9698d80 ubuntu "/usr/bin/top -b" 38 hours ago Up 37 hours topdemo

systemctl show docker-c82c5d0e0a0dac72ce935fd10c49bb0c6f680f009cdce20995b1c731d9698d80.scope


TimeoutStopUSec=1min 30s
Result=success
MemoryCurrent=18446744073709551615
TasksCurrent=18446744073709551615
Delegate=no
CPUAccounting=no
CPUShares=18446744073709551615
StartupCPUShares=18446744073709551615
CPUQuotaPerSecUSec=infinity
BlockIOAccounting=no
BlockIOWeight=18446744073709551615
StartupBlockIOWeight=18446744073709551615
MemoryAccounting=no
MemoryLimit=18446744073709551615
DevicePolicy=auto
TasksAccounting=no
TasksMax=18446744073709551615
KillMode=control-group
KillSignal=15
SendSIGKILL=yes
SendSIGHUP=no
Id=docker-c82c5d0e0a0dac72ce935fd10c49bb0c6f680f009cdce20995b1c731d9698d80.scope
Names=docker-c82c5d0e0a0dac72ce935fd10c49bb0c6f680f009cdce20995b1c731d9698d80.scope
Description=docker-c82c5d0e0a0dac72ce935fd10c49bb0c6f680f009cdce20995b1c731d9698d80.scope
LoadState=not-found
ActiveState=inactive
SubState=dead
InactiveExitTimestampMonotonic=0
ActiveEnterTimestampMonotonic=0
ActiveExitTimestampMonotonic=0
InactiveEnterTimestampMonotonic=0
CanStart=yes
CanStop=yes
CanReload=no
CanIsolate=no
StopWhenUnneeded=no
RefuseManualStart=no
RefuseManualStop=no
AllowIsolate=no
DefaultDependencies=yes
OnFailureJobMode=replace
IgnoreOnIsolate=yes
IgnoreOnSnapshot=yes
NeedDaemonReload=no
JobTimeoutUSec=0
JobTimeoutAction=none
ConditionResult=no
AssertResult=no
ConditionTimestampMonotonic=0
AssertTimestampMonotonic=0
LoadError=org.freedesktop.DBus.Error.FileNotFound "No such file or directory"
Transient=no


cat /proc/meminfo

cat /proc/vmstat


#remove all containers with stress image
docker ps -a | awk '{ print $1,$2 }' | grep stress | awk '{print $1 }' | xargs -I {} docker rm {}
#or even better
docker ps -a -q --filter=ancestor=stress | xargs -I {} docker rm {}

dockerd --iptables=false



References

https://www.javacodegeeks.com/minibook/docker-containerization-cookbook

https://fralef.me/docker-and-iptables.html




Thursday, April 5, 2018

primefaces cookbook on wildfly

The book is covering in depth many examples available on the official PF showcase. Don't expect advanced programming techniques, it's purely about implement not-so-common use cases in PF


sample code is here https://github.com/ova2/primefaces-cookbook

git clone git://github.com/ova2/primefaces-cookbook.git
cd primefaces-cookbook
mvn install

copy $MAVEN_REPO/org/primefaces/cookbook/showcase/2.0.0/showcase-2.0.0.war to /opt/wildfly12/standalone/deployments

http://localhost:8180/pf-cookbook/ (or http://localhost:8080/pf-cookbook/ )