Wednesday, 8 August 2018

Enabling remote (out of container) jms client connection to JBoss 8.2 with embedded HornetQ 2.4.5

Enable your messaging subsystem by using the standalone-full.xml configuration file that is already provided in the installation.

Launch your Widlfy container by pointing to your standalone-full.xml, instead of standalone.xml configuration file :

       
standalone.bat -c=standalone-full.xml


Call the  [your-jboss-installation-directory]/bin/add-user command, add an application user guest with the role of guest :

       
C:\work\development\jboss-as-7.1.0.Final\bin>add-user.bat
Picked up _JAVA_OPTIONS: -Duser.home=C:\Users\dubduan

What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): b

Enter the details of the new user to add.
Using realm 'ApplicationRealm' as discovered from the existing property files.
Username : guest
Password recommendations are listed below. To modify these restrictions edit th
 add-user.properties configuration file.
 - The password should not be one of the following restricted values {root, adm
n, administrator}
 - The password should contain at least 8 characters, 1 alphabetic character(s)
 1 digit(s), 1 non-alphanumeric symbol(s)
 - The password should be different from the username
Password :
JBAS015266: Password must have at least 1 digit.
Are you sure you want to use the password entered yes/no? yes
Re-enter Password :
What groups do you want this user to belong to? (Please enter a comma separated
list, or leave blank for none)[  ]: guest
About to add user 'guest1' for realm 'ApplicationRealm'
Is this correct yes/no? yes
Added user 'guest1' to file 'C:\work\applications\wildfly-8.2.0.Final\standalon
\configuration\application-users.properties'
Added user 'guest1' to file 'C:\work\applications\wildfly-8.2.0.Final\domain\co
figuration\application-users.properties'
Added user 'guest1' with groups guest to file 'C:\work\applications\wildfly-8.2
0.Final\standalone\configuration\application-roles.properties'
Added user 'guest1' with groups guest to file 'C:\work\applications\wildfly-8.2
0.Final\domain\configuration\application-roles.properties'
Is this new user going to be used for one AS process to connect to another AS p
ocess?
e.g. for a slave host controller connecting to the master or for a Remoting con
ection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition ret value="cGFzc3dvcmQ=" />
Press any key to continue . . .





Edit the file [your-jboss-installation-directory]/standalone/configuration/standalone-full.xml, disable security by adding the security-enabled tag :

       


<subsystem xmlns="urn:jboss:domain:messaging:1.1">

<hornetq-server>

<security-enabled>false</security-enabled>

.

.

.

<subsystem>



Make sure to export both your factory and your queue. For example in this case the exported factory is jms/RemoteConnectionFactory. The exported factory is already provided by default, however the an exported default queue is not. Create jms/queue/test queue:



<subsystem xmlns="urn:jboss:domain:messaging:1.1">

<hornetq-server>

.

.

.

   <jms-connection-factories>
.

.

.

   <connection-factory name="RemoteConnectionFactory">
                       <connectors>
                           <connector-ref connector-name="http-connector"/>
                        </connectors>
                       <entries>
                           <entry name="RemoteConnectionFactory"/>
                           <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                        </entries>
                    </connection-factory>
   </jms-connection-factories>
   <jms-destinations>
          <jms-queue name="testQueue">
                        <entry name="queue/test"/>
                        <entry name="java:jboss/exported/jms/queue/test"/>
          </jms-queue>
   </jms-destinations>

.

.

.

<subsystem>

Here are JMS connection attributes required for connection above (queue name, user, and password are yours to put):

       
initialContextFactory =  org.jboss.naming.remote.client.InitialContextFactory
url =  http-remoting://localhost:8080
connectionFactory = jms/RemoteConnectionFactory
queue.jndiQueuName = jms/queue/test
user = guest
password = password

Tuesday, 7 August 2018

Enabling remote (out of container) jms client connection to JBoss 7.1 with embedded HornetQ 2.2.11

Enable your messaging subsystem by using the standalone-full.xml configuration file that is already provided in the installation.

