Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exercise 2 - Asynchronous method call #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
quality-day-training-tasks
==========================
#Excersie 2: Asynchronous method call
##Introduction
This lesson is about following skills:
* creating asynchronous methods in enterprise beans
* EJB self invocation
* concurrency

Various tasks and problems to solve
Expected result of this exercise is an EJB application which uses self invoked asynchronous method calculatePi.

##Before you start, read about...
* Asynchronous invocation: [http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html]
* Session Context [http://docs.oracle.com/javaee/6/api/javax/ejb/SessionContext.html#getBusinessObject(java.lang.Class)]

##The exercise
To complete this exercise you need to follow these steps:
* Refactor calculatePi in `PiCalculator.java` to return promise (read Asynchronous invocation) instead of Object
* Make calculatePi asynchronous
* Annotate Session Context to be injected properly
* In piFullCalculator use sessionContext to recover business object of class `PiCalculator.java` and assign it to the variable
* Use business object for self invocation of asynchronous method calculatePi and pass
iterations as parameter (Important note: You can't invoke private functions)
* Assign return value to existing variable piFuture

Good luck !
95 changes: 95 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.itcrowd.java.exercises</groupId>
<artifactId>java-exercises</artifactId>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>${version.jbossas}</version>
<configuration>
<artifactId>${project.artifactId}</artifactId>
<force>true</force>
<groupId>${project.groupId}</groupId>
<ignoreMissingDeployment>true</ignoreMissingDeployment>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.1_spec</artifactId>
<version>1.0.1.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-remote</artifactId>
<version>7.1.1.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-bom</artifactId>
<version>2.2.0-beta-1</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.5.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<jdk.source>1.7</jdk.source>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<version.jbossas>7.1.1.Final</version.jbossas>
</properties>
</project>
36 changes: 36 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;

@Startup
@Singleton
public class Main {

private Logger logger = LoggerFactory.getLogger(Main.class);

private Double adminPiResult;

@EJB
private PiCalculator calculator;

@PostConstruct
public void main() throws Exception
{
setAdminPiResult(calculator.piFullCalculator(10000000));
logger.info("admin pi precision: " + Double.toString(getAdminPiResult()));
}

public Double getAdminPiResult()
{
return adminPiResult;
}

public void setAdminPiResult(Double adminPiResult)
{
this.adminPiResult = adminPiResult;
}
}
48 changes: 48 additions & 0 deletions src/main/java/PiCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Stateless
public class PiCalculator {

private Logger logger = LoggerFactory.getLogger(PiCalculator.class);

private SessionContext sessionContext;

public Double piFullCalculator(int iterations) throws ExecutionException, InterruptedException
{
Long threadId = Thread.currentThread().getId();

//You are supposed to instantiate piFuture with promise from calculatePi function(you need to fix calculatePi return value)
final Future<Double> piFuture = null;
logger.info("piFullCalculator should appear before calculatePi: " + Long.toString(threadId));

final Object monitor = new Object();
while(!piFuture.isDone()) {
logger.info("Waiting...");
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (monitor) {
monitor.wait(1000);
}
}

return piFuture.get();
}

private Object calculatePi(int iterations)
{
double pi = 4;
boolean plus = false;
for (int i = 3; i < iterations; i += 2) {
pi = plus ? (pi + 4.0 / i) : (pi - 4.0 / i);
plus = !plus;
}
Long threadId = Thread.currentThread().getId();
logger.info("calculatePi, thread id: " + Long.toString(threadId));
return pi;
}
}
11 changes: 11 additions & 0 deletions src/main/webapp/WEB-INF/jboss-ejb3.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:security="urn:security" version="3.1"
impl-version="2.0">
<assembly-descriptor xmlns="http://java.sun.com/xml/ns/javaee">
<security:security>
<security:security-domain>exercise</security:security-domain>
<ejb-name>*</ejb-name>
</security:security>
</assembly-descriptor>
</jboss:ejb-jar>

33 changes: 33 additions & 0 deletions src/test/java/MainTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import junit.framework.Assert;
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.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.ejb.EJB;
import java.io.File;

@RunWith(Arquillian.class)
public class MainTest {

@EJB
private Main main;

@Deployment
public static WebArchive createDeployment()
{
return ShrinkWrap.create(WebArchive.class)
.addClasses(Main.class, PiCalculator.class)
.addAsWebInfResource(new File("src/main/webapp/WEB-INF/jboss-ejb3.xml"))
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}

@Test
public void should_calculatePi_equal() throws Exception
{
Assert.assertEquals(main.getAdminPiResult(), 3.1415924535897797d);
}
}
34 changes: 34 additions & 0 deletions src/test/java/PiCalculatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import junit.framework.Assert;
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.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.ejb.EJB;
import java.io.File;
import java.util.concurrent.Future;

@RunWith(Arquillian.class)
public class PiCalculatorTest {

@EJB
private PiCalculator piCalculator;

@Deployment
public static WebArchive createDeployment()
{
return ShrinkWrap.create(WebArchive.class)
.addClasses(PiCalculator.class)
.addAsWebInfResource(new File("src/main/webapp/WEB-INF/jboss-ejb3.xml"))
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}

@Test
public void should_calculatePi_be_called_asynchronously() throws Exception
{
Assert.assertEquals(((Future) piCalculator.calculatePi(10000)).isDone(), false);
}
}