Skip to content

Commit

Permalink
CarMart with listeners and transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
mgencur committed Apr 18, 2012
1 parent f8fd2e3 commit 2cc0c75
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import javax.faces.event.SystemEventListener;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.UserTransaction;

import org.infinispan.api.BasicCache;
import com.jboss.datagrid.carmart.model.Car;
import com.jboss.datagrid.carmart.model.Car.CarType;
Expand All @@ -52,6 +54,8 @@ public class PopulateCache implements SystemEventListener {
private Logger log = Logger.getLogger(this.getClass().getName());

private CacheContainerProvider provider;

private UserTransaction utx;

@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
Expand All @@ -62,25 +66,39 @@ public void processEvent(SystemEvent event) throws AbortProcessingException {
public void startup() {
BasicCache<String, Object> cars = provider.getCacheContainer().getCache(CarManager.CACHE_NAME);
List<String> carNumbers = new ArrayList<String>();

Car c = new Car("Ford Focus", 1.6, CarType.COMBI, "white", "FML 23-25", Country.CZECH_REPUBLIC);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("BMW X3", 2.0, CarType.SEDAN, "gray", "1P3 2632", Country.CZECH_REPUBLIC);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("Ford Mondeo", 2.2, CarType.COMBI, "blue", "1B2 1111", Country.USA);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("Mazda MX-5", 1.8, CarType.CABRIO, "red", "6T4 2526", Country.USA);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("VW Golf", 1.6, CarType.HATCHBACK, "yellow", "2B2 4946", Country.GERMANY);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
// insert a list of cars' number plates
cars.put(CarManager.CAR_NUMBERS_KEY, carNumbers);
log.info("Successfully imported data!");

utx = getUserTransactionFromJNDI();

try {
utx.begin();
Car c = new Car("Ford Focus", 1.6, CarType.COMBI, "white", "FML 23-25", Country.CZECH_REPUBLIC);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("BMW X3", 2.0, CarType.SEDAN, "gray", "1P3 2632", Country.CZECH_REPUBLIC);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("Ford Mondeo", 2.2, CarType.COMBI, "blue", "1B2 1111", Country.USA);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("Mazda MX-5", 1.8, CarType.CABRIO, "red", "6T4 2526", Country.USA);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
c = new Car("VW Golf", 1.6, CarType.HATCHBACK, "yellow", "2B2 4946", Country.GERMANY);
carNumbers.add(c.getNumberPlate());
cars.put(CarManager.encode(c.getNumberPlate()), c);
// insert a list of cars' number plates
cars.put(CarManager.CAR_NUMBERS_KEY, carNumbers);
utx.commit();
log.info("Successfully imported data!");
} catch (Exception e) {
log.warning("An exception occured while populating the database! Rolling back the transaction.");
if (utx != null) {
try {
utx.rollback();
} catch (Exception e1) {
}
}
}
}

private BeanManager getBeanManagerFromJNDI() {
Expand All @@ -94,6 +112,18 @@ private BeanManager getBeanManagerFromJNDI() {
}
return (BeanManager) result;
}

private UserTransaction getUserTransactionFromJNDI() {
InitialContext context;
Object result;
try {
context = new InitialContext();
result = context.lookup("java:comp/UserTransaction"); // lookup in JBossAS
} catch (NamingException ex) {
throw new RuntimeException("UserTransaction could not be found in JNDI", ex);
}
return (UserTransaction) result;
}

@SuppressWarnings("unchecked")
public <T> T getContextualInstance(final BeanManager manager, final Class<T> type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public class CarManager {
private CacheContainerProvider provider;

private BasicCache<String, Object> carCache;

@Inject
private UserTransaction utx;

private String carId;
private Car car = new Car();
Expand All @@ -58,27 +61,24 @@ public CarManager() {

public String addNewCar() {
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
List<String> carNumbers = getNumberPlateList(carCache);
carNumbers.add(car.getNumberPlate());
carCache.put(CAR_NUMBERS_KEY, carNumbers);
carCache.put(CarManager.encode(car.getNumberPlate()), car);
return "home";
}

public String addNewCarWithRollback() {
boolean throwInducedException = true;
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
List<String> carNumbers = getNumberPlateList(carCache);
carNumbers.add(car.getNumberPlate());
// store the new list of car numbers and then throw an exception -> roll-back
// the car number list should not be stored in the cache
carCache.put(CAR_NUMBERS_KEY, carNumbers);
if (throwInducedException)
throw new RuntimeException("Induced exception");
carCache.put(CarManager.encode(car.getNumberPlate()), car);
try {
utx.begin();
List<String> carNumbers = getNumberPlateList(carCache);
carNumbers.add(car.getNumberPlate());
carCache.put(CAR_NUMBERS_KEY, carNumbers);
carCache.put(CarManager.encode(car.getNumberPlate()), car);
utx.commit();
} catch (Exception e) {
if (utx != null) {
try {
utx.rollback();
} catch (Exception e1) {
}
}
}
return "home";
}

/**
* Operate on a clone of car number list
*/
Expand All @@ -96,25 +96,58 @@ private List<String> getNumberPlateList(BasicCache<String, Object> carCacheLoc)

public String showCarDetails(String numberPlate) {
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
this.car = (Car) carCache.get(encode(numberPlate));
try {
utx.begin();
this.car = (Car) carCache.get(encode(numberPlate));
utx.commit();
} catch (Exception e) {
if (utx != null) {
try {
utx.rollback();
} catch (Exception e1) {
}
}
}
return "showdetails";
}

public List<String> getCarList() {
List<String> result = null;
// retrieve a cache
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
// retrieve a list of number plates from the cache
result = getNumberPlateList(carCache);
try {
utx.begin();
// retrieve a list of number plates from the cache
result = getNumberPlateList(carCache);
utx.commit();
} catch (Exception e) {
if (utx != null) {
try {
utx.rollback();
} catch (Exception e1) {
}
}
}
return result;
}

public String removeCar(String numberPlate) {
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
carCache.remove(encode(numberPlate));
List<String> carNumbers = getNumberPlateList(carCache);
carNumbers.remove(numberPlate);
carCache.put(CAR_NUMBERS_KEY, carNumbers);
try {
utx.begin();
carCache.remove(encode(numberPlate));
List<String> carNumbers = getNumberPlateList(carCache);
carNumbers.remove(numberPlate);
carCache.put(CAR_NUMBERS_KEY, carNumbers);
utx.commit();
} catch (Exception e) {
if (utx != null) {
try {
utx.rollback();
} catch (Exception e1) {
}
}
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,18 @@
import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;
import org.infinispan.api.BasicCacheContainer;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.eviction.EvictionStrategy;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.transaction.LockingMode;
import org.infinispan.transaction.TransactionMode;
import org.infinispan.transaction.lookup.GenericTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;

import com.jboss.datagrid.carmart.session.CacheContainerProvider;

/**
Expand All @@ -48,17 +55,20 @@ public class JBossASCacheContainerProvider implements CacheContainerProvider {

public BasicCacheContainer getCacheContainer() {
if (manager == null) {


//*************** amend the configuration ***************

GlobalConfiguration glob = new GlobalConfigurationBuilder().build();
Configuration loc = new ConfigurationBuilder().build();

//*************** amend the configuration ***************


manager = new DefaultCacheManager(glob, loc, true); //true means start the cache manager immediately
GlobalConfiguration glob = new GlobalConfigurationBuilder()
.nonClusteredDefault().globalJmxStatistics().enable()
.jmxDomain("org.infinispan.lesson05") //prevent collision with non-transactional carmart
.build();
Configuration loc = new ConfigurationBuilder()
.jmxStatistics().enable()
.clustering().cacheMode(CacheMode.LOCAL)
.transaction().transactionMode(TransactionMode.TRANSACTIONAL).autoCommit(false)
.lockingMode(LockingMode.OPTIMISTIC).transactionManagerLookup(new GenericTransactionManagerLookup())
.locking().isolationLevel(IsolationLevel.REPEATABLE_READ)
.eviction().maxEntries(4).strategy(EvictionStrategy.LRU)
.loaders().passivation(true).addFileCacheStore().purgeOnStartup(true)
.build();
manager = new DefaultCacheManager(glob, loc, true);
log.info("=== Using DefaultCacheManager (library mode) ===");
}
return manager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,60 @@
package com.jboss.datagrid.carmart.session;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.stats.Stats;
import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryVisited;
import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryVisitedEvent;
import com.jboss.datagrid.carmart.session.StatisticsProvider;

@Named("stats")
@RequestScoped
@ApplicationScoped //use application scope so that we can get overall statistics
@Listener
public class LocalStatisticsProvider implements StatisticsProvider {

@Inject
private CacheContainerProvider provider;

private Stats stats;
int visits;
int creations;
int removals;

@PostConstruct
public void getStatsObject() {
stats = ((DefaultCacheManager) provider.getCacheContainer()).getCache(CarManager.CACHE_NAME).getAdvancedCache()
.getStats();
((DefaultCacheManager) provider.getCacheContainer()).getCache(CarManager.CACHE_NAME).addListener(this);
}

@CacheEntryCreated
public void print(CacheEntryCreatedEvent event) {
creations++;
}

@CacheEntryVisited
public void print(CacheEntryVisitedEvent event) {
visits++;
}

@CacheEntryRemoved
public void print(CacheEntryRemovedEvent event) {
removals++;
}

public String getVisits() {
return String.valueOf(stats.getHits());
return String.valueOf(visits);
}

public String getCreations() {
return String.valueOf(stats.getStores());
return String.valueOf(creations);
}

public String getRemovals() {
return String.valueOf(stats.getRemoveHits());
return String.valueOf(removals);
}
}

0 comments on commit 2cc0c75

Please sign in to comment.