Class Agent

  • All Implemented Interfaces:
    Serializable
    Direct Known Subclasses:
    Reply

    public class Agent
    extends Object
    implements Serializable
    Represents an object that can be transmitted by KDC to a remote receiver.

    An Agent may carry application data and, when configured with a visit method and API class, may be dispatched by the receiver. During dispatch, KDC invokes the agent's visit method and supplies the receiver's implementation of the specified API.

    An agent is considered dispatchable when it is a subclass of Agent and has both a visit method name and API class name. A plain Agent may therefore be used to transport data without invoking receiver-side application logic.

    Each agent is assigned a unique UUID. KDC also maintains runtime information such as the transport protocol, synchronous state, serialized size, and latency measurements. Application-specific values may be carried using the data methods provided by this class.

    Author:
    Charles B. Kozoyed
    See Also:
    Serialized Form
    • Constructor Detail

      • Agent

        public Agent()
        Creates a new agent.

        The agent is assigned a unique UUID and creation timestamp. Its protocol is initially Protocol.UNKNOWN, and its serialized size is initially zero.

    • Method Detail

      • setData

        public void setData​(String key,
                            Object value)
        Associates an application-defined value with the specified key.

        The data map provides a dynamic alternative to defining application data as fields in an Agent subclass. A value may be null, but the key must not be null or blank.

        Parameters:
        key - the key used to identify the value
        value - the value to associate with the key; may be null
        Throws:
        IllegalArgumentException - if key is null or blank
      • setData

        public void setData​(Enum<?> key,
                            Object value)
        Associates an application-defined value with the name of the specified enum constant.

        The key may be a constant from any enum type. The enum constant's Enum.name() is used as the data key. Using an enum key provides compile-time checking and helps prevent errors caused by mistyped string keys. A value may be null.

        Parameters:
        key - an enum constant whose name is used as the data key
        value - the value to associate with the key; may be null
        Throws:
        IllegalArgumentException - if key is null
      • getData

        public <T> T getData​(Enum<?> key,
                             Class<T> clazz)
        Returns the value associated with the name of the specified enum constant.

        The key may be a constant from any enum type. The enum constant's Enum.name() is used as the data key. The value is returned as the requested type. A stored null value is returned as null. Using an enum key provides compile-time checking and helps prevent errors caused by mistyped string keys.

        Type Parameters:
        T - the expected type of the value
        Parameters:
        key - an enum constant whose name is used as the data key
        clazz - the expected type of the value
        Returns:
        the value associated with the key, or null if the stored value is null
        Throws:
        IllegalArgumentException - if key or clazz is null
        IllegalStateException - if no data is present, the key does not exist, or the value is not of the requested type
      • hasData

        public boolean hasData​(Enum<?> key)
        Determines whether data is associated with the name of the specified enum constant.

        The key may be a constant from any enum type. The enum constant's Enum.name() is used as the data key. This method returns true even if the value associated with the key is null. Using an enum key provides compile-time checking and helps prevent errors caused by mistyped string keys.

        Parameters:
        key - an enum constant whose name is used as the data key
        Returns:
        true if the key exists; otherwise false
        Throws:
        IllegalArgumentException - if key is null
      • getData

        public <T> T getData​(String key,
                             Class<T> clazz)
        Returns the value associated with the specified key.

        The value is returned as the requested type. A stored null value is returned as null.

        Type Parameters:
        T - the expected type of the value
        Parameters:
        key - the key identifying the value
        clazz - the expected type of the value
        Returns:
        the value associated with the key, or null if the stored value is null
        Throws:
        IllegalArgumentException - if key is null or blank, or if clazz is null
        IllegalStateException - if no data is present, the key does not exist, or the value is not of the requested type
      • hasData

        public boolean hasData​(String key)
        Determines whether data is associated with the specified key.

        This method returns true even if the value associated with the key is null.

        Parameters:
        key - the key to check
        Returns:
        true if the key exists; otherwise false
        Throws:
        IllegalArgumentException - if key is null or blank
      • setUUID

        public final void setUUID​(UUID uuid)
        Sets the unique identifier for this agent.
        Parameters:
        uuid - the UUID to assign to the agent
        Throws:
        IllegalArgumentException - if uuid is null
      • getUUID

        public UUID getUUID()
        Returns the unique identifier for this agent.
        Returns:
        the agent UUID
      • getShortUUID

        public String getShortUUID()
        Returns a shortened representation of the agent UUID for use in logging and diagnostics.

        The returned value consists of the most significant 64 bits of the UUID formatted as 16 hexadecimal characters.

        Returns:
        the shortened UUID
      • isSynchronous

        public boolean isSynchronous()
        Determines whether this agent is participating in a synchronous communication.
        Returns:
        true if the agent is synchronous; otherwise false
      • getCreationTimeStamp

        public long getCreationTimeStamp()
        Returns the agent creation timestamp.

        The timestamp is obtained from System.nanoTime() when the agent is created and is intended for measuring elapsed time rather than representing wall-clock time.

        Returns:
        the agent creation timestamp in nanoseconds
      • getStartTime

        public long getStartTime​(LatencyMetric metric)
        Returns the start time recorded for the specified latency metric.
        Parameters:
        metric - the latency metric to query
        Returns:
        the recorded start time in nanoseconds recorded
      • getStopTime

        public long getStopTime​(LatencyMetric metric)
        Returns the stop time recorded for the specified latency metric.
        Parameters:
        metric - the latency metric to query
        Returns:
        the recorded stop time in nanoseconds
      • duration

        public long duration​(LatencyMetric metric)
        Returns the duration recorded for the specified latency metric.

        A duration of 0 is returned when a complete valid measurement is not available for the metric.

        Parameters:
        metric - the latency metric to query
        Returns:
        the recorded duration in nanoseconds, or 0 if a complete valid measurement is not available
      • getLatencyRecord

        public LatencyRecord getLatencyRecord()
        Returns the latency record associated with this agent.

        The latency record contains timing information collected during agent communication and processing. Advanced users may inspect the associated LatencyContext and LatencyMetric values to analyze individual processing stages.

        Latency information may be unavailable if metrics collection is disabled or the record has not been initialized.

        Returns:
        the latency record associated with this agent, or null if no record is available
        See Also:
        LatencyRecord, LatencyContext, LatencyMetric
      • getSizeInBytes

        public int getSizeInBytes()
        Returns the transmitted size of this agent.
        Returns:
        the size of the agent in bytes
      • getClient

        public final Client getClient()
        Returns the client associated with this agent.

        The client represents the KDC connection through which the agent was received and may be used by the agent during receiver-side processing.

        During a visit, an Agent can use this client to send asynchronous Agents back to the sender over the connection on which it arrived. Each returned Agent can invoke a compatible API registered at the original sender.

        For example, an UpdateAgent executing on the server can send update Agents to the client:

        
         public class UpdateAgent extends Agent {
        
             public UpdateAgent() {
                 setVisitMethod("visit", ServerApi.class);
             }
        
             public Reply visit(ServerApi api) throws Exception {
        
                 for (int i = 0; i < 3; i++) {
                     getClient().sendAsync(new ClientUpdateAgent("Update " + i));
                 }
        
                 return null;
             }
         }
         

        Each ClientUpdateAgent executes its visit method using an API registered on the receiving client:

        public class ClientUpdateAgent extends Agent {
        
             public ClientUpdateAgent() {
                 setVisitMethod("visit", ClientUpdateApi.class);
             }
        
             public ClientUpdateAgent(String message) {
                 this();
                 setData("message", message);
             }
        
             public Reply visit(ClientUpdateApi api) {
                 api.onUpdate(getData("message", String.class));
                 return null;
             }
         }
        
         public interface ClientUpdateApi extends API {
        
             void onUpdate(String message);
         }
         

        In this example, ServerApi is an application API registered on the server, and ClientUpdateApi is registered on the client. Compatible Agent classes must be available at their destinations. Updates are dispatched through ClientUpdateApi rather than consumed through the reply queue.

        Returns:
        the client associated with this agent, or null if no client
      • getResponse

        public final Reply getResponse()
        Obtain the reply received from the receiver. This method retrieves the reply object that was generated in response to a request. It is important to note that the reply may be null if no response was received.
        Returns:
        The reply returned by the receiver, or null if no response was available.
      • setResponse

        public final void setResponse​(Reply response)
        Set the response to be received by the receiver.
        Parameters:
        response - The response object to set for this agent. This will be transmitted along with the rest of the agent - or rather the agent in its entirety, back from the to the receiver to the sender.
      • getProtocol

        public Protocol getProtocol()
        Obtain the value of the protocol for this communications entity. This method retrieves the current protocol being used by the communications entity, which may be important for understanding the type of communication and its capabilities. The protocol could influence aspects such as security, data format, and transmission methods.
        Returns:
        The current protocol being used, represented as a Protocol object.
      • setVisitMethod

        public void setVisitMethod​(String visitorMethodName,
                                   Class apiClass)
        Sets the visit method name and API class for the visitor. This specifies the method that will be called on the receiver when it interacts with the receiver. It specifies this be supplying the method name and the one and only parameter the API (apiClass) that is injected into the agent.
        Parameters:
        visitorMethodName - The name of the visit method.
        apiClass - The class of the API that the visit method belongs to.
        Throws:
        IllegalArgumentException - if the visitorMethodName or apiClass is null.
      • setVisitMethod

        public void setVisitMethod​(String visitorMethodName,
                                   String apiClassName)
        Sets the visit method name and API class for the visitor. This specifies the method that will be called on the receiver when it interacts with the receiver. It specifies this be supplying the method name and the one and only parameter the API (apiClass) that is injected into the agent.
        Parameters:
        visitorMethodName - the name of the visit method; must not be null.
        apiClassName - the name of the API class; must not be null.
        Throws:
        IllegalArgumentException - if either the visitorMethodName or apiClassName is null.
      • getVisitorMethodName

        public String getVisitorMethodName()
        Retrieves the name of the visitor method.
        Returns:
        the name of the visitor method as a String.
      • getApiClassName

        public String getApiClassName()
        Returns the name of the API class.
        Returns:
        the name of the API class as a String.
      • getApiMethodKey

        public String getApiMethodKey()
        Returns the API method key composed of the simple name of the class, the visitor method name, and the API class name, separated by the specified key delimiter. If either the visitor method name or the API class name is null, they will be represented as the string "null".
        Returns:
        a string representing the API method key
      • isDispatchable

        public boolean isDispatchable()
        Determines whether the object is 'dispatchable' based on the presence of non-empty visitor method name and API class name.
        Returns:
        true if both the visitor method name and API class name are non-null and non-empty after trimming; false otherwise.
      • toLogString

        public String toLogString​(String logLine)
        Returns a string representation of the current object, which includes the name of the class, the visitor method name, and the API class name. If the visitor method name or API class name is null, it will be represented as "null". The API class name is extracted from its fully qualified name, retaining only the simple class name.
        Parameters:
        logLine - the message to include in the log string
        Returns:
        a string in the format null agent=<class name> method=<visitor method> api=<api class name>