From ae29d65f14aab6b742bd1972865de002fbe83577 Mon Sep 17 00:00:00 2001 From: Steven Hawkins Date: Mon, 5 Nov 2018 16:04:46 -0500 Subject: [PATCH] TEIID-5524 adding minimal standalone jmx (#1106) --- .../org/teiid/adminapi/EngineStatistics.java | 68 +---------- .../teiid/adminapi/EngineStatisticsBean.java | 89 +++++++++++++++ .../main/java/org/teiid/adminapi/Request.java | 50 +------- .../java/org/teiid/adminapi/RequestBean.java | 79 +++++++++++++ .../main/java/org/teiid/adminapi/Session.java | 79 +------------ .../java/org/teiid/adminapi/SessionBean.java | 100 ++++++++++++++++ .../teiid/adminapi/WorkerPoolStatistics.java | 49 +------- .../adminapi/WorkerPoolStatisticsBean.java | 71 ++++++++++++ .../teiid/adminapi/impl/RequestMetadata.java | 5 + .../teiid/dqp/internal/process/DQPCore.java | 6 +- .../internal/process/SessionAwareCache.java | 6 +- .../java/org/teiid/jboss/DQPCoreService.java | 17 ++- .../org/teiid/runtime/EmbeddedServer.java | 6 + .../java/org/teiid/runtime/jmx/Cache.java | 51 +++++++++ .../java/org/teiid/runtime/jmx/CacheBean.java | 34 ++++++ .../org/teiid/runtime/jmx/JMXService.java | 102 +++++++++++++++++ .../java/org/teiid/runtime/jmx/Teiid.java | 108 ++++++++++++++++++ .../java/org/teiid/runtime/jmx/TeiidBean.java | 85 ++++++++++++++ 18 files changed, 757 insertions(+), 248 deletions(-) create mode 100644 admin/src/main/java/org/teiid/adminapi/EngineStatisticsBean.java create mode 100644 admin/src/main/java/org/teiid/adminapi/RequestBean.java create mode 100644 admin/src/main/java/org/teiid/adminapi/SessionBean.java create mode 100644 admin/src/main/java/org/teiid/adminapi/WorkerPoolStatisticsBean.java create mode 100644 runtime/src/main/java/org/teiid/runtime/jmx/Cache.java create mode 100644 runtime/src/main/java/org/teiid/runtime/jmx/CacheBean.java create mode 100644 runtime/src/main/java/org/teiid/runtime/jmx/JMXService.java create mode 100644 runtime/src/main/java/org/teiid/runtime/jmx/Teiid.java create mode 100644 runtime/src/main/java/org/teiid/runtime/jmx/TeiidBean.java diff --git a/admin/src/main/java/org/teiid/adminapi/EngineStatistics.java b/admin/src/main/java/org/teiid/adminapi/EngineStatistics.java index a1b4dbb039..4a1595e64a 100644 --- a/admin/src/main/java/org/teiid/adminapi/EngineStatistics.java +++ b/admin/src/main/java/org/teiid/adminapi/EngineStatistics.java @@ -17,72 +17,6 @@ */ package org.teiid.adminapi; -public interface EngineStatistics extends AdminObject, DomainAware { - - /** - * Active Number of Sessions in the engine - * @return - */ - int getSessionCount(); - - /** - * Total amount memory used by buffer manager for active queries and cached queries - * @return - */ - long getTotalMemoryUsedInKB(); - - /** - * Total memory used by buffer manager for active plans - * @return - */ - long getMemoryUsedByActivePlansInKB(); - - /** - * Number of writes to disk by buffer manager to save the overflow from memory - * @return - */ - long getDiskWriteCount(); - - /** - * Number reads from the disk used by buffer manager that cache overflowed. - * @return - */ - long getDiskReadCount(); - - /** - * Total number of cache reads, includes disk and soft-cache references - * @return - */ - long getCacheReadCount(); - - /** - * Total number of cache writes, includes disk and soft-cache references - * @return - */ - long getCacheWriteCount(); - - /** - * Disk space used by buffer manager to save overflowed memory contents - * @return - */ - long getDiskSpaceUsedInMB(); - - /** - * Current active plan count - * @return - */ - int getActivePlanCount(); - - /** - * Current number of waiting plans in the queue - * @return - */ - int getWaitPlanCount(); - - /** - * High water mark for the waiting plans - * @return - */ - int getMaxWaitPlanWaterMark(); +public interface EngineStatistics extends EngineStatisticsBean, AdminObject, DomainAware { } diff --git a/admin/src/main/java/org/teiid/adminapi/EngineStatisticsBean.java b/admin/src/main/java/org/teiid/adminapi/EngineStatisticsBean.java new file mode 100644 index 0000000000..44ff0a42e5 --- /dev/null +++ b/admin/src/main/java/org/teiid/adminapi/EngineStatisticsBean.java @@ -0,0 +1,89 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.adminapi; + +public interface EngineStatisticsBean { + + /** + * Active Number of Sessions in the engine + * @return + */ + int getSessionCount(); + + /** + * Total amount memory used by buffer manager for active queries and cached queries + * @return + */ + long getTotalMemoryUsedInKB(); + + /** + * Total memory used by buffer manager for active plans + * @return + */ + long getMemoryUsedByActivePlansInKB(); + + /** + * Number of writes to disk by buffer manager to save the overflow from memory + * @return + */ + long getDiskWriteCount(); + + /** + * Number reads from the disk used by buffer manager that cache overflowed. + * @return + */ + long getDiskReadCount(); + + /** + * Total number of cache reads, includes disk and soft-cache references + * @return + */ + long getCacheReadCount(); + + /** + * Total number of cache writes, includes disk and soft-cache references + * @return + */ + long getCacheWriteCount(); + + /** + * Disk space used by buffer manager to save overflowed memory contents + * @return + */ + long getDiskSpaceUsedInMB(); + + /** + * Current active plan count + * @return + */ + int getActivePlanCount(); + + /** + * Current number of waiting plans in the queue + * @return + */ + int getWaitPlanCount(); + + /** + * High water mark for the waiting plans + * @return + */ + int getMaxWaitPlanWaterMark(); + +} diff --git a/admin/src/main/java/org/teiid/adminapi/Request.java b/admin/src/main/java/org/teiid/adminapi/Request.java index 8ab9ed4012..d12cb37a1a 100644 --- a/admin/src/main/java/org/teiid/adminapi/Request.java +++ b/admin/src/main/java/org/teiid/adminapi/Request.java @@ -30,7 +30,7 @@ *

A request is identified by a numbers separated by '|'. usually in they are arranged * in the pattern [session]|[request] or [session]|[request]|[source request]

*/ -public interface Request extends AdminObject, DomainAware { +public interface Request extends RequestBean, AdminObject, DomainAware { public enum ProcessingState { PROCESSING, @@ -44,57 +44,9 @@ public enum ThreadState { IDLE } - /** - * Get the ExecutionId for a Request - * @return ExecutionId - */ - public long getExecutionId(); - - /** - * Get the SessionID for a Request - * - * @return String SessionID - */ - public String getSessionId(); - - /** - * Get the SQL Command sent to the Server for a Request - * - * @return SQL Command - */ - public String getCommand(); - - /** - * Get when the processing began for this Request - * @return Date processing began - */ - public long getStartTime(); - - /** - * Get the TransactionID of the Request - * - * @return String of TransactionID if in a transaction - */ - public String getTransactionId(); - /** * @return Returns whether this is a Source Request. */ public boolean sourceRequest(); - /** - * @return In the case that this is a source request this represents the node id. Otherwise null - */ - public Integer getNodeId(); - - /** - * @return The request state - */ - ProcessingState getState(); - - /** - * @return The thread state - */ - ThreadState getThreadState(); - } diff --git a/admin/src/main/java/org/teiid/adminapi/RequestBean.java b/admin/src/main/java/org/teiid/adminapi/RequestBean.java new file mode 100644 index 0000000000..dc5fd83289 --- /dev/null +++ b/admin/src/main/java/org/teiid/adminapi/RequestBean.java @@ -0,0 +1,79 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.adminapi; + +import org.teiid.adminapi.Request.ProcessingState; +import org.teiid.adminapi.Request.ThreadState; + +public interface RequestBean { + + /** + * Get the ExecutionId for a Request + * @return ExecutionId + */ + public long getExecutionId(); + + /** + * Get the SessionID for a Request + * + * @return String SessionID + */ + public String getSessionId(); + + /** + * Get the SQL Command sent to the Server for a Request + * + * @return SQL Command + */ + public String getCommand(); + + /** + * Get when the processing began for this Request + * @return Date processing began + */ + public long getStartTime(); + + /** + * Get the TransactionID of the Request + * + * @return String of TransactionID if in a transaction + */ + public String getTransactionId(); + + /** + * @return Returns whether this is a Source Request. + */ + public boolean isSourceRequest(); + + /** + * @return In the case that this is a source request this represents the node id. Otherwise null + */ + public Integer getNodeId(); + + /** + * @return The request state + */ + ProcessingState getState(); + + /** + * @return The thread state + */ + ThreadState getThreadState(); + +} diff --git a/admin/src/main/java/org/teiid/adminapi/Session.java b/admin/src/main/java/org/teiid/adminapi/Session.java index e780edcedf..26a9f10a98 100644 --- a/admin/src/main/java/org/teiid/adminapi/Session.java +++ b/admin/src/main/java/org/teiid/adminapi/Session.java @@ -24,83 +24,6 @@ * * A user is allowed to have multiple sessions active simultaneously. */ -public interface Session extends AdminObject, DomainAware { +public interface Session extends SessionBean, AdminObject, DomainAware { - /** - * Get the Last time Client has check to see if the server is still available - * - * @return Date of the last ping to the server. - */ - public long getLastPingTime(); - - - /** - * Get the Application Name - * - * @return String of the Application Name - */ - public String getApplicationName(); - - /** - * Get the unique Teiid session - * within a given Teiid System - * - * @return String of the Session ID - */ - public String getSessionId(); - - /** - * Get User Name for this Session - *
It will not include the Security Domain, see {@link #getSecurityDomain()} - * @return String of UserName - */ - public String getUserName(); - - /** - * Get the VDB Name for this Session - * - * @return String name of the VDB - */ - public String getVDBName(); - - /** - * Get the VDB Version for this Session - * - * @return String name/number of the VDB Version - */ - public String getVDBVersion(); - - /** - * Get the IPAddress for this Session. Note this value is reported from the client. - * @return - */ - public String getIPAddress(); - - - /** - * Get the host name of the machine the client is - * accessing from. Note this value is reported from the client. - * @return - */ - public String getClientHostName(); - - /** - * Get the client hardware (typically MAC) address. Note this value is reported from the client. - * @return the hardware address as a hex string or null if not available. - */ - public String getClientHardwareAddress(); - - /** - * Get the time the {@link Session} was created. - * @return - */ - public long getCreatedTime(); - - - /** - * Security Domain user logged into currently - * @return - */ - public String getSecurityDomain(); - } \ No newline at end of file diff --git a/admin/src/main/java/org/teiid/adminapi/SessionBean.java b/admin/src/main/java/org/teiid/adminapi/SessionBean.java new file mode 100644 index 0000000000..d0149c5d30 --- /dev/null +++ b/admin/src/main/java/org/teiid/adminapi/SessionBean.java @@ -0,0 +1,100 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.adminapi; + +public interface SessionBean { + + /** + * Get the Last time Client has check to see if the server is still available + * + * @return Date of the last ping to the server. + */ + public long getLastPingTime(); + + + /** + * Get the Application Name + * + * @return String of the Application Name + */ + public String getApplicationName(); + + /** + * Get the unique Teiid session + * within a given Teiid System + * + * @return String of the Session ID + */ + public String getSessionId(); + + /** + * Get User Name for this Session + *
It will not include the Security Domain, see {@link #getSecurityDomain()} + * @return String of UserName + */ + public String getUserName(); + + /** + * Get the VDB Name for this Session + * + * @return String name of the VDB + */ + public String getVDBName(); + + /** + * Get the VDB Version for this Session + * + * @return String name/number of the VDB Version + */ + public String getVDBVersion(); + + /** + * Get the IPAddress for this Session. Note this value is reported from the client. + * @return + */ + public String getIPAddress(); + + + /** + * Get the host name of the machine the client is + * accessing from. Note this value is reported from the client. + * @return + */ + public String getClientHostName(); + + /** + * Get the client hardware (typically MAC) address. Note this value is reported from the client. + * @return the hardware address as a hex string or null if not available. + */ + public String getClientHardwareAddress(); + + /** + * Get the time the {@link Session} was created. + * @return + */ + public long getCreatedTime(); + + + /** + * Security Domain user logged into currently + * @return + */ + public String getSecurityDomain(); + +} diff --git a/admin/src/main/java/org/teiid/adminapi/WorkerPoolStatistics.java b/admin/src/main/java/org/teiid/adminapi/WorkerPoolStatistics.java index 6b0b42f2d3..a5588f9fe2 100644 --- a/admin/src/main/java/org/teiid/adminapi/WorkerPoolStatistics.java +++ b/admin/src/main/java/org/teiid/adminapi/WorkerPoolStatistics.java @@ -17,53 +17,6 @@ */ package org.teiid.adminapi; -public interface WorkerPoolStatistics extends AdminObject, DomainAware{ +public interface WorkerPoolStatistics extends WorkerPoolStatisticsBean, AdminObject, DomainAware{ - /** - * Current active thread count - * @return - */ - public int getActiveThreads(); - - /** - * Highest Active threads recorded so far - * @return - */ - public int getHighestActiveThreads(); - - - /** - * Queue Name - * @return - */ - public String getQueueName(); - - - /** - * Max number of active threads allowed - * @return - */ - public int getMaxThreads(); - - /** - * @return Returns the number of requests queued. - * @since 4.3 - */ - public int getQueued(); - - /** - * @return The number of completed tasks - */ - long getTotalCompleted(); - - - /** - * @return The number of submitted tasks - */ - long getTotalSubmitted(); - - /** - * @return Returns the highest queue size - */ - public int getHighestQueued(); } diff --git a/admin/src/main/java/org/teiid/adminapi/WorkerPoolStatisticsBean.java b/admin/src/main/java/org/teiid/adminapi/WorkerPoolStatisticsBean.java new file mode 100644 index 0000000000..b2ba7c86b1 --- /dev/null +++ b/admin/src/main/java/org/teiid/adminapi/WorkerPoolStatisticsBean.java @@ -0,0 +1,71 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.adminapi; + +public interface WorkerPoolStatisticsBean { + + /** + * Current active thread count + * @return + */ + public int getActiveThreads(); + + /** + * Highest Active threads recorded so far + * @return + */ + public int getHighestActiveThreads(); + + + /** + * Queue Name + * @return + */ + public String getQueueName(); + + + /** + * Max number of active threads allowed + * @return + */ + public int getMaxThreads(); + + /** + * @return Returns the number of requests queued. + * @since 4.3 + */ + public int getQueued(); + + /** + * @return The number of completed tasks + */ + long getTotalCompleted(); + + + /** + * @return The number of submitted tasks + */ + long getTotalSubmitted(); + + /** + * @return Returns the highest queue size + */ + public int getHighestQueued(); + +} diff --git a/admin/src/main/java/org/teiid/adminapi/impl/RequestMetadata.java b/admin/src/main/java/org/teiid/adminapi/impl/RequestMetadata.java index 3a810a5f5c..45402efe94 100644 --- a/admin/src/main/java/org/teiid/adminapi/impl/RequestMetadata.java +++ b/admin/src/main/java/org/teiid/adminapi/impl/RequestMetadata.java @@ -153,4 +153,9 @@ public String toString() { return str.toString(); } + + @Override + public boolean isSourceRequest() { + return sourceRequest; + } } diff --git a/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java b/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java index 03354cfbc3..d8eb197843 100644 --- a/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java +++ b/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java @@ -659,6 +659,10 @@ SessionAwareCache getRsCache() { return rsCache; } + public SessionAwareCache getResltSetCache() { + return rsCache; + } + int getProcessorTimeSlice() { return this.config.getTimeSliceInMilli(); } @@ -946,7 +950,7 @@ public int getMaxActivePlans() { return maxActivePlans; } - SessionAwareCache getPrepPlanCache() { + public SessionAwareCache getPrepPlanCache() { return prepPlanCache; } diff --git a/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java b/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java index b17d51311d..5441ce81a8 100644 --- a/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java +++ b/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java @@ -412,10 +412,14 @@ public boolean isTransactional() { return this.localCache.isTransactional() || this.distributedCache.isTransactional(); } + public double getCacheHitRatio() { + return this.getRequestCount() == 0?0:((double)this.getCacheHitCount()/this.getRequestCount())*100; + } + public CacheStatisticsMetadata buildCacheStats(String name) { CacheStatisticsMetadata stats = new CacheStatisticsMetadata(); stats.setName(name); - stats.setHitRatio(this.getRequestCount() == 0?0:((double)this.getCacheHitCount()/this.getRequestCount())*100); + stats.setHitRatio(getCacheHitRatio()); stats.setTotalEntries(this.getTotalCacheEntries()); stats.setRequestCount(this.getRequestCount()); return stats; diff --git a/jboss-integration/src/main/java/org/teiid/jboss/DQPCoreService.java b/jboss-integration/src/main/java/org/teiid/jboss/DQPCoreService.java index 26df137d86..70eab2f9ad 100644 --- a/jboss-integration/src/main/java/org/teiid/jboss/DQPCoreService.java +++ b/jboss-integration/src/main/java/org/teiid/jboss/DQPCoreService.java @@ -26,6 +26,7 @@ import javax.transaction.TransactionManager; import org.jboss.msc.service.Service; +import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.StartContext; import org.jboss.msc.service.StopContext; import org.jboss.msc.value.InjectedValue; @@ -47,6 +48,7 @@ import org.teiid.logging.LogConstants; import org.teiid.logging.LogManager; import org.teiid.logging.MessageLevel; +import org.teiid.runtime.jmx.JMXService; import org.teiid.services.InternalEventDistributorFactory; @@ -55,6 +57,7 @@ public class DQPCoreService extends DQPConfiguration implements Serializable, Se private transient TransactionServerImpl transactionServerImpl = new TransactionServerImpl(); private transient DQPCore dqpCore = new DQPCore(); + private transient JMXService jmx; private final InjectedValue workManagerInjector = new InjectedValue(); private final InjectedValue xaTerminatorInjector = new InjectedValue(); @@ -83,7 +86,11 @@ public void start(final StartContext context) { this.dqpCore.setResultsetCache(getResultSetCacheInjector().getValue()); this.dqpCore.setPreparedPlanCache(getPreparedPlanCacheInjector().getValue()); this.dqpCore.start(this); - + + final SessionService sessionService = (SessionService) context.getController().getServiceContainer().getService(TeiidServiceNames.SESSION).getValue(); + ServiceController repo = context.getController().getServiceContainer().getRequiredService(TeiidServiceNames.BUFFER_MGR); + this.jmx = new JMXService(this.dqpCore, BufferManagerService.class.cast(repo.getService()), sessionService); + this.jmx.registerBeans(); // add vdb life cycle listeners getVdbRepository().addListener(new VDBLifeCycleListener() { @@ -91,8 +98,7 @@ public void start(final StartContext context) { @Override public void removed(String name, CompositeVDB vdb) { // terminate all the previous sessions - SessionService sessionService = (SessionService) context.getController().getServiceContainer().getService(TeiidServiceNames.SESSION).getValue(); - Collection sessions = sessionService.getSessionsLoggedInToVDB(vdb.getVDBKey()); + Collection sessions = sessionService.getSessionsLoggedInToVDB(vdb.getVDBKey()); for (SessionMetadata session:sessions) { sessionService.terminateSession(session.getSessionId(), null); } @@ -140,7 +146,10 @@ public void stop(StopContext context) { } catch(TeiidRuntimeException e) { // this bean is already shutdown } - + if (this.jmx != null) { + jmx.unregisterBeans(); + jmx = null; + } LogManager.logInfo(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50002, new Date(System.currentTimeMillis()).toString())); } diff --git a/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java b/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java index 36bc0b07cf..6175af5559 100644 --- a/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java +++ b/runtime/src/main/java/org/teiid/runtime/EmbeddedServer.java @@ -122,6 +122,7 @@ import org.teiid.query.validator.ValidatorFailure; import org.teiid.query.validator.ValidatorReport; import org.teiid.replication.jgroups.JGroupsObjectReplicator; +import org.teiid.runtime.jmx.JMXService; import org.teiid.services.AbstractEventDistributorFactoryService; import org.teiid.services.BufferServiceImpl; import org.teiid.services.SessionServiceImpl; @@ -328,6 +329,7 @@ public ClassLoader getCallerClassloader() { private ShutDownListener shutdownListener = new ShutDownListener(); private SimpleChannelFactory channelFactory; private NodeTracker nodeTracker = null; + private JMXService jmxService; public EmbeddedServer() { @@ -463,6 +465,8 @@ public Object invoke(Object proxy, Method method, Object[] args) } this.shutdownListener.setBootInProgress(false); this.shutdownListener.started(); + this.jmxService = new JMXService(this.dqp, this.bufferService, this.sessionService); + this.jmxService.registerBeans(); running = true; } @@ -945,6 +949,8 @@ public synchronized void stop() { dqp = null; running = false; this.shutdownListener.setShutdownInProgress(false); + this.jmxService.unregisterBeans(); + this.jmxService = null; } private synchronized void checkStarted() { diff --git a/runtime/src/main/java/org/teiid/runtime/jmx/Cache.java b/runtime/src/main/java/org/teiid/runtime/jmx/Cache.java new file mode 100644 index 0000000000..5b539d4913 --- /dev/null +++ b/runtime/src/main/java/org/teiid/runtime/jmx/Cache.java @@ -0,0 +1,51 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.runtime.jmx; + +import org.teiid.dqp.internal.process.SessionAwareCache; + +class Cache implements CacheBean { + + private SessionAwareCache cache; + + public Cache(SessionAwareCache cache) { + this.cache = cache; + } + + @Override + public double getHitRatio() { + return cache.getCacheHitRatio(); + } + + @Override + public int getTotalEntries() { + return cache.getTotalCacheEntries(); + } + + @Override + public long getRequestCount() { + return cache.getRequestCount(); + } + + @Override + public void clear() { + cache.clearAll(); + } + +} \ No newline at end of file diff --git a/runtime/src/main/java/org/teiid/runtime/jmx/CacheBean.java b/runtime/src/main/java/org/teiid/runtime/jmx/CacheBean.java new file mode 100644 index 0000000000..a7f1cb5409 --- /dev/null +++ b/runtime/src/main/java/org/teiid/runtime/jmx/CacheBean.java @@ -0,0 +1,34 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.runtime.jmx; + +import javax.management.MXBean; + +@MXBean +public interface CacheBean { + + double getHitRatio(); + + int getTotalEntries(); + + long getRequestCount(); + + public void clear(); + +} diff --git a/runtime/src/main/java/org/teiid/runtime/jmx/JMXService.java b/runtime/src/main/java/org/teiid/runtime/jmx/JMXService.java new file mode 100644 index 0000000000..d0859e6dac --- /dev/null +++ b/runtime/src/main/java/org/teiid/runtime/jmx/JMXService.java @@ -0,0 +1,102 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.runtime.jmx; + +import java.lang.management.ManagementFactory; +import java.util.HashSet; +import java.util.Set; + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.OperationsException; + +import org.teiid.dqp.internal.process.DQPCore; +import org.teiid.dqp.service.SessionService; +import org.teiid.logging.LogConstants; +import org.teiid.logging.LogManager; +import org.teiid.runtime.EmbeddedConfiguration; +import org.teiid.runtime.EmbeddedServer; +import org.teiid.services.BufferServiceImpl; + +/** + * Registers Teiid beans with JMX. Assumes only 1 Teiid will be registered + */ +public class JMXService { + + public static String TEIID = "org.teiid:type=Runtime"; //$NON-NLS-1$ + public static String CACHE_PREFIX = "org.teiid:type=Cache,name="; //$NON-NLS-1$ + + private DQPCore dqp; + private BufferServiceImpl bufferService; + private SessionService sessionService; + private MBeanServer server; + private Set registerdBeans = new HashSet<>(); + + public JMXService(DQPCore dqpCore, BufferServiceImpl bufferServiceImpl, + SessionService sessionService) { + this.dqp = dqpCore; + this.bufferService = bufferServiceImpl; + this.sessionService = sessionService; + server = ManagementFactory.getPlatformMBeanServer(); + } + + void setServer(MBeanServer server) { + this.server = server; + } + + public synchronized void registerBeans() { + try { + register(new Teiid(dqp, sessionService, bufferService), TEIID); + register(new Cache(dqp.getPrepPlanCache()), + CACHE_PREFIX + "PreparedPlan"); //$NON-NLS-1$ + register(new Cache(dqp.getResltSetCache()), + CACHE_PREFIX + "ResultSet"); //$NON-NLS-1$ + } catch (MBeanRegistrationException | OperationsException e) { + LogManager.logWarning(LogConstants.CTX_RUNTIME, e, + "JMX Registration Exception - it's likely another Teiid instance is running in this VM"); //$NON-NLS-1$ + } + } + + public synchronized void unregisterBeans() { + registerdBeans.forEach(name -> { + try { + this.server.unregisterMBean(new ObjectName(name)); + } catch (MBeanRegistrationException | InstanceNotFoundException + | MalformedObjectNameException e) { + //ignore + } + }); + registerdBeans.clear(); + } + + void register(Object mbean, String name) + throws OperationsException, MBeanRegistrationException { + this.server.registerMBean(mbean, new ObjectName(name)); + this.registerdBeans.add(name); + } + + public static void main(String[] args) throws Exception { + EmbeddedServer es = new EmbeddedServer(); + es.start(new EmbeddedConfiguration()); + Thread.sleep(1000000); + } +} diff --git a/runtime/src/main/java/org/teiid/runtime/jmx/Teiid.java b/runtime/src/main/java/org/teiid/runtime/jmx/Teiid.java new file mode 100644 index 0000000000..70b04abad9 --- /dev/null +++ b/runtime/src/main/java/org/teiid/runtime/jmx/Teiid.java @@ -0,0 +1,108 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.runtime.jmx; + +import java.util.ArrayList; +import java.util.List; + +import org.teiid.adminapi.AdminException; +import org.teiid.adminapi.AdminProcessingException; +import org.teiid.adminapi.EngineStatisticsBean; +import org.teiid.adminapi.RequestBean; +import org.teiid.adminapi.SessionBean; +import org.teiid.adminapi.WorkerPoolStatisticsBean; +import org.teiid.client.plan.PlanNode; +import org.teiid.core.TeiidComponentException; +import org.teiid.core.TeiidRuntimeException; +import org.teiid.dqp.internal.process.DQPCore; +import org.teiid.dqp.service.SessionService; +import org.teiid.dqp.service.SessionServiceException; +import org.teiid.runtime.EmbeddedAdminFactory; +import org.teiid.services.BufferServiceImpl; + +class Teiid implements TeiidBean { + + private final DQPCore dqp; + private final SessionService sessionService; + private final BufferServiceImpl bufferService; + + public Teiid(DQPCore dqp, SessionService sessionService, + BufferServiceImpl bufferService) { + this.dqp = dqp; + this.sessionService = sessionService; + this.bufferService = bufferService; + } + + @Override + public String getQueryPlan(String sessionId, long executionId) { + PlanNode plan = this.dqp.getPlan(sessionId, executionId); + if (plan == null) { + return null; + } + return plan.toXml(); + } + + @Override + public List getRequests() + throws AdminException { + return new ArrayList<>(dqp.getRequests()); + } + + @Override + public List getSessions() + throws AdminException { + return new ArrayList<>(sessionService.getActiveSessions()); + } + + @Override + public void terminateSession(String sessionId) throws AdminException { + this.dqp.terminateSession(sessionId); + } + + @Override + public void cancelRequest(String sessionId, long executionId) + throws AdminException { + try { + this.dqp.cancelRequest(sessionId, executionId); + } catch (TeiidComponentException e) { + throw new AdminProcessingException(e); + } + } + + @Override + public void terminateTransaction(String transactionId) + throws AdminException { + this.dqp.terminateTransaction(transactionId); + } + + @Override + public WorkerPoolStatisticsBean getWorkerPoolStatisticsBean() { + return this.dqp.getWorkerPoolStatistics(); + } + + @Override + public EngineStatisticsBean getEngineStatisticsBean() { + try { + return EmbeddedAdminFactory.createEngineStats(sessionService.getActiveSessionsCount(), bufferService, dqp); + } catch (SessionServiceException e) { + throw new TeiidRuntimeException(e); + } + } + +} \ No newline at end of file diff --git a/runtime/src/main/java/org/teiid/runtime/jmx/TeiidBean.java b/runtime/src/main/java/org/teiid/runtime/jmx/TeiidBean.java new file mode 100644 index 0000000000..43a7e96646 --- /dev/null +++ b/runtime/src/main/java/org/teiid/runtime/jmx/TeiidBean.java @@ -0,0 +1,85 @@ +/* + * Copyright Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags and + * the COPYRIGHT.txt file distributed with this work. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.teiid.runtime.jmx; + +import java.util.List; + +import javax.management.MXBean; + +import org.teiid.adminapi.AdminException; +import org.teiid.adminapi.EngineStatisticsBean; +import org.teiid.adminapi.RequestBean; +import org.teiid.adminapi.Session; +import org.teiid.adminapi.SessionBean; +import org.teiid.adminapi.WorkerPoolStatisticsBean; + +@MXBean +public interface TeiidBean { + + /** + * Get the Query Plan for the given session with provided execution id. + * @param sessionId + * @param executionId + * @return + */ + String getQueryPlan(String sessionId, long executionId); + + /** + * Get the all Requests that are currently in process + * @return Collection of {@link RequestBean} + */ + List getRequests() throws AdminException; + + /** + * Get all the current Sessions. + * @return Collection of {@link Session} + */ + List getSessions() throws AdminException; + + /** + * Terminate the Session + * + * @param identifier Session Identifier {@link org.teiid.adminapi.Session}. + * No wild cards currently supported, must be explicit + * @throws AdminException + */ + void terminateSession(String sessionId) throws AdminException; + + /** + * Cancel Request + * + * @param sessionId session Identifier for the request. + * @param executionId request Identifier + * + * @throws AdminException + */ + void cancelRequest(String sessionId, long executionId) throws AdminException; + + /** + * Mark the given global transaction as rollback only. + * @param transactionId + * @throws AdminException + */ + void terminateTransaction(String transactionId) throws AdminException; + + WorkerPoolStatisticsBean getWorkerPoolStatisticsBean(); + + EngineStatisticsBean getEngineStatisticsBean(); + +}