вторник, 19 февраля 2013 г.

Apache CXF integration testing

Sometimes it is necessary to make the test of web-service client and service.
If you have an Apache CXF service and client then you can try to use local transport for your test.
So, here is an example.

The client you define like this:
 <jaxws:client id="client" serviceClass="IIdentificationService"  address="local://test"/>.

And here is how you test the integration:

IIdentificationServiceImpl impl = new IIdentificationServiceImpl();
Endpoint ep = Endpoint.publish("local://test", impl);
IIdentificationService client = (IIdentificationService) context.getBean("client");
Result res = client.call("123");
ep.stop();


What is important here is the address of endpoint and client. Both uses the prefix "local". This means that messages will transport inside the JVM.
For reference see http://cxf.apache.org/docs/local-transport.html.

четверг, 14 февраля 2013 г.

Challenges in WS development


1) Work with large and user base.
Solution:
Audit & monitoring.
Multifactor authentication.

2) Long life cycle.
Solution:
Choose solution based on industry standards.

3) Robustness.
Solution:
Architect the solution that will work even if some of it components will go down.

4) Manageability.
Solution:
Take care at monitoring, backup, upgrade.

 5) Integration with legacy applications.
Solution:
Look for interface of other applications.

WS stack technologies review

Recently I started to invest time in learning of web services.
I have learnt the basics of WSDL 1.1.
Now I'm trying to understand other aspects of WS. Where are a lot of WS-* technologies. Some of them are obsolete, some are not supported. So the aim of this post is to understand the widely adopted specifications and the possible use cases for them.

воскресенье, 10 февраля 2013 г.

Ajax and ActiveMQ

Sometimes you need to notify users (browsers) about some events occurred on the server side. For example someone has added the row into the table and you need to be notified about it.
Also the client could be not just the browser but any program component. And this components can be dynamically connected and disconnected.
The solution could be the message queue and publish subscribe pattern.
 After some research I managed to work the solution based of ActiveMQ 5.7.0 and Apache Tomcat 6.0.35. Here is how I did it.

пятница, 8 февраля 2013 г.

JStree AJAX lazy loading and submitting of selected nodes to server

Sometimes your need to work with trees.
After some time of research I could find 2 implementations of javascript trees: jsTree (http://www.jstree.com/) and Dynatree (http://code.google.com/p/dynatree/).

I could only try jsTree because of limited time.
So, here are my requirements:
1) lazy loading of selected nodes. It's because tree size can be quite big. And store all the tree is unnecessary.
2) one can choose any number of nodes and submit selected nodes of the tree to server.

четверг, 24 января 2013 г.

Thoughts after reading "Practical TDD and Acceptance TDD for developers"

TDD for web applications

After reading the book «Practical TDD and Acceptance TDD fot developers» I decided to write some thoughts about testing.

TDD Steps

  1. Write the Test.
  2. Write the code that will pass the test.
  3. Refactor the test and the code. Watch carefully what dependencies can be eliminated or restructed.
The real question is how to write code that can be tested? Not how to test the written code. If code can't be tested — nobody needs such code.

Therefore when writing the code one should rely on the technical solutions that allow you to test the code.

Testing servlets

There is no universal solution to testing the servlets.

The main obstacle — how to make servlet that it could support dependency injection.
Following choices are available:
  • use the interface HttpRequestHandler from Spring library,
  • use methods get and set for setting the dependencies.

Unit testing database access code

How to test jdbc? One can test the code that use the services to access the data or the code that directly work with database.
One can use spring jdbctemplate or hibernate. Along with it you can use EasyMock for testing the code, that access the database.

Hibernate allows you to offload from controlling the differencies in SQL among the databases. Also it looks for opening and closing the resources

Testing database access code in memory database

Testing in HSQLDB. Hibernate settings:
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.url=jdbc:hsqldb:mem:testdb
hibernate.connection.username=sa
hibernate.connection.password=
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create-drop

Automating database schema configuration

Solutions: http://dbdeploy.com/ , http://www.liquibase.org/.
Testing Database access code: http://dbunit.sf.net .

