Return-Path: X-Original-To: apmail-geode-commits-archive@minotaur.apache.org Delivered-To: apmail-geode-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 597EB18668 for ; Thu, 25 Feb 2016 20:33:49 +0000 (UTC) Received: (qmail 59824 invoked by uid 500); 25 Feb 2016 20:27:08 -0000 Delivered-To: apmail-geode-commits-archive@geode.apache.org Received: (qmail 59727 invoked by uid 500); 25 Feb 2016 20:27:08 -0000 Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.incubator.apache.org Delivered-To: mailing list commits@geode.incubator.apache.org Received: (qmail 59699 invoked by uid 99); 25 Feb 2016 20:27:08 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 25 Feb 2016 20:27:08 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 5B874C0858 for ; Thu, 25 Feb 2016 20:27:08 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.78 X-Spam-Level: * X-Spam-Status: No, score=1.78 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id SXfrdbnTE3yY for ; Thu, 25 Feb 2016 20:27:02 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with SMTP id 7F7185FBFC for ; Thu, 25 Feb 2016 20:26:51 +0000 (UTC) Received: (qmail 56232 invoked by uid 99); 25 Feb 2016 20:26:50 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 25 Feb 2016 20:26:50 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 37194E8F2C; Thu, 25 Feb 2016 20:26:50 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jensdeppe@apache.org To: commits@geode.incubator.apache.org Date: Thu, 25 Feb 2016 20:27:31 -0000 Message-Id: In-Reply-To: <73e7879c18f143a3b34041911bfd1983@git.apache.org> References: <73e7879c18f143a3b34041911bfd1983@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [43/50] [abbrv] incubator-geode git commit: Merge branch 'develop' into feature/GEODE-17 http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/GatewaySenderMXBean.java ---------------------------------------------------------------------- diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/GatewaySenderMXBean.java index 0000000,27ad171..0f8642a mode 000000,100644..100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/GatewaySenderMXBean.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/GatewaySenderMXBean.java @@@ -1,0 -1,249 +1,257 @@@ + /* + * 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 com.gemstone.gemfire.management; + + import com.gemstone.gemfire.cache.wan.GatewaySender; ++import com.gemstone.gemfire.management.internal.security.Resource; ++import com.gemstone.gemfire.management.internal.security.ResourceConstants; ++import com.gemstone.gemfire.management.internal.security.ResourceOperation; + + /** + * MBean that provides access to information and management functionality for a + * {@link GatewaySender}. + * + * @author rishim + * @since 7.0 + * + */ + public interface GatewaySenderMXBean { + + /** + * Returns the ID of the GatewaySender. + */ + public String getSenderId(); + + /** + * Returns the id of the remote GatewayReceiver's + * DistributedSystem. + */ + public int getRemoteDSId(); + + /** + * Returns the configured buffer size of the socket connection between this + * GatewaySender and its receiving GatewayReceiver. + */ + public int getSocketBufferSize(); + + /** + * Returns the amount of time (in milliseconds) that a socket read between a + * sending GatewaySender and its receiving GatewayReceiver is + * allowed to block. + */ + public long getSocketReadTimeout(); + + /** + * Returns the name of the disk store that is used for persistence. + */ + public String getOverflowDiskStoreName(); + + /** + * Returns the maximum memory after which the data needs to be overflowed to disk. + */ + public int getMaximumQueueMemory(); + + /** + * Returns the size of a batch that gets delivered by the GatewaySender. + */ + public int getBatchSize(); + + /** + * Returns the interval between transmissions by the GatewaySender. + */ + public long getBatchTimeInterval(); + + /** + * Returns whether batch conflation for the GatewaySender's queue is enabled + * + * @return True if batch conflation is enabled, false otherwise. + */ + public boolean isBatchConflationEnabled(); + + /** + * Returns whether the GatewaySender is configured to be persistent or + * non-persistent. + * + * @return True if the sender is persistent, false otherwise. + */ + + public boolean isPersistenceEnabled(); + + /** + * Returns the alert threshold for entries in a GatewaySender's queue.The + * default value is 0 milliseconds in which case no alert will be logged if + * events are delayed in Queue. + */ + public int getAlertThreshold(); + + /** + * Returns a list of GatewayEventFilters added to this + * GatewaySender. + */ + public String[] getGatewayEventFilters(); + + /** + * Returns a list of GatewayTransportFilters added to this + * GatewaySender. + */ + public String[] getGatewayTransportFilters(); + + /** + * Returns whether the GatewaySender is configured for manual start. + * + * @return True if the GatewaySender is configured for manual start, false otherwise. + */ + public boolean isManualStart(); + + /** + * Returns whether or not this GatewaySender is running. + * + * @return True if the GatewaySender is running, false otherwise. + */ + public boolean isRunning(); + + /** + * Returns whether or not this GatewaySender is paused. + * + * @return True of the GatewaySender is paused, false otherwise. + */ + public boolean isPaused(); + + /** + * Returns the rate of events received per second by this Sender if it's a + * serial-wan. + */ + public float getEventsReceivedRate(); + + /** + * Returns the rate of events being queued. + */ + public float getEventsQueuedRate(); + + /** + * Returns the current size of the event queue. + */ + public int getEventQueueSize(); + + /** + * Returns the number of events received, but not added to the event queue, because + * the queue already contains an event with the same key. + */ + public int getTotalEventsConflated(); + + + /** + * Returns the average number of batches sent per second. + */ + public float getBatchesDispatchedRate(); + + /** + * Returns the average time taken to send a batch of events. + */ + public long getAverageDistributionTimePerBatch(); + + /** + * Returns the total number of batches of events that were resent. + */ + public int getTotalBatchesRedistributed(); + + /** + * Starts this GatewaySender. Once the GatewaySender is running its + * configuration cannot be changed. + * + */ ++ @ResourceOperation(resource=Resource.GATEWAY_SENDER, operation=ResourceConstants.START_GW_SENDER) + public void start(); + + /** + * Stops this GatewaySender. + */ ++ @ResourceOperation(resource=Resource.GATEWAY_SENDER, operation=ResourceConstants.STOP_GW_SENDER) + public void stop(); + + /** + * Pauses this GatewaySender. + */ ++ @ResourceOperation(resource=Resource.GATEWAY_SENDER, operation=ResourceConstants.PAUSE_GW_SENDER) + public void pause(); + + /** + * Resumes this paused GatewaySender. + */ ++ @ResourceOperation(resource=Resource.GATEWAY_SENDER, operation=ResourceConstants.RESUME_GW_SENDER) + public void resume(); + + /** + * Rebalances this GatewaySender. + */ ++ @ResourceOperation(resource=Resource.GATEWAY_SENDER, operation=ResourceConstants.LOAD_BALANCE_GW_SENDER) + public void rebalance(); + + /** + * Returns whether this GatewaySender is primary or secondary. + * + * @return True if this is the primary, false otherwise. + */ + public boolean isPrimary(); + + /** + * Returns the number of dispatcher threads working for this GatewaySender. + */ + public int getDispatcherThreads(); + + /** + * Returns the order policy followed while dispatching the events to remote + * distributed system. Order policy is only relevant when the number of dispatcher + * threads is greater than one. + */ + + public String getOrderPolicy(); + + /** + * Returns whether the isDiskSynchronous property is set for this GatewaySender. + * + * @return True if the property is set, false otherwise. + */ + public boolean isDiskSynchronous(); + + /** + * Returns whether the isParallel property is set for this GatewaySender. + * + * @return True if the property is set, false otherwise. + */ + public boolean isParallel(); + + /** + * Returns the host and port information of GatewayReceiver to which this + * gateway sender is connected. + */ + public String getGatewayReceiver(); + + /** + * Returns whether this GatewaySender is connected and sending data to a + * GatewayReceiver. + */ + public boolean isConnected(); + + /** + * Returns number of events which have exceeded the configured alert threshold. + */ + public int getEventsExceedingAlertThreshold(); + + + + } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/LockServiceMXBean.java ---------------------------------------------------------------------- diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/LockServiceMXBean.java index 0000000,9cec87f..067a799 mode 000000,100644..100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/LockServiceMXBean.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/LockServiceMXBean.java @@@ -1,0 -1,85 +1,89 @@@ + /* + * 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 com.gemstone.gemfire.management; + + import java.util.Map; + + import com.gemstone.gemfire.distributed.internal.locks.DLockService; ++import com.gemstone.gemfire.management.internal.security.Resource; ++import com.gemstone.gemfire.management.internal.security.ResourceConstants; ++import com.gemstone.gemfire.management.internal.security.ResourceOperation; + + /** + * MBean that provides access to information and management functionality for a + * {@link DLockService}. Since any number of DLockService objects can be created + * by a member there may be 0 or more instances of this MBean available. + * + * @author rishim + * @since 7.0 + * + */ + public interface LockServiceMXBean { + + /** + * Returns the name of the lock service. + */ + public String getName(); + + /** + * Returns whether this is a distributed LockService. + * + * @return True is this is a distributed LockService, false otherwise. + */ + public boolean isDistributed(); + + /** + * Returns the number of members using this LockService. + */ + public int getMemberCount(); + + /** + * Returns of the name of the member which grants the lock. + */ + public String fetchGrantorMember(); + + /** + * Returns a list of names of the members using this LockService. + */ + public String[] getMemberNames(); + + /** + * Returns whether this member is the granter. + * + * @return True if this member is the granter, false otherwise. + */ + public boolean isLockGrantor(); + + + /** + * Requests that this member become the granter. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.BECOME_LOCK_GRANTOR) + public void becomeLockGrantor(); + + /** + * Returns a map of the names of the objects being locked on and the names of + * the threads holding the locks. + */ + public Map listThreadsHoldingLock(); + + /** + * Returns a list of names of the locks held by this member's threads. + */ + public String[] listHeldLocks(); + + } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/ManagerMXBean.java ---------------------------------------------------------------------- diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/ManagerMXBean.java index 0000000,39981cf..62a5f52 mode 000000,100644..100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/ManagerMXBean.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/ManagerMXBean.java @@@ -1,0 -1,83 +1,90 @@@ + /* + * 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 com.gemstone.gemfire.management; + + import javax.management.JMException; + + import com.gemstone.gemfire.management.internal.Manager; ++import com.gemstone.gemfire.management.internal.security.Resource; ++import com.gemstone.gemfire.management.internal.security.ResourceConstants; ++import com.gemstone.gemfire.management.internal.security.ResourceOperation; + + + /** + * MBean that provides access to information and management functionality for a + * {@link Manager}. + * + * @author rishim + * @since 7.0 + * + */ + public interface ManagerMXBean { + + /** + * Returns whether the manager service is running on this member. + * + * @return True of the manager service is running, false otherwise. + */ + public boolean isRunning(); + + /** + * Starts the manager service. + * + * @return True if the manager service was successfully started, false otherwise. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.START_MANAGER) + public boolean start() throws JMException; + + /** + * Stops the manager service. + * + * @return True if the manager service was successfully stopped, false otherwise. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.STOP_MANAGER) + public boolean stop() throws JMException; + + /** + * Returns the URL for connecting to the Pulse application. + */ + public String getPulseURL(); + + /** + * Sets the URL for the Pulse application. + * + * @param pulseURL + * The URL for the Pulse application. + */ ++ @ResourceOperation(resource=Resource.DISTRIBUTED_SYSTEM, operation=ResourceConstants.LIST_DS) + public void setPulseURL(String pulseURL); + + /** + * Returns the last set status message. Generally, a subcomponent will call + * setStatusMessage to save the result of its execution. For example, if + * the embedded HTTP server failed to start, the reason for that failure will + * be saved here. + */ + public String getStatusMessage(); + + /** + * Sets the status message. + * + * @param message + * The status message. + */ ++ @ResourceOperation(resource=Resource.DISTRIBUTED_SYSTEM, operation=ResourceConstants.LIST_DS) + public void setStatusMessage(String message); + } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/MemberMXBean.java ---------------------------------------------------------------------- diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/MemberMXBean.java index 0000000,e803825..c4316ae mode 000000,100644..100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/MemberMXBean.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/MemberMXBean.java @@@ -1,0 -1,855 +1,866 @@@ + /* + * 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 com.gemstone.gemfire.management; + + import java.util.Map; + + import com.gemstone.gemfire.distributed.DistributedMember; ++import com.gemstone.gemfire.management.internal.security.Resource; ++import com.gemstone.gemfire.management.internal.security.ResourceConstants; ++import com.gemstone.gemfire.management.internal.security.ResourceOperation; + + + /** + * MBean that provides access to information and management functionality for a + * {@link DistributedMember} of the GemFire distributed system. + * + *

+ * ObjectName of the MBean + * :GemFire:type=Member,member=<name-or-dist-member-id> + * + *

+ * There will be one instance of this MBean per GemFire node. + * + *

+ * List of notification emitted by MemberMXBean. + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Notification TypeNotification SourceMessage
gemfire.distributedsystem.cache.region.createdMember name or IDRegion Created with Name <Region Name>
gemfire.distributedsystem.cache.region.closedMember name or IDRegion Destroyed/Closed with Name <Region Name>
gemfire.distributedsystem.cache.disk.createdMember name or IDDiskStore Created with Name <DiskStore Name>
gemfire.distributedsystem.cache.disk.closedMember name or IDDiskStore Destroyed/Closed with Name <DiskStore Name>
gemfire.distributedsystem.cache.lockservice.createdMember name or IDLockService Created with Name <LockService Name>
gemfire.distributedsystem.cache.lockservice.closedMember name or IDLockservice Closed with Name <LockService Name>
gemfire.distributedsystem.gateway.sender.createdMember name or IDGatewaySender Created in the VM
gemfire.distributedsystem.gateway.sender.startedMember name or IDGatewaySender Started in the VM <Sender Id>
gemfire.distributedsystem.gateway.sender.stoppedMember name or IDGatewaySender Stopped in the VM <Sender Id>
gemfire.distributedsystem.gateway.sender.pausedMember name or IDGatewaySender Paused in the VM <Sender Id>
gemfire.distributedsystem.gateway.sender.resumedMember name or IDGatewaySender Resumed in the VM <Sender Id>
gemfire.distributedsystem.async.event.queue.createdMember name or IDAsync Event Queue is Created in the VM
gemfire.distributedsystem.gateway.receiver.createdMember name or IDGatewayReceiver Created in the VM
gemfire.distributedsystem.gateway.receiver.startedMember name or IDGatewayReceiver Started in the VM
gemfire.distributedsystem.gateway.receiver.stoppedMember name or IDGatewayReceiver Stopped in the VM
gemfire.distributedsystem.cache.server.startedMember name or IDCache Server is Started in the VM
gemfire.distributedsystem.cache.server.stoppedMember name or IDCache Server is stopped in the VM
gemfire.distributedsystem.locator.startedMember name or IDLocator is Started in the VM
+ * + * @author rishim + * @since 7.0 + */ + public interface MemberMXBean { + + /** + * Returns the most recent log entries for the member. + * + * @param numberOfLines + * Number of lines to return, up to a maximum of 100. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.SHOW_LOG) + public String showLog(int numberOfLines); + + /** + * Returns the license string for this member. + * + * @deprecated Removed licensing in 8.0. + */ + @Deprecated + public String viewLicense(); + + /** + * Performs compaction on all of the member's disk stores. + * + * @return A list of names of the disk stores that were compacted. + */ ++ @ResourceOperation(resource=Resource.DISKSTORE, operation=ResourceConstants.COMPACT_DISKSTORE) + public String[] compactAllDiskStores(); + + /** + * Creates a Manager MBean on this member. + * + * @return True if the Manager MBean was successfully create, false otherwise. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.CREATE_MANAGER) + public boolean createManager(); + + /** + * Shuts down the member. This is an asynchronous call and it will + * return immediately without waiting for a result. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.SHUTDOWN) + public void shutDownMember(); + + /** + * Returns JVM metrics. + */ + public JVMMetrics showJVMMetrics(); + + /** + * Returns operating system metrics. + */ + public OSMetrics showOSMetrics(); + + /** + * Executes a command on the member. + * + * @param commandString + * Command to be executed. + * + * @return Result of the execution in JSON format. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.LIST_DS) + String processCommand(String commandString); + + /** + * Executes a command on the member. + * + * @param commandString + * Command to be execute. + * @param env + * Environmental properties to use during command execution. + * @return Result of the execution in JSON format. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.LIST_DS) + String processCommand(String commandString, Map env); + + /** + * Executes a command on the member. + * + * @param commandString + * Command to be execute. + * @param env + * Environmental properties to use during command execution. + * @param binaryData + * Binary data specific to the command being executed. + * @return Result of the execution in JSON format. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.LIST_DS) + String processCommand(String commandString, Map env, Byte[][] binaryData); + + /** + * Returns the name of all disk stores in use by this member. + * + * @param includeRegionOwned + * Whether to include disk stores owned by a region. + */ + public String[] listDiskStores(boolean includeRegionOwned); + + /** + * + * @return list of HDFSStore's present in the Cache + */ + + public String[] getHDFSStores(); + + /** + * Returns the GemFire specific properties for this member. + */ + public GemFireProperties listGemFireProperties(); + + /** + * Returns the name or IP address of the host on which this member is + * running. + */ + public String getHost(); + + /** + * Returns the name of this member. + */ + public String getName(); + + /** + * Returns the ID of this member. + */ + public String getId(); + + /** + * Returns the name of the member if it's been set, otherwise the ID. + */ + public String getMember(); + + /** + * Returns the names of the groups this member belongs to. + */ + public String[] getGroups(); + + /** + * Returns the operating system process ID. + */ + public int getProcessId(); + + /** + * Returns the status. + */ ++ @ResourceOperation(resource=Resource.MEMBER, operation=ResourceConstants.LIST_DS) + public String status(); + + /** + * Returns the GemFire version. + */ + public String getVersion(); + + /** + * Returns whether this member is attached to at least one Locator. + * + * @return True if this member is attached to a Locator, false otherwise. + */ + public boolean isLocator(); + + /** + * Returns the number of seconds that this member will wait for a + * distributed lock. + */ + public long getLockTimeout(); + + /** + * Returns the number of second that this member will lease a distributed + * lock. + */ + public long getLockLease(); + + /** + * Any long-running GemFire process that was started with "start server" command from GFSH. + * It returns true even if that process has --disable-default-server=true. + */ + public boolean isServer(); + + /** + * Returns whether this member has at least one GatewaySender. + * + * @return True if this member has at least one GatwaySender, false otherwise. + */ + public boolean hasGatewaySender(); + + /** + * Returns whether this member is running the Manager service. + * + * @return True if this member is running the Manager service, false otherwise. + */ + public boolean isManager(); + + /** + * Returns whether this member has created the Manager service (it may be + * created, but not running). + * + * @return True if this member has created the Manager service, false otherwise. + */ + public boolean isManagerCreated(); + + /** + * Returns whether this member has at least one GatewayReceiver. + * + * @return True if this member has at least one GatwayReceiver, false otherwise. + */ + public boolean hasGatewayReceiver(); + + /** + * Returns the ClassPath. + */ + public String getClassPath(); + + /** + * Returns the current time on the member's host. + */ + public long getCurrentTime(); + + /** + * Returns the number of seconds that this member has been running. + */ + public long getMemberUpTime(); + + /** + * Returns the time (as a percentage) that this member's process time with + * respect to Statistics sample time interval. If process time between two + * sample time t1 & t2 is p1 and p2 + * cpuUsage = ((p2-p1) * 100) / ((t2-t1)) + * + * ProcessCpuTime is obtained from OperatingSystemMXBean. + * If process CPU time is not available in the platform it will be shown as -1 + * + */ + public float getCpuUsage(); + + /** + * Returns the current size of the heap in megabytes. + * @deprecated Please use {@link #getUsedMemory()} instead. + */ + public long getCurrentHeapSize(); + + /** + * Returns the maximum size of the heap in megabytes. + * @deprecated Please use {@link #getMaxMemory()} instead. + */ + public long getMaximumHeapSize(); + + /** + * Returns the free heap size in megabytes. + * @deprecated Please use {@link #getFreeMemory()} instead. + */ + public long getFreeHeapSize(); + + /** + * Returns the maximum size of the heap in megabytes. + * + */ + public long getMaxMemory(); + + /** + * Returns the free heap size in megabytes. + */ + public long getFreeMemory(); + + /** + * Returns the current size of the heap in megabytes. + */ + public long getUsedMemory(); + + /** + * Returns the current threads. + */ + public String[] fetchJvmThreads(); + + /** + * Returns the maximum number of open file descriptors allowed for the member's + * host operating system. + */ + public long getFileDescriptorLimit(); + + /** + * Returns the current number of open file descriptors. + */ + public long getTotalFileDescriptorOpen(); + + /** + * Returns the number of Regions present in the Cache. + */ + public int getTotalRegionCount(); + + /** + * Returns the number of Partition Regions present in the Cache. + */ + public int getPartitionRegionCount(); + + /** + * Returns a list of all Region names. + */ + public String[] listRegions(); + + + /** + * Returns a list of all disk stores, including those owned by a Region. + */ + public String[] getDiskStores(); + + /** + * Returns a list of all root Region names. + */ + public String[] getRootRegionNames(); + + /** + * Returns the total number of entries in all regions. + */ + public int getTotalRegionEntryCount(); + + /** + * Returns the total number of buckets. + */ + public int getTotalBucketCount(); + + /** + * Returns the number of buckets for which this member is the primary holder. + */ + public int getTotalPrimaryBucketCount(); + + /** + * Returns the cache get average latency. + */ + public long getGetsAvgLatency(); + + /** + * Returns the cache put average latency. + */ + public long getPutsAvgLatency(); + + /** + * Returns the cache putAll average latency. + */ + public long getPutAllAvgLatency(); + + /** + * Returns the number of times that a cache miss occurred for all regions. + */ + public int getTotalMissCount(); + + /** + * Returns the number of times that a hit occurred for all regions. + */ + public int getTotalHitCount(); + + /** + * Returns the number of gets per second. + */ + public float getGetsRate(); + + /** + * Returns the number of puts per second. Only includes puts done explicitly + * on this member's cache, not those pushed from another member. + */ + public float getPutsRate(); + + /** + * Returns the number of putAlls per second. + */ + public float getPutAllRate(); + + /** + * Returns the number of creates per second. + */ + public float getCreatesRate(); + + /** + * Returns the number of destroys per second. + */ + public float getDestroysRate(); + + /** + * Returns the average latency of a call to a CacheWriter. + */ + public long getCacheWriterCallsAvgLatency(); + + /** + * Returns the average latency of a call to a CacheListener. + */ + public long getCacheListenerCallsAvgLatency(); + + /** + * Returns the total number of times that a load on this cache has completed, + * as a result of either a local get or a remote net load. + */ + public int getTotalLoadsCompleted(); + + /** + * Returns the average latency of a load. + */ + public long getLoadsAverageLatency(); + + /** + * Returns the total number of times the a network load initiated by this cache + * has completed. + */ + public int getTotalNetLoadsCompleted(); + + /** + * Returns the net load average latency. + */ + public long getNetLoadsAverageLatency(); + + /** + * Returns the total number of times that a network search initiated by this cache + * has completed. + */ + public int getTotalNetSearchCompleted(); + + /** + * Returns the net search average latency. + */ + public long getNetSearchAverageLatency(); + + /** + * Returns the current number of disk tasks (op-log compaction, asynchronous + * recovery, etc.) that are waiting for a thread to run. + */ + public int getTotalDiskTasksWaiting(); + + /** + * Returns the average number of bytes per second sent. + */ + public float getBytesSentRate(); + + /** + * Returns the average number of bytes per second received. + */ + public float getBytesReceivedRate(); + + /** + * Returns a list of IDs for all connected gateway receivers. + */ + public String[] listConnectedGatewayReceivers(); + + /** + * Returns a list of IDs for all gateway senders. + */ + public String[] listConnectedGatewaySenders(); + + /** + * Returns the number of currently executing functions. + */ + public int getNumRunningFunctions(); + + /** + * Returns the average function execution rate. + */ + public float getFunctionExecutionRate(); + + /** + * Returns the number of currently executing functions that will return + * resutls. + */ + public int getNumRunningFunctionsHavingResults(); + + /** + * Returns the number of current transactions. + */ + public int getTotalTransactionsCount(); + + /** + * Returns the average commit latency in nanoseconds . + */ + public long getTransactionCommitsAvgLatency(); + + /** + * Returns the number of committed transactions. + */ + public int getTransactionCommittedTotalCount(); + + /** + * Returns the number of transactions that were rolled back. + */ + public int getTransactionRolledBackTotalCount(); + + /** + * Returns the average number of transactions committed per second. + */ + public float getTransactionCommitsRate(); + + + /** + * Returns the number of bytes reads per second from all the disks of the member. + */ + public float getDiskReadsRate(); + + /** + * Returns the number of bytes written per second to disk to all the disks of the member. + */ + public float getDiskWritesRate(); + + /** + * Returns the average disk flush latency time in nanoseconds. + */ + public long getDiskFlushAvgLatency(); + + /** + * Returns the number of backups currently in progress for all disk stores. + */ + public int getTotalBackupInProgress(); + + /** + * Returns the number of backups that have been completed. + */ + public int getTotalBackupCompleted(); + + /** + * Returns the number of threads waiting for a lock. + */ + public int getLockWaitsInProgress(); + + /** + * Returns the amount of time (in milliseconds) spent waiting for a lock. + */ + public long getTotalLockWaitTime(); + + /** + * Returns the number of lock services in use. + */ + public int getTotalNumberOfLockService(); + + /** + * Returns the number of locks for which this member is a granter. + */ + public int getTotalNumberOfGrantors(); + + /** + * Returns the number of lock request queues in use by this member. + */ + public int getLockRequestQueues(); + + /** + * Returns the entry eviction rate as triggered by the LRU policy. + */ + public float getLruEvictionRate(); + + /** + * Returns the rate of entries destroyed either by destroy cache operations or + * eviction. + */ + public float getLruDestroyRate(); + + /** + * Returns the number of initial images in progress. + */ + public int getInitialImagesInProgres(); + + /** + * Returns the total amount of time spent performing a "get initial image" + * operation when creating a region. + */ + public long getInitialImageTime(); + + /** + * Return the number of keys received while performing a "get initial image" + * operation when creating a region. + */ + public int getInitialImageKeysReceived(); + + /** + * Returns the average time (in nanoseconds) spent deserializing objects. + * Includes deserializations that result in a PdxInstance. + */ + public long getDeserializationAvgLatency(); + + /** + * Returns the average latency (in nanoseconds) spent deserializing objects. + * Includes deserializations that result in a PdxInstance. + */ + public long getDeserializationLatency(); + + /** + * Returns the instantaneous rate of deserializing objects. + * Includes deserializations that result in a PdxInstance. + */ + public float getDeserializationRate(); + + /** + * Returns the average time (in nanoseconds) spent serializing objects. + * Includes serializations that result in a PdxInstance. + */ + public long getSerializationAvgLatency(); + + /** + * Returns the average latency (in nanoseconds) spent serializing objects. + * Includes serializations that result in a PdxInstance. + */ + public long getSerializationLatency(); + + /** + * Returns the instantaneous rate of serializing objects. + * Includes serializations that result in a PdxInstance. + */ + public float getSerializationRate(); + + /** + * Returns the instantaneous rate of PDX instance deserialization. + */ + public float getPDXDeserializationRate(); + + /** + * Returns the average time, in seconds, spent deserializing PDX instanced. + */ + public long getPDXDeserializationAvgLatency(); + + /** + * Returns the total number of bytes used on all disks. + */ + public long getTotalDiskUsage(); + + /** + * Returns the number of threads in use. + */ + public int getNumThreads(); + + /** + * Returns the system load average for the last minute. The system load + * average is the sum of the number of runnable entities queued to the + * available processors and the number of runnable entities running on the + * available processors averaged over a period of time. + * + * Pulse Attribute + * + * @return The load average or a negative value if one is not available. + */ + public double getLoadAverage(); + + /** + * Returns the number of times garbage collection has occurred. + */ + public long getGarbageCollectionCount(); + + /** + * Returns the amount of time (in milliseconds) spent on garbage collection. + */ + public long getGarbageCollectionTime(); + + /** + * Returns the average number of reads per second. + */ + public float getAverageReads(); + + /** + * Returns the average writes per second, including both put and putAll operations. + */ + public float getAverageWrites(); + + /** + * Returns the number JVM pauses (which may or may not include full garbage + * collection pauses) detected by GemFire. + */ + public long getJVMPauses(); + + + /** + * Returns the underlying host's current cpuActive percentage + */ + public int getHostCpuUsage(); + + /** + * + * Returns true if a cache server is running on this member and able server requests from GemFire clients + */ + public boolean isCacheServer(); + + /** + * Returns the redundancy-zone of the member; + */ + public String getRedundancyZone(); + + /** + * Returns current number of cache rebalance operations being directed by this process. + */ + public int getRebalancesInProgress(); + + /** + * Returns current number of threads waiting for a reply. + */ + public int getReplyWaitsInProgress(); + + /** + * Returns total number of times waits for a reply have completed. + */ + public int getReplyWaitsCompleted(); + + /** + * The current number of nodes in this distributed system visible to this member. + */ + public int getVisibleNodes(); + + /** + * Returns the number of off heap objects. + */ + public int getOffHeapObjects(); + + /** + * Returns the size of the maximum configured off-heap memory in bytes. + */ + public long getOffHeapMaxMemory(); + + /** + * Returns the size of available (or unallocated) off-heap memory in bytes. + */ + public long getOffHeapFreeMemory(); + + /** + * Returns the size of utilized off-heap memory in bytes. + */ + public long getOffHeapUsedMemory(); + + /** + * Returns the percentage of off-heap memory fragmentation. + */ + public int getOffHeapFragmentation(); + + /** + * Returns the total time spent compacting in millseconds. + */ + public long getOffHeapCompactionTime(); + } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java ---------------------------------------------------------------------- diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java index 0000000,3b22eec..e28ddf5 mode 000000,100755..100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/ManagementAgent.java @@@ -1,0 -1,516 +1,526 @@@ + /* + * 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 com.gemstone.gemfire.management.internal; + + import java.io.IOException; + import java.io.Serializable; + import java.lang.management.ManagementFactory; + import java.net.InetAddress; + import java.net.ServerSocket; + import java.net.Socket; + import java.net.UnknownHostException; + import java.rmi.AlreadyBoundException; + import java.rmi.registry.LocateRegistry; + import java.rmi.registry.Registry; + import java.rmi.server.RMIClientSocketFactory; + import java.rmi.server.RMIServerSocketFactory; + import java.rmi.server.UnicastRemoteObject; + import java.util.HashMap; + + import javax.management.MBeanServer; + import javax.management.remote.JMXConnectorServer; + import javax.management.remote.JMXServiceURL; + import javax.management.remote.rmi.RMIConnectorServer; + import javax.management.remote.rmi.RMIJRMPServerImpl; + import javax.management.remote.rmi.RMIServerImpl; + import javax.rmi.ssl.SslRMIClientSocketFactory; + + import org.apache.logging.log4j.Logger; + import org.eclipse.jetty.server.Server; + import org.eclipse.jetty.server.ServerConnector; + + import com.gemstone.gemfire.cache.CacheFactory; + import com.gemstone.gemfire.distributed.internal.DistributionConfig; + import com.gemstone.gemfire.distributed.internal.DistributionManager; + import com.gemstone.gemfire.internal.GemFireVersion; + import com.gemstone.gemfire.internal.SocketCreator; + import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; + import com.gemstone.gemfire.internal.lang.StringUtils; + import com.gemstone.gemfire.internal.logging.LogService; + import com.gemstone.gemfire.internal.tcp.TCPConduit; + import com.gemstone.gemfire.management.ManagementException; + import com.gemstone.gemfire.management.ManagementService; + import com.gemstone.gemfire.management.ManagerMXBean; + import com.gemstone.gemfire.management.internal.security.ManagementInterceptor; + import com.gemstone.gemfire.management.internal.unsafe.ReadOpFileAccessController; + + /** + * Agent implementation that controls the JMX server end points for JMX clients + * to connect, such as an RMI server. + * + * The ManagementAgent could be used in a loner or GemFire client to define and + * control JMX server end points for the Platform MBeanServer and the GemFire + * MBeans hosted within it. + * + * @author VMware, Inc. + * @since 7.0 + */ + public class ManagementAgent { + private static final Logger logger = LogService.getLogger(); + + /** + * True if running. Protected by synchronizing on this Manager instance. I + * used synchronization because I think we'll want to hold the same + * synchronize while configuring, starting, and eventually stopping the RMI + * server, the hidden management regions (in FederatingManager), etc + */ + private boolean running = false; + private Registry registry; + private JMXConnectorServer cs; + private final DistributionConfig config; + private boolean isHttpServiceRunning = false; + private ManagementInterceptor securityInterceptor; + + /** + * 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. + */ + private static final String PULSE_EMBEDDED_PROP = "pulse.embedded"; + + public ManagementAgent(DistributionConfig config) { + this.config = config; + } + + public synchronized boolean isRunning() { + return this.running; + } + + public synchronized boolean isHttpServiceRunning() { + return isHttpServiceRunning; + } + + public synchronized void setHttpServiceRunning(boolean isHttpServiceRunning) { + this.isHttpServiceRunning = isHttpServiceRunning; + } + + private boolean isAPIRestServiceRunning(GemFireCacheImpl cache) { + return (cache != null && cache.getRestAgent() != null && cache.getRestAgent().isRunning()); + } + + private boolean isServerNode(GemFireCacheImpl cache) { + return (cache.getDistributedSystem().getDistributedMember().getVmKind() != DistributionManager.LOCATOR_DM_TYPE + && cache.getDistributedSystem().getDistributedMember().getVmKind() != DistributionManager.ADMIN_ONLY_DM_TYPE && !cache + .isClient()); + } + + public synchronized void startAgent(GemFireCacheImpl cache) { + // Do not start Management REST service if developer REST service is already + // started. + + if (!isAPIRestServiceRunning(cache)) { + startHttpService(isServerNode(cache)); + } else { + if (logger.isDebugEnabled()) { + logger + .debug("Developer REST APIs webapp is already running, Not Starting M&M REST and pulse!"); + } + } + + if (!this.running && this.config.getJmxManagerPort() != 0) { + try { + configureAndStart(); + } catch (IOException e) { + throw new ManagementException(e); + } + this.running = true; + } + } + + public synchronized void stopAgent() { + stopHttpService(); + + if (!this.running) + return; + + if (logger.isDebugEnabled()) { + logger.debug("Stopping jmx manager agent"); + } + try { + cs.stop(); + UnicastRemoteObject.unexportObject(registry, true); + } catch (IOException e) { + throw new ManagementException(e); + } + + this.running = false; + } + + private Server httpServer; + private final String GEMFIRE_VERSION = GemFireVersion.getGemFireVersion(); + private AgentUtil agentUtil = new AgentUtil(GEMFIRE_VERSION); + + private void startHttpService(boolean isServer) { + final SystemManagementService managementService = (SystemManagementService) ManagementService + .getManagementService(CacheFactory.getAnyInstance()); + + final ManagerMXBean managerBean = managementService.getManagerMXBean(); + + if (this.config.getHttpServicePort() != 0) { + if (logger.isDebugEnabled()) { + logger.debug("Attempting to start HTTP service on port ({}) at bind-address ({})...", + this.config.getHttpServicePort(), this.config.getHttpServiceBindAddress()); + } + + // Find the Management WAR file + final String gemfireWar = agentUtil.findWarLocation("geode-web"); + if (gemfireWar == null) { + if (logger.isDebugEnabled()) { + logger.debug("Unable to find GemFire Management REST API WAR file; the Management REST Interface for GemFire will not be accessible."); + } + } + + // Find the Pulse WAR file + final String pulseWar = agentUtil.findWarLocation("geode-pulse"); + + if (pulseWar == null) { + final String message = "Unable to find Pulse web application WAR file; Pulse for GemFire will not be accessible"; + setStatusMessage(managerBean, message); + if (logger.isDebugEnabled()) { + logger.debug(message); + } + } + + // Find developer REST WAR file + final String gemfireAPIWar = agentUtil.findWarLocation("geode-web-api"); + if (gemfireAPIWar == null) { + final String message = "Unable to find GemFire Developer REST API WAR file; the Developer REST Interface for GemFire will not be accessible."; + setStatusMessage(managerBean, message); + if (logger.isDebugEnabled()) { + logger.debug(message); + } + } + + try { + if (agentUtil.isWebApplicationAvailable(gemfireWar, pulseWar, gemfireAPIWar)) { + + final String bindAddress = this.config.getHttpServiceBindAddress(); + final int port = this.config.getHttpServicePort(); + + boolean isRestWebAppAdded = false; + + this.httpServer = JettyHelper.initJetty(bindAddress, port, + this.config.getHttpServiceSSLEnabled(), + this.config.getHttpServiceSSLRequireAuthentication(), + this.config.getHttpServiceSSLProtocols(), this.config.getHttpServiceSSLCiphers(), + this.config.getHttpServiceSSLProperties()); + + if (agentUtil.isWebApplicationAvailable(gemfireWar)) { + this.httpServer = JettyHelper + .addWebApplication(this.httpServer, "/gemfire", gemfireWar); + } + + if (agentUtil.isWebApplicationAvailable(pulseWar)) { + this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/pulse", pulseWar); + } + + if (isServer && this.config.getStartDevRestApi()) { + if (agentUtil.isWebApplicationAvailable(gemfireAPIWar)) { + this.httpServer = JettyHelper.addWebApplication(this.httpServer, "/gemfire-api", + gemfireAPIWar); + isRestWebAppAdded = true; + } + } else { + final String message = "Developer REST API web application will not start when start-dev-rest-api is not set and node is not server"; + setStatusMessage(managerBean, message); + if (logger.isDebugEnabled()) { + logger.debug(message); + } + } + + if (logger.isDebugEnabled()) { + logger.debug("Starting HTTP embedded server on port ({}) at bind-address ({})...", + ((ServerConnector) this.httpServer.getConnectors()[0]).getPort(), bindAddress); + } + + System.setProperty(PULSE_EMBEDDED_PROP, "true"); + + this.httpServer = JettyHelper.startJetty(this.httpServer); + + // now, that Tomcat has been started, we can set the URL used by web + // clients to connect to Pulse + if (agentUtil.isWebApplicationAvailable(pulseWar)) { + managerBean.setPulseURL("http://".concat(getHost(bindAddress)).concat(":") + .concat(String.valueOf(port)).concat("/pulse/")); + } + + // set cache property for developer REST service running + if (isRestWebAppAdded) { + GemFireCacheImpl cache = (GemFireCacheImpl) CacheFactory.getAnyInstance(); + cache.setRESTServiceRunning(true); + + // create region to hold query information (queryId, queryString). + // Added for the developer REST APIs + RestAgent.createParameterizedQueryRegion(); ++ ++ //Rest APIs security ++ if(!StringUtils.isBlank(this.config.SECURITY_CLIENT_AUTHENTICATOR_NAME)){ ++ RestAgent.createTokenToAuthzRequestRegion(); ++ } + } + + // set true for HTTP service running + setHttpServiceRunning(true); + } + } catch (Exception e) { + stopHttpService();// Jetty needs to be stopped even if it has failed to + // start. Some of the threads are left behind even if + // server.start() fails due to an exception + setStatusMessage(managerBean, "HTTP service failed to start with " + + e.getClass().getSimpleName() + " '" + e.getMessage() + "'"); + throw new ManagementException("HTTP service failed to start", e); + } + } else { + setStatusMessage(managerBean, + "Embedded HTTP server configured not to start (http-service-port=0) or (jmx-manager-http-port=0)"); + } + } + + private String getHost(final String bindAddress) throws UnknownHostException { + if (!StringUtils.isBlank(this.config.getJmxManagerHostnameForClients())) { + return this.config.getJmxManagerHostnameForClients(); + } else if (!StringUtils.isBlank(bindAddress)) { + return InetAddress.getByName(bindAddress).getHostAddress(); + } else { + return SocketCreator.getLocalHost().getHostAddress(); + } + } + + private boolean isRunningInTomcat() { + return (System.getProperty("catalina.base") != null || System.getProperty("catalina.home") != null); + } + + private void setStatusMessage(ManagerMXBean mBean, String message) { + mBean.setPulseURL(""); + mBean.setStatusMessage(message); + } + + private void stopHttpService() { + if (this.httpServer != null) { + if (logger.isDebugEnabled()) { + logger.debug("Stopping the HTTP service..."); + } + try { + this.httpServer.stop(); + } catch (Exception e) { + logger.warn("Failed to stop the HTTP service because: {}", e.getMessage(), e); + } finally { + try { + this.httpServer.destroy(); + } catch (Exception ignore) { + logger.error("Failed to properly release resources held by the HTTP service: {}", + ignore.getMessage(), ignore); + } finally { + this.httpServer = null; + System.clearProperty("catalina.base"); + System.clearProperty("catalina.home"); + } + } + } + } + + /** + * http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html + * #gdfvq https://blogs.oracle.com/jmxetc/entry/java_5_premain_rmi_connectors + * https + * ://blogs.oracle.com/jmxetc/entry/building_a_remotely_stoppable_connector + * https + * ://blogs.oracle.com/jmxetc/entry/jmx_connecting_through_firewalls_using + */ + private void configureAndStart() throws IOException { + // KIRK: I copied this from + // https://blogs.oracle.com/jmxetc/entry/java_5_premain_rmi_connectors + // we'll need to change this significantly but it's a starting point + + // get the port for RMI Registry and RMI Connector Server + final int port = this.config.getJmxManagerPort(); + final String hostname; + final InetAddress bindAddr; + if (this.config.getJmxManagerBindAddress().equals("")) { + hostname = SocketCreator.getLocalHost().getHostName(); + bindAddr = null; + } else { + hostname = this.config.getJmxManagerBindAddress(); + bindAddr = InetAddress.getByName(hostname); + } + + final boolean ssl = this.config.getJmxManagerSSLEnabled(); + + if (logger.isDebugEnabled()) { + logger.debug("Starting jmx manager agent on port {}{}", port, + (bindAddr != null ? (" bound to " + bindAddr) : "") + (ssl ? " using SSL" : "")); + } + + final SocketCreator sc = SocketCreator.createNonDefaultInstance(ssl, + this.config.getJmxManagerSSLRequireAuthentication(), + this.config.getJmxManagerSSLProtocols(), this.config.getJmxManagerSSLCiphers(), + this.config.getJmxSSLProperties()); + RMIClientSocketFactory csf = ssl ? new SslRMIClientSocketFactory() : null;// RMISocketFactory.getDefaultSocketFactory(); + // new GemFireRMIClientSocketFactory(sc, getLogger()); + RMIServerSocketFactory ssf = new GemFireRMIServerSocketFactory(sc, bindAddr); + + // Following is done to prevent rmi causing stop the world gcs + System.setProperty("sun.rmi.dgc.server.gcInterval", Long.toString(Long.MAX_VALUE - 1)); + + // Create the RMI Registry using the SSL socket factories above. + // In order to use a single port, we must use these factories + // everywhere, or nowhere. Since we want to use them in the JMX + // RMI Connector server, we must also use them in the RMI Registry. + // Otherwise, we wouldn't be able to use a single port. + // + // Start an RMI registry on port . + registry = LocateRegistry.createRegistry(port, csf, ssf); + + // Retrieve the PlatformMBeanServer. + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + // Environment map. KIRK: why is this declared as HashMap? + final HashMap env = new HashMap(); + - boolean integratedSecEnabled = System.getProperty("resource-authenticator") != null; ++ boolean integratedSecEnabled = isIntegratedSecEnabled(); + if (integratedSecEnabled) { - securityInterceptor = new ManagementInterceptor(logger); ++ securityInterceptor = new ManagementInterceptor((GemFireCacheImpl)CacheFactory.getAnyInstance(), logger); + env.put(JMXConnectorServer.AUTHENTICATOR, securityInterceptor); + } else { + /* Disable the old authenticator mechanism */ + String pwFile = this.config.getJmxManagerPasswordFile(); + if (pwFile != null && pwFile.length() > 0) { + env.put("jmx.remote.x.password.file", pwFile); + } + + String accessFile = this.config.getJmxManagerAccessFile(); + if (accessFile != null && accessFile.length() > 0) { + // Lets not use default connector based authorization + // env.put("jmx.remote.x.access.file", accessFile); + // Rewire the mbs hierarchy to set accessController + ReadOpFileAccessController controller = new ReadOpFileAccessController(accessFile); + controller.setMBeanServer(mbs); + mbs = controller; + } + } + + // Manually creates and binds a JMX RMI Connector Server stub with the + // registry created above: the port we pass here is the port that can + // be specified in "service:jmx:rmi://"+hostname+":"+port - where the + // RMI server stub and connection objects will be exported. + // Here we choose to use the same port as was specified for the + // RMI Registry. We can do so because we're using \*the same\* client + // and server socket factories, for the registry itself \*and\* for this + // object. + final RMIServerImpl stub = new RMIJRMPServerImpl(port, csf, ssf, env); + + // Create an RMI connector server. + // + // As specified in the JMXServiceURL the RMIServer stub will be + // registered in the RMI registry running in the local host on + // port with the name "jmxrmi". This is the same name the + // out-of-the-box management agent uses to register the RMIServer + // stub too. + // + // The port specified in "service:jmx:rmi://"+hostname+":"+port + // is the second port, where RMI connection objects will be exported. + // Here we use the same port as that we choose for the RMI registry. + // The port for the RMI registry is specified in the second part + // of the URL, in "rmi://"+hostname+":"+port + // + // We construct a JMXServiceURL corresponding to what we have done + // for our stub... + final JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + hostname + ":" + port + + "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi"); + + // Create an RMI connector server with the JMXServiceURL + // + // KIRK: JDK 1.5 cannot use JMXConnectorServerFactory because of + // http://bugs.sun.com/view_bug.do?bug_id=5107423 + // but we're using JDK 1.6 + cs = new RMIConnectorServer(new JMXServiceURL("rmi", hostname, port), env, stub, mbs) { + @Override + public JMXServiceURL getAddress() { + return url; + } + + @Override + public synchronized void start() throws IOException { + try { + registry.bind("jmxrmi", stub); + } catch (AlreadyBoundException x) { + final IOException io = new IOException(x.getMessage()); + io.initCause(x); + throw io; + } + super.start(); + } + }; + // This may be the 1.6 way of doing it but the problem is it does not use + // our "stub". + // cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); + + if (integratedSecEnabled) { + cs.setMBeanServerForwarder(securityInterceptor.getMBeanServerForwarder()); + logger.info("Starting RMI Connector with Security Interceptor"); + } + + cs.start(); + if (logger.isDebugEnabled()) { + logger.debug("Finished starting jmx manager agent."); + } + // System.out.println("Server started at: "+cs.getAddress()); + + // Start the CleanThread daemon... KIRK: not sure what CleanThread is... + // + // final Thread clean = new CleanThread(cs); + // clean.start(); + } ++ ++ private boolean isIntegratedSecEnabled() { ++ String authenticatorFactoryName = config.getSecurityClientAuthenticator(); ++ return authenticatorFactoryName != null && !authenticatorFactoryName.isEmpty(); ++ } + + private static class GemFireRMIClientSocketFactory implements RMIClientSocketFactory, + Serializable { + private static final long serialVersionUID = -7604285019188827617L; + + private/* final hack to prevent serialization */transient SocketCreator sc; + + public GemFireRMIClientSocketFactory(SocketCreator sc) { + this.sc = sc; + } + + @Override + public Socket createSocket(String host, int port) throws IOException { + return this.sc.connectForClient(host, port, 0/* no timeout */); + } + }; + + private static class GemFireRMIServerSocketFactory implements RMIServerSocketFactory, + Serializable { + private static final long serialVersionUID = -811909050641332716L; + private/* final hack to prevent serialization */transient SocketCreator sc; + private final InetAddress bindAddr; + + public GemFireRMIServerSocketFactory(SocketCreator sc, InetAddress bindAddr) { + this.sc = sc; + this.bindAddr = bindAddr; + } + + @Override + public ServerSocket createServerSocket(int port) throws IOException { + return this.sc.createServerSocket(port, TCPConduit.getBackLog(), this.bindAddr); + } + }; + } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5c01d5f4/geode-core/src/main/java/com/gemstone/gemfire/management/internal/RestAgent.java ---------------------------------------------------------------------- diff --cc geode-core/src/main/java/com/gemstone/gemfire/management/internal/RestAgent.java index 0000000,d8faea6..f9e4823 mode 000000,100755..100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/RestAgent.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/RestAgent.java @@@ -1,0 -1,217 +1,344 @@@ + /* + * 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 com.gemstone.gemfire.management.internal; + ++import java.security.Principal; ++import java.util.List; ++ + import org.apache.logging.log4j.Logger; + import org.eclipse.jetty.server.Server; + import org.eclipse.jetty.server.ServerConnector; ++import org.springframework.util.Assert; + + import com.gemstone.gemfire.cache.AttributesFactory; ++import com.gemstone.gemfire.cache.Cache; + import com.gemstone.gemfire.cache.CacheFactory; + import com.gemstone.gemfire.cache.DataPolicy; ++import com.gemstone.gemfire.cache.Region; + import com.gemstone.gemfire.cache.RegionAttributes; + import com.gemstone.gemfire.cache.Scope; + import com.gemstone.gemfire.distributed.internal.DistributionConfig; + import com.gemstone.gemfire.internal.GemFireVersion; + import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; + import com.gemstone.gemfire.internal.cache.InternalRegionArguments; ++import com.gemstone.gemfire.internal.lang.StringUtils; + import com.gemstone.gemfire.internal.logging.LogService; ++import com.gemstone.gemfire.internal.security.AuthorizeRequest; ++import com.gemstone.gemfire.internal.security.AuthorizeRequestPP; + import com.gemstone.gemfire.management.ManagementService; + + /** + * Agent implementation that controls the HTTP server end points used for REST + * clients to connect gemfire data node. + * + * The RestAgent is used to start http service in embedded mode on any non + * manager data node with developer REST APIs service enabled. + * + * @author Nilkanth Patel. + * @since 8.0 + */ + public class RestAgent { + private static final Logger logger = LogService.getLogger(); + + private boolean running = false; + private final DistributionConfig config; - ++ ++ public static final String AUTH_METADATA_REGION = "__TokenToAuthzRequest__"; ++ + public RestAgent(DistributionConfig config) { + this.config = config; + } + + public synchronized boolean isRunning() { + return this.running; + } - - private boolean isManagementRestServiceRunning(GemFireCacheImpl cache) { - final SystemManagementService managementService = (SystemManagementService) ManagementService - .getManagementService(cache); - return (managementService.getManagementAgent() != null && managementService - .getManagementAgent().isHttpServiceRunning()); - ++ ++ private static Cache getCache(){ ++ Cache cache = GemFireCacheImpl.getExisting(); ++ Assert.state(cache != null, "The Gemfire Cache reference was not properly initialized"); ++ return cache; ++ } ++ ++ public static Region> getAuthzRegion(final String namePath) { ++ /* ++ return ValidationUtils.returnValueThrowOnNull(getCache().>getRegion(namePath), ++ new GemfireRestException(String.format(" (%1$s) store does not exist!", namePath))); ++ */ ++ try{ ++ return getCache().getRegion(namePath); ++ }catch(Exception e){ ++ throw new RuntimeException("AuthorizeStore does not exist!" + e.getMessage()); ++ } ++ } ++ ++ public static AuthorizeRequest getAuthorizeRequest(String token){ ++ List objs = getAuthzRegion(RestAgent.AUTH_METADATA_REGION).get(token); ++ return (AuthorizeRequest)objs.get(0); ++ } ++ ++ public static AuthorizeRequestPP getAuthorizeRequestPP(String token){ ++ List objs = getAuthzRegion(RestAgent.AUTH_METADATA_REGION).get(token); ++ return (AuthorizeRequestPP)objs.get(1); ++ } ++ ++ public static Principal getPrincipalForToken(String token){ ++ return getAuthorizeRequest(token).getPrincipal(); ++ } ++ ++ public static synchronized void removeAuthzEntry(String token){ ++ //remove the authzCallback. Note that this does not close() it. ++ getAuthzRegion(AUTH_METADATA_REGION).remove(token); ++ } ++ ++ public static void closeAuthz(String token){ ++ //Close the authzCallback ++ try{ ++ AuthorizeRequest authRequest = getAuthorizeRequest(token); ++ if(authRequest != null) { ++ authRequest.close(); ++ } ++ ++ AuthorizeRequestPP authRequestPP = getAuthorizeRequestPP(token); ++ if(authRequestPP != null) { ++ authRequestPP.close(); ++ } ++ } catch(Exception e){ ++ logger.error("Cannot close the authzCallback for token {}", token, e); ++ } ++ } ++ ++ public static synchronized void addAuthzEntry(String token, List authObjects){ ++ getAuthzRegion(AUTH_METADATA_REGION).put(token, authObjects); ++ } ++ ++ private boolean isManagementRestServiceRunning(GemFireCacheImpl cache){ ++ final SystemManagementService managementService = (SystemManagementService) ManagementService.getManagementService( ++ cache); ++ return ( managementService.getManagementAgent() != null && managementService.getManagementAgent().isHttpServiceRunning()); ++ + } + + public synchronized void start(GemFireCacheImpl cache) { + if (!this.running && this.config.getHttpServicePort() != 0 + && !isManagementRestServiceRunning(cache)) { + try { + startHttpService(); + this.running = true; + cache.setRESTServiceRunning(true); + + // create region to hold query information (queryId, queryString). Added + // for the developer REST APIs + RestAgent.createParameterizedQueryRegion(); - - } catch (RuntimeException e) { ++ ++ if(!StringUtils.isBlank(this.config.SECURITY_CLIENT_AUTHENTICATOR_NAME)){ ++ RestAgent.createTokenToAuthzRequestRegion(); ++ } ++ ++ } catch (RuntimeException e){ + logger.debug(e.getMessage(), e); + } + } + + } + + public synchronized void stop() { + if (this.running) { + stopHttpService(); + if (logger.isDebugEnabled()) { + logger.debug("Gemfire Rest Http service stopped"); + } + this.running = false; + } else { + if (logger.isDebugEnabled()) { + logger.debug("Attempt to stop Gemfire Rest Http service which is not running"); + } + } + } - ++ ++ public synchronized void cleanup(){ ++ //close all authzCallback instances currently present in the region; ++ if(!StringUtils.isBlank(this.config.SECURITY_CLIENT_AUTHENTICATOR_NAME)){ ++ for(final String key : getAuthzRegion(AUTH_METADATA_REGION).keySet() ){ ++ try{ ++ closeAuthz(key); ++ ++ }catch(Exception e){ ++ logger.error("Cannot close the authzCallback for token {}", key, e); ++ } ++ } ++ } ++ } ++ + private Server httpServer; + private final String GEMFIRE_VERSION = GemFireVersion.getGemFireVersion(); + private AgentUtil agentUtil = new AgentUtil(GEMFIRE_VERSION); + + private boolean isRunningInTomcat() { + return (System.getProperty("catalina.base") != null || System.getProperty("catalina.home") != null); + } + + // Start HTTP service in embedded mode + public void startHttpService() { + // TODO: add a check that will make sure that we start HTTP service on + // non-manager data node + logger.info("Attempting to start HTTP service on port ({}) at bind-address ({})...", + this.config.getHttpServicePort(), this.config.getHttpServiceBindAddress()); + + // Find the developer REST WAR file + final String gemfireAPIWar = agentUtil.findWarLocation("geode-web-api"); + if (gemfireAPIWar == null) { + logger.info("Unable to find GemFire Developer REST API WAR file; the Developer REST Interface for GemFire will not be accessible."); + } + + try { + // Check if we're already running inside Tomcat + if (isRunningInTomcat()) { + logger.warn("Detected presence of catalina system properties. HTTP service will not be started. To enable the GemFire Developer REST API, please deploy the /geode-web-api WAR file in your application server."); + } else if (agentUtil.isWebApplicationAvailable(gemfireAPIWar)) { + + final String bindAddress = this.config.getHttpServiceBindAddress(); + final int port = this.config.getHttpServicePort(); + + this.httpServer = JettyHelper.initJetty(bindAddress, port, + this.config.getHttpServiceSSLEnabled(), + this.config.getHttpServiceSSLRequireAuthentication(), + this.config.getHttpServiceSSLProtocols(), this.config.getHttpServiceSSLCiphers(), + this.config.getHttpServiceSSLProperties()); + + this.httpServer = JettyHelper.addWebApplication(httpServer, "/gemfire-api", gemfireAPIWar); + + if (logger.isDebugEnabled()) { + logger.debug("Starting HTTP embedded server on port ({}) at bind-address ({})...", + ((ServerConnector) this.httpServer.getConnectors()[0]).getPort(), bindAddress); + } + + this.httpServer = JettyHelper.startJetty(this.httpServer); + logger.info("HTTP service started successfully...!!"); + } + } catch (Exception e) { + stopHttpService();// Jetty needs to be stopped even if it has failed to + // start. Some of the threads are left behind even if + // server.start() fails due to an exception + throw new RuntimeException("HTTP service failed to start due to " + e.getMessage()); + } + } + + private void stopHttpService() { + if (this.httpServer != null) { + logger.info("Stopping the HTTP service..."); + try { + this.httpServer.stop(); + } catch (Exception e) { + logger.warn("Failed to stop the HTTP service because: {}", e.getMessage(), e); + } finally { + try { + this.httpServer.destroy(); + } catch (Exception ignore) { + logger.error("Failed to properly release resources held by the HTTP service: {}", + ignore.getMessage(), ignore); + } finally { + this.httpServer = null; + System.clearProperty("catalina.base"); + System.clearProperty("catalina.home"); + } + } + } + } + + /** + * This method will create a REPLICATED region named _ParameterizedQueries__. + * In developer REST APIs, this region will be used to store the queryId and + * queryString as a key and value respectively. + */ + public static void createParameterizedQueryRegion() { + try { + if (logger.isDebugEnabled()) { + logger.debug("Starting creation of __ParameterizedQueries__ region"); + } + GemFireCacheImpl cache = (GemFireCacheImpl) CacheFactory.getAnyInstance(); + if (cache != null) { + // cache.getCacheConfig().setPdxReadSerialized(true); + final InternalRegionArguments regionArguments = new InternalRegionArguments(); + regionArguments.setIsUsedForMetaRegion(true); + final AttributesFactory attributesFactory = new AttributesFactory(); + + attributesFactory.setConcurrencyChecksEnabled(false); + attributesFactory.setDataPolicy(DataPolicy.REPLICATE); + attributesFactory.setKeyConstraint(String.class); + attributesFactory.setScope(Scope.DISTRIBUTED_NO_ACK); + attributesFactory.setStatisticsEnabled(false); + attributesFactory.setValueConstraint(String.class); + + final RegionAttributes regionAttributes = attributesFactory.create(); + + cache.createVMRegion("__ParameterizedQueries__", regionAttributes, regionArguments); + if (logger.isDebugEnabled()) { + logger.debug("Successfully created __ParameterizedQueries__ region"); + } + } else { + logger.error("Cannot create ParameterizedQueries Region as no cache found!"); + } - } catch (Exception e) { ++ } ++ catch (Exception e) { ++ if (logger.isDebugEnabled()) { ++ logger.debug("Error creating __ParameterizedQueries__ Region with cause {}",e.getMessage(), e); ++ } ++ } ++ } ++ ++ /** ++ * This method will create a REPLICATED region named _ParameterizedQueries__. ++ * In developer REST APIs, this region will be used to store the queryId and queryString as a key and value respectively. ++ */ ++ public static void createTokenToAuthzRequestRegion(){ ++ try { ++ if (logger.isDebugEnabled()) { ++ logger.debug("Starting creation of ({}) region", AUTH_METADATA_REGION); ++ } ++ GemFireCacheImpl cache = (GemFireCacheImpl)CacheFactory.getAnyInstance(); ++ if (cache != null) { ++ //cache.getCacheConfig().setPdxReadSerialized(true); ++ final InternalRegionArguments regionArguments = new InternalRegionArguments(); ++ regionArguments.setIsUsedForMetaRegion(true); ++ final AttributesFactory> attributesFactory = new AttributesFactory>(); ++ ++ attributesFactory.setConcurrencyChecksEnabled(false); ++ attributesFactory.setDataPolicy(DataPolicy.NORMAL); ++ attributesFactory.setKeyConstraint(String.class); ++ attributesFactory.setScope(Scope.LOCAL); ++ attributesFactory.setStatisticsEnabled(false); ++ //attributesFactory.setValueConstraint(AuthorizeRequest.class); ++ ++ final RegionAttributes> regionAttributes = attributesFactory.create(); ++ ++ cache.createVMRegion(AUTH_METADATA_REGION, regionAttributes, regionArguments); ++ if (logger.isDebugEnabled()) { ++ logger.debug("Successfully created ({}) region", AUTH_METADATA_REGION); ++ } ++ }else { ++ logger.error("Cannot create ({}) Region as no cache found!", AUTH_METADATA_REGION); ++ } ++ } ++ catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Error creating __ParameterizedQueries__ Region with cause {}", + e.getMessage(), e); + } + } + } + }