Merge pull request #1543 from nosqlbench/remove-obsolete-drivers

Remove obsolete driver code
This commit is contained in:
Jonathan Shook 2023-09-15 16:55:46 -05:00 committed by GitHub
commit 95afba0281
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 0 additions and 1544 deletions

View File

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2022-2023 nosqlbench
~
~ 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.
-->
<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>
<parent>
<groupId>io.nosqlbench</groupId>
<artifactId>mvn-defaults</artifactId>
<version>4.17.32-SNAPSHOT</version>
<relativePath>../mvn-defaults</relativePath>
</parent>
<artifactId>driver-cockroachdb</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
A CockroachDB ActivityType driver for http://nosqlbench.io/
</description>
<dependencies>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>driver-jdbc</artifactId>
<version>4.17.32-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.1</version>
</dependency>
</dependencies>
</project>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2022-2023 nosqlbench
~
~ 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.
-->
<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">
<parent>
<artifactId>nosqlbench</artifactId>
<groupId>io.nosqlbench</groupId>
<version>4.17.32-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>driver-jdbc</artifactId>
<dependencies>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>engine-api</artifactId>
<version>4.17.32-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,46 +0,0 @@
<!--
~ Copyright (c) 2022-2023 nosqlbench
~
~ 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.
-->
<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>
<parent>
<artifactId>mvn-defaults</artifactId>
<groupId>io.nosqlbench</groupId>
<version>5.17.0-SNAPSHOT</version>
<relativePath>../mvn-defaults</relativePath>
</parent>
<artifactId>driver-jmx</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
A JMX nosqlbench ActivityType (AT) driver module;
This provides the ability to query system via JMX
</description>
<dependencies>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>engine-api</artifactId>
<version>5.17.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx;
import io.nosqlbench.adapter.jmx.mappers.JMXOpMapper;
import io.nosqlbench.engine.api.activityimpl.OpMapper;
import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.engine.api.activityimpl.uniform.DriverSpaceCache;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.nb.annotations.Service;
import io.nosqlbench.nb.api.config.standard.NBConfigModel;
import io.nosqlbench.nb.api.config.standard.NBConfigurable;
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
@Service(value = DriverAdapter.class, selector = "jmx-v2")
public class JMXDriverAdapter implements DriverAdapter<Op,JMXSpace>, NBConfigurable {
private NBConfiguration config;
@Override
public OpMapper<Op> getOpMapper() {
return new JMXOpMapper(getSpaceCache());
}
@Override
public DriverSpaceCache<? extends JMXSpace> getSpaceCache() {
return new DriverSpaceCache<>(JMXSpace::new);
}
@Override
public NBConfiguration getConfiguration() {
return config;
}
@Override
public void applyConfig(NBConfiguration cfg) {
this.config = cfg;
}
@Override
public NBConfigModel getConfigModel() {
return new JMXSpace("test").getConfigModel();
}
}

View File

@ -1,23 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx;
public enum JMXOpTypes {
Read,
Print,
Explain
}

View File

