You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2018/03/05 17:00:09 UTC
[geode] branch develop updated: GEODE-4385: Add list jndi-binding
option (#1547)
This is an automated email from the ASF dual-hosted git repository.
jensdeppe 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 a281d54 GEODE-4385: Add list jndi-binding option (#1547)
a281d54 is described below
commit a281d54f2777b31178d47829e3ba282578d8cf4b
Author: Jens Deppe <jd...@pivotal.io>
AuthorDate: Mon Mar 5 09:00:02 2018 -0800
GEODE-4385: Add list jndi-binding option (#1547)
---
.../apache/geode/internal/jndi/JNDIInvoker.java | 21 ++++++
.../cli/commands/ListJndiBindingCommand.java | 65 ++++++++++++++++
.../cli/functions/ListJndiBindingFunction.java | 58 +++++++++++++++
.../sanctioned-geode-core-serializables.txt | 3 +-
.../commands/ListJndiBindingCommandDUnitTest.java | 69 +++++++++++++++++
.../functions/CreateJndiBindingFunctionTest.java | 87 ++++++++++++++++++++++
.../cli/functions/ListJndiBindingFunctionTest.java | 83 +++++++++++++++++++++
7 files changed, 385 insertions(+), 1 deletion(-)
diff --git a/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java b/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java
index 99898c5..f439047 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/jndi/JNDIInvoker.java
@@ -16,6 +16,7 @@ package org.apache.geode.internal.jndi;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
@@ -379,4 +380,24 @@ public class JNDIInvoker {
public static int getNoOfAvailableDataSources() {
return dataSourceList.size();
}
+
+ public static Map<String, String> getBindingNamesRecursively(Context ctx) throws Exception {
+ Map<String, String> result = new HashMap<>();
+ NamingEnumeration<Binding> enumeration = ctx.listBindings("");
+
+ while (enumeration.hasMore()) {
+ Binding binding = enumeration.next();
+ String name = binding.getName();
+ String separator = name.endsWith(":") ? "" : "/";
+ Object o = binding.getObject();
+ if (o instanceof Context) {
+ Map<String, String> innerBindings = getBindingNamesRecursively((Context) o);
+ innerBindings.forEach((k, v) -> result.put(name + separator + k, v));
+ } else {
+ result.put(name, binding.getClassName());
+ }
+ }
+
+ return result;
+ }
}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListJndiBindingCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListJndiBindingCommand.java
new file mode 100644
index 0000000..2634afb
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ListJndiBindingCommand.java
@@ -0,0 +1,65 @@
+/*
+ * 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.cli.commands;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+import org.springframework.shell.core.annotation.CliCommand;
+
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+import org.apache.geode.management.internal.cli.functions.ListJndiBindingFunction;
+import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.management.internal.cli.result.TabularResultData;
+
+public class ListJndiBindingCommand implements GfshCommand {
+ private static final Logger logger = LogService.getLogger();
+
+ private static final String LIST_JNDIBINDING = "list jndi-binding";
+ private static final String LIST_JNDIBINDING__HELP = "List all jndi bindings.";
+ private static final Function LIST_BINDING_FUNCTION = new ListJndiBindingFunction();
+
+ @CliCommand(value = LIST_JNDIBINDING, help = LIST_JNDIBINDING__HELP)
+ public Result listJndiBinding() {
+ Result result = null;
+ TabularResultData tabularData = ResultBuilder.createTabularResultData();
+
+ Set<DistributedMember> members = findMembers(null, null);
+ if (members.size() == 0) {
+ return ResultBuilder.createUserErrorResult("No members found");
+ }
+
+ List<CliFunctionResult> rc = executeAndGetFunctionResult(LIST_BINDING_FUNCTION, null, members);
+ for (CliFunctionResult oneResult : rc) {
+ Serializable[] serializables = oneResult.getSerializables();
+ for (int i = 0; i < serializables.length; i += 2) {
+ tabularData.accumulate("Member", oneResult.getMemberIdOrName());
+ tabularData.accumulate("Name", serializables[i]);
+ tabularData.accumulate("Class", serializables[i + 1]);
+ }
+ }
+
+ result = ResultBuilder.buildResult(tabularData);
+
+ return result;
+ }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ListJndiBindingFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ListJndiBindingFunction.java
new file mode 100644
index 0000000..1f17ff4
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ListJndiBindingFunction.java
@@ -0,0 +1,58 @@
+/*
+ * 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.cli.functions;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.naming.Context;
+import javax.naming.NameClassPair;
+
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.internal.cache.execute.InternalFunction;
+import org.apache.geode.internal.jndi.JNDIInvoker;
+
+public class ListJndiBindingFunction implements InternalFunction {
+
+ private static final long serialVersionUID = 5254506785395069200L;
+
+ @Override
+ public void execute(FunctionContext context) {
+ List<NameClassPair> namePairs = new ArrayList<>();
+ CliFunctionResult result;
+
+ try {
+ Context ctx = JNDIInvoker.getJNDIContext();
+ Map<String, String> bindings = JNDIInvoker.getBindingNamesRecursively(ctx);
+ List<String> resultValues = bindings.entrySet().stream()
+ .flatMap((e) -> Arrays.stream(new String[] {e.getKey(), e.getValue()}))
+ .collect(Collectors.toList());
+ result = new CliFunctionResult(context.getMemberName(),
+ resultValues.toArray(new Serializable[] {}));
+ } catch (Exception e) {
+ result =
+ new CliFunctionResult(context.getMemberName(), e, "Unable to retrieve JNDI bindings");
+ }
+
+ ResultSender<Object> sender = context.getResultSender();
+ sender.lastResult(result);
+ }
+}
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
index e7e00b2..16ab501 100644
--- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
+++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
@@ -552,6 +552,7 @@ org/apache/geode/management/internal/cli/functions/ListDiskStoresFunction,false
org/apache/geode/management/internal/cli/functions/ListDurableCqNamesFunction,true,1
org/apache/geode/management/internal/cli/functions/ListFunctionFunction,true,1
org/apache/geode/management/internal/cli/functions/ListIndexFunction,false
+org/apache/geode/management/internal/cli/functions/ListJndiBindingFunction,true,5254506785395069200
org/apache/geode/management/internal/cli/functions/NetstatFunction,true,1
org/apache/geode/management/internal/cli/functions/NetstatFunction$NetstatFunctionArgument,true,1,lineSeparator:java/lang/String,withlsof:boolean
org/apache/geode/management/internal/cli/functions/NetstatFunction$NetstatFunctionResult,true,1,compressedBytes:org/apache/geode/management/internal/cli/CliUtil$DeflaterInflaterData,headerInfo:java/lang/String,host:java/lang/String
@@ -586,10 +587,10 @@ org/apache/geode/management/internal/cli/util/LogFilter$LineFilterResult,false
org/apache/geode/management/internal/cli/util/MemberInformation,true,1,cacheXmlFilePath:java/lang/String,cpuUsage:java/lang/String,groups:java/lang/String,heapUsage:java/lang/String,host:java/lang/String,id:java/lang/String,initHeapSize:java/lang/String,locatorBindAddress:java/lang/String,locatorPort:int,locators:java/lang/String,logFilePath:java/lang/String,maxHeapSize:java/lang/String,name:java/lang/String,processId:java/lang/String,serverBindAddress:java/lang/String,statArchiveFilePat [...]
org/apache/geode/management/internal/cli/util/VisualVmNotFoundException,true,-8491645604829510102
org/apache/geode/management/internal/configuration/domain/SharedConfigurationStatus,false
+org/apache/geode/management/internal/configuration/functions/DownloadJarFunction,true,1
org/apache/geode/management/internal/configuration/functions/GetClusterConfigurationFunction,false
org/apache/geode/management/internal/configuration/functions/GetRegionNamesFunction,false
org/apache/geode/management/internal/configuration/functions/RecreateCacheFunction,false
-org/apache/geode/management/internal/configuration/functions/DownloadJarFunction,true,1
org/apache/geode/management/internal/web/domain/QueryParameterSource,true,34131123582155,objectName:javax/management/ObjectName,queryExpression:javax/management/QueryExp
org/apache/geode/management/internal/web/shell/MBeanAccessException,true,813768898269516238
org/apache/geode/memcached/GemFireMemcachedServer$Protocol,false
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ListJndiBindingCommandDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ListJndiBindingCommandDUnitTest.java
new file mode 100644
index 0000000..36ae73e
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ListJndiBindingCommandDUnitTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.cli.commands;
+
+import java.util.Properties;
+
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.management.internal.cli.functions.ListJndiBindingFunction;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+
+@Category(DistributedTest.class)
+public class ListJndiBindingCommandDUnitTest {
+
+ private static MemberVM locator, server;
+
+ @ClassRule
+ public static ClusterStartupRule cluster = new ClusterStartupRule();
+
+ @ClassRule
+ public static GfshCommandRule gfsh = new GfshCommandRule();
+
+ @BeforeClass
+ public static void before() throws Exception {
+ Properties props = new Properties();
+ props.setProperty(ConfigurationProperties.SERIALIZABLE_OBJECT_FILTER,
+ ListJndiBindingFunction.class.getName());
+
+ locator = cluster.startLocatorVM(0);
+ server = cluster.startServerVM(1, props, locator.getPort());
+
+ gfsh.connectAndVerify(locator);
+ }
+
+ @Test
+ public void listJndiBinding() {
+ gfsh.executeAndAssertThat(
+ "create jndi-binding --name=jndi1 --type=SIMPLE --jdbc-driver-class=org.apache.derby.jdbc.EmbeddedDriver --connection-url=\"jdbc:derby:newDB;create=true\"")
+ .statusIsSuccess().tableHasColumnOnlyWithValues("Member", "server-1");
+
+ gfsh.executeAndAssertThat("list jndi-binding").statusIsSuccess()
+ .tableHasColumnWithExactValuesInAnyOrder("Name", "java:jndi1", "java:UserTransaction",
+ "java:TransactionManager")
+ .tableHasColumnWithExactValuesInAnyOrder("Class",
+ "org.apache.geode.internal.datasource.GemFireBasicDataSource",
+ "org.apache.geode.internal.jta.UserTransactionImpl",
+ "org.apache.geode.internal.jta.TransactionManagerImpl");
+ }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/CreateJndiBindingFunctionTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/CreateJndiBindingFunctionTest.java
new file mode 100644
index 0000000..4679e56
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/CreateJndiBindingFunctionTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.cli.functions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+import java.util.logging.Level;
+
+import javax.naming.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.ArgumentCaptor;
+
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.internal.jndi.JNDIInvoker;
+import org.apache.geode.internal.logging.LocalLogWriter;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class CreateJndiBindingFunctionTest {
+
+ private CreateJndiBindingFunction createBindingFunction;
+ private FunctionContext<JndiBindingConfiguration> context;
+ private DistributedSystem distributedSystem;
+ private ResultSender resultSender;
+ private ArgumentCaptor<CliFunctionResult> resultCaptor;
+
+ @Before
+ public void setup() {
+ createBindingFunction = spy(new CreateJndiBindingFunction());
+ context = mock(FunctionContext.class);
+ distributedSystem = mock(DistributedSystem.class);
+ resultSender = mock(ResultSender.class);
+ resultCaptor = ArgumentCaptor.forClass(CliFunctionResult.class);
+
+ when(distributedSystem.getLogWriter()).thenReturn(new LocalLogWriter(Level.FINE.intValue()));
+
+ JNDIInvoker.mapTransactions(distributedSystem);
+ }
+
+ @Test
+ public void createJndiBindingIsSuccessful() throws Exception {
+ JndiBindingConfiguration config = new JndiBindingConfiguration();
+ config.setJndiName("jndi1");
+ config.setType(JndiBindingConfiguration.DATASOURCE_TYPE.SIMPLE);
+ config.setJdbcDriver("org.apache.derby.jdbc.EmbeddedDriver");
+ config.setConnectionUrl("jdbc:derby:newDB;create=true");
+ when(context.getArguments()).thenReturn(config);
+ when(context.getMemberName()).thenReturn("mock-member");
+ when(context.getResultSender()).thenReturn(resultSender);
+
+ createBindingFunction.execute(context);
+
+ verify(resultSender).lastResult(resultCaptor.capture());
+ CliFunctionResult result = resultCaptor.getValue();
+ assertThat(result.isSuccessful()).isTrue();
+
+ Context ctx = JNDIInvoker.getJNDIContext();
+ Map<String, String> bindings = JNDIInvoker.getBindingNamesRecursively(ctx);
+
+ assertThat(bindings.keySet()).containsExactlyInAnyOrder("java:jndi1", "java:UserTransaction",
+ "java:TransactionManager");
+ }
+
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ListJndiBindingFunctionTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ListJndiBindingFunctionTest.java
new file mode 100644
index 0000000..4a13fd8
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ListJndiBindingFunctionTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.cli.functions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.logging.Level;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.ArgumentCaptor;
+
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.internal.jndi.JNDIInvoker;
+import org.apache.geode.internal.logging.LocalLogWriter;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class ListJndiBindingFunctionTest {
+
+ private ListJndiBindingFunction listJndiBindingFunction;
+ private FunctionContext context;
+ private DistributedSystem distributedSystem;
+ private ResultSender resultSender;
+ private ArgumentCaptor<CliFunctionResult> resultCaptor;
+
+ @Before
+ public void setup() {
+ listJndiBindingFunction = spy(new ListJndiBindingFunction());
+ context = mock(FunctionContext.class);
+ distributedSystem = mock(DistributedSystem.class);
+ resultSender = mock(ResultSender.class);
+ resultCaptor = ArgumentCaptor.forClass(CliFunctionResult.class);
+
+ when(distributedSystem.getLogWriter()).thenReturn(new LocalLogWriter(Level.FINE.intValue()));
+
+ JNDIInvoker.mapTransactions(distributedSystem);
+
+ JndiBindingConfiguration config = new JndiBindingConfiguration();
+ config.setJndiName("jndi1");
+ config.setType(JndiBindingConfiguration.DATASOURCE_TYPE.SIMPLE);
+ config.setJdbcDriver("org.apache.derby.jdbc.EmbeddedDriver");
+ config.setConnectionUrl("jdbc:derby:newDB;create=true");
+ JNDIInvoker.mapDatasource(config.getParamsAsMap(), config.getDatasourceConfigurations());
+ }
+
+ @Test
+ public void listJndiBindingIsSuccessful() throws Exception {
+ when(context.getResultSender()).thenReturn(resultSender);
+
+ listJndiBindingFunction.execute(context);
+
+ verify(resultSender).lastResult(resultCaptor.capture());
+ CliFunctionResult result = resultCaptor.getValue();
+
+ assertThat(result.isSuccessful()).isTrue();
+ assertThat(result.getSerializables()).containsExactlyInAnyOrder("java:UserTransaction",
+ "org.apache.geode.internal.jta.UserTransactionImpl", "java:TransactionManager",
+ "org.apache.geode.internal.jta.TransactionManagerImpl", "java:jndi1",
+ "org.apache.geode.internal.datasource.GemFireBasicDataSource");
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
jensdeppe@apache.org.