Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduction of Jolokia Adapter in Jmx Connection Provider #774

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package com.ericsson.bss.cassandra.ecchronos.application.config.connection;

import com.ericsson.bss.cassandra.ecchronos.application.config.Config;
import com.ericsson.bss.cassandra.ecchronos.application.providers.AgentJmxConnectionProvider;
import com.ericsson.bss.cassandra.ecchronos.connection.DistributedJmxConnectionProvider;

Expand All @@ -26,6 +27,7 @@
public class DistributedJmxConnection extends Connection<DistributedJmxConnectionProvider>
{
private RetryPolicyConfig myRetryPolicyConfig = new RetryPolicyConfig();
private JolokiaConfig myJolokiaConfig = new JolokiaConfig();

public DistributedJmxConnection()
{
Expand All @@ -51,13 +53,26 @@ public final void setRetryPolicyConfig(final RetryPolicyConfig retryPolicyConfig
myRetryPolicyConfig = retryPolicyConfig;
}

@JsonProperty("jolokia")
public final JolokiaConfig getJolokiaConfig()
{
return myJolokiaConfig;
}

@JsonProperty("jolokia")
public final void setJolokiaConfig(final JolokiaConfig jolokiaConfig)
{
myJolokiaConfig = jolokiaConfig;
}

/**
* @return
*/
@Override
protected Class<?>[] expectedConstructor()
{
return new Class<?>[] {
Config.class,
Supplier.class,
DistributedNativeConnectionProvider.class,
EccNodesSync.class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2024 Telefonaktiebolaget LM Ericsson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ericsson.bss.cassandra.ecchronos.application.config.connection;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Configuration class for Jolokia integration with JMX.
* This class allows enabling or disabling the Jolokia adapter and specifying the port to use.
*/
public class JolokiaConfig
{
private static final int DEFAULT_JOLOKIA_PORT = 8778;
private boolean myEnabled = false;
private int myPort = DEFAULT_JOLOKIA_PORT;

/**
* Sets whether the Jolokia adapter is enabled.
*
* @param enabled {@code true} to enable the Jolokia adapter; {@code false} otherwise.
*/
@JsonProperty("enabled")
public void setEnabled(final boolean enabled)
{
myEnabled = enabled;
}

/**
* Sets the port to be used by the Jolokia adapter.
*
* @param port the port number for the Jolokia adapter.
*/
@JsonProperty("port")
public void setDefaultJolokiaPort(final int port)
{
myPort = port;
}

/**
* Returns whether the Jolokia adapter is enabled.
*
* @return {@code true} if the Jolokia adapter is enabled; {@code false} otherwise.
*/
@JsonProperty("enabled")
public boolean isEnabled()
{
return myEnabled;
}

/**
* Returns the port used by the Jolokia adapter.
*
* @return the port number for the Jolokia adapter.
*/
@JsonProperty("port")
public int getPort()
{
return myPort;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package com.ericsson.bss.cassandra.ecchronos.application.providers;

import com.datastax.oss.driver.api.core.metadata.Node;
import com.ericsson.bss.cassandra.ecchronos.application.config.Config;
import com.ericsson.bss.cassandra.ecchronos.application.config.connection.JolokiaConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.security.Credentials;
import com.ericsson.bss.cassandra.ecchronos.application.config.security.JmxTLSConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.security.Security;
Expand All @@ -39,7 +41,7 @@
public class AgentJmxConnectionProvider implements DistributedJmxConnectionProvider
{
private static final Logger LOG = LoggerFactory.getLogger(AgentJmxConnectionProvider.class);
private final DistributedJmxConnectionProviderImpl myDistributedJmxConnectionProviderImpl;
private final DistributedJmxConnectionProvider myDistributedJmxConnectionProviderImpl;

/**
* Constructs an {@code AgentJmxConnectionProvider} with the specified parameters.
Expand All @@ -54,21 +56,26 @@ public class AgentJmxConnectionProvider implements DistributedJmxConnectionProvi
* if an I/O error occurs during the initialization of the JMX connection provider.
*/
public AgentJmxConnectionProvider(
final Config config,
final Supplier<Security.JmxSecurity> jmxSecurity,
final DistributedNativeConnectionProvider distributedNativeConnectionProvider,
final EccNodesSync eccNodesSync
) throws IOException
{
JolokiaConfig jolokiaConfig = config.getConnectionConfig().getJmxConnection().getJolokiaConfig();
Supplier<String[]> credentials = () -> convertCredentials(jmxSecurity);
Supplier<Map<String, String>> tls = () -> convertTls(jmxSecurity);

LOG.info("Creating DistributedJmxConnectionConfig");

myDistributedJmxConnectionProviderImpl = DistributedJmxConnectionProviderImpl.builder()
.withCqlSession(distributedNativeConnectionProvider.getCqlSession())
.withNodesList(distributedNativeConnectionProvider.getNodes())
.withCredentials(credentials)
.withEccNodesSync(eccNodesSync)
.withTLS(tls)
.withJolokiaEnabled(jolokiaConfig.isEnabled())
.withJolokiaPort(jolokiaConfig.getPort())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,13 @@ public EccNodesSync eccNodesSync(
*/
@Bean
public DistributedJmxConnectionProvider distributedJmxConnectionProvider(
final Config config,
final DistributedNativeConnectionProvider distributedNativeConnectionProvider,
final EccNodesSync eccNodesSync
) throws IOException
{
return getDistributedJmxConnection(
jmxSecurity::get, distributedNativeConnectionProvider, eccNodesSync);
config, jmxSecurity::get, distributedNativeConnectionProvider, eccNodesSync);
}

@Bean
Expand Down Expand Up @@ -302,13 +303,14 @@ private DistributedNativeConnectionProvider getDistributedNativeConnection(
}

private DistributedJmxConnectionProvider getDistributedJmxConnection(
final Config config,
final Supplier<Security.JmxSecurity> securitySupplier,
final DistributedNativeConnectionProvider distributedNativeConnectionProvider,
final EccNodesSync eccNodesSync
) throws IOException
{
return new AgentJmxConnectionProvider(
securitySupplier, distributedNativeConnectionProvider, eccNodesSync);
config, securitySupplier, distributedNativeConnectionProvider, eccNodesSync);
}

private void refreshSecurityConfig(
Expand Down
12 changes: 11 additions & 1 deletion application/src/main/resources/ecc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ connection:
##
## The class used to provide CQL connections to Apache Cassandra.
## The default provider will be used unless another is specified.
## The default provider will be used unless another is specified.
##
provider: com.ericsson.bss.cassandra.ecchronos.application.providers.AgentNativeConnectionProvider
##
Expand All @@ -99,6 +98,17 @@ connection:
time: 45
unit: MINUTES
jmx:
jolokia:
#
# Specifies whether the Jolokia adapter for connecting to JMX objects is enabled or not.
# Default: false (adapter is disabled if not explicitly configured).
#
enabled: false
#
# Defines the port used by Jolokia for accessing JMX objects.
# Default: 8778 (this port will be used if no other port is configured).
#
port: 8778
VictorCavichioli marked this conversation as resolved.
Show resolved Hide resolved
##
## The class used to provide JMX connections to Apache Cassandra.
## The default provider will be used unless another is specified.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,5 +317,14 @@ public void testInstanceName()
{
assertThat(nativeConnection.getAgentConnectionConfig().getInstanceName()).isEqualTo("unique_identifier");
}

@Test
public void testJolokiaConfig()
{
JolokiaConfig jolokiaConfig = config.getConnectionConfig().getJmxConnection().getJolokiaConfig();
assertThat(jolokiaConfig).isNotNull();
assertThat(jolokiaConfig.isEnabled()).isTrue();
assertThat(jolokiaConfig.getPort()).isEqualTo(7887);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import com.ericsson.bss.cassandra.ecchronos.application.config.connection.ConnectionConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.connection.DistributedJmxConnection;
import com.ericsson.bss.cassandra.ecchronos.application.config.connection.JolokiaConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.connection.RetryPolicyConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.repair.FileBasedRepairConfiguration;
import com.ericsson.bss.cassandra.ecchronos.application.config.repair.GlobalRepairConfig;
Expand Down Expand Up @@ -166,4 +167,13 @@ public void testRepairType()
RepairType repairType = repairConfig.getRepairType();
assertThat(repairType).isEqualTo(RepairType.VNODE);
}

@Test
public void testJolokiaConfig()
{
JolokiaConfig jolokiaConfig = config.getConnectionConfig().getJmxConnection().getJolokiaConfig();
assertThat(jolokiaConfig).isNotNull();
assertThat(jolokiaConfig.isEnabled()).isFalse();
assertThat(jolokiaConfig.getPort()).isEqualTo(8778);
}
}
3 changes: 3 additions & 0 deletions application/src/test/resources/all_set.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ connection:
time: 45
unit: minutes
jmx:
jolokia:
enabled: true
port: 7887
provider: com.ericsson.bss.cassandra.ecchronos.application.providers.AgentJmxConnectionProvider
retryPolicy:
maxAttempts: 5
Expand Down
5 changes: 5 additions & 0 deletions connection.impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-jsr160</artifactId>
</dependency>

<!-- Cassandra driver -->
<dependency>
<groupId>com.datastax.oss</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
import com.datastax.oss.driver.api.core.metadata.Node;
import com.datastax.oss.driver.api.core.servererrors.QueryExecutionException;
import com.ericsson.bss.cassandra.ecchronos.connection.DistributedJmxConnectionProvider;
import com.ericsson.bss.cassandra.ecchronos.connection.impl.providers.DistributedJmxConnectionProviderImpl;
import com.ericsson.bss.cassandra.ecchronos.data.sync.EccNodesSync;
import com.ericsson.bss.cassandra.ecchronos.utils.enums.sync.NodeStatus;
Expand All @@ -44,14 +45,17 @@ public class DistributedJmxBuilder
{
private static final Logger LOG = LoggerFactory.getLogger(DistributedJmxBuilder.class);
private static final String JMX_FORMAT_URL = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi";
private static final String JMX_JOLOKIA_FORMAT_URL = "service:jmx:jolokia://%s:%d/jolokia";
private static final int DEFAULT_JOLOKIA_PORT = 8778;
private static final int DEFAULT_PORT = 7199;

private CqlSession mySession;
private List<Node> myNodesList;
private final ConcurrentHashMap<UUID, JMXConnector> myJMXConnections = new ConcurrentHashMap<>();
private Supplier<String[]> myCredentialsSupplier;
private Supplier<Map<String, String>> myTLSSupplier;

private boolean isJolokiaEnabled = false;
private int myJolokiaPort = DEFAULT_JOLOKIA_PORT;
private EccNodesSync myEccNodesSync;

/**
Expand Down Expand Up @@ -119,19 +123,29 @@ public final DistributedJmxBuilder withEccNodesSync(final EccNodesSync eccNodesS
return this;
}

public final DistributedJmxBuilder withJolokiaEnabled(final boolean jolokiaEnabled)
{
isJolokiaEnabled = jolokiaEnabled;
return this;
}

public final DistributedJmxBuilder withJolokiaPort(final int jolokiaPort)
{
myJolokiaPort = jolokiaPort;
return this;
}

/**
* Build the DistributedJmxConnectionProviderImpl instance.
*
* @return a new instance of DistributedJmxConnectionProviderImpl initialized with the current settings.
* @throws IOException
* if an I/O error occurs during the creation of connections.
*/
public final DistributedJmxConnectionProviderImpl build() throws IOException
public final DistributedJmxConnectionProvider build() throws IOException
{
createConnections();
return new DistributedJmxConnectionProviderImpl(
myNodesList,
myJMXConnections,
this
);
}
Expand All @@ -154,24 +168,36 @@ private void createConnections() throws IOException
}

/***
* Creates a JMXconnection to the host.
* @param node
* Creates a JMX connection to the host.
* @param node the node to connect with.
* @throws EcChronosException
*/
public void reconnect(final Node node) throws EcChronosException
{
try
{
String host = node.getBroadcastRpcAddress().get().getHostString();
Integer port = getJMXPort(node);
JMXServiceURL jmxUrl;
Integer port;
if (isJolokiaEnabled)
{
port = myJolokiaPort;
jmxUrl = new JMXServiceURL(String.format(JMX_JOLOKIA_FORMAT_URL, host, port));
}
else
{
port = getJMXPort(node);
jmxUrl = new JMXServiceURL(String.format(JMX_FORMAT_URL, host, port));
}

if (host.contains(":"))
{
// Use square brackets to surround IPv6 addresses
host = "[" + host + "]";
}

LOG.info("Starting to instantiate JMXService with host: {} and port: {}", host, port);
JMXServiceURL jmxUrl = new JMXServiceURL(String.format(JMX_FORMAT_URL, host, port));

LOG.debug("Connecting JMX through {}, credentials: {}, tls: {}", jmxUrl, isAuthEnabled(), isTLSEnabled());
JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxUrl, createJMXEnv());
if (isConnected(jmxConnector))
Expand Down Expand Up @@ -284,4 +310,14 @@ private static boolean isConnected(final JMXConnector jmxConnector)

return true;
}

public final List<Node> getNodesList()
{
return myNodesList;
}

public final ConcurrentHashMap<UUID, JMXConnector> getJMXConnections()
{
return myJMXConnections;
}
}
Loading