Thursday, 30 September 2010

Running Coherence Query/Command line clients in JDeveloper 11g

Always wanted to run the command line client and query client from JDeveloper but because JDeveloper does not allow you to specify a runnable class which belongs in a JAR file this is not possible. However thanks to the help of an internal employee I found you can do it as follows

The two clients are these two scripts below which use a class in coherence.jar as follows

coherence.cmd - com.tangosol.net.CacheFactory
query.cmd (New In Coherence 3.6) - com.tangosol.coherence.dslquery.QueryPlus

1. Create a new empty project in JDeveloper
2. Add 2 classes as follows for each client.

coherence.cmd - com.tangosol.net.CacheFactory
package pas.au.coherence.utils;

import com.tangosol.net.CacheFactory;

public class JdevCoherenceClient extends CacheFactory
{
  public JdevCoherenceClient()
  {
  }
}

query.cmd (New In Coherence 3.6) - com.tangosol.coherence.dslquery.QueryPlus
package pas.au.coherence.utils;

import com.tangosol.coherence.dslquery.QueryPlus;

public class JdevCoherenceQueryClient extends QueryPlus
{
  public JdevCoherenceQueryClient()
  {
  }
}

3.At a minimum if we use the default cache config file in coherence.jar we simply need to create a run/debug/profile for each client as follows. This is the example for the QueryPlus client where the config is called "CoherenceQueryClient"


Notice how I have set the JVM propery -Dtangosol.coherence.ttl=0 to avoid joining any clusters outside my own machine. Basically this will ensure no packets are sent from my machine. You would specify any other properties here for coherence such as -Dtangosol.coherence.cacheconfig if you have your own config file. Also the "Default Run target" is set to the class we created above which will then use the class we extended.

4. In that dialog select "Tool Settings" and ensure "Allow program Input" is checked as we need to type at the command prompt.

5. Now run your config select the Run icon in the toolbar and then selecting one of the 2 config you created.

Output in the log window would be as follows

Monday, 27 September 2010

Coherence - Continuous Query Caching

Coherence provides the ability to have a cache provide a feature that combines a query result with a continuous stream of related events to maintain an up-to-date query result in a real-time fashio. To demonstrate this here is a simple demo.

1. Create a very simple object which contains a single attribute "gender" for either male's or females.

package pas.au.coherence.querycaching;

public class DemoObject implements java.io.Serializable
{
  private String gender;

  public DemoObject ()
  {  
  }

  public DemoObject (String _gender)
  {  
   gender = _gender;
  }
  
  public String getGender() 
  {
    return gender;
  }

  public void setGender(String gender) 
  {
    this.gender = gender;
  }
  
}
2. Create a simple test class as follows.
package pas.au.coherence.querycaching;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import com.tangosol.net.cache.ContinuousQueryCache;
import com.tangosol.util.Filter;
import com.tangosol.util.filter.EqualsFilter;

import java.util.logging.Level;
import java.util.logging.Logger;

public class ContinuousQueryCacheDemo
{
  private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
  
  public ContinuousQueryCacheDemo()
  {
  }

  public void doLogMessage (String message)
  {
    logger.log (Level.INFO, message);  
  }
  
  public void run()
  {
    NamedCache test = CacheFactory.getCache("mycache");
    
    // put some data in
    test.put("1", new DemoObject("male"));
    test.put("2", new DemoObject("female"));
    test.put("3", new DemoObject("female"));
    test.put("4", new DemoObject("female"));
    test.put("5", new DemoObject("female"));
    test.put("6", new DemoObject("male"));
    
    doLogMessage("Size of mycache [mycache] = " + test.size());
    
    Filter filter = new EqualsFilter("getGender", "male");
    // Create Continuous Query Cache
    ContinuousQueryCache allMales =
      new ContinuousQueryCache(test, filter);
    
    doLogMessage("Created Query Cache with just MALES [allmales]");
    doLogMessage("Size of Continuous Query Caching [allMales] = " + allMales.size());
    
    // add another male entry to test cache
    test.put("7", new DemoObject("male"));
    
    doLogMessage("New MALE object added");
    
    // check if Continuous Query Caching has that entry added
    doLogMessage("Size of Continuous Query Cache [allMales] = " + allMales.size());
    
    doLogMessage("all done.."); 
  }
  
  public static void main(String[] args) 
  {
    ContinuousQueryCacheDemo test = new ContinuousQueryCacheDemo();
    test.run();
  }
}  

3.When you run this example you can see how adding objects to the named cache "mycache" it automatically maintains the ContinuousQueryCache locally on the client.

OUTPUT from an ANT client

