Hello!
In this article I will show you how to create a library to manage clusters for Atlassian Data Center products.
You can find the source code for this article here.
You can watch my video here.
The problem is that if I want to work with a cluster in Jira, Confluence and Bitbucket, we will have to use 3 different managers for it: com.atlassian.jira.cluster.ClusterManager for Jira, com.atlassian.confluence.cluster.ClusterManager for Confluence and com.atlassian.bitbucket.cluster.ClusterService for Bitbucket. If I want to develop an app which can be executed in Jira, Confluence and Bitbucket without changes, then I can not import these managers using atlassian-spring-scanner or JavaConfig. If I import these managers then my app will not start because if I start my app in Jira then managers for Confluence and Bitbucket will not be found which will cause my app not to start.
That is why I decided to develop a library which will define in what Data Center product my app is installed and then my library will import the required manager and use it to work with clusters.
Ok. Let's start.
DefaultAtlassianClusterManager
First of all I have created an adapter for all Atlassian Cluster managers which has common methods to work with each Atlassian cluster manager.
public class DefaultAtlassianClusterManager implements ClusterManager {
private final ClusterManager clusterManager;
public DefaultAtlassianClusterManager() {
ApplicationProperties applicationProperties = OsgiServices.importOsgiService(ApplicationProperties.class);
String app = Utils.getCurrentApplication(applicationProperties);
this.clusterManager = "jira".equals(app) ? new JiraClusterManager() : (
"confluence".equals(app) ? new ConfluenceClusterManager() : new BitbucketClusterManager()
);
}
@Override
public List<ClusterNode> getNodesNames() {
return this.clusterManager.getNodesNames();
}
@Override
public ClusterNode getCurrentNode() {
return this.clusterManager.getCurrentNode();
}
@Override
public boolean isClustered() {
return this.clusterManager.isClustered();
}
}
This class defines in what product the app has been installed and choose the correct manager:
ApplicationProperties applicationProperties = OsgiServices.importOsgiService(ApplicationProperties.class);
String app = Utils.getCurrentApplication(applicationProperties);
this.clusterManager = "jira".equals(app) ? new JiraClusterManager() : (
"confluence".equals(app) ? new ConfluenceClusterManager() : new BitbucketClusterManager()
);
I use ApplicationProperties bean from SAL which has getPlatformId method which returns the product in which the code runs.
After it I initialise the required manager.
JiraClusterManager, ConfluenceClusterManager, BibucketClusterManager
I created a wrapper for each Atlassian Data Center cluster manager. Those wrappers are identical. Here is the code for JiraClusterManager:
private final com.atlassian.jira.cluster.ClusterManager clusterManager;
public JiraClusterManager() {
this.clusterManager = ComponentAccessor.getComponent(com.atlassian.jira.cluster.ClusterManager.class);
}
@Override
public List<ClusterNode> getNodesNames() {
return this.clusterManager.getAllNodes().stream()
.map(node -> new ClusterNode(node.getNodeId()))
.collect(Collectors.toList());
}
@Override
public ClusterNode getCurrentNode() {
return new ClusterNode(this.clusterManager.getNodeId());
}
@Override
public boolean isClustered() {
return this.clusterManager.isClustered();
}
All these wrappers import the cluster manager bean and return the result for required methods.
And that is it.
Use it in Jira app
In the source code you can find how to use this library in all Atlassian Data Center products. But in this article I will show you how to use it for Jira. It is identical for all other Atlassian Data Center products.
First of all I add my library as a dependency in pom.xml:
<dependency>
<groupId>ru.matveev.alexey.data.center</groupId>
<artifactId>cluster-service</artifactId>
<version>1.0.0</version>
</dependency>
Then I need to create a bean out of my DefaultAtlassianClusterManager. That is how I do it:
@Named
public class ClusterManager extends DefaultAtlassianClusterManager {
}
Then I created a rest service to try how my library works. Here is the get method:
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getMessage()
{
String result = "not clustered";
if (clusterManager.isClustered()) {
result = clusterManager.getCurrentNode().getId();
}
return Response.ok(new ClusterResourceModel(result)).build();
}
Here I use my ClusterManager which actually is the AtlassianDefaultClusterManager and get the node id of the current node if I am in the Data Center environment. If not I return that the environment is not clustered.
That is how you can use the library.
Alexey Matveev
software developer
MagicButtonLabs
Philippines
1,574 accepted answers
0 comments