Go to [your-jboss-installation-directory]/bin/standalone.conf(.bat for windows). Set the following attribute to point to your standalone-full.xml, instead of standalone.xml configuration file :

       
set "JAVA_OPTS=%JAVA_OPTS% -Djboss.server.default.config=standalone-full.xml"


Call the  [your-jboss-installation-directory]/bin/add-user command, add an application user with the role of guest :

       
C:\work\development\jboss-as-7.1.0.Final\bin>add-user.bat
Picked up _JAVA_OPTIONS: -Duser.home=C:\Users\dubduan

What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a):b



Enter the details of the new user to add.
Realm (ApplicationRealm) :
Username : guest
Password :
Re-enter Password :
What roles do you want this user to belong to? (Please enter a comma separated l
ist, or leave blank for none) : guest
About to add user 'guest' for realm 'ApplicationRealm'
Is this correct yes/no? yes
Added user 'guest' to file 'C:\work\development\jboss-as-7.1.0.Final\standalone\
configuration\application-users.properties'
Added user 'guest' to file 'C:\work\development\jboss-as-7.1.0.Final\domain\conf
iguration\application-users.properties'
Added user 'guest' with roles guest to file 'C:\work\development\jboss-as-7.1.0.
Final\standalone\configuration\application-roles.properties'
Added user 'guest' with roles guest to file 'C:\work\development\jboss-as-7.1.0.
Final\domain\configuration\application-roles.properties'
Press any key to continue . . .






Edit the file [your-jboss-installation-directory]/standalone/configuration/standalone-full.xml, disable security by adding the security-enabled tag :

       


<subsystem xmlns="urn:jboss:domain:messaging:1.1">

<hornetq-server>

<security-enabled>false</security-enabled>

.

.

.

<subsystem>



Make sure to export both your factory and your queue. For example in this case the exported factory is jms/RemoteConnectionFactory, and the exported queue is jms/queue/test:



<subsystem xmlns="urn:jboss:domain:messaging:1.1">

<hornetq-server>

.

.

.

   <jms-connection-factories>
.

.

.

   <connection-factory name="RemoteConnectionFactory">
                       <connectors>
                           <connector-ref connector-name="netty"/>
                        </connectors>
                       <entries>
                           <entry name="RemoteConnectionFactory"/>
                           <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                        </entries>
                    </connection-factory>
   </jms-connection-factories>
   <jms-destinations>
          <jms-queue name="testQueue">
                        <entry name="queue/test"/>
                        <entry name="java:jboss/exported/jms/queue/test"/>
          </jms-queue>
   </jms-destinations>

.

.

.

<subsystem>

Here are the JMS connection attributes required for connection above (queue name, user, and password are yours to put):

       
initialContextFactory =  org.jboss.naming.remote.client.InitialContextFactory
url =  remote://localhost:4447
connectionFactory = jms/RemoteConnectionFactory
queue.jndiQueuName = jms/queue/test
user = guest
password = password

Friday, 6 July 2018

Building Docker intuition

This short tutorial is not meant to train the reader on known docker commands, but rather to inculcate in reader's mind a meaninful intuition to get around known Docker misconceptions. When dealing with docker, we are probably referring to the Docker daemon, but when we are using it, we are actually using a Docker client. Yet, I have seen that many users are anaware that there are these two parties in play here, a client (command line proxying REST json calls), and a server (docker daemon). This confusion is strengthened by the fact that both parties most likely reside on the same machine. 

We will go through three phases :

1. Check if your linux host is up
2. Client calibration
3. Understand where you are? Are you aware where you are operating? Are you inside the docker container or the host? (a dreamer inside a dream).







 

                                                                  (Figure 1)

If you a pre Hyper-V Windows machine, know that you would need to bring up your linux kernel through a VirtualBox image (pre-Windows 2010), otherwise you can rely on the Hyper-V service.The Hyper-V service will launch your linux image without any hustle. This tutorial is based on the virtual box and the default boot2docker distribution that comes with it. Remember your Docker daemon is installed on that boot2docker linux installation.

Steps for launching your image:

1. Check if your linux host is up:

run : 

       
docker-machine ls


2.  Client calibration : I prefer to call this phase client calibration. Why? Well, your docker command line client does not know to which Docker daemon to point to. You are aware that you have to communicate with the daemon to get your commands through, right? The way to do that is to find what are the connection coordinates of your daemon. You could also communicate with a docker daemon residing on different machine on your network.

Run:

       
docker-machine env


 It will spit out something like:

       

SET DOCKER_TLS_VERIFY=1

SET DOCKER_HOST=tcp://192.168.99.100:2376

SET DOCKER_CERT_PATH=C:\Users\myuser\.docker\machine\machines\

SET DOCKER_MACHINE_NAME=default

SET COMPOSE_CONVERT_WINDOWS_PATHS=true

REM Run this command to configure your shell:

REM     @FOR /f "tokens=*" %i IN ('docker-machine env') DO @%i


Play it safe by avoiding proxy issues: 

As you can see your daemon is identified by an ip address 192.168.99.100. What could happen is that if you are behind a proxy, the requests to your daemon will hit the proxy, but the proxy is anaware of your newly issued ip address. This ip is created ad-hoc locally only on your machine. Hence, you need a way to bypass the proxy when issuing requests to a host located on your own machine.

Run:

docker-machine env --no-proxy

       
SET DOCKER_TLS_VERIFY=1

SET DOCKER_HOST=tcp://192.168.99.100:2376

SET DOCKER_CERT_PATH=C:\Users\myuser\.docker\machine\machines\default

SET DOCKER_MACHINE_NAME=default

SET COMPOSE_CONVERT_WINDOWS_PATHS=true

SET no_proxy=192.168.99.100, .eu.int

REM Run this command to configure your shell:

REM     @FOR /f "tokens=*" %i IN ('docker-machine env --no-proxy') DO @%i


To point your Docker client to your Docker daemon, run the last line of the previous listing, but without the REM comment sign:


@FOR /f "tokens=*" %i IN ('docker-machine env --no-proxy') DO @%i


Now that you are pointing to the right daemon, let's see what containers are instantiated in the Docker daemon. Being in instantiated, doesn't necessarily mean they are also running, they could well be in EXITED state. Be aware that a docker container follows a state lifecycle.

Run :


docker ps -a  

To show you the locally available images:


docker image ls 




                                                             (Figure 2)


3. Understand where you are? Are you aware where you are operating? Are you inside the docker container, the host, or on the docker client? (a dreamer inside a dream).

I have noticed that it is very easy for a Docker user to get confused on what is his exact role and what is he supposed to do and act on.

For a starter, let's log into the host box and snoop around:

docker-machine ssh

You probably ask yourself how come you have just logged gracefully to the machine with no credentials. Well the work has been done on your behalf, you have the private key available under your DOCKER_CERT_PATH (see above when executing docker-machine env )

You will be able now to see the Docker daemon in a listening state on port 2376.



netstat -nat | grep LISTEN

Let's review the process signals and why they are important.

If you are not a linux savvy user, you probably do not know that you can pass to your linux process three signals, Ctrl-C (SIGINT), Ctrl-\ (SIGQUIT), and Ctrl-Z (SIGSTP). Now the docker architecture allows you to access this linux feature when running your docker instance. You have probably stumbled on the already frequent -i  and -t switches when running a docker run command. What do they mean. The -i switch means you are gaining access to standard input of the remote docker process. Yet, you cannot push any data unless you have a console available to your client docker, that's where the -t comes into play. Let's experiment this:

Experiment 1 : standard input available but nothing being heard in your docker instance

Run :

docker run -i tomcat:latest

While your tomcat standard output console will start flooding, try to launch the keyboard combination - Ctrl C. The process was interrupted, but did it really reach the remote process?

Run :

docker ps -a

You will see the following:

CONTAINER ID   IMAGE            COMMAND              CREATED        STATUS           
d154269f742a   tomcat:latest    "catalina.sh run"    1 minute ago   Up 1 minute

As you can see, the docker instance did not pick up on this signal, it is still up.

