WMB入门之十二:使用在Subflow中比较简陋的Cache设计
注:以下Cache未加时效处理,是比较简陋的Cache方案。
AbstractCacheMap基类,用来定义和限制子类的操作:
与AbstractCacheMap类配合使用,用来防止读写线程冲突和线程拥挤的读写锁类:
AbstractCacheMap基类,用来定义和限制子类的操作:
package
cachemap.base;
/**
* Parent class of InnerCacheMap & OutterCacheMap
*
* @author heyang
* @time Sep 23, 2011,4:00:45 PM
*/
public abstract class AbstractCacheMap {
// Read-Write lock,for protecting the cacheMap in the Multi-thread environment
private ReadWriteLock lock;
/**
* Contructor
*/
public AbstractCacheMap() {
lock = new ReadWriteLock();
}
/**
* Put key-value pair into cacheMap
* It can be called by any class
* @param key
* @param value
* @throws Exception
*/
public void writeData(String key, byte [] value) throws Exception{
try {
lock.writeLock();
set(key,value);
} finally {
lock.writeUnlock();
}
}
/**
* Put key-value pair into cacheMap,force child-class to implement.
* It only can be called by child-class
* @param key
* @param value
*/
protected abstract void set(String key, byte [] value) throws Exception;
/**
* Get value by it's key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public byte [] readData(String key) throws Exception{
try {
lock.readLock();
return get(key);
} finally {
lock.readUnlock();
}
}
/**
* Get value by it's key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract byte [] get(String key) throws Exception;
/**
* Judge the existence of a key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public boolean containsKey(String key) throws Exception{
try {
lock.readLock();
return contains(key);
} finally {
lock.readUnlock();
}
}
/**
* Judge the existence of a key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract boolean contains(String key) throws Exception;
/**
* Remove a key-value pair from cacheMap by it's key
* It can be called by any class
*
* @param key
* @throws Exception
*/
public void removeData(String key) throws Exception{
try {
lock.writeLock();
remove(key);
} finally {
lock.writeUnlock();
}
}
/**
* Remove a key-value pair from cacheMap by it's key
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void remove(String key) throws Exception;
/**
* Remove all data in the cacheMap
* It can be called by any class
*
* @throws Exception
*/
public void removeAllData() throws Exception{
try {
lock.writeLock();
removeAll();
} finally {
lock.writeUnlock();
}
}
/**
* Remove all data in the cacheMap
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void removeAll() throws Exception;
}
/**
* Parent class of InnerCacheMap & OutterCacheMap
*
* @author heyang
* @time Sep 23, 2011,4:00:45 PM
*/
public abstract class AbstractCacheMap {
// Read-Write lock,for protecting the cacheMap in the Multi-thread environment
private ReadWriteLock lock;
/**
* Contructor
*/
public AbstractCacheMap() {
lock = new ReadWriteLock();
}
/**
* Put key-value pair into cacheMap
* It can be called by any class
* @param key
* @param value
* @throws Exception
*/
public void writeData(String key, byte [] value) throws Exception{
try {
lock.writeLock();
set(key,value);
} finally {
lock.writeUnlock();
}
}
/**
* Put key-value pair into cacheMap,force child-class to implement.
* It only can be called by child-class
* @param key
* @param value
*/
protected abstract void set(String key, byte [] value) throws Exception;
/**
* Get value by it's key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public byte [] readData(String key) throws Exception{
try {
lock.readLock();
return get(key);
} finally {
lock.readUnlock();
}
}
/**
* Get value by it's key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract byte [] get(String key) throws Exception;
/**
* Judge the existence of a key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public boolean containsKey(String key) throws Exception{
try {
lock.readLock();
return contains(key);
} finally {
lock.readUnlock();
}
}
/**
* Judge the existence of a key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract boolean contains(String key) throws Exception;
/**
* Remove a key-value pair from cacheMap by it's key
* It can be called by any class
*
* @param key
* @throws Exception
*/
public void removeData(String key) throws Exception{
try {
lock.writeLock();
remove(key);
} finally {
lock.writeUnlock();
}
}
/**
* Remove a key-value pair from cacheMap by it's key
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void remove(String key) throws Exception;
/**
* Remove all data in the cacheMap
* It can be called by any class
*
* @throws Exception
*/
public void removeAllData() throws Exception{
try {
lock.writeLock();
removeAll();
} finally {
lock.writeUnlock();
}
}
/**
* Remove all data in the cacheMap
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void removeAll() throws Exception;
}
package
cachemap.base;
/**
* Parent class of InnerCacheMap & OutterCacheMap
*
* @author heyang
* @time Sep 23, 2011,4:00:45 PM
*/
public abstract class AbstractCacheMap {
// Read-Write lock,for protecting the cacheMap in the Multi-thread environment
private ReadWriteLock lock;
/**
* Contructor
*/
public AbstractCacheMap() {
lock = new ReadWriteLock();
}
/**
* Put key-value pair into cacheMap
* It can be called by any class
* @param key
* @param value
* @throws Exception
*/
public void writeData(String key, byte [] value) throws Exception{
try {
lock.writeLock();
set(key,value);
} finally {
lock.writeUnlock();
}
}
/**
* Put key-value pair into cacheMap,force child-class to implement.
* It only can be called by child-class
* @param key
* @param value
*/
protected abstract void set(String key, byte [] value) throws Exception;
/**
* Get value by it's key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public byte [] readData(String key) throws Exception{
try {
lock.readLock();
return get(key);
} finally {
lock.readUnlock();
}
}
/**
* Get value by it's key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract byte [] get(String key) throws Exception;
/**
* Judge the existence of a key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public boolean containsKey(String key) throws Exception{
try {
lock.readLock();
return contains(key);
} finally {
lock.readUnlock();
}
}
/**
* Judge the existence of a key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract boolean contains(String key) throws Exception;
/**
* Remove a key-value pair from cacheMap by it's key
* It can be called by any class
*
* @param key
* @throws Exception
*/
public void removeData(String key) throws Exception{
try {
lock.writeLock();
remove(key);
} finally {
lock.writeUnlock();
}
}
/**
* Remove a key-value pair from cacheMap by it's key
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void remove(String key) throws Exception;
/**
* Remove all data in the cacheMap
* It can be called by any class
*
* @throws Exception
*/
public void removeAllData() throws Exception{
try {
lock.writeLock();
removeAll();
} finally {
lock.writeUnlock();
}
}
/**
* Remove all data in the cacheMap
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void removeAll() throws Exception;
}
/**
* Parent class of InnerCacheMap & OutterCacheMap
*
* @author heyang
* @time Sep 23, 2011,4:00:45 PM
*/
public abstract class AbstractCacheMap {
// Read-Write lock,for protecting the cacheMap in the Multi-thread environment
private ReadWriteLock lock;
/**
* Contructor
*/
public AbstractCacheMap() {
lock = new ReadWriteLock();
}
/**
* Put key-value pair into cacheMap
* It can be called by any class
* @param key
* @param value
* @throws Exception
*/
public void writeData(String key, byte [] value) throws Exception{
try {
lock.writeLock();
set(key,value);
} finally {
lock.writeUnlock();
}
}
/**
* Put key-value pair into cacheMap,force child-class to implement.
* It only can be called by child-class
* @param key
* @param value
*/
protected abstract void set(String key, byte [] value) throws Exception;
/**
* Get value by it's key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public byte [] readData(String key) throws Exception{
try {
lock.readLock();
return get(key);
} finally {
lock.readUnlock();
}
}
/**
* Get value by it's key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract byte [] get(String key) throws Exception;
/**
* Judge the existence of a key
* It can be called by any class
*
* @param key
* @return
* @throws Exception
*/
public boolean containsKey(String key) throws Exception{
try {
lock.readLock();
return contains(key);
} finally {
lock.readUnlock();
}
}
/**
* Judge the existence of a key,force child-class to implement.
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract boolean contains(String key) throws Exception;
/**
* Remove a key-value pair from cacheMap by it's key
* It can be called by any class
*
* @param key
* @throws Exception
*/
public void removeData(String key) throws Exception{
try {
lock.writeLock();
remove(key);
} finally {
lock.writeUnlock();
}
}
/**
* Remove a key-value pair from cacheMap by it's key
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void remove(String key) throws Exception;
/**
* Remove all data in the cacheMap
* It can be called by any class
*
* @throws Exception
*/
public void removeAllData() throws Exception{
try {
lock.writeLock();
removeAll();
} finally {
lock.writeUnlock();
}
}
/**
* Remove all data in the cacheMap
* It only can be called by child-class
*
* @param key
* @return
* @throws Exception
*/
protected abstract void removeAll() throws Exception;
}
用来往CacheMap中异步添加值的CacheMapSetter类:
package
cachemap.setter;
import cachemap.base.AbstractCacheMap;
/**
* CacheMapSetter
* It's use is to set a key-value pair into cacheMap
*
* @author heyang
* @time Sep 26, 2011,10:11:36 AM
*/
public final class CacheMapSetter implements Runnable{
// The reference to the cacheMap
private AbstractCacheMap cacheMap;
private String key;
private byte [] value;
/**
* Constuctor
* @param cacheMap
* @param key
* @param value
*/
public CacheMapSetter(AbstractCacheMap cacheMap,String key, byte [] value){
this .cacheMap = cacheMap;
this .key = key;
this .value = value;
new Thread( this ).start();
}
@Override
public void run(){
try {
cacheMap.writeData(key, value);
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
import cachemap.base.AbstractCacheMap;
/**
* CacheMapSetter
* It's use is to set a key-value pair into cacheMap
*
* @author heyang
* @time Sep 26, 2011,10:11:36 AM
*/
public final class CacheMapSetter implements Runnable{
// The reference to the cacheMap
private AbstractCacheMap cacheMap;
private String key;
private byte [] value;
/**
* Constuctor
* @param cacheMap
* @param key
* @param value
*/
public CacheMapSetter(AbstractCacheMap cacheMap,String key, byte [] value){
this .cacheMap = cacheMap;
this .key = key;
this .value = value;
new Thread( this ).start();
}
@Override
public void run(){
try {
cacheMap.writeData(key, value);
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
AbstractCacheMap的实际子类InnerCacheMap,存储空间使用的是内置的HashMap:
package
cachemap;
import java.util.HashMap;
import java.util.Map;
import cachemap.base.AbstractCacheMap;
/**
* CacheMap used local HashMap
*
* @author heyang
* @time Sep 23, 2011,3:48:17 PM
*/
public class InnerCacheMap extends AbstractCacheMap{
// essential storage
private Map < String, byte [] > map;
/**
* Contructor
*/
public InnerCacheMap(){
super ();
map = new HashMap < String, byte [] > ();
}
@Override
protected byte [] get(String key) throws Exception {
return map.get(key);
}
@Override
protected void set(String key, byte [] value) throws Exception {
map.put(key, value);
}
@Override
protected boolean contains(String key) throws Exception {
return map.containsKey(key);
}
@Override
protected void remove(String key) throws Exception {
map.remove(key);
}
@Override
protected void removeAll() throws Exception {
map.clear();
}
}
import java.util.HashMap;
import java.util.Map;
import cachemap.base.AbstractCacheMap;
/**
* CacheMap used local HashMap
*
* @author heyang
* @time Sep 23, 2011,3:48:17 PM
*/
public class InnerCacheMap extends AbstractCacheMap{
// essential storage
private Map < String, byte [] > map;
/**
* Contructor
*/
public InnerCacheMap(){
super ();
map = new HashMap < String, byte [] > ();
}
@Override
protected byte [] get(String key) throws Exception {
return map.get(key);
}
@Override
protected void set(String key, byte [] value) throws Exception {
map.put(key, value);
}
@Override
protected boolean contains(String key) throws Exception {
return map.containsKey(key);
}
@Override
protected void remove(String key) throws Exception {
map.remove(key);
}
@Override
protected void removeAll() throws Exception {
map.clear();
}
}
AbstractCacheMap的子类WxsCacheMap,使用的是外部的WebSphere Extreme Scale作为存储空间:
与WxsCacheMap配合使用的WxsConnection类:
package
cachemap;
import cachemap.base.AbstractCacheMap;
import com.devwebsphere.wxsutils.WXSMap;
import com.devwebsphere.wxsutils.WXSUtils;
/**
* CacheMap powered by WebSphere eXtreme Scale
*
* @author heyang
* @time Sep 23, 2011,3:47:54 PM
*/
public class WxsCacheMap extends AbstractCacheMap{
// essential storage
private WXSMap < String, byte [] > wxsMap;
/**
* Contructor
*/
public WxsCacheMap(String host,String grid,String businessObjectName){
super ();
try {
WXSUtils wxsUtils = WxsConnection.getWxsConnection(host,grid);
wxsMap = getMap(wxsUtils,businessObjectName);
} catch (Exception ex){
ex.printStackTrace();
}
}
/**
* Get map from WXSUtils
* @param wxsUtils
* @param strBusinessObject
* @return
*/
private WXSMap < String, byte [] > getMap(WXSUtils wxsUtils, String strBusinessObject) {
if (strBusinessObject.equalsIgnoreCase( " CUSTOMER " )){
return wxsUtils.getCache( " BO_CUSTOMER " );
} else if (strBusinessObject.equalsIgnoreCase( " VEHICLE " )){
return wxsUtils.getCache( " BO_VEHICLE " );
} else if (strBusinessObject.equalsIgnoreCase( " NAVIGATION " )){
return wxsUtils.getCache( " NAV_NAVIGATION " );
} else {
return null ;
}
}
@Override
protected byte [] get(String key) throws Exception {
return wxsMap.get(key);
}
@Override
protected void set(String key, byte [] value) throws Exception {
wxsMap.put(key, value);
}
@Override
protected boolean contains(String key) throws Exception {
return wxsMap.contains(key);
}
@Override
protected void remove(String key) throws Exception {
wxsMap.remove(key);
}
@Override
protected void removeAll() throws Exception {
wxsMap.clear();
}
}
import cachemap.base.AbstractCacheMap;
import com.devwebsphere.wxsutils.WXSMap;
import com.devwebsphere.wxsutils.WXSUtils;
/**
* CacheMap powered by WebSphere eXtreme Scale
*
* @author heyang
* @time Sep 23, 2011,3:47:54 PM
*/
public class WxsCacheMap extends AbstractCacheMap{
// essential storage
private WXSMap < String, byte [] > wxsMap;
/**
* Contructor
*/
public WxsCacheMap(String host,String grid,String businessObjectName){
super ();
try {
WXSUtils wxsUtils = WxsConnection.getWxsConnection(host,grid);
wxsMap = getMap(wxsUtils,businessObjectName);
} catch (Exception ex){
ex.printStackTrace();
}
}
/**
* Get map from WXSUtils
* @param wxsUtils
* @param strBusinessObject
* @return
*/
private WXSMap < String, byte [] > getMap(WXSUtils wxsUtils, String strBusinessObject) {
if (strBusinessObject.equalsIgnoreCase( " CUSTOMER " )){
return wxsUtils.getCache( " BO_CUSTOMER " );
} else if (strBusinessObject.equalsIgnoreCase( " VEHICLE " )){
return wxsUtils.getCache( " BO_VEHICLE " );
} else if (strBusinessObject.equalsIgnoreCase( " NAVIGATION " )){
return wxsUtils.getCache( " NAV_NAVIGATION " );
} else {
return null ;
}
}
@Override
protected byte [] get(String key) throws Exception {
return wxsMap.get(key);
}
@Override
protected void set(String key, byte [] value) throws Exception {
wxsMap.put(key, value);
}
@Override
protected boolean contains(String key) throws Exception {
return wxsMap.contains(key);
}
@Override
protected void remove(String key) throws Exception {
wxsMap.remove(key);
}
@Override
protected void removeAll() throws Exception {
wxsMap.clear();
}
}
package
cachemap;
import com.devwebsphere.wxsutils.WXSUtils;
import com.ibm.websphere.objectgrid.ObjectGrid;
import com.ibm.websphere.objectgrid.ObjectGridRuntimeException;
import com.ibm.websphere.objectgrid.TargetNotAvailableException;
public class WxsConnection {
static WXSUtils utils;
static ObjectGrid grid;
/**
* @param strCatalogServerEndPoint: Catalog Server End Point example: localhost:2809
* @param strGrid: Grid name
* @return
*/
public static synchronized WXSUtils getWxsConnection(String strCatalogServerEndPoint,String strGrid) {
if (utils == null ) {
grid = WXSUtils.connectClient(strCatalogServerEndPoint,strGrid);
utils = new WXSUtils(grid);
}
return utils;
}
public static void handleException(ObjectGridRuntimeException e) {
Throwable ne = e.getCause();
if (ne instanceof TargetNotAvailableException) {
// bad target (maybe ip changed)
WXSUtils oldUtils;
synchronized (WxsConnection. class ) {
oldUtils = utils;
utils = null ;
}
oldUtils.getObjectGrid().destroy();
}
}
}
import com.devwebsphere.wxsutils.WXSUtils;
import com.ibm.websphere.objectgrid.ObjectGrid;
import com.ibm.websphere.objectgrid.ObjectGridRuntimeException;
import com.ibm.websphere.objectgrid.TargetNotAvailableException;
public class WxsConnection {
static WXSUtils utils;
static ObjectGrid grid;
/**
* @param strCatalogServerEndPoint: Catalog Server End Point example: localhost:2809
* @param strGrid: Grid name
* @return
*/
public static synchronized WXSUtils getWxsConnection(String strCatalogServerEndPoint,String strGrid) {
if (utils == null ) {
grid = WXSUtils.connectClient(strCatalogServerEndPoint,strGrid);
utils = new WXSUtils(grid);
}
return utils;
}
public static void handleException(ObjectGridRuntimeException e) {
Throwable ne = e.getCause();
if (ne instanceof TargetNotAvailableException) {
// bad target (maybe ip changed)
WXSUtils oldUtils;
synchronized (WxsConnection. class ) {
oldUtils = utils;
utils = null ;
}
oldUtils.getObjectGrid().destroy();
}
}
}
用来从外界得到CacheMap的CacheFactory类:
package
cachemap;
import cachemap.base.AbstractCacheMap;
/**
* CacheMapFacory
* It' used to get the actual cacheMap
*
* @author heyang
* @time Sep 26, 2011,10:41:39 AM
*/
public final class CacheMapFacory{
/**
* getInnerCacheMap
* @return
* @throws Exception
*/
public static AbstractCacheMap getInnerCacheMap() throws Exception{
return new InnerCacheMap();
}
/**
* getWxsCacheMap
* @return
* @throws Exception
*/
public static AbstractCacheMap getWxsCacheMap() throws Exception{
return new WxsCacheMap( " host " , " grid " , " VEHICLE " );
}
}
import cachemap.base.AbstractCacheMap;
/**
* CacheMapFacory
* It' used to get the actual cacheMap
*
* @author heyang
* @time Sep 26, 2011,10:41:39 AM
*/
public final class CacheMapFacory{
/**
* getInnerCacheMap
* @return
* @throws Exception
*/
public static AbstractCacheMap getInnerCacheMap() throws Exception{
return new InnerCacheMap();
}
/**
* getWxsCacheMap
* @return
* @throws Exception
*/
public static AbstractCacheMap getWxsCacheMap() throws Exception{
return new WxsCacheMap( " host " , " grid " , " VEHICLE " );
}
}
JavaCompute节点中使用Cache的Java代码:
import
cachemap.CacheMapFacory;
import cachemap.base.AbstractCacheMap;
import cachemap.setter.CacheMapSetter;
import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
/**
* subflow_JavaCompute class
*
* @author heyang
* @time Sep 26, 2011,10:14:34 AM
*/
public class subflow_JavaCompute extends MbJavaComputeNode {
private static AbstractCacheMap cacheMap;
static {
try {
cacheMap = CacheMapFacory.getInnerCacheMap();
} catch (Exception e) {
e.printStackTrace();
}
}
public void evaluate(MbMessageAssembly inAssembly) throws MbException {
/** **************************
* 1.out&alt
************************** */
MbOutputTerminal out = getOutputTerminal( " out " );
// MbOutputTerminal alt = getOutputTerminal("alternate");
/** **************************
* 2.inMsg& outMsg
************************** */
MbMessage inMsg = inAssembly.getMessage();
MbMessage outMsg = new MbMessage();
/** **************************
* 3.input&output environment
************************** */
MbMessage inputEnv = inAssembly.getLocalEnvironment();
MbMessage outputEnv = new MbMessage(inAssembly.getLocalEnvironment());
/** **************************
* 4.outAssembly
************************** */
MbMessageAssembly outAssembly = new MbMessageAssembly(inAssembly,outputEnv,inAssembly.getExceptionList(),outMsg);
try {
// Copy Headers
copyMessageHeaders(inMsg,outMsg);
// Get key
String key = getKey(inputEnv);
// Get operation
String operation = getOperation(inputEnv);
if ( " READ " .equalsIgnoreCase(operation)){
if (cacheMap.containsKey(key)){
byte [] value = cacheMap.readData(key);
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
if (elementValue == null ){
elementValue = elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Value " , "" );
}
elementValue.setValue(value);
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " SUCCESS " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " CACHE Record Found " );
} else {
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " FAILURE " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " No Record Found " );
}
} else if ( " WRITE " .equalsIgnoreCase(operation)){
if (cacheMap.containsKey(key)){
cacheMap.removeData(key);
}
byte [] value = getValue(outputEnv);
new CacheMapSetter(cacheMap,key, value);
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
if (elementValue == null ){
elementValue = elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Value " , "" );
}
elementValue.detach();
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " SUCCESS " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " Record Added to Cache " );
} else if ( " REMOVEALL " .equalsIgnoreCase(operation)){
cacheMap.removeAllData();
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
if (elementValue == null ){
elementValue = elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Value " , "" );
}
elementValue.detach();
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " SUCCESS " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " Rmoved all data from Cache " );
} else {
throw new Exception( " Unknown Operation: " + operation);
}
// Send Back
out.propagate(outAssembly);
}
catch (Exception ex){
ex.printStackTrace();
}
}
// private
/**
* get operation
* get operation from input environment
*
* @param inputEnv
* @return
* @throws Exception
*/
private String getOperation(MbMessage inputEnv) throws Exception{
MbElement elementInputEnvironment = inputEnv.getRootElement();
MbElement elementOperation = elementInputEnvironment.getFirstElementByPath( " Variables/Operation " );
String strOperation = elementOperation.getValueAsString();
return strOperation;
}
/**
* getKey
* get key from input environment
*
* @param inputEnv
* @return
* @throws Exception
*/
private String getKey(MbMessage inputEnv) throws Exception{
MbElement elementInputEnvironment = inputEnv.getRootElement();
MbElement elementKey = elementInputEnvironment.getFirstElementByPath( " Variables/BOKey " );
String strKey = elementKey.getValueAsString();
return strKey;
}
/**
* getValue
* get value from output environment
*
* @param outputEnv
* @return
* @throws Exception
*/
private byte [] getValue(MbMessage outputEnv) throws Exception{
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
byte [] byteInputObject = ( byte [])elementValue.getValue();
return byteInputObject;
}
/**
* copyMessageHeaders
* @param inMessage
* @param outMessage
* @throws MbException
*/
private void copyMessageHeaders(MbMessage inMessage, MbMessage outMessage) throws MbException {
MbElement outRoot = outMessage.getRootElement();
// iterate though the headers starting with the first child of the root element
MbElement header = inMessage.getRootElement().getFirstChild();
while (header != null && header.getNextSibling() != null ) // stop before the last child of the body
{
// copy the header and add it to the out message
outRoot.addAsLastChild(header.copy());
// move along to next header
header = header.getNextSibling();
}
}
}
import cachemap.base.AbstractCacheMap;
import cachemap.setter.CacheMapSetter;
import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
/**
* subflow_JavaCompute class
*
* @author heyang
* @time Sep 26, 2011,10:14:34 AM
*/
public class subflow_JavaCompute extends MbJavaComputeNode {
private static AbstractCacheMap cacheMap;
static {
try {
cacheMap = CacheMapFacory.getInnerCacheMap();
} catch (Exception e) {
e.printStackTrace();
}
}
public void evaluate(MbMessageAssembly inAssembly) throws MbException {
/** **************************
* 1.out&alt
************************** */
MbOutputTerminal out = getOutputTerminal( " out " );
// MbOutputTerminal alt = getOutputTerminal("alternate");
/** **************************
* 2.inMsg& outMsg
************************** */
MbMessage inMsg = inAssembly.getMessage();
MbMessage outMsg = new MbMessage();
/** **************************
* 3.input&output environment
************************** */
MbMessage inputEnv = inAssembly.getLocalEnvironment();
MbMessage outputEnv = new MbMessage(inAssembly.getLocalEnvironment());
/** **************************
* 4.outAssembly
************************** */
MbMessageAssembly outAssembly = new MbMessageAssembly(inAssembly,outputEnv,inAssembly.getExceptionList(),outMsg);
try {
// Copy Headers
copyMessageHeaders(inMsg,outMsg);
// Get key
String key = getKey(inputEnv);
// Get operation
String operation = getOperation(inputEnv);
if ( " READ " .equalsIgnoreCase(operation)){
if (cacheMap.containsKey(key)){
byte [] value = cacheMap.readData(key);
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
if (elementValue == null ){
elementValue = elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Value " , "" );
}
elementValue.setValue(value);
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " SUCCESS " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " CACHE Record Found " );
} else {
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " FAILURE " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " No Record Found " );
}
} else if ( " WRITE " .equalsIgnoreCase(operation)){
if (cacheMap.containsKey(key)){
cacheMap.removeData(key);
}
byte [] value = getValue(outputEnv);
new CacheMapSetter(cacheMap,key, value);
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
if (elementValue == null ){
elementValue = elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Value " , "" );
}
elementValue.detach();
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " SUCCESS " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " Record Added to Cache " );
} else if ( " REMOVEALL " .equalsIgnoreCase(operation)){
cacheMap.removeAllData();
// TODO:
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
if (elementValue == null ){
elementValue = elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Value " , "" );
}
elementValue.detach();
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Status " , " SUCCESS " );
elementOutputVariables.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, " Message " , " Rmoved all data from Cache " );
} else {
throw new Exception( " Unknown Operation: " + operation);
}
// Send Back
out.propagate(outAssembly);
}
catch (Exception ex){
ex.printStackTrace();
}
}
// private
/**
* get operation
* get operation from input environment
*
* @param inputEnv
* @return
* @throws Exception
*/
private String getOperation(MbMessage inputEnv) throws Exception{
MbElement elementInputEnvironment = inputEnv.getRootElement();
MbElement elementOperation = elementInputEnvironment.getFirstElementByPath( " Variables/Operation " );
String strOperation = elementOperation.getValueAsString();
return strOperation;
}
/**
* getKey
* get key from input environment
*
* @param inputEnv
* @return
* @throws Exception
*/
private String getKey(MbMessage inputEnv) throws Exception{
MbElement elementInputEnvironment = inputEnv.getRootElement();
MbElement elementKey = elementInputEnvironment.getFirstElementByPath( " Variables/BOKey " );
String strKey = elementKey.getValueAsString();
return strKey;
}
/**
* getValue
* get value from output environment
*
* @param outputEnv
* @return
* @throws Exception
*/
private byte [] getValue(MbMessage outputEnv) throws Exception{
MbElement elementOutputVariables = outputEnv.getRootElement().getFirstElementByPath( " Variables " );
MbElement elementValue = elementOutputVariables.getFirstElementByPath( " Value " );
byte [] byteInputObject = ( byte [])elementValue.getValue();
return byteInputObject;
}
/**
* copyMessageHeaders
* @param inMessage
* @param outMessage
* @throws MbException
*/
private void copyMessageHeaders(MbMessage inMessage, MbMessage outMessage) throws MbException {
MbElement outRoot = outMessage.getRootElement();
// iterate though the headers starting with the first child of the root element
MbElement header = inMessage.getRootElement().getFirstChild();
while (header != null && header.getNextSibling() != null ) // stop before the last child of the body
{
// copy the header and add it to the out message
outRoot.addAsLastChild(header.copy());
// move along to next header
header = header.getNextSibling();
}
}
}
源码下载:
http://www.blogjava.net/Files/heyang/SimpleCacheInJavaComputeNode_01.rar