summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Srnicek <jsrnicek@cisco.com>2017-01-31 10:00:51 +0100
committerJan Srnicek <jsrnicek@cisco.com>2017-01-31 10:00:51 +0100
commit92afaeb4a959ea5a6a072fe3ed7a01088d703e0b (patch)
treefc98660011e75ca71f97c25e641638dce37158bd
parent60e463b17b05458c1f9a7fd72f9e99d71124eedf (diff)
HONEYCOMB-293 - Memory benchmarking
Contains configuration for benchmarks: - Honeycomb on rest(just infra, no data) - Honeycomb with 1000 data nodes - Honeycomb with 10000 data nodes Each benchmark outputs two files: - out_path_name-HeapMemoryUsage.csv - out_path_name-NonHeapMemoryUsage.csv Both files are in format : committed,init,max,used 109576192,109051904,1525153792,12194752 Data sample sizes can be easily adjusted, just by changing start parameter -DsampleSize Change-Id: If6f9919307574237689326b4a38d410ec563200a Signed-off-by: Marek Gradzki <mgradzki@cisco.com> Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
-rw-r--r--infra/it/management/asciidoc/Readme.adoc35
-rw-r--r--infra/it/management/pom.xml50
-rw-r--r--infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.java54
-rw-r--r--infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java49
-rw-r--r--infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java58
-rw-r--r--infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java51
-rw-r--r--infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java45
-rw-r--r--infra/it/management/src/main/resources/management.json2
-rw-r--r--infra/it/memory-benchmark-api/asciidoc/Readme.adoc5
-rw-r--r--infra/it/memory-benchmark-api/pom.xml15
-rw-r--r--infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang19
-rw-r--r--infra/it/memory-benchmark-scripts/pom.xml72
-rw-r--r--infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy38
-rw-r--r--infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript2
-rw-r--r--infra/it/memory-benchmark/asciidoc/Readme.adoc68
-rw-r--r--infra/it/memory-benchmark/pom.xml184
-rw-r--r--infra/it/memory-benchmark/src/main/assembly/assembly.xml30
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java95
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java125
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java87
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java38
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java97
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java46
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java54
-rw-r--r--infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java38
-rw-r--r--infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java64
-rw-r--r--infra/it/pom.xml22
27 files changed, 1441 insertions, 2 deletions
diff --git a/infra/it/management/asciidoc/Readme.adoc b/infra/it/management/asciidoc/Readme.adoc
new file mode 100644
index 000000000..89bbf65d3
--- /dev/null
+++ b/infra/it/management/asciidoc/Readme.adoc
@@ -0,0 +1,35 @@
+= management
+
+This modules is used to enable JMX monitoring on honeycomb Instance.
+
+= Tutorial
+== Configure
+To build honeycomb with management module incldued
+
+ mvn clean install -DskipTests -Pmanagement
+
+After this management module must be included to honeycomb module configuration.
+In /minimal-distribution/modules , just include fully qualified name of management module like so
+
+ io.fd.honeycomb.management.jmx.HoneycombManagementModule
+
+This will start all necessary beans to allow jmx connections to honeycomb instance.
+Also in logs , you will see all available JMX beans
+
+== Use
+
+To get any available JMX bean,
+use interface *JMXBeanProvider* that defines utility method to get *JMXConnector*
+
+ // get configured instance of jxm connection url according to HoneycombManagementConfig
+ @Inject JMXServiceUrl url;
+
+ // creates JMX connector
+ final JMXConnector connector = getConnector(url);
+ // to get any available bean
+ final String beanType = "java.lang:type=Memory";
+ final String beanName = "HeapMemoryUsage";
+ final Object jmxBean = getJMXAttribute(connector, beanType, beanName);
+
+
+
diff --git a/infra/it/management/pom.xml b/infra/it/management/pom.xml
new file mode 100644
index 000000000..0a8e97200
--- /dev/null
+++ b/infra/it/management/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2017 Cisco and/or its affiliates.
+ ~
+ ~ 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>
+ <groupId>io.fd.honeycomb.common</groupId>
+ <artifactId>honeycomb-parent</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ <relativePath>../../../common/honeycomb-parent</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <properties>
+ <jetty-jmx.version>9.3.11.v20160721</jetty-jmx.version>
+ </properties>
+
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>management</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-jmx</artifactId>
+ <version>${jetty-jmx.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>minimal-distribution</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.java
new file mode 100644
index 000000000..625c63cb8
--- /dev/null
+++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/ConnectorServerProvider.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.management.jmx;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.infra.distro.ProviderTrait;
+import org.eclipse.jetty.jmx.ConnectorServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.remote.JMXServiceURL;
+
+/**
+ * Provides and start JMX connector server
+ * */
+public class ConnectorServerProvider extends ProviderTrait<ConnectorServer> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ConnectorServerProvider.class);
+
+ @Inject
+ private HoneycombManagementConfig config;
+
+ @Inject
+ private JMXServiceURL jmxServiceUrl;
+
+ @Override
+ protected ConnectorServer create() {
+ try {
+ final ConnectorServer connectorServer = new ConnectorServer(jmxServiceUrl,
+ "org.eclipse.jetty.jmx:name="+HoneycombManagementConfig.JXM_CONNECTOR_SERVER_NAME);
+
+ LOG.info("Starting connector server {}", connectorServer);
+ connectorServer.doStart();
+
+ return connectorServer;
+ } catch (Exception e) {
+ throw new IllegalStateException("Unable to create jmx connector server", e);
+ }
+ }
+}
diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java
new file mode 100644
index 000000000..2362b6f43
--- /dev/null
+++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementConfig.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.management.jmx;
+
+
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+import java.util.Optional;
+
+@BindConfig(value = "management", syntax = Syntax.JSON)
+public class HoneycombManagementConfig {
+
+ public static final String JMX_PROTOCOL = "rmi";
+ public static final String JXM_CONNECTOR_SERVER_NAME = "rmi";
+
+ public static final String PROP_JMX_HOST = "jetty.jmxrmihost";
+ public static final String PROP_JMX_PORT = "jetty.jmxrmiport";
+
+
+ @InjectConfig(PROP_JMX_HOST)
+ private String jmxHost;
+
+ @InjectConfig(PROP_JMX_PORT)
+ private String jmxPort;
+
+ public String getJmxHost() {
+ return Optional.ofNullable(jmxHost).orElse("localhost");
+ }
+
+ public int getJmxPort() {
+ return Integer.parseInt(Optional.ofNullable(jmxPort).orElse("1099"));
+ }
+}
diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java
new file mode 100644
index 000000000..bc75cd01f
--- /dev/null
+++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/HoneycombManagementModule.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.management.jmx;
+
+
+import com.google.inject.AbstractModule;
+import net.jmob.guice.conf.core.ConfigurationModule;
+import org.eclipse.jetty.jmx.ConnectorServer;
+import org.eclipse.jetty.jmx.MBeanContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.ObjectInstance;
+import javax.management.remote.JMXServiceURL;
+import java.lang.management.ManagementFactory;
+
+public class HoneycombManagementModule extends AbstractModule {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HoneycombManagementModule.class);
+
+ @Override
+ protected void configure() {
+ install(ConfigurationModule.create());
+ requestInjection(HoneycombManagementConfig.class);
+ bind(MBeanContainer.class).toInstance(new MBeanContainer(ManagementFactory.getPlatformMBeanServer()));
+ bind(JMXServiceURL.class).toProvider(JMXServiceUrlProvider.class);
+ // .asEagerSingleton(); will cause also start defined in provider
+ bind(ConnectorServer.class).toProvider(ConnectorServerProvider.class).asEagerSingleton();
+
+ showAvailableBeans();
+ }
+
+ /**
+ * Prints all available JMX beans
+ */
+ protected static void showAvailableBeans() {
+ for (final ObjectInstance instance : ManagementFactory.getPlatformMBeanServer().queryMBeans(null, null)) {
+ LOG.info("MBean Found:");
+ LOG.info("Class Name:{}", instance.getClassName());
+ LOG.info("Object Name:{}", instance.getObjectName());
+ LOG.info("****************************************");
+ }
+ }
+}
diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java
new file mode 100644
index 000000000..557acb464
--- /dev/null
+++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXBeanProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.management.jmx;
+
+import javax.annotation.Nonnull;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import java.io.IOException;
+
+public interface JMXBeanProvider {
+
+ /**
+ * Provides JMX connector to specified url
+ */
+ default JMXConnector getConnector(@Nonnull final JMXServiceURL url) {
+ try {
+ return JMXConnectorFactory.connect(url);
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to create JMX connector", e);
+ }
+ }
+
+ /**
+ * Requests specified jxm bean from provided connector
+ */
+ default Object getJMXAttribute(@Nonnull final JMXConnector connector, @Nonnull final String beanType,
+ @Nonnull final String beanName) {
+ try {
+ return connector.getMBeanServerConnection().getAttribute(new ObjectName(beanType), beanName);
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ String.format("Unable to query mbean of type %s, name %s", beanType, beanName), e);
+ }
+ }
+}
diff --git a/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java
new file mode 100644
index 000000000..1b9136501
--- /dev/null
+++ b/infra/it/management/src/main/java/io/fd/honeycomb/management/jmx/JMXServiceUrlProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.management.jmx;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.infra.distro.ProviderTrait;
+
+import javax.management.remote.JMXServiceURL;
+import java.net.MalformedURLException;
+
+/**
+ * Provides properly binded {@link JMXServiceURL}
+ */
+public class JMXServiceUrlProvider extends ProviderTrait<JMXServiceURL> {
+
+ @Inject
+ private HoneycombManagementConfig config;
+
+ @Override
+ protected JMXServiceURL create() {
+ try {
+ return new JMXServiceURL(
+ HoneycombManagementConfig.JMX_PROTOCOL,
+ config.getJmxHost(),
+ config.getJmxPort(),
+ "/jndi/rmi://" + config.getJmxHost() + ":" + config.getJmxPort() + "/jmxrmi");
+ } catch (MalformedURLException e) {
+ throw new IllegalStateException("Unable to create JXM Service url", e);
+ }
+ }
+}
diff --git a/infra/it/management/src/main/resources/management.json b/infra/it/management/src/main/resources/management.json
new file mode 100644
index 000000000..7a73a41bf
--- /dev/null
+++ b/infra/it/management/src/main/resources/management.json
@@ -0,0 +1,2 @@
+{
+} \ No newline at end of file
diff --git a/infra/it/memory-benchmark-api/asciidoc/Readme.adoc b/infra/it/memory-benchmark-api/asciidoc/Readme.adoc
new file mode 100644
index 000000000..c63073613
--- /dev/null
+++ b/infra/it/memory-benchmark-api/asciidoc/Readme.adoc
@@ -0,0 +1,5 @@
+= memory-benchmark-api
+
+Overview of memory-benchmark-api
+
+Provides test models for honeycomb memory benchmark. \ No newline at end of file
diff --git a/infra/it/memory-benchmark-api/pom.xml b/infra/it/memory-benchmark-api/pom.xml
new file mode 100644
index 000000000..8b92303ec
--- /dev/null
+++ b/infra/it/memory-benchmark-api/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>api-parent</artifactId>
+ <groupId>io.fd.honeycomb.common</groupId>
+ <version>1.17.04-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>memory-benchmark-api</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+</project> \ No newline at end of file
diff --git a/infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang b/infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang
new file mode 100644
index 000000000..e01550659
--- /dev/null
+++ b/infra/it/memory-benchmark-api/src/main/yang/memory-benchmark.yang
@@ -0,0 +1,19 @@
+module memory-benchmark {
+
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:memory:benchmark";
+ prefix "mm-bench";
+
+ revision "2016-12-04" {
+ description "Memory benchmark test api";
+ }
+
+ container config-data {
+ list config-list {
+ key name;
+ leaf name {
+ type string;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/infra/it/memory-benchmark-scripts/pom.xml b/infra/it/memory-benchmark-scripts/pom.xml
new file mode 100644
index 000000000..b6b29e5e2
--- /dev/null
+++ b/infra/it/memory-benchmark-scripts/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+
+ <!-- have to basically duplicate common-scripts, it cannot be used as parent because of jar packaging -->
+
+ <properties>
+ <!-- groovy -->
+ <maven.groovy.version>2.0</maven.groovy.version>
+ <groovy.version>2.4.7</groovy.version>
+ <groovy.eclipse.compiler.version>2.9.2-01</groovy.eclipse.compiler.version>
+ <groovy.eclipse.batch.version>2.4.3-01</groovy.eclipse.batch.version>
+ </properties>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>benchmark-scripts</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ <skipDeploy>true</skipDeploy>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-eclipse-compiler</artifactId>
+ <version>${groovy.eclipse.compiler.version}</version>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <!-- 2.8.0-01 and later require maven-compiler-plugin 3.1 or higher -->
+ <configuration>
+ <compilerId>groovy-eclipse-compiler</compilerId>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-eclipse-compiler</artifactId>
+ <version>${groovy.eclipse.compiler.version}</version>
+ </dependency>
+ <!-- for 2.8.0-01 and later you must have an explicit dependency on groovy-eclipse-batch -->
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-eclipse-batch</artifactId>
+ <version>${groovy.eclipse.batch.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy b/infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy
new file mode 100644
index 000000000..1db656aca
--- /dev/null
+++ b/infra/it/memory-benchmark-scripts/src/main/groovy/io/fd/honeycomb/benchmark/script/MemoryBenchmarkStartupScriptGenerator.groovy
@@ -0,0 +1,38 @@
+package io.fd.honeycomb.benchmark.script
+
+import groovy.text.SimpleTemplateEngine
+
+import java.nio.file.Files
+import java.nio.file.Paths
+
+class MemoryBenchmarkStartupScriptGenerator {
+
+ static final def STARTUP_SCRIPT_ON_REST_TEMPLATE = MemoryBenchmarkStartupScriptGenerator.getResource("/memoryBenchmarkScript")
+ static final def STARTUP_SCRIPT_NAME_BASE = "honeycomb-memory-footprint-benchmark-"
+
+ static final def FOOTPRINT_TEST_CLASS = "io.fd.honeycomb.benchmark.memory.HoneycombFootprintTest"
+
+ static final def OUTPUT_PATH_PARAM = "-DoutPath=\$(dirname \$0)/"
+ static final def SAMPLE_SIZE_PARAM = "-DsampleSize="
+
+ /**
+ * Generate script to run io.fd.honeycomb.benchmark.memory.HoneycombWithDataTest with provided params
+ * */
+ public static void generateWithDataScript(project, log, String outputFileName, dataSampleSize) {
+ log.info "Binding execution script for with-data benchmark[output=${outputFileName},sampleSize=${dataSampleSize}]"
+ def scriptContent = new SimpleTemplateEngine().createTemplate(STARTUP_SCRIPT_ON_REST_TEMPLATE).make(
+ [
+ "testParams" : "${OUTPUT_PATH_PARAM}${outputFileName}-${dataSampleSize} ${SAMPLE_SIZE_PARAM}${dataSampleSize}",
+ "testClass" : FOOTPRINT_TEST_CLASS
+ ]).toString()
+ flushScript(Paths.get(project.build.directory, "${STARTUP_SCRIPT_NAME_BASE}${dataSampleSize}"), scriptContent, log)
+ }
+
+ private static flushScript(filePath, content,log) {
+ log.info "Saving script to path ${filePath}"
+ def file = Files.createFile(filePath).toFile()
+
+ file.text = content
+ file.setExecutable(true)
+ }
+}
diff --git a/infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript b/infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript
new file mode 100644
index 000000000..120cb00e0
--- /dev/null
+++ b/infra/it/memory-benchmark-scripts/src/main/resources/memoryBenchmarkScript
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+java -cp .:memory-benchmark-1.0.0-with-tests.jar ${testParams} org.junit.runner.JUnitCore ${testClass} \ No newline at end of file
diff --git a/infra/it/memory-benchmark/asciidoc/Readme.adoc b/infra/it/memory-benchmark/asciidoc/Readme.adoc
new file mode 100644
index 000000000..80e2ffb6f
--- /dev/null
+++ b/infra/it/memory-benchmark/asciidoc/Readme.adoc
@@ -0,0 +1,68 @@
+= memory-benchmark
+
+Overview of memory-benchmark
+
+= Tutorial
+= Configure
+
+To run honeycomb memory benchmark, use maven profile *memory-benchmark* like so
+
+ mvn clean install -DskipTests -Pmemory-benchmark
+
+This will add following modules to build
+
+* _management_ - Enable JMX for honeycomb
+* _memory-benchmark-scripts_ - Script generation for benchmarks
+* _memory-benchmark-api_ - Test models for benchmark
+* _memory-benchmark_ - Benchmark itself
+
+By default, 3 versions of run scripts are produces in project build folder
+
+* _honeycomb-memory-footprint-benchmark-0_ - Tests honeycomb memory footprint on rest without any config/context data
+* _honeycomb-memory-footprint-benchmark-1000_ - Tests honeycomb memory footprint while 1000 data nodes present in config data
+* _honeycomb-memory-footprint-benchmark-10000_ - Tests honeycomb memory footprint while 10000 data nodes present in config data
+
+Any other data sample size can be tested by modifying script parameter *-DsampleSize*
+
+== Run
+
+To run benchmark
+
+ ./honeycomb-memory-footprint-benchmark-0
+
+This will produce two output files.
+
+* memory-benchmark-on-rest-out-0-HeapMemoryUsage.csv
+* memory-benchmark-on-rest-out-0-NonHeapMemoryUsage.csv
+
+For further explanation look at
+
+ https://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html
+
+
+Each of these files contains values in following format
+
+ committed,init,max,used
+ 132644864,109051904,1525153792,12577144
+
+These values stands for
+
+
+* init - Represents the initial amount of memory (in bytes) that the Java virtual machine requests from the operating system for memory management during startup.
+The Java virtual machine may request additional memory from the operating system and may also release memory to the system over time.
+The value of init may be undefined(-1).
+* used - Represents the amount of memory currently used (in bytes).
+* committed - Represents the amount of memory (in bytes) that is guaranteed to be available for use by the Java virtual machine.
+The amount of committed memory may change over time (increase or decrease). The Java virtual machine may release memory to the system and committed could be less than init.
+Committed will always be greater than or equal to used.
+* max - Represents the maximum amount of memory (in bytes) that can be used for memory management. Its value may be undefined(-1).
+ The maximum amount of memory may change over time if defined.
+ The amount of used and committed memory will always be less than or equal to max if max is defined.
+ A memory allocation may fail if it attempts to increase the used memory
+ such that used > committed even if used <= max would still be true (for example, when the system is low on virtual memory).
+
+
+
+
+
+
diff --git a/infra/it/memory-benchmark/pom.xml b/infra/it/memory-benchmark/pom.xml
new file mode 100644
index 000000000..8c93c0bef
--- /dev/null
+++ b/infra/it/memory-benchmark/pom.xml
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2016 Cisco and/or its affiliates.
+ ~
+ ~ 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 set as common script to use all groovy dependency versions, etc-->
+ <parent>
+ <groupId>io.fd.honeycomb.common</groupId>
+ <artifactId>honeycomb-parent</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ <relativePath>../../../common/honeycomb-parent</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>memory-benchmark</artifactId>
+ <!-- Static version, we don't want it to be deployed anyway-->
+ <version>1.0.0</version>
+ <properties>
+ <commons-csv.version>1.4</commons-csv.version>
+ <honeycomb.version>1.17.04-SNAPSHOT</honeycomb.version>
+ <maven.groovy.version>2.0</maven.groovy.version>
+ <groovy.version>2.4.7</groovy.version>
+ <groovy.eclipse.compiler.version>2.9.2-01</groovy.eclipse.compiler.version>
+ <groovy.eclipse.batch.version>2.4.3-01</groovy.eclipse.batch.version>
+ </properties>
+ <!-- to be runnable from command line -->
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>memory-benchmark-api</artifactId>
+ <version>${honeycomb.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>minimal-distribution</artifactId>
+ <version>${honeycomb.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>management</artifactId>
+ <version>${honeycomb.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-csv</artifactId>
+ <version>${commons-csv.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <!-- Skip deploy -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+
+ <!-- skips test by default but compile them -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.19.1</version>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+
+ <!-- assemble jar with all dependencies and test classes -->
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <descriptor>src/main/assembly/assembly.xml</descriptor>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- generate scripts for benchmarks -->
+ <plugin>
+ <groupId>org.codehaus.gmaven</groupId>
+ <artifactId>groovy-maven-plugin</artifactId>
+ <executions>
+ <!-- script for on-rest memory benchmark -->
+ <execution>
+ <id>generate-on-rest-benchmark-script</id>
+ <phase>package</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <!-- 0 data samples == empty config file, therefore same as honeycomb on rest -->
+ <configuration>
+ <source>
+ io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-on-rest-out", 0)
+ </source>
+ </configuration>
+ </execution>
+ <!-- script for memory benchmark with 1000 nodes in config data-->
+ <execution>
+ <id>generate-with-data-1000-benchmark-script</id>
+ <phase>package</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>
+ io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-with-data-out", 1000)
+ </source>
+ </configuration>
+ </execution>
+ <!-- script for memory benchmark with 10000 nodes in config data-->
+ <execution>
+ <id>generate-with-data-10000-benchmark-script</id>
+ <phase>package</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source>
+ io.fd.honeycomb.benchmark.script.MemoryBenchmarkStartupScriptGenerator.generateWithDataScript(project, log, "memory-benchmark-with-data-out", 10000)
+ </source>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>io.fd.honeycomb.it</groupId>
+ <artifactId>benchmark-scripts</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/infra/it/memory-benchmark/src/main/assembly/assembly.xml b/infra/it/memory-benchmark/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..385d0dcb8
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/assembly/assembly.xml
@@ -0,0 +1,30 @@
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+ <id>with-tests</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>/</outputDirectory>
+ <useProjectArtifact>true</useProjectArtifact>
+ <!-- Will include junit-->
+ <useProjectAttachments>true</useProjectAttachments>
+ <unpack>true</unpack>
+ <scope>test</scope>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.directory}/test-classes</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>**/*.class</include>
+ </includes>
+ <useDefaultExcludes>true</useDefaultExcludes>
+ </fileSet>
+ </fileSets>
+</assembly> \ No newline at end of file
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java
new file mode 100644
index 000000000..c7717d593
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/BenchmarkFilesProvider.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory;
+
+
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
+import org.slf4j.Logger;
+
+import javax.annotation.Nonnull;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.function.Supplier;
+
+public interface BenchmarkFilesProvider {
+
+ default void outputBenchmarkResult(@Nonnull final MemoryInfo benchmarkResult,
+ @Nonnull final String outputPath,
+ @Nonnull final Supplier<Logger> loggerSupplier) {
+ // specifies output file in form specified_name-memory_info_type.csv
+ final Path outPath = Paths.get(outputPath + "-" + benchmarkResult.getMemoryInfoTypeName() + ".csv");
+ final CSVFormat csvFormat = CSVFormat.RFC4180.withHeader(MemoryInfo.COMMITTED, MemoryInfo.INIT, MemoryInfo.MAX, MemoryInfo.USED);
+
+ try (final CSVPrinter csvPrinter = new CSVPrinter(new StringBuilder(), csvFormat)) {
+ // prints values in same order that header is
+ csvPrinter.printRecord(benchmarkResult.getCommitted(), benchmarkResult.getInit(), benchmarkResult.getMax(), benchmarkResult.getUsed());
+
+ loggerSupplier.get().info("Creating output file {}", outPath);
+ // writes output to separate file
+ Files.write(Files.createFile(outPath), Collections.singleton(csvPrinter.getOut().toString()));
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to output results of benchmark", e);
+ }
+ }
+
+
+ default String generateEmptyJsonFile(final String fileName) {
+ try {
+ Path tempFilePath = Files.createTempFile(fileName, ".json");
+
+ Files.write(tempFilePath, Arrays.asList("{}"));
+
+ return tempFilePath.normalize().toString();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to create temp config data file");
+ }
+ }
+
+ /**
+ * Generate dummy data file to be provided for honeycomb as config data
+ */
+ default String generateNonEmptyConfigDataFile(final String fileName, final int dataSampleSize) {
+ try {
+ Path tempFilePath = Files.createTempFile(fileName, ".json");
+
+ StringBuilder dataBuilder = new StringBuilder();
+
+ dataBuilder.append("{\"mm-bench:config-data\":{\"config-list\":[");
+
+ for (int i = 0; i < dataSampleSize; i++) {
+ dataBuilder.append("{\"name\":\"")
+ .append(String.valueOf(i))
+ .append("\"}");
+ if (i != dataSampleSize - 1) {
+ dataBuilder.append(",");
+ }
+ }
+
+ dataBuilder.append("]}}");
+
+ Files.write(tempFilePath, Arrays.asList(dataBuilder.toString()));
+
+ return tempFilePath.normalize().toString();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to create temp config data file");
+ }
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java
new file mode 100644
index 000000000..48d805975
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryFootprintBenchmark.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import io.fd.honeycomb.benchmark.memory.config.BindableCfgAttrsModule;
+import io.fd.honeycomb.benchmark.memory.config.StaticHoneycombManagementModule;
+import io.fd.honeycomb.benchmark.memory.write.NoopWritersModule;
+import io.fd.honeycomb.infra.distro.Main;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+import io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule;
+import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule;
+import io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule;
+import io.fd.honeycomb.infra.distro.netconf.NetconfModule;
+import io.fd.honeycomb.infra.distro.netconf.NetconfReadersModule;
+import io.fd.honeycomb.infra.distro.restconf.RestconfModule;
+import io.fd.honeycomb.infra.distro.schema.SchemaModule;
+import io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule;
+import io.fd.honeycomb.management.jmx.JMXBeanProvider;
+import org.eclipse.jetty.server.Server;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXServiceURL;
+import java.util.Set;
+
+/**
+ * Measure memory consumption of config data storage
+ */
+public class MemoryFootprintBenchmark implements JMXBeanProvider, BenchmarkFilesProvider {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MemoryFootprintBenchmark.class);
+
+ /**
+ * All modules from infra to load.Not static to not persist state
+ */
+ private final Set<Module> BASE_MODULES = ImmutableSet.of(
+ new YangBindingProviderModule(),
+ new SchemaModule(),
+ new ConfigAndOperationalPipelineModule(),
+ new ContextPipelineModule(),
+ new InitializerPipelineModule(),
+ new NetconfModule(),
+ new NetconfReadersModule(),
+ new RestconfModule(),
+ // to enable jmx
+ new StaticHoneycombManagementModule(),
+ //adds noop writers
+ new NoopWritersModule());
+
+ // configuration class used to run benchmark, allows us to switch between honeycomb with data, or on rest
+ private final HoneycombConfiguration configuration;
+
+ // output file path
+ private final String outputPath;
+
+ public MemoryFootprintBenchmark(@Nonnull final HoneycombConfiguration configuration, @Nonnull final String outputPath) {
+ this.configuration = configuration;
+ this.outputPath = outputPath;
+ }
+
+ public void run() throws Exception {
+ // start honeycomb with configuration of BASE_MODULES + configuration class
+ final Injector injector = startHoneycomb();
+
+ // query memory beans with JMX and output results on output path
+ queryMemoryBeans(injector.getInstance(JMXServiceURL.class))
+ .forEach(memoryInfo -> outputBenchmarkResult(memoryInfo, outputPath, () -> LOG));
+ // shutdowns server instance
+ injector.getInstance(Server.class).stop();
+ }
+
+ /**
+ * start honeycomb with basic modules + provided static configuration
+ */
+ private Injector startHoneycomb() {
+ LOG.info("Starting embedded server with configuration {}", configuration);
+ return Main.init(ImmutableSet.<Module>builder()
+ .add(new BindableCfgAttrsModule(configuration))
+ .addAll(BASE_MODULES).build());
+ }
+
+ /**
+ * Queries heap and non-heap memory usage
+ */
+ private Set<MemoryInfo> queryMemoryBeans(final JMXServiceURL url) {
+ LOG.info("Requesting memory bean on url {}", url);
+
+ try (final JMXConnector connector = getConnector(url)) {
+ MemoryInfo heapMemoryInfo = new MemoryInfo(
+ (CompositeDataSupport) getJMXAttribute(connector, MemoryInfo.MEMORY_MBEAN_TYPE,
+ MemoryInfo.HEAP_MEMORY), MemoryInfo.HEAP_MEMORY);
+ LOG.info("Heap memory usage {}", heapMemoryInfo);
+
+ MemoryInfo nonHeapMemoryInfo = new MemoryInfo(
+ (CompositeDataSupport) getJMXAttribute(connector, MemoryInfo.MEMORY_MBEAN_TYPE,
+ MemoryInfo.NON_HEAP_MEMORY), MemoryInfo.NON_HEAP_MEMORY);
+ LOG.info("NonHeap memory usage {}", nonHeapMemoryInfo);
+ return ImmutableSet.of(heapMemoryInfo, nonHeapMemoryInfo);
+ } catch (Exception e) {
+ throw new IllegalStateException("Unable to query memory beans", e);
+ }
+ }
+
+}
+
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java
new file mode 100644
index 000000000..f79006f78
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/MemoryInfo.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory;
+
+import javax.annotation.Nonnull;
+import javax.management.openmbean.CompositeDataSupport;
+import java.util.Arrays;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Wrapped from data extracted from JMX beans of type Memory
+ * */
+public final class MemoryInfo {
+
+ public static final String MEMORY_MBEAN_TYPE = "java.lang:type=Memory";
+ public static final String HEAP_MEMORY = "HeapMemoryUsage";
+ public static final String NON_HEAP_MEMORY = "NonHeapMemoryUsage";
+
+ public static final String COMMITTED = "committed";
+ public static final String INIT = "init";
+ public static final String MAX = "max";
+ public static final String USED = "used";
+
+ private final String memoryInfoTypeName;
+ private final long committed, init, max, used;
+
+ public MemoryInfo(@Nonnull final CompositeDataSupport compositeData, @Nonnull final String memoryInfoTypeName) {
+ checkArgument(compositeData.getCompositeType().keySet().containsAll(Arrays.asList(COMMITTED, INIT, MAX, USED)),
+ "Submitted composite data %s does not contains necessary attributes", compositeData);
+ this.memoryInfoTypeName = memoryInfoTypeName;
+ this.committed = compositeDataAttributeValue(compositeData.get(COMMITTED));
+ this.init = compositeDataAttributeValue(compositeData.get(INIT));
+ this.max = compositeDataAttributeValue(compositeData.get(MAX));
+ this.used = compositeDataAttributeValue(compositeData.get(USED));
+
+ }
+
+ public String getMemoryInfoTypeName() {
+ return memoryInfoTypeName;
+ }
+
+ public long getCommitted() {
+ return committed;
+ }
+
+ public long getInit() {
+ return init;
+ }
+
+ public long getMax() {
+ return max;
+ }
+
+ public long getUsed() {
+ return used;
+ }
+
+ @Override
+ public String toString() {
+ return memoryInfoTypeName + "[" +
+ "committed=" + committed +
+ ",init=" + init +
+ ",max=" + max +
+ ",used=" + used +
+ ']';
+ }
+
+ private static Long compositeDataAttributeValue(final Object commited) {
+ checkArgument(commited instanceof Long, "Unsupported memory attribute value %s", commited.getClass());
+ return Long.class.cast(commited);
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java
new file mode 100644
index 000000000..03e3774db
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/BindableCfgAttrsModule.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory.config;
+
+
+import com.google.inject.AbstractModule;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+
+/**
+ * Provides ability to bind specific instance of static configuration
+ * */
+public class BindableCfgAttrsModule extends AbstractModule {
+
+ private final HoneycombConfiguration configToBind;
+
+ public BindableCfgAttrsModule(HoneycombConfiguration configToBind) {
+ this.configToBind = configToBind;
+ }
+
+ @Override
+ protected void configure() {
+ // Inject non-dependency configuration
+ bind(HoneycombConfiguration.class).toInstance(configToBind);
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java
new file mode 100644
index 000000000..6bcf7ef68
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombConfiguration.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory.config;
+
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+
+import javax.annotation.Nonnull;
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Optional;
+
+/**
+ * Static configuration to prevent injecting of properties from json fles
+ */
+public class StaticHoneycombConfiguration extends HoneycombConfiguration implements Closeable {
+
+ public StaticHoneycombConfiguration(@Nonnull final String persistConfigPath, @Nonnull final String persistContextPath) {
+ this.peristConfigPath = persistConfigPath;
+ this.peristContextPath = persistContextPath;
+
+ this.username = "admin";
+ this.password = "admin";
+ this.notificationServiceQueueDepth = 1;
+ this.restconfBindingAddress = Optional.of("/restconf");
+ this.restconfPort = Optional.of(8187);
+ this.restconfBindingAddress = Optional.of("127.0.0.1");
+ this.persistedConfigRestorationType = "Merge";
+ this.persistedContextRestorationType = "Merge";
+ this.restconfWebsocketPort = Optional.of(7890);
+ }
+
+ @Override
+ public boolean isConfigPersistenceEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isRestconfHttpsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isRestconfHttpEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isRestconfEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isNetconfTcpEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isContextPersistenceEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isNetconfEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isNetconfSshEnabled() {
+ return false;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (Files.exists(Paths.get(peristConfigPath))) {
+ Files.delete(Paths.get(peristConfigPath));
+ }
+
+ if (Files.exists(Paths.get(peristContextPath))) {
+ Files.delete(Paths.get(peristContextPath));
+ }
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java
new file mode 100644
index 000000000..a91d6ba84
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/config/StaticHoneycombManagementModule.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory.config;
+
+import io.fd.honeycomb.management.jmx.ConnectorServerProvider;
+import io.fd.honeycomb.management.jmx.HoneycombManagementConfig;
+import io.fd.honeycomb.management.jmx.HoneycombManagementModule;
+import io.fd.honeycomb.management.jmx.JMXServiceUrlProvider;
+import org.eclipse.jetty.jmx.ConnectorServer;
+import org.eclipse.jetty.jmx.MBeanContainer;
+
+import javax.management.remote.JMXServiceURL;
+import java.lang.management.ManagementFactory;
+
+/**
+ * In this case we need to override Honeycomb config, but if standard management module is active,
+ * configuration module injection will cause attempt to inject attributes in HoneycombConfiguration,
+ * even if static instance is provider. Therefore here we need to override configure to also provide
+ * static instance for HoneycombManagementConfig
+ */
+public class StaticHoneycombManagementModule extends HoneycombManagementModule {
+
+ @Override
+ protected void configure() {
+ // all values are wrapped in Optionals with default values
+ bind(HoneycombManagementConfig.class).toInstance(new HoneycombManagementConfig());
+ bind(MBeanContainer.class).toInstance(new MBeanContainer(ManagementFactory.getPlatformMBeanServer()));
+ bind(JMXServiceURL.class).toProvider(JMXServiceUrlProvider.class);
+ bind(ConnectorServer.class).toProvider(ConnectorServerProvider.class).asEagerSingleton();
+
+ showAvailableBeans();
+ }
+}
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java
new file mode 100644
index 000000000..000a176df
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWriter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory.write;
+
+import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.translate.write.Writer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public final class NoopWriter<T extends DataObject> implements Writer<T> {
+
+ private final InstanceIdentifier<T> id;
+
+ public NoopWriter(final InstanceIdentifier<T> id) {
+ this.id = id;
+ }
+
+ @Override
+ public void update(@Nonnull final InstanceIdentifier<? extends DataObject> id,
+ @Nullable final DataObject dataBefore,
+ @Nullable final DataObject dataAfter,
+ @Nonnull final WriteContext ctx) throws WriteFailedException {
+ // NOOP
+ }
+
+ @Nonnull
+ @Override
+ public InstanceIdentifier<T> getManagedDataObjectType() {
+ return id;
+ }
+
+ @Override
+ public String toString() {
+ return "NoopWriter{" +
+ id.getTargetType().getSimpleName() + '}';
+ }
+} \ No newline at end of file
diff --git a/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java
new file mode 100644
index 000000000..a88c514c4
--- /dev/null
+++ b/infra/it/memory-benchmark/src/main/java/io/fd/honeycomb/benchmark/memory/write/NoopWritersModule.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory.write;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.memory.benchmark.rev161204.ConfigData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.memory.benchmark.rev161204.config.data.ConfigList;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NoopWritersModule extends AbstractModule {
+ @Override
+ protected void configure() {
+
+ final Multibinder<WriterFactory> writeBinder = Multibinder.newSetBinder(binder(), WriterFactory.class);
+ writeBinder.addBinding().toInstance(registry -> {
+ // Add noop writers for all data written in this benchmark
+
+ registry.add(new NoopWriter<>(InstanceIdentifier.create(ConfigData.class)));
+ registry.add(new NoopWriter<>(InstanceIdentifier.create(ConfigData.class).child(ConfigList.class)));
+ });
+ }
+
+}
diff --git a/infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java b/infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java
new file mode 100644
index 000000000..b8817f8f4
--- /dev/null
+++ b/infra/it/memory-benchmark/src/test/java/io/fd/honeycomb/benchmark/memory/HoneycombFootprintTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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.fd.honeycomb.benchmark.memory;
+
+import io.fd.honeycomb.benchmark.memory.config.StaticHoneycombConfiguration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Test honeycomb memory footprint while containing amount of nodes specified by
+ * parameter sampleSize.<br>
+ * Test must be triggered by separated scripts, not by Parametrized runner,<br>
+ * because of classes like WebSocketServer that is internally a singleton, therefore it holds static reference<br>
+ * on itself and would fail on second run on precondition, because junit kills threads, but does not unload classes
+ */
+public class HoneycombFootprintTest implements BenchmarkFilesProvider {
+
+ private static final String SAMPLE_SIZE_PROP = "sampleSize";
+ private static final String OUTPUT_PROP = "outPath";
+
+ private StaticHoneycombConfiguration staticHoneycombConfiguration;
+ private String outputPath;
+
+ @Before
+ public void init() {
+ outputPath = Objects.requireNonNull(System.getProperty(OUTPUT_PROP),
+ "No output file path specified, make sure you've specified -D" + OUTPUT_PROP + " parameter");
+ }
+
+ @Test
+ public void testHoneycombMemoryFootprintWithData() throws Exception {
+ final int dataSampleSize = Integer.valueOf(Objects.requireNonNull(System.getProperty(SAMPLE_SIZE_PROP),
+ "No sample data size defined, make sure you've specified -D" + SAMPLE_SIZE_PROP + " parameter"));
+
+ staticHoneycombConfiguration = new StaticHoneycombConfiguration(
+ generateNonEmptyConfigDataFile("temp-config", dataSampleSize),
+ generateEmptyJsonFile("temp-empty-context"));
+
+ new MemoryFootprintBenchmark(staticHoneycombConfiguration, outputPath).run();
+ }
+
+ @After
+ public void destroyTest() throws IOException {
+ // removes temp files,etc
+ staticHoneycombConfiguration.close();
+ }
+}
diff --git a/infra/it/pom.xml b/infra/it/pom.xml
index da6e3c2b8..cbf8eae62 100644
--- a/infra/it/pom.xml
+++ b/infra/it/pom.xml
@@ -34,15 +34,33 @@
<module>it-test</module>
</modules>
-
- <!-- Activate from command line with mvn <goals> -Pbenchmark -->
<profiles>
+ <!-- Activate from command line with mvn <goals> -Pbenchmark -->
<profile>
<id>benchmark</id>
<modules>
<module>benchmark</module>
</modules>
</profile>
+
+ <!-- Activate management module -->
+ <profile>
+ <id>management</id>
+ <modules>
+ <module>management</module>
+ </modules>
+ </profile>
+
+ <!-- Activate memory benchmarking modules -->
+ <profile>
+ <id>memory-benchmark</id>
+ <modules>
+ <module>management</module>
+ <module>memory-benchmark-scripts</module>
+ <module>memory-benchmark</module>
+ <module>memory-benchmark-api</module>
+ </modules>
+ </profile>
</profiles>
<!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->