Experiment 2 : standard input available, signal does go trough to your docker instance

Run :

docker run -it tomcat:latest

While your tomcat standard output console will start flooding, try to launch the keyboard combination - Ctrl C. The process was interrupted, but did it really reach the remote process?

Run :

docker ps -a

You will see the following:

CONTAINER ID   IMAGE            COMMAND              CREATED        STATUS           
d154269f742a   tomcat:latest    "catalina.sh run"    1 minute ago   Exited    

In this case, the docker instance did receive the signal, subsequently got interrupted, and an exit status showed up.


Here is a breakup of the decision tree of the signals (figure 3).




(Figure 3)


If you launch your instance in the background and still want to gain access to the STDOUT, you can use :


docker logs -f instance-name


Now that we are done with the signals overview, let's move on to another topic, the physical changes that your image goes through, the so called "layering" process.

How about the changes made to your container and image. If you are eager to inspect the commands that led your image its last saved state, run :


docker history image-id

To render prettier the history listing:

docker history --no-trunc image-id  | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n  & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*[kMG]*B\s*$,,g' | head -n -1


Docker client - Docker instance interaction

Now let's showcase a command that runs involves the docker client side. Here is the copy command. You can either copy a file from the container to your local client machine



docker cp [container]:/pathtofile localpathtofile 

or vice-versa:


docker cp localpathflie [container]:/pathtofile


Now let's provide an example of a command that bridges between the host and the daemon. Typically we would like to get two things from our docker daemon : communication access to our new service, and file system access, right?

In this example, we would like to mount a volume for an instance of Tomcat and share it. We would also like to access the docker instance port, namely, the regular Tomcat port 8080. We will create a corresponding linux host port on port 8888. Remember we cannot reach the docker instance when we are acting as a docker client. We can only reach the linux host, that's why we are making these two services available to the linux host.

As for sharing a common directory, make sure to create on your linux host a directory named - /home/hostVolume. In case you are launching a VirtualBox boot2docker image, there is an additional step, you will have to also mount a local directory on your Windows machine by adding an entry in:


VirtualBox->Your boot2docker image->Settings->Shared Folders->Adds new shared folder


Now, place some files inside.  Run the following command which will bridge between the ports and also share the file directories in one go:

docker run -it -d -v /home/hostVolume:/home/dockerVolume --publish 8888:8080 --name tomcatInstance tomcat:latest 


Now let's test our shared file directory. You are going to tap into your docker instance by typing into your shell:


docker exec -it tomcatInstance bash
cd /home/dockerVolume

Monday, 2 July 2018

JMS Client tool to easily post messages to ActiveMQ, HornetQ or Weblogic. Could be used for testing

Setting up a jms client can be a little tricky when put into practice.

I will try to summarize the properties and jar libraries needed for ActiveMQ, Hornetq (embedded in Jboss 7.1 and Wildfly 8.2) and Weblogic:

Activemq

       
initialContextFactory =  org.apache.activemq.jndi.ActiveMQInitialContextFactory
url =  tcp://localhost:61616
connectionFactory,ConnectionFactory
queue.jndiQueuName = brokerQueueName
user =
password =

Jboss 7.1 - HornetQ 2.2.11


       
initialContextFactory =  org.jboss.naming.remote.client.InitialContextFactory
url =  remote://localhost:4447
connectionFactory = jms/RemoteConnectionFactory
queue.jndiQueuName = brokerQueueName
user = 
password =



Wildfly 8.2 - HornetQ 2.4.5


       
initialContextFactory =  org.jboss.naming.remote.client.InitialContextFactory
url =  http-remoting://localhost:8080
connectionFactory = jms/RemoteConnectionFactory
queue.jndiQueuName = brokerQueueName
user = 
password =


Weblogic

       
initialContextFactory =  weblogic.jndi.WLInitialContextFactory
url =  t3://localhost:7001
connectionFactory = ConnectionFactory
queue.jndiQueuName = brokerQueueName
user =
password =


Running the application:


If you intend to post your messages with no hustle just by providing a connection file, a header properties file and a payload that you can edit freely. You can use this tool to script JMS posting in your tests.


       

git clone https://github.com/duband/JMSPoster.git

cd JMSPoster

mvn clean install

mvn com.github.duband:jmsposter:[version]:install -DinstallationDirectory=[your installation directory] -DtargetBrokerType=[activemq|weblogic|hornetq-jboss7.1|hornetq-wildfly8.2]
cd [your installation directory]

postMsg.bat



Friday, 22 June 2018

Dynamic programming applied on the Ant Stack problem from Google Jam Code 2018

You are probably overviewing a problem that are is polynomial non-deterministic and you heard that it is possible to solve a subset of its instances by using pseudo-polynomial technique. Yes, this technique is dynamic programming and how you get to master this technique is a matter of pure intuition.

I will try exemplify what I mean by providing a sample problem from the Google Code Jam 2018, Round 1C 2018, Written by Pablo Heiber and pprepared by Kevin Tran.


The problem description:

Scott has an ant farm containing N ants. Each ant has a certain length and weight.
Today, as a challenge for the ants, Scott has placed some food at the top of the ant farm. The ants will try to reach it by arranging themselves into a vertical stack, with each ant in the stack directly holding the next on its back. In this way, each ant bears the weight of all ants above it. Scott's ants are very strong for their size and are able to carry up to 6 times their own weight. For example, an ant that weights 8 milligrams can carry two other ants weighing 24 milligrams each! Each ant also has a body length; the exact lengths are not important, except that they are all different.
  • The stack must be linear. Each ant except for the top ant must be directly below exactly one ant, and each ant except for the bottom ant must be directly above exactly one ant.
  • The lengths of the ants in the stack must be strictly decreasing from the bottom to the top of the stack; this ensures that each new ant that joins the stack will be able to climb up to the top.
  • For each ant, the sum of the weights of all the ants above it in the stack must be no more than 6 times the weight of that ant.

What is the maximum number of these ants that can form such a stack?

Input

The first line of the input gives the number of test cases, TT test cases follow. Each begins with one line with an integer N: the number of ants in the colony. Then, a second line follows containing N integers W1,W2, ..., WN, where Wi is the weight in milligrams of the i-th ant. The ants are listed in strictly increasing order of length. Notice that no actual length values are given; only the order is important.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum number of the given ants that can form a stack that obeys the rules above.

Limits

7 ≤ T ≤ 100.
Time limit: 15 seconds per test set.
Memory limit: 1GB.

Test set 1 (Visible)

For exactly 6 cases, N = 100; for the other T - 6 cases, 2 ≤ N ≤ 50.
1 ≤ Wi ≤ 1000, for all i.

Test set 2 (Hidden)

For exactly 6 cases, N = 105; for the other T - 6 cases, 2 ≤ N ≤ 500.
1 ≤ Wi ≤ 109, for all i.

So how did I solve it?

First, let's recall the pipe of steps involved in building a dynamic programming solution, namely:

  1. Recursion
  2. Memoization
  3. Bottom-up


Recursion

This problem reminds us of the knapsack 0-1 problem whose dynamic programming solution is laid out as a decision tree. Similarily we try to establish a decision tree for this problem. At each node encoded as state [n,w] , we need to establish the appropiate weight and the value of the node which will represent the maximum number of ants up to this node.

We start with the maximal supported weight among all ants. For each child node, we apply the following logic :

pseudocode:       

we compare the current ant weight to the current supported weight 

If we cannot support the current ant

        then we go one ant downwards

else

        we calculate a potential new weight as  min(6 * ants[i - 1], supported weight - ants[i - 1]);

        node [i][w] = max(1 + node[i - 1][new weight], node[i - 1][supported weight]);

end else



We have n levels in our decision tree with 3 nodes children on each node. The complexity of this algorithm goes to 3n  time units. Under a large n this algorithm will not finish, hence we need to find another way to span our state space.











Here is the solution:

import java.io.*;
import java.util.*;

