środa, 13 maja 2015

Web service in Mule 3.6 (producer)

I wouldn't call it a tutorial. This "article" depicts my first attempt to produce a web service using Mule 3.6. Probably (well, for sure) there is a better, more efficient approach, but this one works and for my purposes is sufficient. In next part, I'll show how to consume it.

We will start with WSDL file. I prefer contract first apporach, therefore in the very first step I have prepared WSDL contract.


Now, lets start Mule with a new project - I have called mine "SimpleWS". Nothing special to be set, just use default options. After project and its structure is created, copy hasher.wsdl to src/main/api:


First, we have to define HTTP connector and its configuration. By simply dragging HTTP icon from toolbox (?) we will create a new flow (assuming that there has been no flow yet):

Now configuration. Click on HTTP connector and in its General properties, General Settings tab, add new Connector Configuration:


First - give it a moreless meaningful name, then define a port that will be used by this connector. Next, in Basic Settings > Path enter the path to your WS:


It's high time we created a web service. Mule documentation encourages to use CXF component, so let it be:

CXF component requires a bit more effort to configure it. At the beginning add new CXF configuration (General > Generic> Config Reference). I personally don't find it necessary to change anything, default values are ok.
Next we choose the purpose of this component (General > Generic > Operation). In this case you should choose  "JAX-WS service".
Since we are applying contract-first apporach, we can now choose a WSDL file and generate java classes for our service:


In dialog window, enter a path to WSDL file and a package for java classes that will be generated from definition file:

After confirmation, you can see that a Service Class has been chosen automagically (in fact this is an interface, but that is not relevant at this momemnt).
We could run our application now, and call a service,  but we would end up with an error:

org.apache.cxf.interceptor.Fault: Marshalling Error: Instance of "pl.edu.pwr.isi.hasher.HashRequest" is substituting "pl.edu.pwr.isi.hasher.HashResponse"

Why did it happen? Well, after http request reaches HTTP connector it's being transformed and send to CXF component, which performs its magic, and in the end we have a payload set to an instance of a HashRequest class . Payload is not being changed and is treated as a response, which should be a HashResponse object (and that's the reason for substitution issue)

We should handle somehow this request and prepare a response. 
I have chosen a Spring bean for that purpose :)

In your first window choose "Global Elements" and create a new bean: (Beans > Bean):

We have to provide a bean definition (and add a new class implementing HashPort interface):


The only thing left is to call our newly defined bean. Add an Expression component to our flow:

and enter proper expression for this component:

payload = app.registry['requestHandler'].handleRequest(payload);

And that's all... What is happening in our flow?
  • ws client calls our service - HTTP connector receives the request and forwards it to CXF component
  • CXF analyses request and based on which operation is called, transforms request data into proper java object, which becomes now the payload in the flow
  • Expression component calls a method handleRequest with a payload as its parameter. Thanks to method overloading we can have one expression that could handle all possible operations.
  • Bean "requestHandler" creates a proper response object, which becomes now the payload in the flow.
  • CXF takes a response object and transforms it into a response data that are being sent back to client
If you don't know how to call this web service - use SoapUI. Create a new SOAP project, with WSDL at this location: http://localhost:8888/ws/hasher?wsdl. 

Whole project is here.

wtorek, 5 sierpnia 2014

Matrix editor

[Under construction]

Description soon... Working functionality first ;)




Rows:
Columns:





piątek, 1 sierpnia 2014

Soon

And now... Some pictures as a teaser of upcoming post :)





What will that be?
[Date reedited :) Project restarted. ]


wtorek, 17 września 2013

How to disable annoying java updates.

I use java. Every day. I know precisely what version I should use for given task, therefore I do mind being notified about "There is an update availabe. Would you....? "
NO. I would not :)

To disable this annoying feature on windows 7 (probably on every windows) you have to:
* run console as administrator
* run file C:\Program Files (x86)\Java\jre6\bin\javacpl.exe
* disable updated :)

Or you could run the file directly as an administrator, but using console is more natural to me :)

And that's all.

poniedziałek, 2 września 2013

SQL Developer and the User-Related Information Location

Sql Developer generates a lot of data stored by default in home directory. Usually it is not a problem, but if you have a quota on your directory, well... Fortunatelly there is a way to change the location of user related data: http://docs.oracle.com/cd/E18464_01/doc.30/e17472/intro.htm#CIHFCGCD
The only thing that must be done is to define IDE_USER_DIR environment variable.
But!
Before doing that you should copy already existing data to new directory, or at least export your connections :)


wtorek, 16 kwietnia 2013

RPi - Running services at boot

I wanted to start a few services while my Rasperry Pi is booting. Since my days as linux "administrator" are gone, I needed to do some research how to achieve that.

Services to be started: H2 database server, serial port listening service, tomcat - in that order.

Naturally, all applications have been installed.
First step - prepare script files:

/etc/init.d/h2 file:
#!/bin/bash

### BEGIN INIT INFO
# Provides:          h2
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: h2 database
# Description:       h2 database
### END INIT INFO


test -f /lib/lsb/init-functions || exit 1
. /lib/lsb/init-functions

H2_HOME=/opt/h2
DAEMON=h2server
ARGS=


#PID=$(get_pid $DAEMON)

case "$1" in
 start)
  log_begin_msg "Starting h2 database"
   $H2_HOME/bin/$DAEMON $ARGS & #>/dev/null
   log_end_msg 0
   ;;
 stop)
   log_begin_msg "Stopping $DAEMON"
   kill `ps aux | awk '/h2.*jar/{print $2}'` > /dev/null
   ;;
 restart)
   $0 stop
   sleep 1
   $0 start
   ;;
 *)
   echo "usage: $0 {start|stop|restart}"  
