Skip to content
GigaSpaces Logo GigaSpaces Logo
  • Products, Solutions & Roles
    • Products
      • InsightEdge Portfolio
        • Smart Cache
        • Smart ODS
        • Smart Augmented Transactions
        • Compare InsightEdge Products
      • GigaSpaces Cloud
    • Solutions
      • Industry
        • Financial Services
        • Insurance
        • Retail and eCommerce
        • Telecommunications
        • Transportations
      • Technical
        • Operational BI
        • Mainframe & AS/400 Modernization
        • In Memory Data Grid
        • Transactional and Analytical Processing (HTAP)
        • Hybrid Cloud Data Fabric
        • Multi-Tiered Storage
        • Kubernetes Deployment
        • Streaming Analytics for Stateful Apps
    • Building a Successful Hybrid and Multicloud Strategy
      vid-icon Guide

      Learn how to build and deploy a successful hybrid and multicloud strategy to achieve: agility and scalability, faster go-to-market, application acceleration, legacy modernization, and more.

      DOWNLOAD
    • Contact
    • Try Free
  • Resources
    • Resource Hub
      • Webinars
      • Demos
      • Solution Briefs & Whitepapers
      • Case Studies
      • Benchmarks
      • ROI Calculators
      • Analyst Reports
      • eBooks
    • Featured Case Studies
      • Mainframe Offload with Groupe PSA
      • Digital Transformation with Avanza Bank
      • High Peak Handling with PriceRunner
      • Optimizing Business Communications with Avaya
    • col3
      • Blog
      • Technical Documentation
    • Live Webinar: Enable Digital Transformation With a High Performing Data Platform
      article-icon Live Webinar | March 11 - 9 AM EST/3 PM CET

      Join Capgemini and GigaSpaces for a discussion on the latest modernization trends for enterprises that are embarking on digital and business transformation

      REGISTER NOW
    • Contact Us
    • Try Free
  • Company
    • Col1
      • About
      • Customers
      • Management
      • Board Members
      • Investors
      • Events
      • News
      • Careers
    • Col2
      • Partners
      • OEM
      • System Integrators
      • Technology Partners
      • Value Added Resellers
    • Col3
      • Support & Services
      • University
      • Services
      • Support
    • GigaSpaces is Headed to CDAO 2021
      article-icon Event | March 2-4

      Join us at CDAO 2021, the premier Virtual Summit for Data and Analytics Leaders. We'll be moderating "Transforming Financial Services to a Customer-Centric Business", alongside USAA Bank, Regions Bank, and Capital Group.

      SIGN UP NOW
    • Contact Us
    • Try Free
  • Search
  • Contact Us
  • Try Free

Routing Information Effectively : Divide and Conquer!

Subscribe to our blog!

Subscribe for Updates
Close
Back

Routing Information Effectively : Divide and Conquer!

Owen October 17, 2007
7 minutes read

 



RoutingExample.java

Divide and Conquer:

In the pursuit of colocation and affinity the architect/developer must articulate
what the criteria is
for routing the information in the system to the best place.
With GigaSpaces,
this means establishing a routing value that will instruct the
proxy how to route the instance of the object in question.
Here I propose a pattern to direct the routing value and allow
for increased
topology transparency within the deployment environment.

Firstly: it is important to specify a dedicated property rather than reuse an
existing one as the runtime routing value needs to be flexible.

Secondly: many times utilizing a primitive is desired by the designer of a system
and once
this is done, a null-equivalent is required to allow for wide-ranging
queries accross multiple partitions. I take the opportunity here to specify a
common routing value
for numerics expressed initially as a String to be parsed as
a
float or int or double etc by the associated java.lang.Float etc… type.

The pattern specifies the use of a Routable
interface (which must be implemented
by any Object seeking to be routed) and a SpaceRoutingHelper utility that is clever
enough to route Routables to the appropriate partition without change of code ie:
‘transparently’ regardless of whether there is one or 99 partitions in the Space.

Here is the Routable
interface:
package gslabs.util;

/**
* Created by IntelliJ IDEA.
* User: owen
* Date: 5-Jun-2007
* Time: 12:25:12 PM
*/

public interface Routable {
public static final String DEFAULT_NUMERIC_NULL_VALUE=“-9999”;
public void setRoutingFieldValue(int val);
public int getRoutingFieldValue();
}


Here is the SpaceRoutingHelper:
package gslabs.util;

import com.j_spaces.core.IJSpace;
import com.j_spaces.core.cluster.ClusterPolicy;
import com.j_spaces.core.admin.IRemoteJSpaceAdmin;


/**
* Created by IntelliJ IDEA.
* User: owen
* Date: 5-Jun-2007
* Time: 12:09:12 PM
*/

