Integration tests with Oracle Coherence - java

We have a set of integration tests, that use Oracle Coherence. All of them use the same config and the problem is that when you are running them in parallel, their coherence nodes join into one cluster and it is possible that one test affects others. Is there a simple way to prevent this joining?
Thanks!

We use LittleGrid in our tests rather than start Coherence natively. You can programmatically set up the grid and set the configuration.

For creating different clusters on a single machine for testing, you can use different tangosol-override config file.Just keep a tangosol-override file in the classpath of each cluster, provide different name to the clusters and specify different multi-cast address (not mandatory i guess). If you are using coherence 12C then you can also create different managed cluster in a single domain of weblogic server.
When you start a coherence node, it will read the tangosol-override file and issue multi-cast messages to the address mentioned in the file. When it doesn't find any other node or cluster with same cluster name. It starts it's own cluster as identifies itself as the master node.

Related

Redis Cluster Configuration

I am using spring redisTemplate(jedis, 2.0.0) with redis-server(2.9.50). It's working perfectly for the single instance but I want to create a cluster master-slave environment with two different instances in which replication and failover happen automatically (over configuration).
Please answer the following queries
what's the proper way to create master/slave Redis cluster(right now I've only redis-server installed with no config change)?
how to connect jedis with redis cluster ?
what should I use to replicate data between redis clusters nodes ?
I think you need to upgrade your version of jedis to get the cluster support. From the README, the usage looks straight-forward:
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
//Jedis Cluster will attempt to discover cluster nodes automatically
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNodes);
jc.set("foo", "bar");
String value = jc.get("foo");
In terms of setup, there's a lot of considerations, you should consult this tutorial for basic setup and considerations. The section Creating a Redis Cluster using the create-cluster script will get you up and running pretty quickly and you can make tweaks & changes from there.

Is there a way to split read/write queries in Quartz Scheduler to use mysql master slave replication?

I am using Quartz scheduler in my application and I am also using master-slave replication for my other DB queries. I want to use the master-slave replication for Quartz scheduler as well hence I want to know if there is a way I can make the changes to split write/read queries which quartz makes to master/slave respectively?
I tried changing the "quartz.properties" but then all the calls going to the master node only
org.quartz.dataSource.quartzDS.driver=com.mysql.jdbc.ReplicationDriver
org.quartz.dataSource.quartzDS.URL=jdbc:mysql:replication://localhost:3306,localhost:3307/quartz?useUnicode=true&characterEncoding=utf8&useTimezone=true&serverTimezone=UTC&useLegacyDatetimeCode=false
org.quartz.dataSource.quartzDS.user=root
org.quartz.dataSource.quartzDS.password=root
org.quartz.dataSource.quartzDS.maxConnections=10
org.quartz.dataSource.quartzDS.validationQuery=select 1
You can define multiple datasources in quartz.properties.
quartzDS is a specific datasource. You can add more with different names by tagging the properties with the name you want (like org.quartz.dataSource.quartzDSTheSecond).
See: http://www.quartz-scheduler.org/documentation/quartz-1.x/configuration/ConfigDataSources
You then can get a connection using DBConnectionManager.getInstance().getConnection("quartzDSTheSecond");

Identify the primary node in a Java EE cluster

I have a web application that get deployed on a jboss (eap 6.2) domain with 2 nodes.
There are certain startup processes that need to be excecuted, however right now the processes run on both nodes. This is undesirable, I need the process to run only on 1 server (identified as primary).
Obviously this can be done by having a special system property set up 1 of the servers, howeever I am wondering if there is a standard Java EE way of designating a node as primary and then reading that configuration in the code?
There is no defined standard. Some application servers provide HA Singletons (https://developer.jboss.org/wiki/JBMHASingleton for JBoss 4.x and http://www.jboss.org/quickstarts/eap/cluster-ha-singleton/ for JBoss 7/Wildfly 8).
There are some approaches like using JGroups or persisting the state in some sort of database. You could also use a clustered JMS Topic. The first node broadcasts "I'm initializing" and others have to listen to it. That's not the best approach but it's within Java EE bounds.

How to share some property between servers in a Weblogic cluster?

How can I reliably share a single property value between multiple servers in a Weblogic cluster -- which gets sets by one of the servers (the first one to try and access it).
Imagine it is like a static variable across the whole cluster, and the first server to access the variable gets to set it's value and that value is seen by every other server in the cluster.
I had thought the JNDI would be appropriate for this, as I read that the JNDI in a clustered environment ensures the object is shared amongst the cluster. So I set a string object in the cluster under a JNDI name and expected other servers who tried to bind the same name would get a Name Already Bound exception and thus know to use the already bound value from another server. But its not working. Each server is setting their own value in the JNDI with seemingly nothing to suggest they are accessing the same JNDI.
I propose to investigate distributed caches: http://java-source.net/open-source/cache-solutions. They have a mechanism to have single interface for all nodes in cluster. You can learn how they do it and then implement your lightweight implementation. Or add one library to your dependencies.

How to programmatically find/list all nodes in a J2EE Application-Cluster?

Is there a way to find all nodes belonging to the cluster of the web-application? I know on JBoss i can use HAServiceMBeanSupport to get information about all nodes(hostname, IP-adress), but how can I achieve something similar on Tomcat, WebSpere, Glassfish, Oracle AS, Jetty, WebLogic?
(Best would be an interface which works for all of them)
There is no standard drop-in solution for what you are asking for.
Technically it can be achieved in many ways - both within java ecosystem and outside e.g. Jgroups cluster forming, Zookeeper or simple Redis or other K/V server where each server instance would register upon startup and subscribe for changes in the cluster group.
The support and required effort will vary though. The general approach would be to use some startup hook e.g. Servlet container initialization or EJB #Startup #Singleton to contact the topology discovery service(your redis server for example), provide the info about your instance and query info about the other instances already active. If you need leader election, you can use many algorithms, e.g. first come-first serve basis, or based on voting. Then you need to subscribe and actively listen for changes in topology, and possibly provide some kind of health metric - e.g. periodically let others know, that your instance is still active
On a general note, can you elaborate why would your app need to have the knowledge about other instances of the same type? Do you need Master election or HA cluster-wide singleton functionality? The best practice for building stable scalable solutions is to keep the app stateless and unaware of the scaling details.
Functions, that need to be only executed in sequence or on a single node at the time, could be extracted into a dedicated service e.g. batch job service, scheduler service etc.
Most JEE server vendors offer some custom solution for this e.g. JBoss HASingleton service, or HA singleton deployment(app will always run only on a single instance in the cluster) which also takes care of failover.
As far as I know, it depends of the capabilities of your Applicationserver.
There is no "standardway" to do this.
You can try the following:
The class ServletContextListener has two methods. You can calculate the hostname and the IP-Adress(es) within the create method, and delete the node in the destroy method.
This way has problems during a VM-crash the destroy-method will not be called, for instance.
EDIT:
Does your software need a Database? If so, all clusternodes have to use the same database instance. If your app is deployed without a cluster it uses a "private" database. You need a shared DB:
Table: NODES
HOST | IP
as1.cluster | < ip >
as2.cluster | < ip2 >
If only onne line inserted to that DB, there is no cluster.
But this table may be corrupted, if a node crashes and does not remove its entry from this Table.

Categories

Resources