This is an automated email from the ASF dual-hosted git repository. klund pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push: new c43dbc5 GEODE-9064: Configure serial filter during ManagementAgent start (#6196) c43dbc5 is described below commit c43dbc59dd54df3538598e85243698840f8b6541 Author: Kirk Lund <kl...@apache.org> AuthorDate: Tue Apr 6 09:43:22 2021 -0700 GEODE-9064: Configure serial filter during ManagementAgent start (#6196) The Geode JMX layer will configure the system property “jmx.remote.rmi.server.serial.filter.pattern" to only accept JDK classes identified as open-types required for JMX. If the system property already has a value then Geode will log a statement and leave the system property alone. --- ...gerConfiguresJmxSerialFilterAcceptanceTest.java | 115 +++++++ ...gerConfiguresJmxSerialFilterAcceptanceTest.java | 111 +++++++ ...erConfiguresJmxSerialFilterIntegrationTest.java | 204 ++++++++++++ ...erConfiguresJmxSerialFilterIntegrationTest.java | 201 ++++++++++++ .../internal/JmxRmiOpenTypesSerialFilter.java | 148 +++++++++ .../management/internal/JmxRmiSerialFilter.java | 21 ++ .../geode/management/internal/ManagementAgent.java | 7 +- .../internal/ManagementAgentFactory.java | 25 ++ .../internal/SystemManagementService.java | 25 +- .../internal/JmxRmiOpenTypesSerialFilterTest.java | 351 +++++++++++++++++++++ .../internal/SystemManagementServiceTest.java | 6 +- 11 files changed, 1198 insertions(+), 16 deletions(-) diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/LocatorManagerConfiguresJmxSerialFilterAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/LocatorManagerConfiguresJmxSerialFilterAcceptanceTest.java new file mode 100644 index 0000000..de0b8c8 --- /dev/null +++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/LocatorManagerConfiguresJmxSerialFilterAcceptanceTest.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management; + +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtMost; +import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPorts; +import static org.apache.geode.management.internal.JmxRmiOpenTypesSerialFilter.PROPERTY_NAME; +import static org.apache.geode.test.awaitility.GeodeAwaitility.await; +import static org.assertj.core.api.Assumptions.assumeThat; + +import java.nio.file.Path; + +import org.apache.commons.lang3.JavaVersion; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import org.apache.geode.test.assertj.LogFileAssert; +import org.apache.geode.test.junit.rules.RequiresGeodeHome; +import org.apache.geode.test.junit.rules.gfsh.GfshRule; + +public class LocatorManagerConfiguresJmxSerialFilterAcceptanceTest { + + private static final String NAME = "the-locator"; + + private Path workingDir; + private int locatorPort; + private int jmxPort; + private Path locatorLogFile; + + @Rule + public RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome(); + @Rule + public GfshRule gfshRule = new GfshRule(); + + @Before + public void setUpOutputFiles() { + TemporaryFolder temporaryFolder = gfshRule.getTemporaryFolder(); + + workingDir = temporaryFolder.getRoot().toPath().toAbsolutePath(); + locatorLogFile = workingDir.resolve(NAME + ".log"); + } + + @Before + public void setUpRandomPorts() { + int[] ports = getRandomAvailableTCPPorts(2); + + locatorPort = ports[0]; + jmxPort = ports[1]; + } + + @Test + public void startingLocatorWithJmxManager_configuresSerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + String startLocatorCommand = String.join(" ", + "start locator", + "--name=" + NAME, + "--dir=" + workingDir, + "--port=" + locatorPort, + "--J=-Dgemfire.enable-cluster-configuration=false", + "--J=-Dgemfire.http-service-port=0", + "--J=-Dgemfire.jmx-manager=true", + "--J=-Dgemfire.jmx-manager-port=" + jmxPort, + "--J=-Dgemfire.jmx-manager-start=true"); + + gfshRule.execute(startLocatorCommand); + + await().untilAsserted(() -> { + LogFileAssert.assertThat(locatorLogFile.toFile()) + .as(locatorLogFile.toFile().getAbsolutePath()) + .exists() + .contains("System property " + PROPERTY_NAME + " is now configured with"); + }); + } + + @Test + public void startingLocatorWithJmxManager_configuresSerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + String startLocatorCommand = String.join(" ", + "start locator", + "--name=" + NAME, + "--dir=" + workingDir, + "--port=" + locatorPort, + "--J=-Dgemfire.enable-cluster-configuration=false", + "--J=-Dgemfire.http-service-port=0", + "--J=-Dgemfire.jmx-manager=true", + "--J=-Dgemfire.jmx-manager-port=" + jmxPort, + "--J=-Dgemfire.jmx-manager-start=true"); + + gfshRule.execute(startLocatorCommand); + + await().untilAsserted(() -> { + LogFileAssert.assertThat(locatorLogFile.toFile()) + .as(locatorLogFile.toFile().getAbsolutePath()) + .exists() + .doesNotContain("System property " + PROPERTY_NAME + " is now configured with"); + }); + } +} diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/ServerManagerConfiguresJmxSerialFilterAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/ServerManagerConfiguresJmxSerialFilterAcceptanceTest.java new file mode 100644 index 0000000..7754dec --- /dev/null +++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/ServerManagerConfiguresJmxSerialFilterAcceptanceTest.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management; + +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtMost; +import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPort; +import static org.apache.geode.management.internal.JmxRmiOpenTypesSerialFilter.PROPERTY_NAME; +import static org.apache.geode.test.awaitility.GeodeAwaitility.await; +import static org.assertj.core.api.Assumptions.assumeThat; + +import java.nio.file.Path; + +import org.apache.commons.lang3.JavaVersion; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import org.apache.geode.test.assertj.LogFileAssert; +import org.apache.geode.test.junit.rules.RequiresGeodeHome; +import org.apache.geode.test.junit.rules.gfsh.GfshRule; + +public class ServerManagerConfiguresJmxSerialFilterAcceptanceTest { + + private static final String NAME = "the-server"; + + private Path workingDir; + private int jmxPort; + private Path serverLogFile; + + @Rule + public RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome(); + @Rule + public GfshRule gfshRule = new GfshRule(); + + @Before + public void setUpOutputFiles() { + TemporaryFolder temporaryFolder = gfshRule.getTemporaryFolder(); + + workingDir = temporaryFolder.getRoot().toPath().toAbsolutePath(); + serverLogFile = workingDir.resolve(NAME + ".log"); + } + + @Before + public void setUpRandomPorts() { + jmxPort = getRandomAvailableTCPPort(); + } + + @Test + public void startingServerWithJmxManager_configuresSerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + String startServerCommand = String.join(" ", + "start server", + "--name=" + NAME, + "--dir=" + workingDir, + "--disable-default-server", + "--J=-Dgemfire.enable-cluster-configuration=false", + "--J=-Dgemfire.http-service-port=0", + "--J=-Dgemfire.jmx-manager=true", + "--J=-Dgemfire.jmx-manager-port=" + jmxPort, + "--J=-Dgemfire.jmx-manager-start=true"); + + gfshRule.execute(startServerCommand); + + await().untilAsserted(() -> { + LogFileAssert.assertThat(serverLogFile.toFile()) + .as(serverLogFile.toFile().getAbsolutePath()) + .exists() + .contains("System property " + PROPERTY_NAME + " is now configured with"); + }); + } + + @Test + public void startingServerWithJmxManager_configuresSerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + String startServerCommand = String.join(" ", + "start server", + "--name=" + NAME, + "--dir=" + workingDir, + "--disable-default-server", + "--J=-Dgemfire.enable-cluster-configuration=false", + "--J=-Dgemfire.http-service-port=0", + "--J=-Dgemfire.jmx-manager=true", + "--J=-Dgemfire.jmx-manager-port=" + jmxPort, + "--J=-Dgemfire.jmx-manager-start=true"); + + gfshRule.execute(startServerCommand); + + await().untilAsserted(() -> { + LogFileAssert.assertThat(serverLogFile.toFile()) + .as(serverLogFile.toFile().getAbsolutePath()) + .exists() + .doesNotContain("System property " + PROPERTY_NAME + " is now configured with"); + }); + } +} diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/LocatorManagerConfiguresJmxSerialFilterIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/LocatorManagerConfiguresJmxSerialFilterIntegrationTest.java new file mode 100644 index 0000000..47f196f --- /dev/null +++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/LocatorManagerConfiguresJmxSerialFilterIntegrationTest.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal; + +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtMost; +import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE; +import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPorts; +import static org.apache.geode.management.internal.JmxRmiOpenTypesSerialFilter.PROPERTY_NAME; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assumptions.assumeThat; + +import java.io.File; + +import org.apache.commons.lang3.JavaVersion; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import org.apache.geode.distributed.LocatorLauncher; +import org.apache.geode.test.junit.rules.CloseableReference; + +public class LocatorManagerConfiguresJmxSerialFilterIntegrationTest { + + private static final String NAME = "locator"; + + private File workingDirectory; + private int locatorPort; + private int jmxPort; + private String expectedSerialFilter; + + @Rule + public CloseableReference<LocatorLauncher> locator = new CloseableReference<>(); + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void setUp() throws Exception { + workingDirectory = temporaryFolder.newFolder(NAME); + int[] ports = getRandomAvailableTCPPorts(2); + locatorPort = ports[0]; + jmxPort = ports[1]; + expectedSerialFilter = new JmxRmiOpenTypesSerialFilter().createSerialFilterPattern(); + } + + @After + public void tearDown() { + System.clearProperty(PROPERTY_NAME); + } + + @Test + public void startingLocatorWithJmxManager_configuresSerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + locator.set(new LocatorLauncher.Builder() + .setMemberName(NAME) + .setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(expectedSerialFilter); + } + + @Test + public void startingLocatorWithJmxManager_changesEmptySerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + System.setProperty(PROPERTY_NAME, ""); + + locator.set(new LocatorLauncher.Builder() + .setMemberName(NAME) + .setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(expectedSerialFilter); + } + + @Test + public void startingLocatorWithJmxManager_skipsNonEmptySerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + String existingSerialFilter = "!*"; + System.setProperty(PROPERTY_NAME, existingSerialFilter); + + locator.set(new LocatorLauncher.Builder() + .setMemberName(NAME) + .setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(existingSerialFilter); + } + + @Test + public void startingLocatorWithJmxManager_skipsSerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + locator.set(new LocatorLauncher.Builder() + .setMemberName(NAME) + .setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isNull(); + } + + @Test + public void startingLocatorWithJmxManager_skipsEmptySerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + System.setProperty(PROPERTY_NAME, ""); + + locator.set(new LocatorLauncher.Builder() + .setMemberName(NAME) + .setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(""); + } + + @Test + public void startingLocatorWithJmxManager_skipsNonEmptySerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + String existingSerialFilter = "!*"; + System.setProperty(PROPERTY_NAME, existingSerialFilter); + + locator.set(new LocatorLauncher.Builder() + .setMemberName(NAME) + .setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(existingSerialFilter); + } +} diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/ServerManagerConfiguresJmxSerialFilterIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/ServerManagerConfiguresJmxSerialFilterIntegrationTest.java new file mode 100644 index 0000000..f77438e --- /dev/null +++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/ServerManagerConfiguresJmxSerialFilterIntegrationTest.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal; + +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtMost; +import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE; +import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPort; +import static org.apache.geode.management.internal.JmxRmiOpenTypesSerialFilter.PROPERTY_NAME; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assumptions.assumeThat; + +import java.io.File; + +import org.apache.commons.lang3.JavaVersion; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import org.apache.geode.distributed.ServerLauncher; +import org.apache.geode.test.junit.rules.CloseableReference; + +public class ServerManagerConfiguresJmxSerialFilterIntegrationTest { + + private static final String NAME = "server"; + + private File workingDirectory; + private int jmxPort; + private String expectedSerialFilter; + + @Rule + public CloseableReference<ServerLauncher> server = new CloseableReference<>(); + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void setUp() throws Exception { + workingDirectory = temporaryFolder.newFolder(NAME); + jmxPort = getRandomAvailableTCPPort(); + expectedSerialFilter = new JmxRmiOpenTypesSerialFilter().createSerialFilterPattern(); + } + + @After + public void tearDown() { + System.clearProperty(PROPERTY_NAME); + } + + @Test + public void startingServerWithJmxManager_configuresSerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + server.set(new ServerLauncher.Builder() + .setMemberName(NAME) + .setDisableDefaultServer(true) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(expectedSerialFilter); + } + + @Test + public void startingServerWithJmxManager_changesEmptySerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + System.setProperty(PROPERTY_NAME, ""); + + server.set(new ServerLauncher.Builder() + .setMemberName(NAME) + .setDisableDefaultServer(true) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(expectedSerialFilter); + } + + @Test + public void startingServerWithJmxManager_skipsNonEmptySerialFilter_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + String existingSerialFilter = "!*"; + System.setProperty(PROPERTY_NAME, existingSerialFilter); + + server.set(new ServerLauncher.Builder() + .setMemberName(NAME) + .setDisableDefaultServer(true) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(existingSerialFilter); + } + + @Test + public void startingServerWithJmxManager_skipsSerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + server.set(new ServerLauncher.Builder() + .setMemberName(NAME) + .setDisableDefaultServer(true) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isNull(); + } + + @Test + public void startingServerWithJmxManager_skipsEmptySerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + System.setProperty(PROPERTY_NAME, ""); + + server.set(new ServerLauncher.Builder() + .setMemberName(NAME) + .setDisableDefaultServer(true) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(""); + } + + @Test + public void startingServerWithJmxManager_skipsNonEmptySerialFilter_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + String existingSerialFilter = "!*"; + System.setProperty(PROPERTY_NAME, existingSerialFilter); + + server.set(new ServerLauncher.Builder() + .setMemberName(NAME) + .setDisableDefaultServer(true) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .set(LOG_FILE, new File(workingDirectory, NAME + ".log").getAbsolutePath()) + .build()) + .get() + .start(); + + String serialFilter = System.getProperty(PROPERTY_NAME); + assertThat(serialFilter).isEqualTo(existingSerialFilter); + } +} diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/JmxRmiOpenTypesSerialFilter.java b/geode-core/src/main/java/org/apache/geode/management/internal/JmxRmiOpenTypesSerialFilter.java new file mode 100644 index 0000000..803bc03 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/JmxRmiOpenTypesSerialFilter.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal; + +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.rmi.MarshalledObject; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import javax.management.ObjectName; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularType; + +import org.apache.commons.lang3.JavaVersion; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.Logger; + +import org.apache.geode.annotations.VisibleForTesting; +import org.apache.geode.logging.internal.log4j.api.LogService; + +/** + * Configure the “jmx.remote.rmi.server.serial.filter.pattern” system property if Java version is + * greater than Java 8. The serial pattern will be configured to accept only standard JMX + * open-types. If the system property already has a non-null value, then leave it as is. + */ +public class JmxRmiOpenTypesSerialFilter implements JmxRmiSerialFilter { + + private static final Logger logger = LogService.getLogger(); + + @VisibleForTesting + public static final String PROPERTY_NAME = "jmx.remote.rmi.server.serial.filter.pattern"; + + private final Consumer<String> infoLogger; + private final Supplier<Boolean> supportsSerialFilter; + + JmxRmiOpenTypesSerialFilter() { + this(logger::info, () -> isJavaVersionAtLeast(JavaVersion.JAVA_9)); + } + + @VisibleForTesting + JmxRmiOpenTypesSerialFilter(Consumer<String> infoLogger, Supplier<Boolean> supportsSerialFilter) { + this.infoLogger = infoLogger; + this.supportsSerialFilter = supportsSerialFilter; + } + + @Override + public void configureSerialFilter() { + if (supportsDedicatedSerialFilter()) { + setPropertyValueUnlessExists(createSerialFilterPattern()); + } + } + + @VisibleForTesting + boolean supportsDedicatedSerialFilter() { + return supportsSerialFilter.get(); + } + + /** + * Sets the value of the system property {@code jmx.remote.rmi.server.serial.filter.pattern} + * unless it exists with a value that is not null or empty (""). + */ + @VisibleForTesting + void setPropertyValueUnlessExists(String value) { + String existingValue = System.getProperty(PROPERTY_NAME); + if (StringUtils.isNotEmpty(existingValue)) { + infoLogger.accept("System property " + PROPERTY_NAME + " is already configured."); + return; + } + + System.setProperty(PROPERTY_NAME, value); + infoLogger.accept("System property " + PROPERTY_NAME + " is now configured with '" + + value + "'."); + } + + /** + * Returns a serial filter pattern that accepts all open MBean data types and rejects everything + * not included in the pattern. + */ + @VisibleForTesting + String createSerialFilterPattern() { + // note: java.util.* may also be needed + return new StringBuilder() + // accept all open MBean data types + .append(Boolean.class.getName()) + .append(';') + .append(Byte.class.getName()) + .append(';') + .append(Character.class.getName()) + .append(';') + .append(Short.class.getName()) + .append(';') + .append(Integer.class.getName()) + .append(';') + .append(Long.class.getName()) + .append(';') + .append(Float.class.getName()) + .append(';') + .append(Double.class.getName()) + .append(';') + .append(String.class.getName()) + .append(';') + .append(BigInteger.class.getName()) + .append(';') + .append(BigDecimal.class.getName()) + .append(';') + .append(ObjectName.class.getName()) + .append(';') + .append(OpenType.class.getName()) + .append(';') + .append(CompositeData.class.getName()) + .append(';') + .append(TabularData.class.getName()) + .append(';') + .append(SimpleType.class.getName()) + .append(';') + .append(CompositeType.class.getName()) + .append(';') + .append(TabularType.class.getName()) + .append(';') + .append(ArrayType.class.getName()) + .append(';') + .append(MarshalledObject.class.getName()) + .append(';') + // reject all other classes + .append("!*") + .toString(); + } +} diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/JmxRmiSerialFilter.java b/geode-core/src/main/java/org/apache/geode/management/internal/JmxRmiSerialFilter.java new file mode 100644 index 0000000..4a187e0 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/JmxRmiSerialFilter.java @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal; + +@FunctionalInterface +public interface JmxRmiSerialFilter { + + void configureSerialFilter(); +} diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java index 6d721ab..3ad1102 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java @@ -108,6 +108,8 @@ public class ManagementAgent { private int port; private RemoteStreamExporter remoteStreamExporter = null; + private final JmxRmiSerialFilter serialFilter; + /** * This system property is set to true when the embedded HTTP server is started so that the * embedded pulse webapp can use a local MBeanServer instead of a remote JMX connection. @@ -118,10 +120,12 @@ public class ManagementAgent { private static final String PULSE_USESSL_MANAGER = "pulse.useSSL.manager"; private static final String PULSE_USESSL_LOCATOR = "pulse.useSSL.locator"; - public ManagementAgent(DistributionConfig config, InternalCache cache) { + public ManagementAgent(DistributionConfig config, InternalCache cache, + JmxRmiSerialFilter serialFilter) { this.config = config; this.cache = cache; this.securityService = cache.getSecurityService(); + this.serialFilter = serialFilter; } public synchronized boolean isRunning() { @@ -130,6 +134,7 @@ public class ManagementAgent { public synchronized void startAgent() { + serialFilter.configureSerialFilter(); loadWebApplications(); if (!this.running && this.config.getJmxManagerPort() != 0) { diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgentFactory.java b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgentFactory.java new file mode 100644 index 0000000..bff205e --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgentFactory.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.internal.cache.InternalCache; + +@FunctionalInterface +interface ManagementAgentFactory { + + ManagementAgent create(DistributionConfig config, InternalCache cache, + JmxRmiSerialFilter serialFilter); +} diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java index 1d36426..76f47c5 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; -import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -41,7 +40,6 @@ import org.apache.geode.annotations.VisibleForTesting; import org.apache.geode.cache.execute.FunctionService; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.distributed.DistributedSystemDisconnectedException; -import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.ResourceEvent; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; @@ -115,7 +113,7 @@ public class SystemManagementService extends BaseManagementService { private final StatisticsFactory statisticsFactory; private final StatisticsClock statisticsClock; private final FederatingManagerFactory federatingManagerFactory; - + private final Function<SystemManagementService, LocalManager> localManagerFactory; /** * whether the service is closed or not if cache is closed automatically this service will be @@ -137,30 +135,34 @@ public class SystemManagementService extends BaseManagementService { * Managing node. */ private ManagementMembershipListener listener; - private final Function<SystemManagementService, LocalManager> localManagerFactory; static BaseManagementService newSystemManagementService( InternalCacheForClientAccess cache) { - return newSystemManagementService(cache, NotificationHub::new, + return newSystemManagementService( + cache, + NotificationHub::new, SystemManagementService::createLocalManager, - createFederatingManagerFactory(), ManagementAgent::new); + createFederatingManagerFactory(), + ManagementAgent::new); } @VisibleForTesting - static BaseManagementService newSystemManagementService(InternalCacheForClientAccess cache, + static BaseManagementService newSystemManagementService( + InternalCacheForClientAccess cache, Function<ManagementResourceRepo, NotificationHub> notificationHubFactory, Function<SystemManagementService, LocalManager> localManagerFactory, FederatingManagerFactory federatingManagerFactory, - BiFunction<DistributionConfig, InternalCacheForClientAccess, ManagementAgent> managementAgentFactory) { + ManagementAgentFactory managementAgentFactory) { return new SystemManagementService(cache, notificationHubFactory, localManagerFactory, federatingManagerFactory, managementAgentFactory).init(); } - private SystemManagementService(InternalCacheForClientAccess cache, + private SystemManagementService( + InternalCacheForClientAccess cache, Function<ManagementResourceRepo, NotificationHub> notificationHubFactory, Function<SystemManagementService, LocalManager> localManagerFactory, FederatingManagerFactory federatingManagerFactory, - BiFunction<DistributionConfig, InternalCacheForClientAccess, ManagementAgent> managementAgentFactory) { + ManagementAgentFactory managementAgentFactory) { this.cache = cache; system = cache.getInternalDistributedSystem(); this.localManagerFactory = localManagerFactory; @@ -177,7 +179,8 @@ public class SystemManagementService extends BaseManagementService { notificationHub = notificationHubFactory.apply(repo); if (system.getConfig().getJmxManager()) { - agent = managementAgentFactory.apply(system.getConfig(), cache); + agent = managementAgentFactory.create(system.getConfig(), cache, + new JmxRmiOpenTypesSerialFilter()); } else { agent = null; } diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/JmxRmiOpenTypesSerialFilterTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/JmxRmiOpenTypesSerialFilterTest.java new file mode 100644 index 0000000..c8f8ea9 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/management/internal/JmxRmiOpenTypesSerialFilterTest.java @@ -0,0 +1,351 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal; + +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtMost; +import static org.apache.geode.util.internal.UncheckedUtils.uncheckedCast; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assumptions.assumeThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.rmi.MarshalledObject; +import java.util.function.Consumer; + +import javax.management.ObjectName; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularType; + +import org.apache.commons.lang3.JavaVersion; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; + +public class JmxRmiOpenTypesSerialFilterTest { + + private Consumer<String> infoLogger; + + @Rule + public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); + + @Before + public void setUp() { + infoLogger = uncheckedCast(mock(Consumer.class)); + } + + @Test + public void propertyValueIsNullByDefault() { + String propertyValue = System.getProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME); + + assertThat(propertyValue).isNull(); + } + + @Test + public void supportsDedicatedSerialFilter_returnsTrue_atLeastJava9() { + assumeThat(isJavaVersionAtLeast(JavaVersion.JAVA_9)).isTrue(); + + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + boolean result = jmxRmiOpenTypesSerialFilter.supportsDedicatedSerialFilter(); + + assertThat(result).isTrue(); + } + + @Test + public void supportsDedicatedSerialFilter_returnsFalse_atMostJava8() { + assumeThat(isJavaVersionAtMost(JavaVersion.JAVA_1_8)).isTrue(); + + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + boolean result = jmxRmiOpenTypesSerialFilter.supportsDedicatedSerialFilter(); + + assertThat(result).isFalse(); + } + + @Test + public void setPropertyValue_setsValue_ifExistingValueIsNull() { + String value = "value-of-property"; + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + jmxRmiOpenTypesSerialFilter.setPropertyValueUnlessExists(value); + + String propertyValue = System.getProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME); + assertThat(propertyValue).isEqualTo(value); + } + + @Test + public void setPropertyValue_setsValue_ifExistingValueIsEmpty() { + System.setProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME, ""); + String value = "value-of-property"; + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + jmxRmiOpenTypesSerialFilter.setPropertyValueUnlessExists(value); + + String propertyValue = System.getProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME); + assertThat(propertyValue).isEqualTo(value); + } + + @Test + public void setPropertyValue_logsMessage_ifExistingValueIsEmpty() { + System.setProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME, ""); + String value = "value-of-property"; + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = + new JmxRmiOpenTypesSerialFilter(infoLogger, () -> true); + + jmxRmiOpenTypesSerialFilter.setPropertyValueUnlessExists(value); + + String expectedLogMessage = "System property " + JmxRmiOpenTypesSerialFilter.PROPERTY_NAME + + " is now configured with '" + value + "'."; + verify(infoLogger).accept(expectedLogMessage); + } + + @Test + public void setPropertyValue_leavesExistingValue_ifExistingValueIsNotEmpty() { + String existingValue = "existing-value-of-property"; + System.setProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME, existingValue); + String value = "value-of-property"; + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + jmxRmiOpenTypesSerialFilter.setPropertyValueUnlessExists(value); + + String propertyValue = System.getProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME); + assertThat(propertyValue).isEqualTo(existingValue); + } + + @Test + public void setPropertyValue_logsMessage_ifExistingValueIsNotEmpty() { + String existingValue = "existing-value-of-property"; + System.setProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME, existingValue); + String value = "value-of-property"; + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = + new JmxRmiOpenTypesSerialFilter(infoLogger, () -> true); + + jmxRmiOpenTypesSerialFilter.setPropertyValueUnlessExists(value); + + String expectedLogMessage = "System property " + JmxRmiOpenTypesSerialFilter.PROPERTY_NAME + + " is already configured."; + verify(infoLogger).accept(expectedLogMessage); + } + + @Test + public void createSerialFilterPattern_includesBoolean() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Boolean.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesByte() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Byte.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesCharacter() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Character.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesShort() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Short.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesInteger() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Integer.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesLong() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Long.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesFloat() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Float.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesDouble() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(Double.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesString() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(String.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesBigInteger() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(BigInteger.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesBigDecimal() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(BigDecimal.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesObjectName() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(ObjectName.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesCompositeData() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(CompositeData.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesTabularData() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(TabularData.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesSimpleType() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(SimpleType.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesCompositeType() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(CompositeType.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesTabularType() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(TabularType.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesArrayType() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(ArrayType.class.getName()); + } + + @Test + public void createSerialFilterPattern_includesMarshalledObject() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).contains(MarshalledObject.class.getName()); + } + + @Test + public void createSerialFilterPattern_rejectsAllOtherTypes() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = new JmxRmiOpenTypesSerialFilter(); + + String result = jmxRmiOpenTypesSerialFilter.createSerialFilterPattern(); + + assertThat(result).endsWith("!*"); + } + + @Test + public void configureSerialFilterIfEmpty_setsPropertyValue_atLeastJava9() { + JmxRmiOpenTypesSerialFilter jmxRmiOpenTypesSerialFilter = + new JmxRmiOpenTypesSerialFilter(infoLogger, () -> true); + + jmxRmiOpenTypesSerialFilter.configureSerialFilter(); + + String propertyValue = System.getProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME); + assertThat(propertyValue).isNotEmpty(); + } + + @Test + public void configureSerialFilterIfEmpty_setsPropertyValue_atMostJava8() { + JmxRmiSerialFilter jmxRmiOpenTypesSerialFilter = + new JmxRmiOpenTypesSerialFilter(infoLogger, () -> false); + + jmxRmiOpenTypesSerialFilter.configureSerialFilter(); + + String propertyValue = System.getProperty(JmxRmiOpenTypesSerialFilter.PROPERTY_NAME); + assertThat(propertyValue).isNull(); + } +} diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/SystemManagementServiceTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/SystemManagementServiceTest.java index 627a5b4..e5e792e 100644 --- a/geode-core/src/test/java/org/apache/geode/management/internal/SystemManagementServiceTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/internal/SystemManagementServiceTest.java @@ -12,7 +12,6 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ - package org.apache.geode.management.internal; import static org.apache.geode.distributed.internal.ResourceEvent.MANAGER_START; @@ -29,7 +28,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.mockito.quality.Strictness.LENIENT; -import java.util.function.BiFunction; import java.util.function.Function; import org.junit.Before; @@ -66,7 +64,7 @@ public class SystemManagementServiceTest { @Mock private ManagementAgent managementAgent; @Mock - private BiFunction<DistributionConfig, InternalCacheForClientAccess, ManagementAgent> managementAgentFactory; + private ManagementAgentFactory managementAgentFactory; @Mock private Function<ManagementResourceRepo, NotificationHub> notificationHubFactory; @Mock @@ -87,7 +85,7 @@ public class SystemManagementServiceTest { .create(any(), any(), any(), any(), any(), any(), any(), any(), any())) .thenReturn(federatingManager); - when(managementAgentFactory.apply(any(), any())).thenReturn(managementAgent); + when(managementAgentFactory.create(any(), any(), any())).thenReturn(managementAgent); when(notificationHubFactory.apply(any())).thenReturn(mock(NotificationHub.class)); when(localManagerFactory.apply(any())).thenReturn(mock(LocalManager.class)); }