EJB 3: Audit Invocation Trail with Interceptors

Tags

, , , , ,

In this tutorial we will learn how to Audit EJB 3 Invocation Trail with Interceptors .

EJB 3+ is capable of applying custom interceptors to the business methods of your session and message driven beans. EJB 3 interceptors take the form of methods annotated with the @javax.ejb.AroundInvoke annotation & having following signature:

@javax.ejb.AroundInvoke
public Object (javax.ejb.InvocationContext ctx) throws java.lang.Exception

Either define an interceptor method

  • in the EJB itself,
  • or in a separate class

but remember that there can only be one interceptor method per class. We will use the separate class approach which is more maintainable.

Define Interceptor Method

public class EJB3InvocationAuditInterceptor { 
  @Resource 
  private EJBContext context; 
  @AroundInvoke 
  protected Object audit(InvocationContext ctx) throws Exception { 
    Principal principal = context.getCallerPrincipal(); 
    Logger.getLogger().info("Received a call from "+principal.getName());
    if (userIsValid(principal)) { 

      }else{ 
           //TODO log & throw exception
    } 
    return ctx.proceed(); 
  } 
}

Apply Custom Interceptor on EJB

@Interceptors(EJB3InvocationAuditInterceptor.class) 
@Stateless 
public class AuditedEJB3Bean { 
  // TODO: your EJB3 Bean content
}

Deploy & Access EJB

Bingo! You should see
Received a call from ...

RESTFul Web Service: Submit Form with Jersey (Jax-RS)

Tags

, ,

In this tutorial, we will learn how to submit form to a RESTFul Web Service (JAX-RS).

Resolve Dependency

Include & configure any of the Jax-RS provider e.g Jersey, RESTEasy etc.

HTML Form

<form action="rest/FormSubmitSample" method="post" 
      enctype="application/x-www-form-urlencoded">
   <input id="_name" type="text" name="_name" />
   <input type="submit" />
</form>

Enable JAX-RS Service

@javax.ws.rs.ApplicationPath("rest")
public class ApplicationConfig extends javax.ws.rs.core.Application {
}

JAX-RS Form Submit Service

 @Path("FormSubmitSample")
public class FormSubmitSample {
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @POST
    public String addPost(@FormParam("_name") String name) {
        return "Hello "+name;
    }
}

RESTFul Webservice: File Upload with Jersey

Tags

, ,

In this tutorial, we will learn how do to file upload with Jersey, A RESTFul Webservice(JAX-RS) implementation.

File upload feature of html form works by wrapping the file content inside a multipart envelope as the content type “application/x-www-form-urlencoded” is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type “multipart/form-data” should be used for submitting forms that contain files, non-ASCII data, and binary data.

  1. Resolve Dependency

    For the “multipart/form-data” support we need to include “jersey-multipart.jar” and dependencies from here [for glassfish v3.1 & upward you will find it in glassfish\modules].

  2.  <html>
    <body>
        <h1>Upload File with RESTFul WebService</h1>
        <form action="rest/fileupload" method="post" enctype="multipart/form-data">
           <p>
            Choose a file : <input type="file" name="file" />
           </p>
           <input type="submit" value="Upload" />
        </form>
    </body>
    </html>
    
  3. Java File Upload Client

    We will use Apache HTTPClient library to resolve dependency. It is an optional step & the code could be exploited to build a test-client.

     HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(url);
    FileBody fileContent= new FileBody(new File(fileName));
    StringBody comment = new StringBody("Filename: " + fileName);
    MultipartEntity reqEntity = new MultipartEntity();
    reqEntity.addPart("file", fileContent);
    httppost.setEntity(reqEntity);
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity resEntity = response.getEntity();
    
  4. Create JAX-RS File Upload Service with Jersey

    Jersey uses  @FormDataParam to receive the uploaded file. To get the uploaded file name or header detail, compare with “FormDataContentDisposition” which represents a “Content-Disposition” header whose value is “form-data”.

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    import com.sun.jersey.core.header.FormDataContentDisposition;
    import com.sun.jersey.multipart.FormDataParam;
    
    @Path("/fileupload")
    public class UploadFileService {
    
    	@POST
    	@Consumes(MediaType.MULTIPART_FORM_DATA)
    	public Response uploadFile(
    		@FormDataParam("file") InputStream uploadedInputStream,
    		@FormDataParam("file") FormDataContentDisposition fileDetail) {
    
    		String uploadedFileLocation = "c://uploadedFiles/" + fileDetail.getFileName();
    
    		// save it
    		saveToFile(uploadedInputStream, uploadedFileLocation);
    
    		String output = "File uploaded via Jersey based RESTFul Webservice to: " + uploadedFileLocation;
    
    		return Response.status(200).entity(output).build();
    
    	}
    
    	// save uploaded file to new location
    	private void saveToFile(InputStream uploadedInputStream,
    		String uploadedFileLocation) {
    
    		try {
    			OutputStream out = null;
    			int read = 0;
    			byte[] bytes = new byte[1024];
    
    			out = new FileOutputStream(new File(uploadedFileLocation));
    			while ((read = uploadedInputStream.read(bytes)) != -1) {
    				out.write(bytes, 0, read);
    			}
    			out.flush();
    			out.close();
    		} catch (IOException e) {
    
    			e.printStackTrace();
    		}
    
    	}
    
    }
    
  5. Test Your Service

    1. Deploy & Browse to {App_URL}/{File_Upload_html}
    2. Upload A file and check.
  6. Source Code

    You can download source-code here.