Testing code working with files

For working with files it is better to use http://commons.apache.org/vfs/.
One can use RAM filesystem for unit testing.

Testing code dealing with time

One of the solutions is to create your onw interface and substitute different implementations on the demand. Also you can take a look at joda-time library. Also watch for the strategy pattern.

четверг, 17 января 2013 г.

Axis 2 basic authentication on client

Some time ago I need to connect to web-service which use HTTP basic authentication. I had an Axis 2 client. So, here what I did:
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setPreemptiveAuthentication(true);
auth.setUsername(login);
auth.setPassword(password);
stub._getServiceClient().getOptions().setProperty(HTTPConstants.AUTHENTICATE,auth); 

Now you can connect to protected services.

вторник, 1 января 2013 г.

понедельник, 31 декабря 2012 г.

Netbeans 7.2.1 change user interface language

I've setup a Netbeans IDE 7.2.1 and by default it's user interface uses your system language. Sometimes it's good, but i prefer to see the IDE in English.

So, let's fix it. Open the <netbeans_install_dir>/etc/netbeans.conf and change the line netbeans_default_options. Append to the end of it "-J-Duser.language=en -J-Duser.region=US". Restart your IDE and you will see english interface.

четверг, 27 декабря 2012 г.

Make friends: Apache CXF client + WSS4J + CryptoPro

Many of you who worked with government webservices know that the information passed to the service should be signed with GOST algorithm. This leads to the use of CryptoPro library. So here is the interesting part. What I have:
  1. jdk 1.6.0.38 + JCP CryptoPro
  2. ready to use keystore
  3. wss4j 1.6.6
  4. apache cxf 2.6.1 
  5. XMLDSigRI.jar
Generate the client to webservice.
Then, configure the crypto.properties file for wss4j: org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=HDImageStore
org.apache.ws.security.crypto.merlin.keystore.password=1234567890
org.apache.ws.security.crypto.merlin.keystore.alias=tester
org.apache.ws.security.crypto.merlin.keystore.file=c:/cert.store

Then, configure your client:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://cxf.apache.org/jaxws 
          http://cxf.apache.org/schemas/jaxws.xsd">
 <!-- The SOAP client bean -->
  <jaxws:client id="client"
                serviceClass="ru.my.IService"
                address="http://test/IService/IdentificationService.svc">
    <jaxws:inInterceptors>
      <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
    </jaxws:inInterceptors>
     <jaxws:outInterceptors>
         <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
         <ref bean="wss4jOutConfiguration" /> 
     </jaxws:outInterceptors>
   </jaxws:client>
 <bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
  <property name="properties">
  <map>
  <entry key="action" value="Signature"/>
  <entry key="signaturePropFile" value="crypto.properties"/>
  <entry key="signatureKeyIdentifier" value="DirectReference"/>  
  <entry key="user" value="tester"/> 
  <entry key="signatureUser" value="tester"/>
  <entry key="passwordCallbackClass" value="ru.client.KeystorePasswordCallback"></entry> 
     <entry key="signatureDigestAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
        <entry key="signatureAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>       
      </map>
  </property>
</bean>
</beans>

Everything seems good, but your client won't work.
Here is the example of client:
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});

        ru.IService client = (ru.IService) context.getBean("client");

        ru.CryptoPro.JCPxml.XmlInit.init();

        if(!JCPXMLDSigInit.isInitialized()){
            JCPXMLDSigInit.init();
        }

        Result res = client.callMethod(123);


For this to work I had to patch WSS4j. Download the sources for WSS4j 1.6.6 and edit the file org.apache.ws.security.message.WSSecSignature.java. Find the init method and replace it with this code:
  private void init() {
        Provider xmlDSigProvider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
        signatureFactory = XMLSignatureFactory.getInstance("DOM", xmlDSigProvider);//XMLSignatureFactory.getInstance("DOM");
        keyInfoFactory = KeyInfoFactory.getInstance("DOM", xmlDSigProvider);
    }

       
Compile the file and add the compiled class to the wss4j jar.
After this, I could successfully run the client.