esac


/etc/init.d/rxreader file:
#!/bin/bash

### BEGIN INIT INFO
# Provides:          rxreader
# Required-Start: $tomcat
# Required-Stop: $tomcat
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: rxreader
# Description:       rxreader
### END INIT INFO


test -f /lib/lsb/init-functions || exit 1
. /lib/lsb/init-functions

RXRD_HOME=/opt/rxreader
DAEMON=read
ARGS=


case "$1" in
 start)
  log_begin_msg "Starting h2 database"
   #[ -z "$PID" ] && 
   $RXRD_HOME/bin/$DAEMON $ARGS & #>/dev/null
   log_end_msg 0
   ;;
 stop)
   log_begin_msg "Stopping $DAEMON"
   kill `ps aux | awk '/rxreader/{print $2}'` > /dev/null
   ;;
 restart)
   $0 stop
   sleep 1
   $0 start
   ;;
 *)
   echo "usage: $0 {start|stop|restart}"  
esac

/etc/init.d/tomcat file:
#!/bin/bash

### BEGIN INIT INFO
# Provides:          tomcat
# Required-Start: $h2
# Required-Stop: $h2
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: tomcat
# Description:       tomcat
### END INIT INFO


test -f /lib/lsb/init-functions || exit 1
. /lib/lsb/init-functions

TOMCAT_HOME=/opt/apache-tomcat-7
DAEMON=startup.sh
ARGS=


case "$1" in
 start)
  log_begin_msg "Starting apache tomcat"
   $TOMCAT_HOME/bin/$DAEMON $ARGS & #>/dev/null
   log_end_msg 0
   ;;
 stop)
   log_begin_msg "Stopping $DAEMON"
   $TOMCAT_HOME/bin/shutdown.sh
   ;;
 restart)
   $0 stop
   sleep 1
   $0 start
   ;;
 *)
   echo "usage: $0 {start|stop|restart}"  
esac

When file are in /etc/init.d directory we have to run update-rc command, which installs (or removes) System-V style init script links:
sudo update-rc.d h2 defaults
sudo update-rc.d tomcat defaults
sudo update-rc.d rxreader defaults

Now you can restart RPi or start services manually:
sudo service h2 start
sudo service rxreader start
sudo service tomcat start

wtorek, 22 stycznia 2013

Java and RPi - continued


After I had installed both jdk (open and oracle's), I started wondering what is the difference between them, when it comes to performance. Recently I found some time in the evening and wrote simple tests, which are not very accurate, but give the general notion about performance.

Let's take a look into tests:
ArrayListAppendTest
List<Long> list = new ArrayList<Long>();
for (long l = 0; l <1000000; l++) {
   list.add(l);
}

ArrayListInsertMiddleTest
List<Long> list = new ArrayList<Long>();
for (long l = 0; l < 1000; l++) {
   list.add(l);
}
for (long l = 0; l < 10000; l++) {
   list.add(500, l);
} 

ArrayListSortTest
List list = new ArrayList();
for (int i = 100000; i > 0; i--) {
   String str = String.format("String nr %5s", i);
   list.add(str);
}
Collections.sort(list);

LinkedListAppendTest, LinkedListInsertMiddleTest, LinkedListSortTest are exactly the same as for ArrayList, but with subtle change...

DoubleAddTest
double val = 0.0;
for (int i = 0; i< 1000000; i++) {
   val += (double) i;
}

SinusTest
for(int i = 0; i < 1000000; i++) {
   double val = Math.sin((double) i);
}

StringAppendTest
String [] strings = new String[1000];
for (int i = 0; i < strings.length; i++) {
   strings[i] = String.format("Str %d", i);
}
String concat = "";
for (int i = 0; i < strings.length; i++) {
   concat += strings[i];
}

All tests *ISTest use various input streams, *OSTest - output streams.

When it comes to reflection tests, I tried to instantiate class using classe's newInstance method, in case of CallMethod test I'm calling one argument method using reflection. Simple...

For comparison I executed test on my ancient computer (Amd64 3500+). After that I compiled and run tests on Raspberry Pi using proper JDK.

And the resulst are... interesting (execution time is in ms):

Test nameJDK Oracle 1.7 @ AMD64 3500Oracle JDK 1.8 ea @ RPiOpen JDK 1.7 @ RPiRatio
ArrayListAppendTest 348,6 2632 10965,1 4,2
ArrayListInsertMiddleTest 72,6 285,7 1024,7 3,6
ArrayListSortTest 19,6 292,9 2394,4 8,2
BufferedFileOS 12,2 45,4 856,4 18,9
DoubleAddTest 0,2 35,8 390,5 10,9
FileISTest 25,3 183,8 231,5 1,3
FileOSTest 96,8 524,9 1618,9 3,1
LinkedListAppendTest 636,1 3393,7 16634,3 4,9
LinkedListInsertMiddleTest 23,3 99,5 2159 21,7
LinkedListSortTest 44,8 270,9 2225,9 8,2
ReflectionCallMethodTest 116,3 803,2 3496,7 4,4
ReflectionNewInstanceTest 55,5 202,5 542,4 2,7
SinusTest 268,6 562,5 3722 6,6
StringAppendTest 49,3 254,4 489,1 1,9

As you can see Open JDK in those test is far behind oracle's (in column Ratio you can see, how much slower Open JDK was :/).
I think I stick to JDK 1.8 ea...