Securing, Versioning and Auditing REST (JAX-RS, Jersey) APIs

Tags

,

Puspendu Banerjee:

Worthy to read but unnecessary engagement of Spring Framework smells bad.

Originally posted on animesh kumar:

Now that your functionalities are working, you want a layer of security to authenticate/authorize your APIs. Though this is a bad approach towards security, but – I know – real life is a tough game and nothing happens they way they should be… and so be it. Additionally, you might want to control API versions (i.e. expose newer APIs only to newer clients) and audit API usage.

Well, I am going to propose a tangential way to implement these concerns. You won’t need to touch any of your business logic as such. Only few annotations (custom and otherwise) would need to be applied. That way, you won’t feel bad about missing these things when you started the project and your concerns will be taken care of in the most un-obtrusive way possible. Wonderful… eh?

First, you will need to create some sort of sign-in API, which will accept username/password (or…

View original 1,354 more words

Painless Integration Testing with Arquillian, JUnit & Java EE 6

Tags

, , ,

JBoss Arquillian is an awesome tool for integration testing of Java EE applications brought by JBoss team to the community. It enables real in-container testing with no mocks, and writing the tests is made very simple, just like if you would write ordinary unit tests.

Arquillian wraps a lifecycle around test execution that provides the following services:

  • Manages the lifecycle of one or more containers
  • Bundles the test case, dependent classes and resources as Shrink-wrap archives
  • Deploys the archives to the containers
  • Enriches the test case with dependency injection and other declarative services
  • Executes the tests inside (or against) the containers
  • Returns the results to the test runner for reporting

Create a new Maven Project with Group Id=org.jboss.weld.archtypes & Artifact id=jboss-javaee6-webapp

write a testcase for a CDI injectable Bean/EJB

import static org.junit.Assert.assertEquals;

import javax.ejb.EJB;

import org.jboss.arquillian.container.test.api.Deployment;

import org.jboss.arquillian.junit.Arquillian;

import org.jboss.shrinkwrap.api.ShrinkWrap;

import org.jboss.shrinkwrap.api.spec.JavaArchive;

import org.junit.Test;

import org.junit.runner.RunWith;

 

@RunWith(Arquillian.class)

public class CalculatorTest {

    @Deployment

    public static JavaArchive createDeployment() {

        return ShrinkWrap.create(JavaArchive.class) //define the type of bundle

            .addClass(Calculator.class) //bundle any class or resource you want

            .addAsManifestResource(EmptyAsset.INSTANCE, “beans.xml”);//You need bean.xml to activate CDI in your app

    }

 

    @Inject

    Greeter greeter;

 

    @Test

    publicvoid should_create_greeting() {

        assertEquals(5,Calculator.sum(2,3));

    }

}

Run the test

Wow! You did it without writing a single line of code to get & manage the context Application Server

Is not it truly painless?

How to call a stored procedure and map resultset to entity with Derby and EclipseLink

Tags

, ,

Assume you have a stored procedure in your Derby/JavaDB instance with following signature:

APP.PICK_AIRLINES(AIRLINE CHAR(2))

This stored procedure returns a resultset that you want to map with your Entity class, say, Airline.

Firstly I should let you know that, till date, Apache Derby [my version is 10.5] does not support Named Parameter in Callable Statements.

So, we cannot simply use @NamedStoredProcedureQuery Annotation with @StoredProcedureParameter , rather we need to use StoredProcedureCall method. Continue reading

JPA Cache Database Synch in heterogenious Environment

Tags

, , ,

1.      We have a system in which 2 applications share the same database instance. Application 1 uses BC4J, while Application 2 uses Toplink/JPA. Because of the Toplink cache, all the changes persisted to DB done by Application 1 is not recognized by Application 2, unless we bounce the Application 2 server, or we wait for a long time. I guess this is a common problem that others encountered before. Please share your advice on this problem. Continue reading

Hibernate as JPA provider for Entity Beans in EJB3

Tags

, , ,

In recent past I was having a discussion with a person from a large MNC who wondered when I told that I have used Hibernate with EJB 3 entity beans , then asked me the significance of using such configuration. Well, I tried my level-best to make him understand that, but alas! the person who is not even aware of JPA spec and tied up with Java EE 1.4 with Weblogic and WebSphere, how can I make him understand!

Well, if you are aware of Java EE 6, EJB 3 Spec, JPA then and only then read ahead, else it will be wastage of your time.

Hibernate also support Entity beans and Java Persistence Provider(JPA) of EJB3.0+ specification. In fact many of the concepts of Entity beans has been taken from Hibernate. JBoss application server uses Hibernate as the default persistence provider for Entity beans and JPA. JPA has the notion of persistence unit which represents the configuration.
EntityManagerFactory of JPA corresponds to SessionFactory and EntityManager corresponds to Session.

Basically, EJB 3, JPA are spec and Hibernate is an implementation of JPA spec[ as TopLink, EclipseLink etc] so, if Entity Beans can use JPA then the underlying implementation could be be any JPA provider e.g. Hibernate,TopLink, EclipseLink etc.

Now, let me answer the second question: Significance of using Hibernate[JPA] with Entity Beans.

  • You are free from any Vendor-LockIn, change your JPA implementation when-ever you need it.
  • You are free to change your DataBase provider at any point of time with-out changing a single line of code[ except orm.xml or persistence.xml file]
  • Even you can use the bean validation features of Entity beans with Hibernate validator.
  • Use features like dynamic queries and named queries , which will be a really helpful if concurrency and application performance are of your concern.
  • As well as most of the features of ORM tools are readily available.

Reference:

  1. http://www.oracle.com/technetwork/articles/javaee/jpa-137156.html
  2. http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html

Understanding Java EE 6 and CDI

Tags

, ,

As Java EE 6 tutorial says:

The two most fundamental services provided by CDI are as follows:

  • Contexts: The ability to bind the lifecycle and interactions of stateful components to well-defined but extensible lifecycle contexts
  • Dependency injection: The ability to inject components into an application in a type-safe way, including the ability to choose at deployment time which implementation of a particular interface to inject

Let’s discuss with an example.

Suppose you are a frequent traveler need to travel from New Heaven to New York thrice a week and your nearest airport is Hartford. Every time you take a cab or drive to airport then take flight and fly to NY., i.e you are a dependent of  transport service.

So, we can say that,in this case the type (Concrete Implementation) of the service depends on the source and destination and putting that concrete implementation in place at runtime (Injection) depending on scenario(i.e. Context) is  Context & Dependency Injection.

JEE 6 uses annotation(Which had been introduced at Java 5) heavily to make developers’ life hassle free from writing lines of XML configuration.Five annotation constructs :

  1. @Inject,
  2. @Qualifier,
  3. @Produces,
  4. @Disposes and
  5. @Named

provide the basic building blocks for getting a thin loosely coupled layered modular structure to the view, hiding the boilerplate code one had to write before JEE 6.

I shall write more on this topic as I shall learn more. :)

Follow

Get every new post delivered to your Inbox.