public class SpaceRoutingHelper {
IJSpace space =
null;
public int NUMBER_PARTITIONS = 1;

/**
*
@param val The Routable Object to be used with a partitioned Space
*
@param seed The provided value that will determine the target partition (if left null, target partition is
* determined randomly)
*
@return The prepared version of the Routable Object with the routingField specified
*/

public Routable prepareRoutable(Routable val, Object seed) {
if (space == null) {
throw new IllegalStateException(“Cannot Route Routable: target space = null”);
}
int router = 0;
if (seed == null) {
router = (
int) System.nanoTime() % NUMBER_PARTITIONS;
}
else {
router = seed.hashCode() % NUMBER_PARTITIONS;
}
val.setRoutingFieldValue(router);
return val;
}

public void setSpace(IJSpace space) {
this.space = space;
if (space != null) {
try {
IRemoteJSpaceAdmin spaceAdmin = (IRemoteJSpaceAdmin) space.getAdmin();
ClusterPolicy cpolicy = spaceAdmin.getClusterPolicy();
if(cpolicy!=null){
java.util.List l = cpolicy.m_AllClusterMemberList;
if (l.size() > 1) {
int partitionValue = 1;
try {
partitionValue = cpolicy.m_ReplicationGroups.size();
if (partitionValue == 0) {
//no replicationGroups, so #partitions == size of space names
partitionValue = l.size();
}
}
catch (NullPointerException npe) {
//no replicationGroups, so #partitions == size of space names
partitionValue = l.size();
}
NUMBER_PARTITIONS = partitionValue;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}

Example:

The following service writes Offers to the space. In doing so the decision of
how to route the various instances is made using the SpaceRoutingHelper. This
means that without changing the code, the application can be deployed against a
cluster of any number of spaces or a single embedded space.

Additionally, I will show the use of the Routable.DEFAULT_NUMERIC_NULL_VALUE.
****

package os.example.trading;

import org.openspaces.events.adapter.SpaceDataEvent;
import org.openspaces.core.GigaSpace;
import os.example.trading.common;
import java.math.BigDecimal;
import gslabs.util.SpaceRoutingHelper;

/**
*
<p>A simple bean that is run within a Spring context that acts
* as the processing unit context as well (when executed within a
* processing unit container).
*
*
<p>Is handed SpaceDataEvents from a polling container.<br />
* This removes the need to use space.take and space.write in the code.
*
*
<p>The SQLQuery for the polling container is defined in the pu.xml.
*/

public class MarketMakerWorker {

gsutil.SpaceRoutingHelper router =
new SpaceRoutingHelper();
private float lastPrice_NASD,lastPrice_NYSE,lastPrice_AMEX;
private GigaSpace space;
private float highPrice, lowPrice;

public MarketMakerWorker(GigaSpace space, float highPrice, float lowPrice){
this.space = space;
this.highPrice = highPrice;
this.lowPrice = lowPrice;
/*
IT IS NECESSARY TO PREPARE THE SpaceRoutingHelper by passing it a
reference to the Space. Using this reference it determines the total
number of partitions and routes the Routables properly.
*/

router.setSpace(space.getSpace());
}
/**
* This method is called any time the matching event is produced by the space.
*
<p>The OpenSpaces PollingEventContainer will automagically call this method.
*
@param data The data source of the event defined for this bean.
* In this example, the Stock object is evidence of a change in the market
* price for this instrument.
* [The return value is written to the space by the Spring container]
*/

@SpaceDataEvent
public Offer dataProcessed( Stock data) {
Offer offer =
null;
if((data.getCurrentPrice().compareTo(new BigDecimal(highPrice))>0)){
offer =
new Offer();
//bogus code used to set various criteria for demo purposes…
offer.setNumberOfShares(((System.nanoTime()%
50)*1000)+500);
offer.setOfferID(
“”+new java.sql.Date(
System.currentTimeMillis())+
“_”+data.getSymbol()+“_sell”);
offer.setPrice(data.getCurrentPrice());
offer.setSymbol(data.getSymbol());
offer.setSell(Offer.IS_SELL_TRUE);

/*
NOTICE THE USE OF THE SpaceRoutingHelper and the decision to
Specify an affinity between the (data) Stock object and the
resulting Offer object. If desired, volume of shares could be
used in conjunction with Stock symbol to provide a finer-grained
partitioning strategy.
*/

offer = (Offer) router.prepareRoutable(
offer,
new Integer(data.getRoutingFieldValue()));
}
else if((data.getCurrentPrice().compareTo(
new BigDecimal(lowPrice))<0)){
offer =
new Offer();
//bogus code used to set various criteria for demo purposes…
offer.setNumberOfShares(((System.nanoTime()%
50)*1000)+500);
offer.setOfferID(
“”+new java.sql.Date(System.currentTimeMillis())+“_”+data.getSymbol()+“_sell”);
offer.setPrice(data.getCurrentPrice());
offer.setSymbol(data.getSymbol());
offer.setSell(Offer.IS_SELL_FALSE);
/*
NOTICE THE USE OF THE SpaceRoutingHelper and the decision to
Specify an affinity between the (data) Stock object and the
resulting Offer object. If desired, volume of shares could be
used in conjunction with Stock symbol to provide a finer-grained
partitioning strategy.
*/

offer = (Offer) router.prepareRoutable(offer,
new Integer(data.getRoutingFieldValue()));
}
return offer;
}

public float getLastAMEXPrice(){
return lastPrice_AMEX;
}
public float getLastNASDPrice(){
return lastPrice_NASD;
}
public float getLastNYSEPrice(){
return lastPrice_NYSE;
}
}


The following
class definition requires several OpenSpaces-specific annotations
to play nicely with that framework – these will be demonstrated – in addition, I
will show the placement of the routingFieldValue and the exposure of several
primitive fields.

package os.example.trading.common;
import com.gigaspaces.annotation.pojo.SpaceId;
import com.gigaspaces.annotation.pojo.SpaceProperty;
import com.gigaspaces.annotation.pojo.SpaceRouting;
import java.math.BigDecimal;
/**
* Created by IntelliJ IDEA.
* User: owen
* Date: Oct 9, 2007
* Time: 3:46:00 PM
*/

public class Offer implements gslabs.util.Routable{
private String offerID;
private String symbol;
private long numberOfShares;
private BigDecimal price;
private int isSell;
public static final int IS_SELL_FALSE=0;
public static final int IS_SELL_TRUE=1;
private int routingFieldValue;

public void setRoutingFieldValue(int val) {
routingFieldValue = val;
}

@SpaceProperty(nullValue=Routable.DEFAULT_NUMERIC_NULL_VALUE)
@SpaceRouting
public int getRoutingFieldValue() {
return routingFieldValue;
}

@SpaceId
public String getOfferID() {
return offerID;
}

public void setOfferID(String offerID) {
this.offerID = offerID;
}

public String getSymbol() {
return symbol;
}

public void setSymbol(String symbol) {
this.symbol = symbol;
}

@SpaceProperty(nullValue=Routable.DEFAULT_NUMERIC_NULL_VALUE)
public long getNumberOfShares() {
return numberOfShares;
}

public void setNumberOfShares(long numberOfShares) {
this.numberOfShares = numberOfShares;
}

public BigDecimal getPrice() {
return price;
}

public void setPrice(BigDecimal price) {
this.price = price;
}

@SpaceProperty(nullValue=Routable.DEFAULT_NUMERIC_NULL_VALUE)
public int getSell() {
return isSell;
}

public void setSell(int sell) {
isSell = sell;
}
}

CATEGORIES

  • GigaSpaces
  • Java
  • OpenSpaces
Owen

All Posts (36)

YOU MAY ALSO LIKE

September 24, 2008

Oracle and Cloud Computing. Funny.
3 minutes read

August 17, 2009

A GigaSpaces solution to the…
4 minutes read

February 10, 2009

Simple and cost effective Enterprise-SOA…
4 minutes read
  • Copied to clipboard

PRODUCTS, SOLUTIONS & ROLES

  • Products
  • Smart Cache
  • Smart Operational Data Store
  • Smart Augmented Transactions
  • GigaSpaces Cloud
  • Roles
  • Architects
  • CIOs
  • Product Team
  • Solutions
  • Industry
    • Financial Services
    • Insurance
    • Retail and eCommerce
    • Telecommunications
    • Transportation
  • Technical
    • Operational BI
    • Mainframe & AS/400 Modernization
    • In Memory Data Grid
    • HTAP
    • Hybrid Cloud Data Fabric
    • Multi-Tiered Storage
    • Kubernetes Deployment
    • Streaming Analytics for Stateful Apps

RESOURCES

  • Resource Hub
  • Webinars
  • Demos
  • Case Studies
  • Solution Briefs & Whitepapers
  • Benchmarks
  • Cost Reduction Calculators
  • Analyst Reports
  • eBooks
  • Blogs
  • Documentation
  • Featured Case Studies
  • Mainframe Offload with Groupe PSA
  • Digital Transformation with Avanza Bank
  • High Peak Handling with PriceRunner
  • Optimizing Business Communications with Avaya

COMPANY

  • About
  • Customers
  • Management
  • Board Members
  • Investors
  • News
  • Events
  • Careers
  • Contact Us
  • Book A Demo
  • Try GigaSpaces For Free
  • Partners
  • OEM Partners
  • System Integrators
  • Value Added Resellers
  • Technology Partners
  • Support & Services
  • University
  • Services
  • Support
Copyright © GigaSpaces 2020 All rights reserved | Privacy Policy
LinkedInTwitterFacebook