package org.infinispan.quickstart.compatibility.market; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.configuration.Configuration; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; import org.infinispan.quickstart.compatibility.common.SharesUpdate; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.Random; import java.util.TimeZone; /** * Periodically updates the remote cache (through HotRod client) with a new value of shares. * * @author Martin Gencur */ public class MarketUpdater extends Thread { static volatile boolean keepUpdating = true; private final String SERVER_HOST = "localhost"; private final int SERVER_PORT = 11222; private final DateFormat KEY_DATE_FORMAT = new SimpleDateFormat("dd_MMM_yyyy_HH_mm_ss", Locale.US); private final int MAX_TREND_LENGTH = 15; //how long the value of a stock can grow or fall before next change in trend private final float RANDOM_VALUE_FACTOR = 0.5f; private final int UPDATE_SHARES_INTERVAL = 500; private final String NAME_OF_SHARES; private final String LAST_UPDATE_SUFFIX = "last"; private SharesTrend sharesTrend; private Calendar cal = new GregorianCalendar(); private RemoteCacheManager rcm; private RemoteCache<String, SharesUpdate> cache; public MarketUpdater(String stockName, float initialValue) { this.NAME_OF_SHARES = stockName; this.sharesTrend = new SharesTrend(stockName, initialValue); KEY_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT")); //configure the HotRod client and retrieve the cache Configuration config = new ConfigurationBuilder().addServer().host(SERVER_HOST).port(SERVER_PORT).build(); rcm = new RemoteCacheManager(config); cache = rcm.getCache(); } public void run() { System.out.println("Starting MarketUpdater for " + NAME_OF_SHARES + ". Press Ctrl-C to exit..."); while (keepUpdating) { updateMarket(); try { Thread.sleep(UPDATE_SHARES_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); } } if (rcm != null) { System.out.println("Shutting down the cache manager..."); rcm.stop(); } } private void updateMarket() { float nextValue = nextValueOfShares(); Date nextDate = getNextDate(); String nextDateString = KEY_DATE_FORMAT.format(nextDate); SharesUpdate update = new SharesUpdate(nextDate, NAME_OF_SHARES, nextValue); //store an update in the cache cache.put(NAME_OF_SHARES + "_" + nextDateString, update); //also remember the last stored update cache.put(NAME_OF_SHARES + "_" + LAST_UPDATE_SUFFIX, update); } private Date getNextDate() { cal.add(Calendar.SECOND, 1); return cal.getTime(); } private float nextValueOfShares() { if (sharesTrend.currentUpdateIndex == sharesTrend.nextChangeInTrend) { sharesTrend.isGrowingTrend = sharesTrend.RANDOM_GENERATOR.nextBoolean(); sharesTrend.nextChangeInTrend += sharesTrend.RANDOM_GENERATOR.nextInt(MAX_TREND_LENGTH) + 1; //avoid 0 } sharesTrend.currentUpdateIndex++; sharesTrend.valueOfShares += (sharesTrend.RANDOM_GENERATOR.nextFloat() * RANDOM_VALUE_FACTOR) * (sharesTrend.isGrowingTrend == false ? -1 : 1); return sharesTrend.valueOfShares; } /* * Being used to generate the course of shares. */ class SharesTrend { final Random RANDOM_GENERATOR; float valueOfShares; int currentUpdateIndex; boolean isGrowingTrend; //specifies whether the value of shares is currently growing or not int nextChangeInTrend; SharesTrend(String nameOfShares, float valueOfShares) { this.valueOfShares = valueOfShares; this.RANDOM_GENERATOR = new Random(nameOfShares.hashCode()); } } }