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 */