001/* 002 * ============================================================================ 003 * Copyright © 2002-2026 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * Licensed to the public under the agreements of the GNU Lesser General Public 007 * License, version 3.0 (the "License"). You may obtain a copy of the License at 008 * 009 * http://www.gnu.org/licenses/lgpl.html 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package org.tquadrat.foundation.perflog.remote; 019 020import static org.apiguardian.api.API.Status.STABLE; 021import static org.tquadrat.foundation.mgmt.JMXUtils.composeServiceURL; 022 023import javax.management.AttributeNotFoundException; 024import javax.management.DynamicMBean; 025import javax.management.InstanceNotFoundException; 026import javax.management.IntrospectionException; 027import javax.management.MBeanException; 028import javax.management.MBeanInfo; 029import javax.management.NotificationListener; 030import javax.management.ObjectName; 031import javax.management.ReflectionException; 032import javax.management.remote.JMXServiceURL; 033 034import java.io.IOException; 035import java.net.MalformedURLException; 036 037import org.apiguardian.api.API; 038import org.tquadrat.foundation.annotation.ClassVersion; 039import org.tquadrat.foundation.perflog.remote.internal.PerfLogRemoteImpl; 040 041/** 042 * <p>{@summary The declaration of a remote client for the Foundation 043 * Performance Logging and Monitoring.}</p> 044 * 045 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 046 * @version $Id: PerfLogRemote.java 1229 2026-05-04 19:11:41Z tquadrat $ 047 * @since 0.25.0 048 * 049 * @UMLGraph.link 050 */ 051@ClassVersion( sourceVersion = "$Id: PerfLogRemote.java 1229 2026-05-04 19:11:41Z tquadrat $" ) 052@API( status = STABLE, since = "0.25.0" ) 053public sealed interface PerfLogRemote extends AutoCloseable 054 permits PerfLogRemoteImpl 055{ 056 /*-----------*\ 057 ====** Constants **======================================================== 058 \*-----------*/ 059 /** 060 * <p>{@summary The domain name part of the 061 * {@link ObjectName} 062 * identifying the Performance Logging MBean 063 * in the MBean server: {@value}}.</p> 064 */ 065 public static final String DOMAIN_NAME = "org.tquadrat.foundation.PerfLog"; 066 067 /** 068 * The name of the JSON boolean that holds the aborted flag: 069 * {@value}. 070 */ 071 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 072 public static final String JSONField_Aborted = "Aborted"; 073 074 /** 075 * The name of the JSON Number that holds the number of aborted runs for 076 * the performance section: {@value}. 077 */ 078 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 079 public static final String JSONField_AbortedRuns = "Aborted"; 080 081 /** 082 * The name of the JSON String that holds the cause for the abort of a 083 * performance section: {@value}. 084 */ 085 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 086 public static final String JSONField_Cause = "Cause"; 087 088 /** 089 * The name of the JSON Number that holds the number of completed runs for 090 * the performance section: {@value}. 091 */ 092 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 093 public static final String JSONField_CompletedRuns = "Completed"; 094 095 /** 096 * The name of the JSON Object that holds the performance section context: 097 * {@value}. 098 */ 099 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 100 public static final String JSONField_Context = "Context"; 101 102 /** 103 * The name of the JSON Object that holds the elapsed time: {@value}. 104 */ 105 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 106 public static final String JSONField_ElapsedTime = "ElapsedTime"; 107 108 /** 109 * The name of the JSON Object that holds an error message: {@value}. 110 */ 111 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 112 public static final String JSONField_Error = "Error"; 113 114 /** 115 * The name of the JSON boolean that holds threshold exceeded flag: 116 * {@value}. 117 */ 118 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 119 public static final String JSONField_ExceededThreshold = "ExceededThreshold"; 120 121 /** 122 * The name of the JSON String that holds the time of the first start of 123 * the performance section: {@value}. 124 */ 125 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 126 public static final String JSONField_FirstStart = "FirstStart"; 127 128 /** 129 * The name of the JSON String that holds the time when the performance 130 * section was last updated: {@value}. 131 */ 132 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 133 public static final String JSONField_LastUpdated = "LastUpdated"; 134 135 /** 136 * The name of the JSON String that holds the text of an error message: 137 * {@value}. 138 */ 139 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 140 public static final String JSONField_Message = "Message"; 141 142 /** 143 * The name of the JSON Object that holds the data from the performance 144 * section: {@value}. 145 */ 146 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 147 public static final String JSONField_Section = "PerformanceSection"; 148 149 /** 150 * The name of the JSON String that holds the description of the 151 * performance section: {@value}. 152 */ 153 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 154 public static final String JSONField_SectionDescription = "Description"; 155 156 /** 157 * The name of the JSON Boolean that holds the flag indicating whether the 158 * performance section is currently ignored: {@value}. 159 */ 160 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 161 public static final String JSONField_SectionIgnored = "Ignored"; 162 163 /** 164 * The name of the JSON String that holds the name of the performance 165 * section: {@value}. 166 */ 167 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 168 public static final String JSONField_SectionName = "Name"; 169 170 /** 171 * The name of the JSON Object that holds the execution statistics of the 172 * performance section: {@value}. 173 */ 174 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 175 public static final String JSONField_SectionStatistics = "Statistics"; 176 177 /** 178 * The name of the JSON Object that holds the threshold time from the 179 * performance section: {@value}. 180 */ 181 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 182 public static final String JSONField_SectionThreshold = "Threshold"; 183 184 /** 185 * The name of the JSON boolean that holds the flag indicating whether a 186 * report should be sent only when the threshold was exceeded: {@value}. 187 */ 188 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 189 public static final String JSONField_SectionThresholdOnlyReport = "ThresholdOnlyReport"; 190 191 /** 192 * The name of the JSON Object that holds the timeout time from the 193 * performance section: {@value}. 194 */ 195 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 196 public static final String JSONField_SectionTimeout = "Timeout"; 197 198 /** 199 * The name of the JSON String that holds the time when the performance 200 * section was entered: {@value}. 201 */ 202 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 203 public static final String JSONField_StartTime = "StartTime"; 204 205 /** 206 * The name of the JSON Object that holds a success message: {@value}. 207 */ 208 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 209 public static final String JSONField_Success = "Success"; 210 211 /** 212 * The name of the JSON Number that holds the number of performance 213 * section runs where the threshold was exceeded: {@value}. 214 */ 215 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 216 public static final String JSONField_ThresholdExceededRuns = "ThresholdExceeded"; 217 218 /** 219 * The name of the JSON boolean that holds timed out flag: {@value}. 220 */ 221 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 222 public static final String JSONField_TimedOut = "TimedOut"; 223 224 /** 225 * The name of the JSON Number that holds the number of performance 226 * section runs that timed out: {@value}. 227 */ 228 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 229 public static final String JSONField_TimedOutRuns = "TimedOut"; 230 231 /** 232 * The name of the JSON String that holds the unit for the dimension from 233 * a dimensioned value: {@value}. 234 * 235 * @see #JSONField_SectionThreshold 236 * @see #JSONField_SectionTimeout 237 */ 238 @SuppressWarnings( "StaticMethodOnlyUsedInOneClass" ) 239 public static final String JSONField_Unit = "Unit"; 240 241 /** 242 * The name of the JSON Number that holds the value from a dimensioned 243 * value: {@value}. 244 * 245 * @see #JSONField_SectionThreshold 246 * @see #JSONField_SectionTimeout 247 */ 248 public static final String JSONField_Value = "Value"; 249 250 /** 251 * The type for the 252 * {@link ObjectName} 253 * identifying the Performance Logging MBean 254 * in the MBean server: {@value}. 255 */ 256 public static final String MBEAN_TYPE = "PerformanceLogging"; 257 258 /** 259 * The type for the 260 * {@link javax.management.Notification} 261 * instances emitted by Performance Logging MBean: {@value}. 262 */ 263 public static final String NOTIFICATION_Type = "org.tquadrat.foundation.perflog.SectionExec"; 264 265 /*---------*\ 266 ====** Methods **========================================================== 267 \*---------*/ 268 /** 269 * {@inheritDoc} 270 */ 271 @Override 272 public void close(); 273 274 /** 275 * <p>{@summary Connects to the Performance Logging MBean specified 276 * through the given port number and the 277 * {@link ObjectName} 278 * returned by 279 * {@link #getPerfLogMBeanObjectName()}.}</p> 280 * <p>This method creates a local connection (both processes are running 281 * on the same machine).</p> 282 * 283 * @param registryPort The number of the registry port. 284 * @param listener The notification listener. 285 * @return The {@code PerfLogRemote} instance that manages the connection 286 * to the performance logging MBean. 287 * @throws IOException Unable to connect to the MBean server. 288 * @throws InstanceNotFoundException There is no performance logging 289 * MBean registered on the MBean server. 290 */ 291 @SuppressWarnings( "ClassReferencesSubclass" ) 292 public static PerfLogRemote connect( final int registryPort, final NotificationListener listener ) throws InstanceNotFoundException, IOException 293 { 294 final var url = composeServiceURL( registryPort ); 295 final var retValue = PerfLogRemoteImpl.connect( url, listener ); 296 297 //---* Done *---------------------------------------------------------- 298 return retValue; 299 } // connect() 300 301 /** 302 * <p>{@summary Connects to the Performance Logging MBean specified 303 * through the given host name, port numbers and the 304 * {@link ObjectName} 305 * returned by 306 * {@link #getPerfLogMBeanObjectName()}.}</p> 307 * <p>This method creates a remote connection (both processes are probably 308 * running on different machines).</p> 309 * 310 * @param hostName The host name. 311 * @param registryPort The number of the registry port. 312 * @param dataPort The number of the data port; can be the same as the 313 * registry port. 314 * @param listener The notification listener. 315 * @return The {@code PerfLogRemote} instance that manages the connection 316 * to the performance logging MBean. 317 * @throws MalformedURLException It is not possible to compose a valid 318 * {@link JMXServiceURL} 319 * with the given {@code hostName}. 320 * @throws IOException Unable to connect to the MBean server. 321 * @throws InstanceNotFoundException There is no performance logging 322 * MBean registered on the MBean server. 323 */ 324 @SuppressWarnings( "ClassReferencesSubclass" ) 325 public static PerfLogRemote connect( final String hostName, final int registryPort, final int dataPort, final NotificationListener listener ) throws IOException, InstanceNotFoundException 326 { 327 final var url = composeServiceURL( hostName, registryPort, dataPort ); 328 final var retValue = PerfLogRemoteImpl.connect( url, listener ); 329 330 //---* Done *---------------------------------------------------------- 331 return retValue; 332 } // connect() 333 334 /** 335 * Returns the 336 * {@link MBeanInfo} 337 * for the performance logging MBean. 338 * 339 * @return The {@code MBeanInfo}. 340 * @throws IllegalStateException The instance was already closed. 341 * @throws IntrospectionException An exception occurred during 342 * introspection. 343 * @throws InstanceNotFoundException The MBean specified was not found. 344 * @throws ReflectionException An exception occurred when trying to invoke 345 * the method 346 * {@link DynamicMBean#getMBeanInfo() getMBeanInfo()} of a 347 * {@linkplain DynamicMBean Dynamic MBean}. 348 * @throws IOException A communication problem occurred when talking to 349 * the MBean server. 350 */ 351 public MBeanInfo getMBeanInfo() throws IllegalStateException, ReflectionException, InstanceNotFoundException, IntrospectionException, IOException; 352 353 /** 354 * Returns the 355 * {@link ObjectName} 356 * for the Performance Logging MBean. 357 * 358 * @return The object name for the MBean. 359 */ 360 public static ObjectName getPerfLogMBeanObjectName() { return PerfLogRemoteImpl.getPerfLogMBeanObjectName(); } 361 362 /** 363 * <p>{@summary Returns the status for the given performance section.}</p> 364 * 365 * @param name The name of the performance section. 366 * @return The status of the performance section, or a message indicating 367 * what failed in case of error, as a JSON String. 368 * @throws IllegalStateException The instance was already closed. 369 * @throws ReflectionException An exception occurred when trying to invoke 370 * the method 371 * {@link DynamicMBean#getAttribute(String) getAttribute()} of a 372 * {@linkplain DynamicMBean Dynamic MBean}. 373 * @throws MBeanException Wraps an exception thrown by the MBean method. 374 * @throws InstanceNotFoundException The MBean specified was not found. 375 * @throws IOException A communication problem occurred when talking to 376 * the MBean server. 377 */ 378 public String getPerformanceSection( final String name ) throws IllegalStateException, ReflectionException, InstanceNotFoundException, MBeanException, IOException; 379 380 /** 381 * <p>{@summary Returns a list of the currently defined performance 382 * sections.}</p> 383 * 384 * @return The list of the performance section names. 385 * @throws IllegalStateException The instance was already closed. 386 * @throws ReflectionException An exception occurred when trying to invoke 387 * the method 388 * {@link DynamicMBean#getAttribute(String) getAttribute()} of a 389 * {@linkplain DynamicMBean Dynamic MBean}. 390 * @throws MBeanException Wraps an exception thrown by the MBean method. 391 * @throws InstanceNotFoundException The MBean specified was not found. 392 * @throws AttributeNotFoundException The attribute was missing. 393 * @throws IOException A communication problem occurred when talking to 394 * the MBean server. 395 */ 396 @SuppressWarnings( "MethodWithTooExceptionsDeclared" ) 397 public String [] getPerformanceSections() throws IllegalStateException, ReflectionException, AttributeNotFoundException, InstanceNotFoundException, MBeanException, IOException; 398} 399// interface PerfLogRemote 400 401/* 402 * End of File 403 */