/** 
 Copyright belongs to Dub Andrei-Manuel. 
 Please refer this author to any reference 

**/

public class Solution {

    static boolean logTime = false;

    public static Map getLadder() {
        Map map = new HashMap();
        long top = (long) Math.pow(10, 9);
        long load = 0;
        long weight = 1;
        int ants = 1;
        while (weight < top) {
            if (load <= (6 * weight)) {
                load += weight;
                map.put(ants, weight);
                    System.out.println(ants+" : "+
                            weight);
                ants++;
            } else {
                weight++;
            }
        }
        return map;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        int t = in.nextInt();
        for (int i = 1; i <= t; ++i) {

            int antsNr = in.nextInt();
            long[] ants = new long[antsNr];

            for (int j = 0; j < antsNr; j++) {
                int weight = in.nextInt();
                ants[j] = weight;
            }


            long start = System.currentTimeMillis();

            int maxAnts2 = solutionDP2(ants);

            long end = System.currentTimeMillis();

            System.out.println("Case #" + i + ": " + maxAnts2);

            if (logTime)
                System.out.println(end - start);

        }
    }


    public static long getMaxWeight(long[] ants) {
        long max = 0l;
        for (long weight : ants) {
            if (weight > max)
                max = weight;
        }
        return max;
    }


    public static int solutionDP2(long[] ants) {
        int max = searchDP2(ants, ants.length);
        return max;
    }

    public static int solutionDP(long[] ants) {
        long capacity = getMaxWeight(ants) * 7;
        int max = searchDP(ants, ants.length, capacity);
        return max;
    }




    public static int searchDP2(long[] ants, int n) {
        int max = 0;

        int k = 139;
        long[][] g = new long[n + 1][k + 1];

        for (int x = 0; x <= n; x++) {
            for (int y = 0; y <= k; y++) {
                if (y > x) {
                    g[x][y] = Long.MAX_VALUE;
                } else if (x == 0 || y == 0) {
                    g[x][y] = 0;
                } else if (x == 1 && y == 1) {
                    g[x][y] = ants[x - 1];
                } else {

                    if (g[x - 1][y - 1] > 6 * ants[x - 1]) {
                        g[x][y] = g[x - 1][y];
                    } else {
                        g[x][y] = Math.min(g[x - 1][y - 1] + ants[x - 1], g[x - 1][y]);
                    }

                }

            }


        }



        for (int y = 0; y <= k; y++) {
            if (y > max && g[n][y] < Long.MAX_VALUE) {
                max = y;
            }
        }

        return max;
    }


    public static int searchDP(long[] ants, int n, long availableCapacity) {

        int[][] K = new int[n + 1][((int) availableCapacity) + 1];

        for (int i = 0; i <= n; i++) {
            for (int w = 0; w <= availableCapacity; w++) {
                if (i == 0 || w == 0) {
                    K[i][w] = 0;
                } else {

                    long potentialCapacity = Math.min(6 * ants[i - 1], w - ants[i - 1]);

                    if (ants[i - 1] > w)
                        K[i][w] = K[i - 1][w];
                    else                        
                       K[i][w] = Math.max(1 + K[i - 1][(int) potentialCapacity], K[i - 1][w]);

                }

            }


        }

        return K[n][(int) availableCapacity];
    }




}




Monday, 18 June 2018

If you are getting Invalid UTF-8 middle/second byte or other parsing errors within your JVM, just know


that  :

"The default charset is determined during virtual-machine startup and typically depends upon the locale and charset being used by the underlying operating system."

This is an official excerpt from  :



Other sources that just relate to how to determine or set it up:



Now, how do you know what character set is your JVM defaulting to?

In debug, try to execute the following command:

java.nio.charset.Charset.defaultCharset()

You will get one of the charset listed here (most popular being  iso-8859-1):


To make sure you have a broad encoding character set, solve this issue by overriding your system charset by starting the jvm with this option:


-Dfile.encoding=UTF-8


Familiar exceptions :

       


com.fasterxml.jackson.core.JsonParseException:



com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 middle byte 0x... 

About Me

My Photo