Pas Apicella
Information on Pivotal -> Product Family - GemFire, SQLFire, tc Server, RabbitMQ, Pivotal HD, Greenplum DBPas Apicellahttp://www.blogger.com/profile/09389663166398991762noreply@blogger.comBlogger227125
Updated: 8 hours 53 min ago
Naming Members in vFabric SQLFire
I find it useful to give a member a meaningful name. In SQLFire you could simply give each member a name by adding a property "name" as follows to the sqlfire.properties file for the member.
sqlfire.properties
# sqlfire.properties for data store or accessor member
license-serial-number=XXXXXXXXXXX
name=server1
Note: The same can be done with GemFire as well.
Then when the system is up the ID for each system member includes the given name as shown below.
sqlfire.properties
# sqlfire.properties for data store or accessor member
license-serial-number=XXXXXXXXXXX
name=server1
Note: The same can be done with GemFire as well.
Then when the system is up the ID for each system member includes the given name as shown below.
sqlf> select substr(id, 1 , 35) as "Member" from sys.members; Member ----------------------------------- 172.16.62.1(server2:38971)<v2>:4265 172.16.62.1(server1:38970)<v1>:1660 127.0.0.1(38744):29535 3 rows selectedhttp://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
JMX access to vFabric SQLFire
With the release of vFabric SQLFire 11 we can now start a JMX manager with the locator itself. To do that we add the following to the sqlfire.properties file of the locator itself.
jmx-manager=true
jmx-manager-start=true
jmx-manager-ssl=false
jmx-manager-http-port=8083
Then with the locator started we can verify we have it running on the default port of 1099 as shown below.
[Thu May 02 09:45:49 papicella@:~/sqlfire/vFabric_SQLFire_11_b40332/pasdemos/agent-test/locator ] $ netstat -an | grep 1099
tcp4 0 0 127.0.0.1.1099 127.0.0.1.64803 ESTABLISHED
tcp4 0 0 127.0.0.1.1099 127.0.0.1.64801 ESTABLISHED
tcp4 0 0 127.0.0.1.64801 127.0.0.1.1099 ESTABLISHED
tcp4 0 0 127.0.0.1.64803 127.0.0.1.1099 ESTABLISHED
tcp4 0 0 127.0.0.1.1099 127.0.0.1.64799 ESTABLISHED
tcp4 0 0 127.0.0.1.64799 127.0.0.1.1099 ESTABLISHED
tcp46 0 0 *.1099 *.* LISTEN
Finally start jconsole and connect using a service URL as follows
Format:
service:jmx:rmi://{hotname}/jndi/rmi://{hostname}:1099/jmxrmi
Example:
service:jmx:rmi://Pas-Apicellas-MacBook-Pro.local/jndi/rmi://Pas-Apicellas-MacBook-Pro.local:1099/jmxrmi
Once connected you can browse the MBean as shown in the image below.
More Information
http://pubs.vmware.com/vfabric53/index.jsp?topic=/com.vmware.vfabric.sqlfire.1.1/manage_guide/jmx/jmx_intro.htmlhttp://feeds.feedburner.com/TheBlasFromPas
jmx-manager=true
jmx-manager-start=true
jmx-manager-ssl=false
jmx-manager-http-port=8083
Then with the locator started we can verify we have it running on the default port of 1099 as shown below.
[Thu May 02 09:45:49 papicella@:~/sqlfire/vFabric_SQLFire_11_b40332/pasdemos/agent-test/locator ] $ netstat -an | grep 1099
tcp4 0 0 127.0.0.1.1099 127.0.0.1.64803 ESTABLISHED
tcp4 0 0 127.0.0.1.1099 127.0.0.1.64801 ESTABLISHED
tcp4 0 0 127.0.0.1.64801 127.0.0.1.1099 ESTABLISHED
tcp4 0 0 127.0.0.1.64803 127.0.0.1.1099 ESTABLISHED
tcp4 0 0 127.0.0.1.1099 127.0.0.1.64799 ESTABLISHED
tcp4 0 0 127.0.0.1.64799 127.0.0.1.1099 ESTABLISHED
tcp46 0 0 *.1099 *.* LISTEN
Finally start jconsole and connect using a service URL as follows
Format:
service:jmx:rmi://{hotname}/jndi/rmi://{hostname}:1099/jmxrmi
Example:
service:jmx:rmi://Pas-Apicellas-MacBook-Pro.local/jndi/rmi://Pas-Apicellas-MacBook-Pro.local:1099/jmxrmi
Once connected you can browse the MBean as shown in the image below.
More Information
http://pubs.vmware.com/vfabric53/index.jsp?topic=/com.vmware.vfabric.sqlfire.1.1/manage_guide/jmx/jmx_intro.htmlhttp://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
Explain Plan in vFabric SQLFire improved
With the recently released vFabric SQLFire 11 version the query execution plan is much easier to read then previously. An example below.
[Wed May 01 11:32:11 papicella@:~/sqlfire/vFabric_SQLFire_11_b40332/pasdemos/sqlfire ] $ sqlf
sqlf version 10.4
sqlf> connect peer 'bind-address=localhost;mcast-port=12333;host-data=false' as peerClient;
sqlf> explain select * from emp where deptno = 20;
MEMBER_PLAN
--------------------------------------------------------------------------------------------------------------------------------
ORIGINATOR 192.168.14.167(73118)<v6>:61492 BEGIN TIME 2013-05-01 11:32:39.735 END TIME 2013-05-01 11:32:39.777
DISTRIBUTION to &
Slowest Member Plan:
member 192.168.14.167(72048)<v1>:42223 begin_execution 2013-05-01 11:32:39.74 end_execution 2013-05-01 11:&
Fastest Member Plan:
member 192.168.14.167(72048)<v1>:42223 begin_execution 2013-05-01 11:32:39.74 end_execution 2013-05-01 11:&
3 rows selected
sqlf> select STMT_ID, STMT_TEXT from SYS.STATEMENTPLANS;
STMT_ID |STMT_TEXT
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
00000001-ffff-ffff-ffff-000400000016| select * from emp where deptno = <?>
1 row selected
sqlf> explain '00000001-ffff-ffff-ffff-000400000016';
stmt_id 00000001-ffff-ffff-ffff-000400000016 SQL_stmt select * from emp where deptno = <?> begin_execution 2013-05-01 11:32:39.735 end_execution 2013-05-01 11:32:39.777
QUERY-SCATTER execute_time 0.0 ms
QUERY-SEND
RESULT-RECEIVE
SEQUENTIAL-ITERATION (0.38%) execute_time 0.136 ms returned_rows 5 no_opens 1
RESULT-HOLDER returned_rows 5 no_opens 1
DISTRIBUTION-END (99.61%) execute_time 35.073 ms returned_rows 5
member 192.168.14.167(72048)<v1>:42223 begin_execution 2013-05-01 11:32:39.74 end_execution 2013-05-01 11:32:39.774
QUERY-RECEIVE
RESULT-SEND
RESULT-HOLDER returned_rows 5 no_opens 1
ROWIDSCAN (1.71%) execute_time 0.148 ms returned_rows 5 no_opens 1 node_details EMP :
CONSTRAINTSCAN (98.28%) execute_time 8.482 ms returned_rows 5 no_opens 1 scan_qualifiers None scanned_object APP.6__EMP__DEPTNO:base-table:APP.EMP scan_type node_details WHERE : ((DEPTNO = CONSTANT:20) and true)
http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
Handling DML Events Synchronously with vFabric SQLFire
SQLFire provides synchronous cache plug-in mechanisms to handle cache events. This example is a synchronous listener. A listener
enables you to receive after-event notifications of changes to a table (insert,
update and delete). Any number of listeners can be defined for the same table.
Listener callbacks are called synchronously, so they will cause the DML
operation to block if the callback blocks.
CommandTableEventCallBackListenerImpl.java
Attach Listener to a table.
More Information
http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.sqlfire.1.1/caching_database/cache-plug-ins.htmlhttp://feeds.feedburner.com/TheBlasFromPas
CommandTableEventCallBackListenerImpl.java
package pivotal.au.demo.poc.listener;
import java.sql.ResultSet;
import java.sql.SQLException;
import pivotal.au.demo.poc.domain.Command;
import pivotal.au.demo.poc.executor.ExecutorCommand;
import pivotal.au.demo.poc.executor.ExecutorFactory;
import com.vmware.sqlfire.callbacks.Event;
import com.vmware.sqlfire.callbacks.Event.Type;
import com.vmware.sqlfire.callbacks.EventCallback;
public class CommandTableEventCallBackListenerImpl implements EventCallback
{
public void close() throws SQLException
{
}
public void init(String configuration) throws SQLException
{
System.out.println("configuration = " + configuration);
System.out.println("CommandTableEventCallBackListenerImpl.init");
}
public void onEvent(Event event) throws SQLException
{
if (event.getType() == Type.AFTER_INSERT)
{
ResultSet rset = event.getNewRowsAsResultSet();
Command cmd =
new Command(rset.getInt(1),
rset.getString(2),
rset.getString(3),
rset.getString(4),
rset.getString(5));
System.out.println("Table[" + event.getTableName() + "] Command = " + cmd.toString());
handleEvent(cmd);
}
else
{
System.out.println("Not processing event " + event.getType().toString());
}
}
private void handleEvent (Command cmd)
{
System.out.println("Handling event for Command with id = " + cmd.getId());
ExecutorCommand execCommand = null;
if (cmd.getType().equalsIgnoreCase("OS"))
{
execCommand = ExecutorFactory.getOSExecutorImpl();
execCommand.runCommand(cmd.getCommand(), null);
}
else
{
// expecting to execute SQL so check if firing on sqlfire or greenplum at this stage
execCommand = ExecutorFactory.getSQLExecutorImpl();
if (cmd.getExecuteOnGreenplum().equalsIgnoreCase("Y"))
{
execCommand.runCommand(cmd.getCommand(), "GP");
}
if (cmd.getExecuteOnSqlfire().equalsIgnoreCase("Y"))
{
execCommand.runCommand(cmd.getCommand(), "SQLFIRE");
}
}
}
}
Attach Listener to a table.
CREATE TABLE command_table
(ID INT generated always as identity NOT NULL,
EXECUTE_ON_SQLFIRE VARCHAR(1) default 'N',
EXECUTE_ON_GREENPLUM VARCHAR(1) default 'Y',
command_type varchar(10),
COMMAND VARCHAR(200) not null
)
SERVER GROUPS (MYGROUP);
call sys.ADD_LISTENER('CommandTableEventCallBackListenerImpl', 'apples', 'command_table', 'pivotal.au.demo.poc.listener.CommandTableEventCallBackListenerImpl', '', 'MYGROUP');
More Information
http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.sqlfire.1.1/caching_database/cache-plug-ins.htmlhttp://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
ADO .NET c# Connection Pooling with vFabric SQLFire
Whether it's accessing a database using JAVA or in this case c# I always want to use a connection pool and in this example I show and simple way to do this with a c# ADO .NET client accessing SQLFire.
1. Add a reference to your Visual Studio project in the VMware.Data.SQLFire.dll. This DLL is installed in the
vFabric_SQLFire_11_bNNNNN\adonet\lib directory.
2. Reference the driver namespace in each source file where you want to use SQLFire components. For example, include this directive with all other references required in your application:
3. Create a c# console application as follows
Output as follows
Dept[deptno=10, dname=ACCOUNTING]
Dept[deptno=20, dname=RESEARCH]
Dept[deptno=30, dname=SALES]
Dept[deptno=40, dname=OPERATIONS]
Dept[deptno=50, dname=MARKETING]
Dept[deptno=60, dname=DEV]
Dept[deptno=70, dname=SUPPORT]
Press any key to continue . . .http://feeds.feedburner.com/TheBlasFromPas
1. Add a reference to your Visual Studio project in the VMware.Data.SQLFire.dll. This DLL is installed in the
vFabric_SQLFire_11_bNNNNN\adonet\lib directory.
2. Reference the driver namespace in each source file where you want to use SQLFire components. For example, include this directive with all other references required in your application:
using VMware.Data.SQLFire;
3. Create a c# console application as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VMware.Data.SQLFire;
using System.Data;
namespace SQLFireDemo
{
class QueryDemo
{
private string sqlfHost = "192.168.1.4";
private int sqlfPort = 1527;
public QueryDemo()
{
}
private string GetConnectionString()
{
return string.Format(@"server={0}:{1}", sqlfHost, sqlfPort);
}
public void run()
{
using (SQLFClientConnection conn = new SQLFClientConnection(GetConnectionString()))
{
conn.Open();
SQLFCommand command = new SQLFCommand
(string.Format("SELECT * FROM dept"), conn);
SQLFDataReader reader = command.ExecuteReader();
try
{
StringBuilder row = new StringBuilder();
while (reader.Read())
{
Console.WriteLine(string.Format("Dept[deptno={0}, dname={1}]",
reader.GetString(0),
reader.GetString(1)));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
reader.Close();
}
}
}
static void Main(string[] args)
{
QueryDemo test = new QueryDemo();
test.run();
}
}
}
Output as follows
Dept[deptno=10, dname=ACCOUNTING]
Dept[deptno=20, dname=RESEARCH]
Dept[deptno=30, dname=SALES]
Dept[deptno=40, dname=OPERATIONS]
Dept[deptno=50, dname=MARKETING]
Dept[deptno=60, dname=DEV]
Dept[deptno=70, dname=SUPPORT]
Press any key to continue . . .http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
vFabric GemFire and the Native Client World using c#
Recently I had to step out of my comfort zone and learn how to create a c# client to access a GemFire 7 distributed system for a demo to a customer. OIf course there was more to it then just that but this outlines what you need to do to connect as a c# client to GemFire. I was using the following here.
https://my.vmware.com/web/vmware/info/slug/application_platform/vmware_vfabric_gemfire/7_0
2. Once installed setup an ENV variable as shown below pointing to the location of the native client install.
C:\Windows\system32>echo %GFCPP%
C:\vFabric_NativeClient_32bit_7010
3. In your Visual Studio 2012 Project / Solution add a reference to GemFire DLL as shown below.
4. In Visual Studio 2012 create a cache.xml as shown below. This client cache is going to use a locator to connect to a cache server instance for the client itself.
xml/cache.xml
5. Create 2 c# classes as shown below.
GemFireClient.cs
GemFireTest.cs
Output omitted but this should give you the general idea.
http://feeds.feedburner.com/TheBlasFromPas
- Visual Studio 2012
- GemFire 32 bit Naive Client
https://my.vmware.com/web/vmware/info/slug/application_platform/vmware_vfabric_gemfire/7_0
2. Once installed setup an ENV variable as shown below pointing to the location of the native client install.
C:\Windows\system32>echo %GFCPP%
C:\vFabric_NativeClient_32bit_7010
3. In your Visual Studio 2012 Project / Solution add a reference to GemFire DLL as shown below.
4. In Visual Studio 2012 create a cache.xml as shown below. This client cache is going to use a locator to connect to a cache server instance for the client itself.
xml/cache.xml
<?xml version="1.0"?>
<!DOCTYPE client-cache PUBLIC
"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<client-cache>
<pool name="client" subscription-enabled="true">
<locator host="172.16.62.1" port="10334" />
</pool>
<region name="CommandRegion">
<region-attributes refid="PROXY" pool-name="client">
</region-attributes>
</region>
<region name="changeTrackingRegion">
<region-attributes data-policy="normal" pool-name="client">
</region-attributes>
</region>
</client-cache>
5. Create 2 c# classes as shown below.
GemFireClient.cs
using GemStone.GemFire.Cache.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace pivotal.au.company.poc
{
class GemFireClient
{
private static bool isStarted = false;
private static GemFireClient instance = new GemFireClient();
private string configFileLocation = "xml/cache.xml";
private Properties<string, string> properties = Properties<string, string>.Create<string, string>();
private CacheFactory cacheFactory;
private Cache cache;
IRegion<string, string> ctrRegion;
private GemFireClient()
{
Console.WriteLine("Reading properties file xml/cache.xml...");
string clientCacheXml = getCacheConfigLocation(configFileLocation);
properties.Insert("cache-xml-file", clientCacheXml);
Serializable.RegisterPdxSerializer(new ReflectionBasedAutoSerializer());
cacheFactory = CacheFactory.CreateCacheFactory(properties);
cache = cacheFactory.Create();
ctrRegion = cache.GetRegion<string, string>("changeTrackingRegion");
ctrRegion.GetSubscriptionService().RegisterRegex(".");
Console.WriteLine("ctrRegion size = " + ctrRegion.Count);
}
public static GemFireClient getInstance()
{
return instance;
}
public void closeClientCache()
{
cache.Close();
Console.WriteLine("Client Cache closed...");
}
public Cache getCache()
{
return cache;
}
private static string getCacheConfigLocation(string cacheXml)
{
var directoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (File.Exists(System.Environment.GetEnvironmentVariable("COMPANY_CONFIG") + "/" + cacheXml) == true)
{
return System.Environment.GetEnvironmentVariable("COMPANY_CONFIG") + "/" + cacheXml;
}
else if (File.Exists(Path.Combine(directoryName, cacheXml)) == true)
{
return Path.Combine(directoryName, cacheXml);
}
else
{
throw new SystemException("Unable to find /" + cacheXml);
}
}
}
}
GemFireTest.cs
using pivotal.au.company.poc.domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GemStone.GemFire.Cache.Generic;
namespace pivotal.au.company.poc
{
class GemFireTest
{
GemFireClient gfClient;
public void doInsert()
{
gfClient = GemFireClient.getInstance();
// get command region
IRegion<string, Command> commandRegion = gfClient.getCache().GetRegion<string, Command>("CommandRegion");
// insert a Command Object into the region
Command command = new Command();
command.eventType = "INSERT";
command.tableName = "Holiday";
command.tableKey = "1";
command.sequence = 31;
command.payload = new Dictionary<object, object>()
{
{"Id", "1"},
{"name", "apples"},
{"createdate", "10-10-2009"}
};
Console.WriteLine(command.ToString());
commandRegion[command.tableKey] = command;
}
public void queryCommandRegion()
{
gfClient = GemFireClient.getInstance();
Console.WriteLine("about to query commandRegion");
QueryService<string, Command> queryService = gfClient.getCache().GetQueryService<string, Command>();
Query<Command> qry = queryService.NewQuery("SELECT * FROM /CommandRegion");
ISelectResults<Command> results = qry.Execute();
SelectResultsIterator<Command> iter = results.GetIterator();
while (iter.MoveNext())
{
Console.WriteLine(iter.Current.ToString());
}
}
public void closeCache()
{
gfClient.closeClientCache();
}
public void run()
{
GemFireTest test = new GemFireTest();
test.doInsert();
test.queryCommandRegion();
test.closeCache();
}
}
}
Output omitted but this should give you the general idea.
http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
Implementing an AsyncEventListener for Write-Behind Cache Event Handling
As part of GemFire 70 release they have introduced as AsyncEventListener for write behind capability which is more or less very similar to the Gateway Listener in GemFire 6.x
An AsyncEventListener receives callbacks for events that change region data. You can use an AsyncEventListener implementation as a write-behind cache event handler to synchronize region updates with a database.
It documented as follows.
http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.gemfire.7.0/developing/events/implementing_write_behind_event_handler.html
So how would my cache.xml file for a member look like here.
Finally the code to write an AsyncEventListener would be as follows.
An AsyncEventListener receives callbacks for events that change region data. You can use an AsyncEventListener implementation as a write-behind cache event handler to synchronize region updates with a database.
It documented as follows.
http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.gemfire.7.0/developing/events/implementing_write_behind_event_handler.html
So how would my cache.xml file for a member look like here.
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<cache>
<async-event-queue id="GreenplumQueue" parallel="true" batch-size="500">
<async-event-listener>
<class-name>vmware.pivotal.example.listener.GreenplumGatewayListener</class-name>
</async-event-listener>
</async-event-queue>
<cache-server port="40001" notify-by-subscription="true"/>
<region name="greenplumRegion">
<region-attributes refid="PARTITION_REDUNDANT" async-event-queue-ids="GreenplumQueue"/>
</region>
</cache>
Finally the code to write an AsyncEventListener would be as follows.
package vmware.pivotal.example.listener;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import vmware.pivotal.example.dao.jdbcbatch.JdbcBatch;
import vmware.pivotal.example.dao.jdbcbatch.JdbcBatchDAO;
import com.gemstone.gemfire.cache.Declarable;
import com.gemstone.gemfire.cache.Operation;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
public class GreenplumGatewayListener implements AsyncEventListener, Declarable
{
private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
private ApplicationContext context;
private static final String BEAN_NAME = "jdbcBatchDAOImpl";
private JdbcBatchDAO jdbcBatchDAO;
public GreenplumGatewayListener()
{
context = new ClassPathXmlApplicationContext("application-context.xml");
jdbcBatchDAO = (JdbcBatchDAO) context.getBean(BEAN_NAME);
logger.log (Level.INFO, "GreenplumGatewayListener started...");
}
@Override
public boolean processEvents(@SuppressWarnings("rawtypes") List<AsyncEvent> list)
{
logger.log (Level.INFO, String.format("Size of List<GatewayEvent> = %s", list.size()));
List<JdbcBatch> newEntries = new ArrayList<JdbcBatch>();
List<JdbcBatch> updatedEntries = new ArrayList<JdbcBatch>();
List<String> destroyedEntries = new ArrayList<String>();
int possibleDulicates = 0;
for (@SuppressWarnings("rawtypes") AsyncEvent ge: list)
{
if (ge.getPossibleDuplicate())
possibleDulicates++;
if ( ge.getOperation().equals(Operation.UPDATE))
{
updatedEntries.add((JdbcBatch) ge.getDeserializedValue());
}
else if ( ge.getOperation().equals(Operation.CREATE))
{
newEntries.add((JdbcBatch) ge.getDeserializedValue());
}
else if ( ge.getOperation().equals(Operation.DESTROY))
{
destroyedEntries.add(ge.getKey().toString());
}
}
if (newEntries.size() > 0)
{
jdbcBatchDAO.storeInsertBatch(newEntries);
}
if (updatedEntries.size() > 0)
{
jdbcBatchDAO.storeUpdateBatch(updatedEntries);
}
if (destroyedEntries.size() > 0)
{
jdbcBatchDAO.storeDeleteBatch(destroyedEntries);
}
logger.log (Level.INFO,
String.format("New Entries = [%s], Updated Entries = [%s], Destroyed Entries = [%s], Possible Duplicates = [%s]",
newEntries.size(),
updatedEntries.size(),
destroyedEntries.size(),
possibleDulicates));
return true;
}
public void init(Properties arg0) {
// TODO Auto-generated method stub
}
public void close() {
// TODO Auto-generated method stub
}
}
http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
MyBatis-Spring with vFabric SQLFire
MyBatis-Spring helps you integrate your MyBatis code seamlessly with
Spring. Using the classes in this library, Spring will load the
necessary MyBatis factory and session classes for you. This library also
provides an easy way to inject MyBatis data mappers into your service
beans. Finally, MyBatis-Spring will handle transactions and translate
MyBatis exceptions into Spring DataAccessExceptions.
Here is a simple exampled based on the classic DEPT table.
1. We are working with a DEPT table in SQLFire defined as follows.
DEPT table
2. Setup your pom.xml to include the following.
pom.xml
3. Create the domain modelclass Dept.java, with the standard getter/setters for each attribute. Omitting the full class here.
Dept.java
4.Create a DeptMapper.xml file. I prefer to keep SQL out of the java class wheever I can , hence avoided using annotations here.
DeptMapper.xml
5. Create a DeptMapper interface file. Notice how this is a clean interface and no annotations to specify the SQL we are using as that's in the DeptMapper.xml file above.
DeptMapper.java
6. Create a service class for the DEPT table as shown below.
DeptService.java
7. Create a spring application context file as shown below.
application-context.xml
8. Finally create a test class to verify the setup as shown below.
SpringDeptTest.java
9. Run SpringDeptTest.java and verfy output as shown below.
Feb 20, 2013 9:14:39 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1fff7a1e: startup date [Wed Feb 20 21:14:39 EST 2013]; root of context hierarchy
Feb 20, 2013 9:14:39 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [application-context.xml]
Feb 20, 2013 9:14:40 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@57ac3379: defining beans [dataSource,sqlSessionFactory,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,deptService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.mybatis.spring.mapper.MapperScannerConfigurer#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,deptMapper]; root of factory hierarchy
New DEPT added to SQLFire
Dept [deptno=10, dname=ACCOUNTING, loc=NEW YORK]
Dept [deptno=20, dname=RESEARCH, loc=DALLAS]
Dept [deptno=30, dname=SALES, loc=CHICAGO]
Dept [deptno=40, dname=OPERATIONS, loc=BRISBANE]
Dept [deptno=50, dname=MARKETING, loc=ADELAIDE]
Dept [deptno=60, dname=DEV, loc=PERTH]
Dept [deptno=70, dname=SUPPORT, loc=SYDNEY]
Dept [deptno=99, dname=MYBATIS-TEST, loc=BUNDOORA]
Dept [deptno=20, dname=RESEARCH, loc=DALLAS]
The full project structure is as follows showing where the XML files exists in this setup.
http://feeds.feedburner.com/TheBlasFromPas
Here is a simple exampled based on the classic DEPT table.
1. We are working with a DEPT table in SQLFire defined as follows.
DEPT table
sqlf> describe dept; COLUMN_NAME |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL& ------------------------------------------------------------------------------ DEPTNO |INTEGER |0 |10 |10 |NULL |NULL |NO DNAME |VARCHAR |NULL|NULL|14 |NULL |28 |YES LOC |VARCHAR |NULL|NULL|13 |NULL |26 |YES 3 rows selected
2. Setup your pom.xml to include the following.
pom.xml
<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>sqlfire-mybatis</groupId>
<artifactId>sqlfire-mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sqlfire-mybatis</name>
<properties>
<spring.version>3.1.2.RELEASE</spring.version>
<mybatis.version>3.1.1</mybatis.version>
<mybatis.spring.version>1.1.1</mybatis.spring.version>
<dbcp.version>1.4</dbcp.version>
<cglib.version>2.2.2</cglib.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${dbcp.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>mybatis-snapshot</id>
<name>MyBatis Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
</project>
3. Create the domain modelclass Dept.java, with the standard getter/setters for each attribute. Omitting the full class here.
Dept.java
package pas.au.vmware.se.mybatis.domain;
public class Dept
{
private int deptno;
private String dname;
private String loc;
public Dept()
{
}
public Dept(int deptno, String dname, String loc)
{
super();
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
......
4.Create a DeptMapper.xml file. I prefer to keep SQL out of the java class wheever I can , hence avoided using annotations here.
DeptMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pas.au.vmware.se.mybatis.mapper.DeptMapper">
<resultMap id="result" type="pas.au.vmware.se.mybatis.domain.Dept">
<result property="deptno" column="DEPTNO"/>
<result property="dname" column="DNAME"/>
<result property="loc" column="LOC"/>
</resultMap>
<select id="getAll" resultMap="result">
SELECT * FROM DEPT
</select>
<select id="getById" parameterType="int" resultMap="result">
SELECT * FROM DEPT WHERE DEPTNO = #{deptno}
</select>
<insert id="insertDept" parameterType="pas.au.vmware.se.mybatis.domain.Dept">
INSERT INTO dept (deptno, dname, loc)
VALUES (#{deptno}, #{dname}, #{loc})
</insert>
</mapper>
5. Create a DeptMapper interface file. Notice how this is a clean interface and no annotations to specify the SQL we are using as that's in the DeptMapper.xml file above.
DeptMapper.java
package pas.au.vmware.se.mybatis.mapper;
import java.util.List;
import pas.au.vmware.se.mybatis.domain.Dept;
public interface DeptMapper
{
public List<Dept> getAll();
public Dept getById (int deptno);
public void insertDept (Dept dept);
}
6. Create a service class for the DEPT table as shown below.
DeptService.java
package pas.au.vmware.se.mybatis.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pas.au.vmware.se.mybatis.domain.Dept;
import pas.au.vmware.se.mybatis.mapper.DeptMapper;
@Service("deptService")
public class DeptService
{
@Autowired
private DeptMapper deptMapper;
public DeptMapper getDeptMapper() {
return deptMapper;
}
public void setDeptMapper(DeptMapper deptMapper) {
this.deptMapper = deptMapper;
}
public List<Dept> getAll()
{
return getDeptMapper().getAll();
}
public Dept getById(int deptno)
{
return getDeptMapper().getById(deptno);
}
@Transactional
public void insertDept (Dept dept)
{
getDeptMapper().insertDept(dept);
}
}
7. Create a spring application context file as shown below.
application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.vmware.sqlfire.jdbc.ClientDriver" />
<property name="url" value="jdbc:sqlfire://localhost:1527/" />
<property name="username" value="app" />
<property name="password" value="app" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven />
<context:component-scan base-package="pas.au.vmware.se.mybatis.service" />
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="pas.au.vmware.se.mybatis.mapper" />
</bean>
</beans>
8. Finally create a test class to verify the setup as shown below.
SpringDeptTest.java
package pas.au.vmware.se.mybatis.test;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pas.au.vmware.se.mybatis.domain.Dept;
import pas.au.vmware.se.mybatis.service.DeptService;
public class SpringDeptTest
{
/**
* @param args
*/
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext(
"application-context.xml");
DeptService deptService = (DeptService) context.getBean("deptService");
Dept dept = new Dept(99, "MYBATIS-TEST", "BUNDOORA");
deptService.insertDept(dept);
System.out.println("New DEPT added to SQLFire\n");
List<Dept> deps = deptService.getAll();
for (Dept d: deps)
{
System.out.println(d);
}
System.out.println("\n" + deptService.getById(20));
}
}
9. Run SpringDeptTest.java and verfy output as shown below.
Feb 20, 2013 9:14:39 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1fff7a1e: startup date [Wed Feb 20 21:14:39 EST 2013]; root of context hierarchy
Feb 20, 2013 9:14:39 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [application-context.xml]
Feb 20, 2013 9:14:40 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@57ac3379: defining beans [dataSource,sqlSessionFactory,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,deptService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.mybatis.spring.mapper.MapperScannerConfigurer#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,deptMapper]; root of factory hierarchy
New DEPT added to SQLFire
Dept [deptno=10, dname=ACCOUNTING, loc=NEW YORK]
Dept [deptno=20, dname=RESEARCH, loc=DALLAS]
Dept [deptno=30, dname=SALES, loc=CHICAGO]
Dept [deptno=40, dname=OPERATIONS, loc=BRISBANE]
Dept [deptno=50, dname=MARKETING, loc=ADELAIDE]
Dept [deptno=60, dname=DEV, loc=PERTH]
Dept [deptno=70, dname=SUPPORT, loc=SYDNEY]
Dept [deptno=99, dname=MYBATIS-TEST, loc=BUNDOORA]
Dept [deptno=20, dname=RESEARCH, loc=DALLAS]
The full project structure is as follows showing where the XML files exists in this setup.
http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
Adding JSON Documents into GemFire Cache
The
JSONFormatter API allows you to put JSON formatted
documents into regions and retrieve them later by storing the documents
internally as PdxInstances. vFabric GemFire now supports the use of JSON formatted documents
natively. When you add a JSON document to a GemFire cache, you call the
JSONFormatter APIs to transform them into the PDX format (as a
PdxInstance), which enables GemFire to understand the
JSON document at a field level.
In terms of querying and indexing, because the documents are stored internally as PDX, applications can index on any field contained inside the JSON document including any nested field (within JSON objects or JSON arrays.) Any queries run on these stored documents will return PdxInstances as results. To update a JSON document stored in GemFire, you can execute a function on the PdxInstance.
You can then use the JSONFormatter to convert the PdxInstance results back into the JSON document.
Here is a simple example.
1. server side cache.xml file, in this demo we just start up one cache server
cache.xml
2. Client side cache.xml
client.xml
3. Java class to insert some JSON formatted documents into the cache then how to query them back using a field from the JSON document itself.
JSONGemFireClient.java
4. Run the java class above and verify output as follows
....
[info 2013/02/13 09:41:15.464 EST tid=0x1] Defining: PdxType[
id=1, name=__GEMFIRE_JSON, fields=[
age:byte:0:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=0
name:String:1:idx0(relativeOffset)=1:idx1(vlfOffsetIndex)=-1]]
Number of entries where age = 30 is -> 5
** JSON data **
Name = Person1
Full JSON data ->
{
"age" : 30,
"name" : "Person1"
}
** JSON data **
Name = Person4
Full JSON data ->
{
"age" : 30,
"name" : "Person4"
}
** JSON data **
Name = Person2
Full JSON data ->
{
"age" : 30,
"name" : "Person2"
}
** JSON data **
Name = Person5
Full JSON data ->
{
"age" : 30,
"name" : "Person5"
}
** JSON data **
Name = Person3
Full JSON data ->
{
"age" : 30,
"name" : "Person3"
}
....
5. Finally use GFSH to query the region itself and you wouldn't even know your using JSON stored documents and would rely on using JSONFormatter to convert the data back into JSON document.
More information can be found on the link below.
http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.gemfire.7.0/developing/data_serialization/jsonformatter_pdxinstances.htmlhttp://feeds.feedburner.com/TheBlasFromPas
In terms of querying and indexing, because the documents are stored internally as PDX, applications can index on any field contained inside the JSON document including any nested field (within JSON objects or JSON arrays.) Any queries run on these stored documents will return PdxInstances as results. To update a JSON document stored in GemFire, you can execute a function on the PdxInstance.
You can then use the JSONFormatter to convert the PdxInstance results back into the JSON document.
Here is a simple example.
1. server side cache.xml file, in this demo we just start up one cache server
cache.xml
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<cache>
<cache-server port="40404"/>
<region name="jsonregion">
<region-attributes refid="REPLICATE" />
</region>
</cache>
2. Client side cache.xml
client.xml
<?xml version="1.0"?>
<!DOCTYPE client-cache PUBLIC
"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<!--
| Client.xml
|
| Configures a region as a client region in a client/server cache. The
| region's pool connects to a cacheserver listening on port 40404.
-->
<client-cache>
<pool name="client" subscription-enabled="true">
<server host="localhost" port="40404" />
</pool>
<region name="jsonregion">
<region-attributes refid="PROXY">
</region-attributes>
</region>
</client-cache>
3. Java class to insert some JSON formatted documents into the cache then how to query them back using a field from the JSON document itself.
JSONGemFireClient.java
package vmware.au.gemfire7.json.client;
import java.util.List;
import org.json.simple.JSONObject;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.query.SelectResults;
import com.gemstone.gemfire.pdx.JSONFormatter;
import com.gemstone.gemfire.pdx.PdxInstance;
public class JSONGemFireClient
{
public static final String REGION_NAME = "jsonregion";
public ClientCache cache = null;
public JSONGemFireClient()
{
cache = new ClientCacheFactory()
.set("name", "JSONClient")
.set("cache-xml-file", "xml/client.xml")
.create();
}
@SuppressWarnings("unchecked")
public void run() throws Exception
{
JSONObject obj = null;
System.out.println("Connecting to the distributed system and creating the cache.");
// Get the exampleRegion
Region<String, PdxInstance> jsonregion = cache.getRegion(REGION_NAME);
System.out.println("Example region \"" + jsonregion.getFullPath() + "\" created in cache.");
// add 5 entries with age = 30
for (int i = 1; i <= 5; i++)
{
obj = new JSONObject();
obj.put("name", String.format("Person%s", i));
obj.put("age", 30);
jsonregion.put(String.valueOf(i), JSONFormatter.fromJSON(obj.toJSONString()));
}
// add 5 entries with age = 20
for (int i = 6; i <= 10; i++)
{
obj = new JSONObject();
obj.put("name", String.format("Person%s", i));
obj.put("age", 20);
jsonregion.put(String.valueOf(i), JSONFormatter.fromJSON(obj.toJSONString()));
}
// Query region
SelectResults<PdxInstance> sr = jsonregion.query("age = 30");
System.out.println("Number of entries where age = 30 is -> " + sr.size());
List<PdxInstance> entries = sr.asList();
for (PdxInstance val: entries)
{
System.out.println("\n** JSON data ** ");
System.out.println("Name = " + val.getField("name"));
System.out.println("Full JSON data -> \n" + JSONFormatter.toJSON(val));
}
cache.close();
}
/**
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
JSONGemFireClient test = new JSONGemFireClient();
try
{
test.run();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4. Run the java class above and verify output as follows
....
[info 2013/02/13 09:41:15.464 EST tid=0x1] Defining: PdxType[
id=1, name=__GEMFIRE_JSON, fields=[
age:byte:0:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=0
name:String:1:idx0(relativeOffset)=1:idx1(vlfOffsetIndex)=-1]]
Number of entries where age = 30 is -> 5
** JSON data **
Name = Person1
Full JSON data ->
{
"age" : 30,
"name" : "Person1"
}
** JSON data **
Name = Person4
Full JSON data ->
{
"age" : 30,
"name" : "Person4"
}
** JSON data **
Name = Person2
Full JSON data ->
{
"age" : 30,
"name" : "Person2"
}
** JSON data **
Name = Person5
Full JSON data ->
{
"age" : 30,
"name" : "Person5"
}
** JSON data **
Name = Person3
Full JSON data ->
{
"age" : 30,
"name" : "Person3"
}
....
5. Finally use GFSH to query the region itself and you wouldn't even know your using JSON stored documents and would rely on using JSONFormatter to convert the data back into JSON document.
gfsh>connect --jmx-manager=localhost[1099] Connecting to Manager at [host=localhost, port=1099] .. Successfully connected to: [host=localhost, port=1099] gfsh>list regions; List of regions --------------- jsonregion gfsh>query --query="select * from /jsonregion"; Result : true startCount : 0 endCount : 20 Rows : 10 age | name --- | -------- 30 | Person1 30 | Person4 20 | Person8 20 | Person10 20 | Person6 30 | Person2 30 | Person5 20 | Person9 20 | Person7 30 | Person3 NEXT_STEP_NAME : END
More information can be found on the link below.
http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.gemfire.7.0/developing/data_serialization/jsonformatter_pdxinstances.htmlhttp://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware
JSON messages with RabbitMQ
Using JSON message solution in RabbitMQ gives you something that's a bit more friendly in polyglot systems, and leaves your application with more future flexibility. Although we can use Java Objects this puts restrictions on the the recipients of your message as they're also going to need to be in Java. JSON (JavaScript Object Notation) is rather common
alternative that is more flexible and portable across different
languages and platforms.
In the example below we use the following
RabbitMQ 3.0 - http://www.rabbitmq.com/
JSON-Simple - http://code.google.com/p/json-simple/
1. Create a start up script to start a single RabbitMQ server.
export RABBITMQ_NODE_PORT=5676
export RABBITMQ_NODENAME=rabbit_standalone
export RABBIT_HOME=/Users/papicella/vmware/software/rabittMQ/rabbitmq_server-3.0.0
$RABBIT_HOME/sbin/rabbitmq-server -detached
netstat -an | grep 5676
2. Start as shown below.
[Mon Feb 11 21:07:17 papicella@:~/rabbitMQ/standalone-rabbit ] $ sudo ./node1.sh
Warning: PID file not written; -detached was passed.
tcp4 0 0 *.5676 *.* LISTEN
tcp46 0 0 *.5676 *.* LISTEN
3. Create a RECEIVE client which will create a QUEUE and wait for messages. IT is expecting a JSON string to be sent.
JSONRecv.java
4. Create a SEND client and place 10 JSON objects onto the QUEUE
JSONSend.java
5. Run JSONRecv.java and verify output as follows
[*] Waiting for messages. To exit press CTRL+C
6. Run JSONSend.java and then check the output from JSONRecv.java.
[*] Waiting for messages. To exit press CTRL+C
[x] Received '{"name":"Person1","age":37}'
[x] Received '{"name":"Person2","age":37}'
[x] Received '{"name":"Person3","age":37}'
[x] Received '{"name":"Person4","age":37}'
[x] Received '{"name":"Person5","age":37}'
[x] Received '{"name":"Person6","age":37}'
[x] Received '{"name":"Person7","age":37}'
[x] Received '{"name":"Person8","age":37}'
[x] Received '{"name":"Person9","age":37}'
[x] Received '{"name":"Person10","age":37}'
For more information on RabbitMQ view the link below.
http://www.rabbitmq.com/
http://feeds.feedburner.com/TheBlasFromPas
In the example below we use the following
RabbitMQ 3.0 - http://www.rabbitmq.com/
JSON-Simple - http://code.google.com/p/json-simple/
1. Create a start up script to start a single RabbitMQ server.
export RABBITMQ_NODE_PORT=5676
export RABBITMQ_NODENAME=rabbit_standalone
export RABBIT_HOME=/Users/papicella/vmware/software/rabittMQ/rabbitmq_server-3.0.0
$RABBIT_HOME/sbin/rabbitmq-server -detached
netstat -an | grep 5676
2. Start as shown below.
[Mon Feb 11 21:07:17 papicella@:~/rabbitMQ/standalone-rabbit ] $ sudo ./node1.sh
Warning: PID file not written; -detached was passed.
tcp4 0 0 *.5676 *.* LISTEN
tcp46 0 0 *.5676 *.* LISTEN
3. Create a RECEIVE client which will create a QUEUE and wait for messages. IT is expecting a JSON string to be sent.
JSONRecv.java
package pas.au.rabbitmq30.tutorial.helloworld.json;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
public class JSONRecv
{
private final static String QUEUE_NAME = "json-example";
private ConnectionFactory factory = null;
private JSONParser parser;
public JSONRecv()
{
parser = new JSONParser();
}
public void run () throws Exception
{
factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5676);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
JSONObject obj = (JSONObject) parser.parse(message);
System.out.println(" [x] Received '" + obj.toJSONString() + "'");
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
// TODO Auto-generated method stub
JSONRecv test = new JSONRecv();
test.run();
}
}
4. Create a SEND client and place 10 JSON objects onto the QUEUE
JSONSend.java
package pas.au.rabbitmq30.tutorial.helloworld.json;
import org.json.simple.JSONObject;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class JSONSend
{
private final static String QUEUE_NAME = "json-example";
private ConnectionFactory factory = null;
public JSONSend()
{
// TODO Auto-generated constructor stub
}
@SuppressWarnings("unchecked")
public void run() throws Exception
{
factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5676);
System.out.println("connected to rabbitMQ on localhost ...");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
for (int i = 1; i <= 10; i++)
{
JSONObject obj = new JSONObject();
obj.put("name", String.format("Person%s", i));
obj.put("age", new Integer(37));
channel.basicPublish("", QUEUE_NAME, null, obj.toJSONString().getBytes());
System.out.println(" [x] Sent '" + obj.toJSONString() + "'");
}
channel.close();
connection.close();
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
// TODO Auto-generated method stub
JSONSend test = new JSONSend();
test.run();
}
}
5. Run JSONRecv.java and verify output as follows
[*] Waiting for messages. To exit press CTRL+C
6. Run JSONSend.java and then check the output from JSONRecv.java.
[*] Waiting for messages. To exit press CTRL+C
[x] Received '{"name":"Person1","age":37}'
[x] Received '{"name":"Person2","age":37}'
[x] Received '{"name":"Person3","age":37}'
[x] Received '{"name":"Person4","age":37}'
[x] Received '{"name":"Person5","age":37}'
[x] Received '{"name":"Person6","age":37}'
[x] Received '{"name":"Person7","age":37}'
[x] Received '{"name":"Person8","age":37}'
[x] Received '{"name":"Person9","age":37}'
[x] Received '{"name":"Person10","age":37}'
For more information on RabbitMQ view the link below.
http://www.rabbitmq.com/
http://feeds.feedburner.com/TheBlasFromPas
Categories: Fusion Middleware