@ -1,112 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx;
import io.nosqlbench.engine.api.util.SSLKsFactory;
import io.nosqlbench.nb.api.errors.OpConfigError;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
public class JMXSpace implements NBConfigurable {
private final String name;
private JMXConnector connector;
private NBConfiguration cfg;
public JMXSpace(String name) {
this.name = name;
}
@Override
public void applyConfig(NBConfiguration cfg) {
this.cfg = cfg;
}
public NBConfigModel getConfigModel() {
return ConfigModel.of(JMXSpace.class)
.add(Param.optional("username", String.class))
.add(Param.optional("password", String.class))
.add(SSLKsFactory.get().getConfigModel())
.asReadOnly();
}
public synchronized JMXConnector getConnector() {
if (this.connector == null) {
this.connector = bindConnector();
}
return this.connector;
}
private JMXConnector bindConnector() {
Map<String, Object> connectorEnv = new HashMap<>();
String username = cfg.getOptional("username")
.map(u -> SecureUtils.readSecret("JMX username", u))
.orElse(null);
String password = cfg.getOptional("password")
.map(p -> SecureUtils.readSecret("JMX password", p))
.orElse(null);
if (username != null && password != null) {
connectorEnv.put(JMXConnector.CREDENTIALS, new String[]{username, password});
}
JMXConnector connector = null;
try {
JMXServiceURL url = bindJMXServiceURL();
connector = JMXConnectorFactory.connect(url, connectorEnv);
} catch (IOException e) {
e.printStackTrace();
}
return connector;
}
private JMXServiceURL bindJMXServiceURL() {
JMXServiceURL url = null;
url = cfg.getOptional("url")
.map(
u -> {
try {
return new JMXServiceURL(u);
} catch (MalformedURLException e) {
throw new OpConfigError("Error with JMX URL: " + e);
}
})
.orElse(null);
if (url!=null) {
return url;
}
String host = cfg.get("host");
String protocol = cfg.get("protocol");
int port = cfg.getOrDefault("port", 0);
String path = cfg.get("path");
try {
return new JMXServiceURL(protocol, host, port, path);
} catch (MalformedURLException e) {
throw new OpConfigError("Error with JMX URL parameters: " + e);
}
}
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class SecureUtils {
private final static Logger logger = LogManager.getLogger(SecureUtils.class);
public static String readSecret(String description, String source) {
if (source==null) {
return null;
}
if (source.startsWith("file:")) {
String sourceFile = source.substring("file:".length());
try {
return Files.readString(Path.of(sourceFile), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else if (source.startsWith("console:")||source.equals("")) {
System.out.print("Enter " + description+":");
char[] chars = System.console().readPassword("%s:",description);
return new String(chars);
} else {
logger.warn("Parameter for '" + description + "' was passed directly. This is less secure." +
" Consider using 'file:<file>' or 'console:' for this value instead");
return source;
}
}
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx;
public class ValueConverter {
public static Object convert(String typeName, Object o) {
if (!typeName.contains(".")) {
if (Number.class.isAssignableFrom(o.getClass())) {
switch (typeName) {
case "String":
return o.toString();
case "long":
case "Long":
return (((Number) o).longValue());
case "int":
case "Integer":
return (((Number) o).intValue());
case "double":
case "Double":
return (((Number) o).doubleValue());
case "float":
case "Float":
return (((Number) o).floatValue());
case "short":
case "Short":
return (((Number) o).shortValue());
case "byte":
case "Byte":
return (((Number) o).byteValue());
default:
throw new RuntimeException("For numeric values, you can only convert to long,int,double,float,byte,short or String");
}
} else {
String value;
if (CharSequence.class.isAssignableFrom(o.getClass())) {
value = (String) o;
} else {
value = o.toString();
}
switch (typeName) {
case "String":
return value;
case "long":
case "Long":
return Long.parseLong(value);
case "int":
case "Integer":
return Integer.parseInt(value);
case "double":
case "Double":
return Double.parseDouble(value);
case "float":
case "Float":
return Float.parseFloat(value);
case "short":
case "Short":
return Short.parseShort(value);
case "byte":
case "Byte":
return Byte.parseByte(value);
default:
throw new RuntimeException("For String values, you can only convert to long, int, double, float, short, byte, or String");
}
}
}
try {
Class<?> aClass = Class.forName(typeName);
return aClass.cast(o);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.dispensers;
import io.nosqlbench.adapter.jmx.JMXSpace;
import io.nosqlbench.adapter.jmx.operations.JMXExplainOperation;
import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.engine.api.templating.ParsedOp;
import javax.management.ObjectName;
import java.util.function.LongFunction;
public class JMXExplainDispenser extends BaseOpDispenser<Op> {
private final LongFunction<JMXSpace> spaceF;
private final LongFunction<ObjectName> nameF;
public JMXExplainDispenser(LongFunction<JMXSpace> spaceF, LongFunction<ObjectName> nameF, ParsedOp op) {
super(op);
this.spaceF =spaceF;
this.nameF = nameF;
}
@Override
public Op apply(long value) {
return new JMXExplainOperation(
spaceF.apply(value).getConnector(),
nameF.apply(value)
);
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.dispensers;
import io.nosqlbench.adapter.jmx.JMXSpace;
import io.nosqlbench.adapter.jmx.operations.JMXPrintOperation;
import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.engine.api.templating.ParsedOp;
import io.nosqlbench.virtdata.library.basics.core.threadstate.SharedState;
import javax.management.ObjectName;
import java.util.function.LongFunction;
public class JMXPrintDispenser extends BaseOpDispenser<Op> {
private final LongFunction<JMXSpace> spaceF;
private final LongFunction<ObjectName> nameF;
private final LongFunction<String> readvarF;
private final LongFunction<String> asTypeF;
private final LongFunction<String> asNameF;
private final LongFunction<SharedState.Scope> scopeF;
public JMXPrintDispenser(LongFunction<JMXSpace> spaceF, LongFunction<ObjectName> nameF, ParsedOp op) {
super(op);
this.spaceF =spaceF;
this.nameF = nameF;
this.readvarF = op.getAsFunctionOr("readvar","Value");
this.asTypeF = op.getAsFunctionOr("as_type","String");
this.asNameF = op.getAsOptionalFunction("as_name", String.class).orElse(readvarF);
this.scopeF = op.getAsOptionalEnumFunction("scope", SharedState.Scope.class).orElse(l -> SharedState.Scope.thread);
}
@Override
public Op apply(long value) {
return new JMXPrintOperation(
spaceF.apply(value),
nameF.apply(value),
readvarF.apply(value),
asTypeF.apply(value),
asNameF.apply(value),
scopeF.apply(value)
);
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.dispensers;
import io.nosqlbench.adapter.jmx.JMXSpace;
import io.nosqlbench.adapter.jmx.operations.JMXReadOperation;
import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.engine.api.templating.ParsedOp;
import io.nosqlbench.virtdata.library.basics.core.threadstate.SharedState;
import javax.management.ObjectName;
import java.util.function.LongFunction;
public class JMXReadDispenser extends BaseOpDispenser<Op> {
private final LongFunction<JMXSpace> spaceF;
private final LongFunction<ObjectName> nameF;
private final LongFunction<String> readvarF;
private final LongFunction<String> asTypeF;
private final LongFunction<String> asNameF;
private final LongFunction<SharedState.Scope> scopeF;
public JMXReadDispenser(LongFunction<JMXSpace> spaceF, LongFunction<ObjectName> nameF, ParsedOp op) {
super(op);
this.spaceF =spaceF;
this.nameF = nameF;
this.readvarF = op.getAsFunctionOr("readvar","Value");
this.asTypeF = op.getAsFunctionOr("as_type","String");
this.asNameF = op.getAsOptionalFunction("as_name", String.class).orElse(readvarF);
this.scopeF = op.getAsOptionalEnumFunction("scope", SharedState.Scope.class).orElse(l -> SharedState.Scope.thread);
}
@Override
public Op apply(long value) {
return new JMXReadOperation(
spaceF.apply(value),
nameF.apply(value),
readvarF.apply(value),
asTypeF.apply(value),
asNameF.apply(value),
scopeF.apply(value)
);
}
}

View File

@ -1,135 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.formats;
import javax.management.*;
import java.util.Map;
public class MBeanInfoConsoleFormat {
private static final Map<Integer,String> MbeanOpImpacts = Map.of(
MBeanOperationInfo.ACTION,"ACTION",
MBeanOperationInfo.ACTION_INFO,"ACTION_INFO",
MBeanOperationInfo.UNKNOWN,"UNKNOWN",
MBeanOperationInfo.INFO,"INFO");
// Not including Descriptors here
public static String formatAsText(MBeanInfo info, ObjectName objectName) {
StringBuilder sb = new StringBuilder();
sb.append("### MBeanInfo for '").append(objectName).append("'\n");
String className = info.getClassName();
sb.append("# classname: ").append(className).append("\n");
String description = info.getDescription();
sb.append("# ").append(description).append("\n");
MBeanConstructorInfo[] constructors = info.getConstructors();
if (constructors.length > 0) {
sb.append("## constructors:\n");
for (MBeanConstructorInfo constructor : constructors) {
String ctorDesc = constructor.getDescription();
sb.append("# ").append(ctorDesc).append("\n");
String name = constructor.getName();
sb.append("# ").append(name).append("(");
sb.append(pramDetail(constructor.getSignature(), " "));
sb.append(" )\n");
// sb.append(" [").append(descriptorDetail(constructor.getDescriptor())).append("]\n");
}
}
MBeanAttributeInfo[] attributes = info.getAttributes();
if (attributes.length > 0) {
sb.append("## attributes:\n");
for (MBeanAttributeInfo attribute : attributes) {
String attrDesc = attribute.getDescription();
String attrName = attribute.getName();
String attrType = attribute.getType();
sb.append("# ").append(attrDesc).append("\n");
sb.append("- '").append(attrName).append("' type=").append(attrType);
sb.append("readable=").append(attribute.isReadable()).append(" writable=").append(attribute.isWritable()).append(" is_is=").append(attribute.isIs());
sb.append("\n");
// sb.append(" [").append(descriptorDetail(attribute.getDescriptor())).append("]\n");
}
}
MBeanNotificationInfo[] notifications = info.getNotifications();
if (notifications.length > 0) {
sb.append("## notifications:\n");
for (MBeanNotificationInfo notification : notifications) {
String notifName = notification.getName();
String notifDesc = notification.getDescription();
String[] notifTypes = notification.getNotifTypes();
Class<? extends MBeanNotificationInfo> notifClass = notification.getClass();
sb.append("# ").append(notifDesc).append("\n");
sb.append("- ").append(notifName).append(" [").append(descriptorDetail(notification.getDescriptor())).append("]\n");
if (notifTypes.length > 0) {
for (String notifType : notifTypes) {
sb.append(" - ").append(notifType).append("\n");
}
}
}
}
MBeanOperationInfo[] operations = info.getOperations();
if (operations.length > 0) {
sb.append("## operations:\n");
for (MBeanOperationInfo operation : operations) {
String opDesc = operation.getDescription();
String opName = operation.getName();
MBeanParameterInfo[] opSig = operation.getSignature();
Class<? extends MBeanOperationInfo> opClass = operation.getClass();
sb.append("# ").append(opDesc).append("\n");
sb.append("- ").append(opName).append("(");
sb.append(pramDetail(operation.getSignature(), " "));
sb.append(") -> ").append(operation.getReturnType());
sb.append(" impact=").append(MbeanOpImpacts.get(operation.getImpact())).append("\n");
}
}
return sb.toString();
}
private static String descriptorDetail(Descriptor descriptor) {
StringBuilder sb = new StringBuilder();
sb.append("valid=").append(descriptor.isValid());
String[] fieldNames = descriptor.getFieldNames();
for (String field : fieldNames) {
sb.append(" ").append(field).append("=").append(descriptor.getFieldValue(field));
}
return sb.toString();
}
private static String pramDetail(MBeanParameterInfo[] signature, String prefix) {
StringBuilder sb = new StringBuilder();
for (MBeanParameterInfo paramInfo : signature) {
String desc = paramInfo.getDescription();
if (desc != null) {
sb.append(prefix).append(" # ").append(desc).append("\n");
}
sb.append(prefix).append(" - ").append(paramInfo.getName()).append("\n");
}
return sb.toString();
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.mappers;
import io.nosqlbench.adapter.jmx.JMXOpTypes;
import io.nosqlbench.adapter.jmx.JMXSpace;
import io.nosqlbench.adapter.jmx.dispensers.JMXExplainDispenser;
import io.nosqlbench.adapter.jmx.dispensers.JMXPrintDispenser;
import io.nosqlbench.adapter.jmx.dispensers.JMXReadDispenser;
import io.nosqlbench.engine.api.activityimpl.OpDispenser;
import io.nosqlbench.engine.api.activityimpl.OpMapper;
import io.nosqlbench.engine.api.activityimpl.uniform.DriverSpaceCache;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.engine.api.templating.ParsedOp;
import io.nosqlbench.engine.api.templating.TypeAndTarget;
import io.nosqlbench.nb.api.errors.OpConfigError;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import java.util.function.LongFunction;
public class JMXOpMapper implements OpMapper<Op> {
private final DriverSpaceCache<? extends JMXSpace> jmxCache;
public JMXOpMapper(DriverSpaceCache<? extends JMXSpace> jmxCache) {
this.jmxCache = jmxCache;
}
@Override
public OpDispenser<? extends Op> apply(ParsedOp op) {
LongFunction<String> spaceNameFunc = op.getAsFunctionOr("space","default");
LongFunction<JMXSpace> spaceFunc = l -> jmxCache.get(spaceNameFunc.apply(l));
LongFunction<? extends String> nameFunction = op.getAsRequiredFunction("object");
LongFunction<ObjectName> oNameFunc = n -> {
try {
String name = nameFunction.apply(n);
return new ObjectName(name);
} catch (MalformedObjectNameException e) {
throw new OpConfigError("You must specify a valid object name for any JMX operation:" + e);
}
};
TypeAndTarget<JMXOpTypes, String> optype = op.getTypeAndTarget(JMXOpTypes.class, String.class, "type", "target");
return switch (optype.enumId) {
case Read -> new JMXReadDispenser(spaceFunc, oNameFunc, op);
case Print -> new JMXPrintDispenser(spaceFunc, oNameFunc, op);
case Explain -> new JMXExplainDispenser(spaceFunc, oNameFunc, op);
};
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.operations;
import io.nosqlbench.adapter.jmx.formats.MBeanInfoConsoleFormat;
import javax.management.*;
import javax.management.remote.JMXConnector;
public class JMXExplainOperation extends JmxOp {
public final static String EXPLAIN = "explain";
public JMXExplainOperation(JMXConnector connector, ObjectName objectName) {
super(connector,objectName);
}
@Override
public void execute() {
MBeanServerConnection bean = getMBeanConnection();
try {
MBeanInfo info = bean.getMBeanInfo(objectName);
String mbeanInfoText = MBeanInfoConsoleFormat.formatAsText(info, objectName);
System.out.println(mbeanInfoText);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.operations;
import io.nosqlbench.adapter.jmx.JMXSpace;
import io.nosqlbench.adapter.jmx.ValueConverter;
import io.nosqlbench.virtdata.library.basics.core.threadstate.SharedState;
import javax.management.ObjectName;
public class JMXPrintOperation extends JMXReadOperation {
public JMXPrintOperation(
JMXSpace space,
ObjectName oname,
String readvar,
String asType,
String asName,
SharedState.Scope scope
) {
super(space, oname, readvar, asType, asName, scope);
}
@Override
public void execute() {
Object value = readObject(readvar);
System.out.println("# read JMX attribute '" + readvar + "' as " + value.getClass() +
((asType != null) ? " as_type=" + asType : "") +
((asName != null) ? " as_name=" + asName : ""));
if (asType != null) {
value = ValueConverter.convert(asType, value);
}
String storedName = (asName == null) ? readvar : asName;
System.out.println(storedName + "=" + value + "\n");
}
}

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.operations;
import io.nosqlbench.adapter.jmx.JMXSpace;
import io.nosqlbench.adapter.jmx.ValueConverter;
import io.nosqlbench.virtdata.library.basics.core.threadstate.SharedState;
import javax.management.ObjectName;
public class JMXReadOperation extends JmxOp {
protected final String readvar;
protected final String asType;
protected final String asName;
protected final SharedState.Scope scope;
public JMXReadOperation(
JMXSpace space,
ObjectName oname,
String readvar,
String asType,
String asName,
SharedState.Scope scope
) {
super(space.getConnector(), oname);
this.readvar = readvar;
this.asType = asType;
this.asName = asName;
this.scope = scope;
}
@Override
public void execute() {
Object value = readObject(readvar);
value = ValueConverter.convert(asType, value);
String storedName = asName;
SharedState.put(scope, storedName, value);
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.adapter.jmx.operations;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
/**
* All JMX Operations should built on this base type.
*/
public abstract class JmxOp implements Op,Runnable {
protected final static Logger logger = LogManager.getLogger(JmxOp.class);
protected JMXConnector connector;
protected ObjectName objectName;
public JmxOp(JMXConnector connector, ObjectName objectName) {
this.connector = connector;
this.objectName = objectName;
}
public MBeanServerConnection getMBeanConnection() {
MBeanServerConnection connection = null;
try {
connection = connector.getMBeanServerConnection();
return connection;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected Object readObject(String attributeName) {
try {
Object value = getMBeanConnection().getAttribute(objectName, attributeName);
logger.trace(() -> "read attribute '" + value + "': " + value);
return value;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public abstract void execute();
public void run() {
execute();
}
}

View File

@ -1,118 +0,0 @@
# JMX Driver
The JMX Driver allows you to do various JMX operations against a JMX service URL
and object name.
You must specify the service URL and object name in the op template. Alternately, you can specify
the protocol, host, port and path. Each cycle, the full JMX operation is derived from the
op template, and executed.
In the first version of this driver, only reads are supported.
# Connection Options
JMX transports can be configured in a myriad of ways. The options below allow you to add
connection options such as SSL and authentication.
- **username** - The username to authenticate to the JMX server as. This can be specifed as the
actual username to use, or 'file:...' to indicate a filename to load the user name from, or as
'console:' to force the user name to be prompted for on the console. If an empty value is provided,
then the console is used by default.
- **password** - The password to authentiate to the JMX server with. This can be specifed as the
actual password to use, or 'file:...' to indicate a filename to load the user name from, or as
'console:' to force the user name to be prompted for on the console. If an empty value is provided,
then the console is used by default.
# Example Operations
## readvar
The readvar operation is used to read a named attribute of the named object and store it in the
thread local variable map.
```yaml
statements:
- read1:
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
readvar: Value
as_type: int
as_name: pending_tasks
# process or thread, process is default
scope: process
```
The `as_type` and `as_name`, and `scope` are optional, and if provided will set the name and
data type used in the thread local variable map, and whether the variable is stored in the
thread scope or the process (global) scope.
- *as_type* can be any of long, int, double, float, byte, short, or String. If the original type
is convertable to a number, then it will be converted to a number and then to the desired type. If it
is not, it will be converted to String form first and then to the desired type. If the type name
contains dots, as in a fully-qualified class name, then direct class casting will be used if the
types are compatible.
- *as_name* will change the name used to store the value in the map.
- *scope* can be either `thread` or `process` and determines the scope of the varaible map
which is used to store the variable.
A combined format is available if you don't want to put every command property on a separate line.
In this format, the first entry in the command map is taken as the command name and a set of key=value
command arguments. It is semantically equivalent to the above example, only more compact.
```yaml
statements:
- read1: readvar=Value as_type=int as_name=pending_tasks
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
```
## printvar
If you want to simply read a value from a metric and print it out on stdout, you can do it with
the `printvar` command. This is identical to the readvar command except that it puts the resulting
variable (after any as_name and as_type options are applied) on the console.
```yaml
statements:
- read1: printvar=Value as_type=int as_name=pending_tasks
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
```
This will produce an output like this:
```yaml
# read JMX attribute ' Value' as class java.lang.Integer as_type=int as_name=pending_tasks
pending_tasks=0
```
## explain
If you want to see the details about a managed object, you can use the explain command:
```yaml
statements:
- explain1:
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
explain: object
```
This will use the MBeanInfo to interrogate the named management bean and provide a summary
of it's available attriburtes, operations, notifications, and constructors to stdout.
This is not meant for bulk testing, but more for explaining and documenting JMX beans.
The above example will produce an output like this:
```text
### MBeanInfo for 'org.apache.cassandra.metrics:type=Compaction,name=PendingTasks'
# classname: org.apache.cassandra.metrics.CassandraMetricsRegistry$JmxGauge
# Information on the management interface of the MBean
## attributes:
# Attribute exposed for management
- 'Value' type=java.lang.Objectreadable=true writable=false is_is=false
## operations:
# Operation exposed for management
- objectName() -> javax.management.ObjectName impact=UNKNOWN
```

View File

@ -1,22 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.driver.jmx;
import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op;
public class BaseJMXOp implements Op {
}

View File

@ -1,121 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.driver.jmx;
import io.nosqlbench.adapter.jmx.SecureUtils;
import io.nosqlbench.engine.api.util.SSLKsFactory;
import io.nosqlbench.nb.api.errors.OpConfigError;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
public class JMXSpace implements NBConfigurable {
private final String name;
private NBConfiguration config;
private SSLContext sslContext;
private JMXConnector connector;
public JMXSpace(String name, NBConfiguration config) {
this.name = name;
this.config = config;
SSLKsFactory.get().getContext(config);
}
public synchronized JMXConnector getConnector() {
if (this.connector == null) {
this.connector = bindConnector();
}
return this.connector;
}
private JMXConnector bindConnector() {
Map<String, Object> connectorEnv = new HashMap<>();
String username = config.get("username", String.class);
String password = config.get("password", String.class);
username = SecureUtils.readSecret("JMX username", username);
password = SecureUtils.readSecret("JMX password", password);
if (username != null && password != null) {
connectorEnv.put(JMXConnector.CREDENTIALS, new String[]{username, password});
}
JMXConnector connector = null;
try {
JMXServiceURL url = bindJMXServiceURL();
connector = JMXConnectorFactory.connect(url, connectorEnv);
} catch (IOException e) {
e.printStackTrace();
}
return connector;
}
private JMXServiceURL bindJMXServiceURL() {
JMXServiceURL url = null;
try {
url = config.getOptional("url")
.map(u -> {
try {
return new JMXServiceURL(u);
} catch (MalformedURLException e) {
throw new OpConfigError("Error while configuring JMX service URL: " + e.getMessage());
}
})
.orElse(null);
if (url==null) {
String host = config.get("host");
String protocol = config.get("protocol");
int port = config.get("port", Integer.class);
String path = config.get("path");
url = new JMXServiceURL(protocol, host, port, path);
}
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
return url;
}
@Override
public void applyConfig(NBConfiguration config) {
this.config = config;
}
@Override
public NBConfigModel getConfigModel() {
return ConfigModel.of(JMXSpace.class)
.add(Param.optional("url"))
.add(Param.optional("host"))
.add(Param.optional("protocol"))
.add(Param.optional("port",Integer.class))
.add(Param.optional("path"))
.add(Param.optional("username"))
.add(Param.optional("password"))
.add(SSLKsFactory.get().getConfigModel())
.asReadOnly();
}
// NBConfiguration sslCfg = SSLKsFactory.get().getConfigModel().extractConfig(activityDef.getParams());
// this.sslContext= SSLKsFactory.get().getContext(sslCfg);
}

View File

@ -1,32 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* 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 io.nosqlbench.driver.jmx;
import io.nosqlbench.adapter.jmx.ValueConverter;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class ValueConverterTest {
@Test
public void testConvertStringDouble() {
String s = "3";
double d = (double) ValueConverter.convert("double", s);
}
}

View File

@ -1,12 +0,0 @@
# (src/test/resources/activities/) jmx-test-1.yaml
statements:
- read1:
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
readvar: Value
as_type: int
as_name: pending_tasks
#op=url=service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi object=org.apache.cassandra.metrics:type=Compaction,name=PendingTasks readvar=Value as_type=int as_name=pending_tasks

View File

@ -1,8 +0,0 @@
# (src/test/resources/activities/) jmx-test-2.yaml
statements:
- explain1:
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
explain: object

View File

@ -1,4 +0,0 @@
statements:
- read1: readvar=Value as_type=int as_name=pending_tasks
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks

View File

@ -1,75 +0,0 @@
<!--
~ Copyright (c) 2022-2023 nosqlbench
~
~ 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.
-->
<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>
<parent>
<artifactId>mvn-defaults</artifactId>
<groupId>io.nosqlbench</groupId>
<version>4.17.32-SNAPSHOT</version>
<relativePath>../mvn-defaults</relativePath>
</parent>
<artifactId>driver-kafka</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
A Kafka driver for nosqlbench. This provides the ability to inject synthetic data
into a kafka topic.
</description>
<dependencies>
<!-- core dependencies -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.8.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.avro/avro -->
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.11.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.confluent/kafka-avro-serializer -->
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-avro-serializer</artifactId>
<version>7.2.1</version>
</dependency>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>engine-api</artifactId>
<version>4.17.32-SNAPSHOT</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>confluent</id>
<url>https://packages.confluent.io/maven/</url>
</repository>
</repositories>
</project>

View File

@ -1,94 +0,0 @@
<!--
~ Copyright (c) 2022-2023 nosqlbench
~
~ 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.
-->
<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>
<parent>
<artifactId>mvn-defaults</artifactId>
<groupId>io.nosqlbench</groupId>
<version>4.17.32-SNAPSHOT</version>
<relativePath>../mvn-defaults</relativePath>
</parent>
<artifactId>driver-pulsar</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
A Pulsar driver for nosqlbench. This provides the ability to inject synthetic data
into a pulsar system.
</description>
<properties>
<pulsar.version>2.10.2</pulsar.version>
</properties>
<dependencies>
<!-- core dependencies -->
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-client</artifactId>
<version>${pulsar.version}</version>
</dependency>
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-client-admin</artifactId>
<version>${pulsar.version}</version>
</dependency>
<dependency>
<groupId>io.nosqlbench</groupId>
<artifactId>engine-api</artifactId>
<version>4.17.32-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-configuration2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-configuration2</artifactId>
<version>2.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.avro/avro -->
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.11.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
</project>