ICE09 . playing with java, scala, groovy and spring .

Playing with Spring

Archive for the ‘Uncategorized’ Category

Sample Questions for EIwS-1.x-certification-study-guide

Posted by ice09 on January 16, 2012

Currently, I am preparing for the Enterprise Integration with Spring 1.x Certification, with the Study Guide.

After having tried to google some of the questions, I had to realize that nobody did try to answer the questions (at least openly). Therefore, I will give it a try.
Please be aware that these answers are based on my unterstanding of the question topics. It is not very likely, but they may even be completely false. If they are, please tell me…

Topics by Subject Area

Remoting

General

  • The concepts involved with Spring Remoting on both server- and client-side Configuration and Exposition of Business Services declaratively (with no code changes) using exporters Support of different protocols in a consistent way: RMI, EJB, HttpInvoker, Hessian/Burlap Usage of remote Business Services transparently on client side (using proxy mechanisms with FactoryBeans) Proxy can be injected as Business Service interface, client does not know the service call is remote
  • The benefits of Spring Remoting over traditional remoting technologies No dependency on a concrete Remoting Technology (is abstracted by exception coversion and automatic proxy creation) No adherence to a particular Remoting Technology Binding etc. is done by Spring Exporters Remoting is done by Proxies generated from FactoryBeans
  • The remoting protocols supported by Spring RMI(-IIOP), Stateless EJB, HttpInvoker, Hessian/Burlap

RMI-based Spring Remoting

  • How Spring Remoting-based RMI is less invasive than plain RMI Through the use of the RmiProxyFactoryBean and the RmiServiceExporter Spring supports both traditional RMI (with java.rmi.Remote interfaces and java.rmi.RemoteException) and transparent remoting via RMI invokers (with any Java interface) Client does not have to deal with RemoteExceptions, Server does not have to extend RMI classes

Spring HTTP Invoker

  • How client and server interact with each other The HttpInvokerProxy (client) sends a POST request (transparently by calling a method invocation) to the HttpInvokerServiceExporter (server) using Java serialization (HTTP as transport protocol)

(Reference)

Web Services

General

  • How do Web Services compare to Remoting and Messaging Web Services are interoperable across several platforms. Source and Destination can change, there are no direct dependencies (as with remote method invocation (RPC)). Web Services (can) resemble Document-based messaging more than RPC with loose coupling as a result, but both styles (RPC vs. document-oriented approach) exist. Spring supports the document-oriented Contract-first approach.