....
     [java]   ThisMember=Member(Id=1, Timestamp=2010-09-27 09:36:06.633, Address=10.187.114.243:8088, MachineId=50163, L
ocation=machine:paslap-au,process:4176, Role=PasAuContinuousQueryCacheDemo)
     [java]   OldestMember=Member(Id=1, Timestamp=2010-09-27 09:36:06.633, Address=10.187.114.243:8088, MachineId=50163,
 Location=machine:paslap-au,process:4176, Role=PasAuContinuousQueryCacheDemo)
     [java]   ActualMemberSet=MemberSet(Size=1, BitSetCount=2
     [java]     Member(Id=1, Timestamp=2010-09-27 09:36:06.633, Address=10.187.114.243:8088, MachineId=50163, Location=m
achine:paslap-au,process:4176, Role=PasAuContinuousQueryCacheDemo)
     [java]     )
     [java]   RecycleMillis=1200000
     [java]   RecycleSet=MemberSet(Size=0, BitSetCount=0
     [java]     )
     [java]   )
     [java]
     [java] TcpRing{Connections=[]}
     [java] IpMonitor{AddressListSize=0}
     [java]
     [java] 2010-09-27 09:36:10.003/4.197 Oracle Coherence GE 3.6.0.0 (thread=Invocation:Management, member=1): Ser
vice Management joined the cluster with senior service member 1
     [java] 2010-09-27 09:36:10.174/4.368 Oracle Coherence GE 3.6.0.0 (thread=DistributedCache, member=1): Service
DistributedCache joined the cluster with senior service member 1
     [java] 27/09/2010 9:36:10 AM pas.au.coherence.querycaching.ContinuousQueryCacheDemo doLogMessage
     [java] INFO: Size of mycache [mycache] = 6
     [java] 27/09/2010 9:36:10 AM pas.au.coherence.querycaching.ContinuousQueryCacheDemo doLogMessage
     [java] INFO: Created Query Cache with just MALES [allmales]
     [java] 27/09/2010 9:36:10 AM pas.au.coherence.querycaching.ContinuousQueryCacheDemo doLogMessage
     [java] INFO: Size of Continuous Query Caching [allMales] = 2
     [java] 27/09/2010 9:36:10 AM pas.au.coherence.querycaching.ContinuousQueryCacheDemo doLogMessage
     [java] INFO: New MALE object added
     [java] 27/09/2010 9:36:10 AM pas.au.coherence.querycaching.ContinuousQueryCacheDemo doLogMessage
     [java] INFO: Size of Continuous Query Cache [allMales] = 3
     [java] 27/09/2010 9:36:10 AM pas.au.coherence.querycaching.ContinuousQueryCacheDemo doLogMessage
     [java] INFO: all done..
     [java]


More info on this as follows

Oracle® Coherence Developer's Guide
Release 3.6

Part Number E15723-01
http://download.oracle.com/docs/cd/E15357_01/coh.360/e15723/api_continuousquery.htm

Monday, 20 September 2010

Display Cache Scheme from Coherence

Whenever I run coherence.cmd (windows) and I ask for a NamedCache using "cache pastest" for example it prints out the current scheme which I thought was handy for my own testing. After help from Patrick here is what your own code would like like to get that information yourself, if required.

 Note: I was using Coherence 3.6 but same code should work in 3.5 as well

1. Create a class as follows.

package pas.au.coherence.utils;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import com.tangosol.net.DefaultConfigurableCacheFactory.CacheInfo;
import com.tangosol.net.DefaultConfigurableCacheFactory;

public class DisplaySchemeName 
{
    private static final String CACHE_NAME = "repl-pas";
  
    public DisplaySchemeName() 
    {
    }

    public static void main(String[] args) 
    {
      // TODO Auto-generated method stub
      NamedCache pastest = CacheFactory.getCache(CACHE_NAME);
      
      DefaultConfigurableCacheFactory factory = 
       (DefaultConfigurableCacheFactory) CacheFactory.getConfigurableCacheFactory();

      CacheInfo info = factory.findSchemeMapping(CACHE_NAME);
      
      System.out.println(String.valueOf(factory.resolveScheme(info)));
      System.out.println("all done..");
  
    }
}

2. Run it to verify it displays the cache scheme we are using as shown below.

....
....
TcpRing{Connections=[]}
IpMonitor{AddressListSize=0}

2010-09-20 12:43:17.259/4.898 Oracle Coherence GE 3.6.0.0 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
2010-09-20 12:43:17.463/5.102 Oracle Coherence GE 3.6.0.0 <D5> (thread=ReplicatedCache, member=1): Service ReplicatedCache joined the cluster with senior service member 1
<replicated-scheme>
  <scheme-name>example-replicated</scheme-name>
  <service-name>ReplicatedCache</service-name>
  <backing-map-scheme>
    <local-scheme>
      <scheme-ref>unlimited-backing-map</scheme-ref>
    </local-scheme>
  </backing-map-scheme>
  <autostart>true</autostart>
</replicated-scheme>
all done..
2010-09-20 12:43:17.510/5.149 Oracle Coherence GE 3.6.0.0 <D4> (thread=ShutdownHook, member=1): ShutdownHook: stopping cluster node
2010-09-20 12:43:17.510/5.149 Oracle Coherence GE 3.6.0.0 <D5> (thread=Cluster, member=1): Service Cluster left the cluster