Spring Web Services

  • The approach to Spring Web Service that Spring-WS supports Spring-WS uses the Contract-first approach (start with XSD/WSDL) instead of annotating pre-existing methods
  • The Object-to-XML frameworks supported by Spring-OXM JAXB1/2, Castor, XMLBeans, XStream and JiBX
  • The strategies supported to map requests to endpoints Message Payload, SOAP Action Header, WS-Adressing and XPath General Request Processing (Message Dispatcher -> Endpoint Mapping -> Endpoint Adapter -> Endpoint) PayloadRootAnnotationMethodEndpointMapping and SoapActionAnnotationMethodEndpointMapping Request -> MessageDispatcher -> EndpointMapping -> EndpointInvocationChain -> Endpoint and Interceptors
  • Of these strategies, how does @PayloadRoot work exactly? Sample: @PayloadRoot(localPart = "orderRequest", namespace = "http://samples") @ResponsePayload public Order getOrder(@RequestPayload OrderRequest orderRequest) { For this to work the PayloadRootAnnotationMethodEndpointMapping must be registered as a bean
  • The functionality offered by the WebServiceTemplate WebServiceTemplate simplifies client Web Service (SOAP) access in the usual Spring Template way (cp. JDBCTemplate, JMSTemplate) The main functionality is sending an XML Source and receiving an XML Result This functionality can be extended by the usual callback mechanisms (eg. access SOAP Header) Can use different protocols (JMS, Mail, XMPP)

Web Services Security

  • The underlying WS-Security implementations supported by Spring-WS XML Web Services and Security (http://xwss.java.net/), integration with XwsSecurityInterceptor Uses callback mechanisms and policy configuration files Integration with Spring Security (http://static.springsource.org/spring-security/site/)
  • How key stores are supported by Spring-WS for use with WS-Security Usage of KeyStoreFactoryBean (Properties password (Keystore) and location (JKS-File)) Usage of KeyStoreCallbackHandler (with private key password)

RESTFul services with Spring-MVC

General

  • The main REST principles With usage of identifiable resources, an uniform interface (GET, HEAD, PUT, POST, DELETE) is used to represent the (abstract) resources with different representations (HTML, XML, PDF, etc.). A control flow (client state transition) is introduced by using hypermedia links as return values.

REST support in Spring-MVC

  • Spring-MVC is an alternative to JAX-RS, not an implementation
  • The @RequestMapping annotation, including URI template support Sample: @Controller @RequestMapping("/edit{number}") public class EditForm { @RequestMapping(method = RequestMethod.POST) public String processSubmit( @ModelAttribute("edit") Edit edit, BindingResult result, SessionStatus status) {
  • The @RequestBody and @ResponseBody annotations @RequestBody annotated parameters for access to the HTTP request body. Parameter values are converted to the declared method argument type using HttpMessageConverters. If the method is annotated with @ResponseBody, the return type is written to the response HTTP body. The return value will be converted to the declared method argument type using HttpMessageConverters (a href='http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html'>Reference)
  • The functionality offered by the RestTemplate Similar to the WebServiceTemplate The central class for client-side HTTP access. It simplifies communication with HTTP servers, and enforces RESTful principles. It handles HTTP connections, leaving application code to provide URLs (with possible template variables) and extract results. (a href='http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html'>Reference)

JMS with Spring

General

  • Where can Spring-JMS applications obtain their JMS resources from The container provides the resource, which can be a standalone JMS provider (eg. ActiveMQConnectionFactory) or an application server (jee:jndi-lookup jndi-name="...") - is valid for ConnectionFactory and Destination
  • The functionality offered by Spring's JMS message listener container, including the use of a MessageListenerAdapter through the 'method' attribute in the element With the a MessageListener call be called, by specifying the method attribute, any POJO can be used (automatically a MessageListenerAdapter is generated for the POJO by the framework)
  • The functionality offered by the JmsTemplate JmsTemplate delegates to MessageConverter and DestinationResolver. MessageConverter: String -> TextMessage, Serializable -> ObjectMessage, Map -> MapMessage, byte[] -> BytesMessage DynamicDestinationResolver or JndiDestinationResolver, simple one-method-interface Also ConnectionFactory necessary to create a JmsTemplate

Transactions

Local JMS Transactions with Spring

  • How to enable local JMS transactions with Spring's message listener container acknowledge="transacted"
  • If and if so, how is a local JMS transaction made available to the JMSTemplate sessionTransacted=true ConnectionFactoryUtils.doGetTransactionalSession
  • How does Spring attempt to synchronize a local JMS transaction and a local database transaction DataSourceTransactionManager: commit only after successful database commit
  • The functionality offered by the JmsTransactionManager send and receive multiple messages in one transaction works together with declarative transaction management

JTA and Two-phased commit transactions with Spring

  • What guarantees does JTA provide that local transactions do not provide ACID guarantees: Atomic, Consistent, Isolated, Durable ...but on local transactions only in a single resource

Batch processing with Spring Batch

General

  • Main concepts (Job, Step, Job Instance, Job Execution, Step Execution, etc. Job has its own identity, has steps, has an execution (which has start and stop times and status) Client starts JobLauncher, which starts Job (use JobParameters to create JobInstance, which has JobExecutions - same for steps) JobLauncher also updates Job metadata in JobRepository Reader (single entry) and Writer (chunked) with FieldSetMapper
  • The interfaces typically used to implement a chunk-oriented Step implements ItemWriter with write(List list) method
  • How and where state can be store Is handled by JobRepository (ie. in a database or a Map)
  • What are job parameters and how are they used JobParameters can parameterize a JobInstance (eg. schedule.date)
  • What is a FieldSetMapper and what is it used for Can be used to customzie an FlatFileItemReader, which uses it to map values (with LineTokenizer and FieldSetMapper)

Spring Integration

General

  • Main concepts (Messages, Channels, Endpoint types) Message Channel, Message Endpoint, Pipes and Filters, Message Router, Message Translator Framework polls to an event source and notifies/invokes services as necessary (SoC) Rules: A Message is sent by an Endpoint, Endpoints are connected by Channels and receive Messages from them A Message is MessageHeaders and a payload - is immutable always A MessageChannel is used for decoupling, with optional buffereing MessageChannel can be Point-to-Point, Publish-subscribe and Pollable Types of MessageEndpoints (which are the filters in "pipes-and-filter"): Channel Adapter (Jms, File, Method invokation), Service Activator (Invoke Method and wrap result), Gateway (two way integration, sync, inbound waits for reply, outbound waits for response)
  • How to programmatically create new Messages Use MessageBuilder (is immutable, uses Builder pattern)
  • Using chains and bridges Chain subsumes several different Endpoints in one channel Uses same Thread, Transaction Boundaries, etc.

Synchronous vs. asynchronous message passing

  • The different Channel types and how each of them should be used Subscribable (Direct, Publish Subscribe) Pollable (Queue, Priority, Rendezvous)
  • The corresponding effects on things like transactions and security Context is lost by switching to queued channel (sync -> async)
  • The need for active polling and how to configure that Active components are sometimes necessary (JMS, File, etc.) Configure poller on the Enpoints

(Reference)

Advertisements

Posted in Uncategorized | 13 Comments »

Mocking and Stubbing with Mockito

Posted by ice09 on January 9, 2011

 

Intention

Let’s assume there is a new requirement for an existing CRM-like system: send a mail to all customers with a balance greater than 1000. Since we are not allowed to access the database directly, we will have to use existing services.

image

Since we are using Spring, the configuration is obvious, the services are injected, that’s it.

Mocking

However, for testing purposes, we want to mock the services. By examining the classes and methods, we will see why mocking is necessary, but not enough in this case.

Setup

Only the interfaces of the services are shown, they are mocked anyway.

MailService

 
public interface MailService { 
    
    void sendMails(List<customer> customers); 

}

CustomerDao

 
public interface CustomerDao { 

    List<customer> getCustomers(); 

} 

This is the class under test, the filter method should be tested.

 
public class CustomerService { 
    
    private CustomerDao customerDao; 
    private MailService mailService; 
    
    public void notifyCustomersWithBalanceGreaterThan(long cbalance) { 
        List<customer> notificationList = new ArrayList<customer>(); 
        List<customer> customers = customerDao.getCustomers(); 
        for (Customer customer : customers) { 
            if (customer.getBalance() > cbalance) { 
                notificationList.add(customer); 
            } 
        }
        mailService.sendMails(notificationList); 
    } 

} 

Testing…

How do we test if everything worked? There is no result object to check, since mails are sent. Here mocking comes into play, a breeze with Mockito.

 
@RunWith(MockitoJUnitRunner.class)
public class TestClass {

	private @Mock CustomerDao customerDao;
	private @Mock MailService mailService;
	
	private @InjectMocks CustomerService customerService = new CustomerService();

	private @Captor ArgumentCaptor<List<Customer>> customerCaptor;

	@Before
	public void setup() {
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void testIt() {
		//preparation (stubbing)
		when(customerDao.getCustomers()).thenReturn(prepareList());
		
		customerService.notifyCustomersWithBalanceGreaterThan(1000);

		//verification (mocking)
		//has customerDao be called correctly?
		verify(customerDao, times(1)).getCustomers();
		verifyNoMoreInteractions(customerDao);

		//have the mails be sent?
		verify(mailService).sendMails(customerCaptor.capture());
		
		//is the list of customers to notify correct? 
		assertEquals(2, customerCaptor.getValue().size());
		assertEquals(new Customer(3, "eva", "mustermann", 2000), customerCaptor.getValue().get(0)); 
		assertEquals(new Customer(6, "hanna", "mustermann", 1001), customerCaptor.getValue().get(1)); 
		verifyNoMoreInteractions(mailService);
	}

	private List<Customer> prepareList() {
		List<Customer> customers = new ArrayList<Customer>();
		customers.add(new Customer(1, "hans", "mustermann", 100));
		customers.add(new Customer(2, "max", "mustermann", 1000));
		customers.add(new Customer(3, "eva", "mustermann", 2000));
		customers.add(new Customer(4, "anna", "mustermann", 0));
		customers.add(new Customer(6, "hanna", "mustermann", 1001));
		return customers;
	}

}

The mocking part is straightforward. However, we have to stub as well, since we want the CustomerDao to actually return our prepared Customer list. No problem with Mockito (search for Test Spy to see why there are differences in Mocking frameworks regarding the support of Mocking, Stubbing or both – then being a Test Spy).

Dependency injection

Really interesting is the wiring of the components. The MockitoJUnitRunner.class is used to run the Unittest, we do not use Spring for this test. But magically, after calling MockitoAnnotations.initMocks(this) the @Mock annotated Mocks are injected into the @InjectMocks annotated class automatically. This being great already, we are furthermore using the @Captor annotation to create a argument captor for all List arguments. Now we can examine the submitted list with Customers to sent mail to and determine, if the correct Customers have been filtered.
So, we have a nice dependency injection, combined with stubbing and mocking. Mockito is really powerful (and much easier to use than similar Mocking frameworks), you can even partially stub objects. However, there should be a really good reason for doing this…

Posted in Uncategorized | 1 Comment »

Quick Tip: Extending WebDriver to react on stopwords

Posted by ice09 on July 18, 2010

The requirement

Happily using WebDriver for some time now, I realized that it makes sense to intercept each call that changes the page source in a way that certain “stopwords”, eg. “exception”, “error”, etc. cause an immediate exception. This is useful if you want to be sure that in a complex test case an exception will never occur. Otherwise, you would have to manually check for it each time the page source is altered.

The problem

I wanted to use the ProxyBeanFactory for this requirement, since it seemed the least compromising way of manipulating the calls to the actual WebDriver. However, I realized that I would have to use AspectJ for this, since calls to private/protected methods inside the bean itself cannot be intercepted by proxies. This is necessary to intercept the call to the method sendMessage, which is used by WebDriver and WebElement for methods which actually change the page source (which makes sense, since this method actually communicates with the plugin via Commands).

The solution

I decided not to use proxies, but just to subclass the FireFoxWebDriver with my own one, which just overwrites the “sendMessage” method. That’s it, the code is as follows.

The Spring config

<?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"
	xmlns:util="http://www.springframework.org/schema/util"
	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
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <context:annotation-config/>
    <context:component-scan base-package="de.demo.proxy"/>

	<util:list id="stopwords">
    	<value>exception</value>
    	<value>Comment</value>
	</util:list>
    
</beans>

The new WebDriver

package de.demo.proxy;

import java.util.List;

import javax.annotation.Resource;

import org.openqa.selenium.firefox.Command;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.springframework.stereotype.Component;

@Component
public class InterceptedFireFoxDriver extends FirefoxDriver {
	
	@Resource(name="stopwords")
	private List<String> stopwords;
	
	@Override
	protected String sendMessage(Class<? extends RuntimeException> throwOnFailure, Command command) {
		String result = super.sendMessage(throwOnFailure, command);
		// avoid endless recursion, sendMessage... is called by getPageSource as well
		if (command.getCommandName().equals("getPageSource")) {
	        return result;
		}
		String content = super.getPageSource();
		// might be null due to initialization issues (already called during spring context creation)
		if (stopwords != null) {
			for (String stopword : stopwords) {
				if (content.contains(stopword)) {
					throw new IllegalStateException("command [" + command.getCommandName() + "] causes page content with stopword: " + stopword);
				}
			}
		}
		return result;
	}

}

The sample class

package de.demo.proxy;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class MainClass {
	
    @Autowired
	private WebDriver driver;
    
    public void start() {
        driver.get("http://www.google.com");

        // Find the text input element by its name
        WebElement element = driver.findElement(By.name("q"));

        // Enter something to search for
        element.sendKeys("Hello");

        // Now submit the form. WebDriver will find the form for us from the element
        element.submit();

        // Check the title of the page
        System.out.println("Page title is: " + driver.getTitle());
        
        driver.findElement(By.xpath("//a")).click();
        
        driver.close();
    }
	
	public static void main(String[] args) {
			ApplicationContext appCtx = new ClassPathXmlApplicationContext("app.xml");
			MainClass mc = appCtx.getBean(MainClass.class);
			try {
				mc.start();
			} finally {
				mc.driver.close();
			}
	}

}

Posted in Uncategorized | Leave a Comment »