Class MatsTraceFieldImpl<Z>

java.lang.Object
io.mats3.serial.impl.MatsTraceFieldImpl<Z>
All Implemented Interfaces:
MatsTrace<Z>, Cloneable
Direct Known Subclasses:
MatsTraceStringImpl

public class MatsTraceFieldImpl<Z> extends Object implements MatsTrace<Z>, Cloneable
An implementation of MatsTrace which uses fields to hold all state necessary for a Mats flow, including "holders" for the serialization of DTOs and STOs, with type 'Z'. It is meant to be "field-serialized", thus the field names are short. The most relevant types of Z are String and byte[], using e.g. JSON or Smile for serializing the DTOs and STOs payloads, but it might be relevant to use a container/holder type too. You should create an extension of this class to set the type. In 'mats-serial-json', a MatsTraceStringImpl variant exists.
  • Constructor Details

    • MatsTraceFieldImpl

      protected MatsTraceFieldImpl()
    • MatsTraceFieldImpl

      protected MatsTraceFieldImpl(String traceId, String flowId, MatsTrace.KeepMatsTrace keepMatsTrace, boolean nonPersistent, boolean interactive, long ttlMillis, boolean noAudit)
  • Method Details

    • withDebugInfo

      public MatsTrace<Z> withDebugInfo(String initializingAppName, String initializingAppVersion, String initializingHost, String initiatorId, String debugInfo)
      Description copied from interface: MatsTrace
      Can only be set once..
      Specified by:
      withDebugInfo in interface MatsTrace<Z>
      initiatorId - the id set using matsInitiate.from(initiatorId) - it is not the name of the initiator.
      Returns:
      this, for chaining. Note that this is opposed to the add[Request|Send|Next|Reply]Call(..) methods, which return a new, independent instance.
    • withChildFlow

      public MatsTrace<Z> withChildFlow(String parentMatsMessageId, int totalCallNumber)
      Description copied from interface: MatsTrace
      If this newly created MatsTrace is a child-flow (initiated within a Stage) of an existing flow, then this method should be invoked to set the parent MatsMessageId, and the "total call number" which is a "Call Overflow protection" mechanism.

      Parent Mats Message Id: The MatsMessageId of the message whose processing spawned this new flow.

      Total Call Number: Initializes the MatsTrace.getTotalCallNumber(). If this message is initiated within an existing call flow, set to the current call's MatsTrace.getTotalCallNumber() + 1. This number will increase for every subsequent call this flow is going through, just as with MatsTrace.getCallNumber() - the difference being that it should continue increasing if a new message is initiated within a flow. Thereby it is possible to stop an out-of-control initiate-send/request recursion, by checking that the MatsTrace.getTotalCallNumber() doesn't ever go above a fixed number, e.g. 100.

      Specified by:
      withChildFlow in interface MatsTrace<Z>
      Parameters:
      parentMatsMessageId - the MatsMessageId of the message whose processing spawned this new flow.
      totalCallNumber - the MatsTrace.getTotalCallNumber() to initialize this MatsTrace with.
      Returns:
      this, for chaining. Note that this is opposed to the add[Request|Send|Next|Reply]Call(..) methods, which return a new, independent instance.
    • overrideInitializationTimestamp

      public void overrideInitializationTimestamp(long timestamp)
      NOTICE! This is NOT meant for public usage!
    • getTraceId

      public String getTraceId()
      Specified by:
      getTraceId in interface MatsTrace<Z>
      Returns:
      the TraceId that this MatsTrace was initiated with - this is set once, at initiation time, and follows the processing till it terminates. (All log lines will have the traceId set on the MDC.)
    • getFlowId

      public String getFlowId()
      Specified by:
      getFlowId in interface MatsTrace<Z>
      Returns:
      the "FlowId", which is a system-specified, guaranteed-globally-unique TraceId - and shall be the prefix of each MatsTrace.Call.getMatsMessageId(), separated by a "_".
    • getInitializedTimestamp

      public long getInitializedTimestamp()
      Specified by:
      getInitializedTimestamp in interface MatsTrace<Z>
    • getKeepTrace

      public MatsTrace.KeepMatsTrace getKeepTrace()
      Specified by:
      getKeepTrace in interface MatsTrace<Z>
      Returns:
      to which extent the Call history (with State) should be kept. The default is MatsTrace.KeepMatsTrace.COMPACT.
    • isNonPersistent

      public boolean isNonPersistent()
      Specified by:
      isNonPersistent in interface MatsTrace<Z>
      Returns:
      whether the message should be JMS-style "non-persistent", default is false (i.e. persistent, reliable).
    • isInteractive

      public boolean isInteractive()
      Specified by:
      isInteractive in interface MatsTrace<Z>
      Returns:
      whether the message should be prioritized in that a human is actively waiting for the reply, default is false.
    • getTimeToLive

      public long getTimeToLive()
      Specified by:
      getTimeToLive in interface MatsTrace<Z>
      Returns:
      the number of milliseconds the message should live before being time out. 0 means "forever", and is the default.
    • isNoAudit

      public boolean isNoAudit()
      Specified by:
      isNoAudit in interface MatsTrace<Z>
      Returns:
      a hint to the underlying implementation, or to any monitoring/auditing tooling on the Message Broker, that it does not make much value in auditing this message flow, typically because it is just a "getter" of information to show to some user, or a health-check validating that some service is up and answers in a timely fashion.
    • getInitializingAppName

      public String getInitializingAppName()
      Specified by:
      getInitializingAppName in interface MatsTrace<Z>
    • getInitializingAppVersion

      public String getInitializingAppVersion()
      Specified by:
      getInitializingAppVersion in interface MatsTrace<Z>
    • getInitializingHost

      public String getInitializingHost()
      Specified by:
      getInitializingHost in interface MatsTrace<Z>
    • getInitiatorId

      public String getInitiatorId()
      Specified by:
      getInitiatorId in interface MatsTrace<Z>
      Returns:
      a fictive "endpointId" of the initiator, see MatsInitiator.MatsInitiate.from(String).
    • getDebugInfo

      public String getDebugInfo()
      Specified by:
      getDebugInfo in interface MatsTrace<Z>
    • getCallNumber

      public int getCallNumber()
      Specified by:
      getCallNumber in interface MatsTrace<Z>
      Returns:
      the number of calls that this MatsTrace have been through, i.e. how many times MatsTrace.add[Request|Next|Reply..](..) has been invoked on this MatsTrace. This means that right after a new MatsTrace has been created, before a call has been added, 0 is returned. With KeepMatsTrace at FULL or COMPACT, the returned number will be the same as MatsTrace.getCallFlow().size(), but with MINIMAL, that number of always 1, but this number will still return the number of calls that has been added through the flow.
      See Also:
    • getTotalCallNumber

      public int getTotalCallNumber()
      Description copied from interface: MatsTrace
      "Stack overflow protection" mechanism.
      Specified by:
      getTotalCallNumber in interface MatsTrace<Z>
      Returns:
      the total call number, which is the same as MatsTrace.getCallNumber() unless this flow was initiated within a stage, in which case the totalCallNumber starts at the current call number at that stage (as set with MatsTrace.withChildFlow(String, int)). This ensures that if we end up with e.g. a mats flow initiating a new mats flow to itself, thus creating a loop, this number will continuously increase, and we can thus break out at some obviously-too-large value.
    • getParentMatsMessageId

      public String getParentMatsMessageId()
      Description copied from interface: MatsTrace
      If this is a child flow of an existing flow, this should return the MatsMessageId of the message whose processing spawned this new flow.
      Specified by:
      getParentMatsMessageId in interface MatsTrace<Z>
      Returns:
      the MatsMessageId of the message whose processing spawned this new flow.
    • setTraceProperty

      public void setTraceProperty(String propertyName, Z propertyValue)
      Description copied from interface: MatsTrace
      Sets a trace property, refer to ProcessContext.setTraceProperty(String, Object). Notice that on the MatsTrace-side, the value must be of type Z.
      Specified by:
      setTraceProperty in interface MatsTrace<Z>
      Parameters:
      propertyName - the name of the property.
      propertyValue - the value of the property.
      See Also:
    • getTraceProperty

      public Z getTraceProperty(String propertyName)
      Description copied from interface: MatsTrace
      Retrieves a property value set by MatsTrace.setTraceProperty(String, Object), refer to ProcessContext.getTraceProperty(String, Class). Notice that on the MatsTrace-side, the value is of type Z.
      Specified by:
      getTraceProperty in interface MatsTrace<Z>
      Parameters:
      propertyName - the name of the property to retrieve.
      Returns:
      the value of the property.
      See Also:
    • getTracePropertyKeys

      public Set<String> getTracePropertyKeys()
      Specified by:
      getTracePropertyKeys in interface MatsTrace<Z>
      Returns:
      the set of keys containing trace properties.
      See Also:
    • addRequestCall

      public MatsTraceFieldImpl<Z> addRequestCall(String from, String to, MatsTrace.Call.MessagingModel toMessagingModel, String replyTo, MatsTrace.Call.MessagingModel replyToMessagingModel, Z data, Z replyState, Z initialState)
      Description copied from interface: MatsTrace
      Adds a REQUEST Call, which is an invocation of a service where one expects a Reply from this service to go to a specified endpoint, typically the next stage in a multi-stage endpoint: Envision a normal invocation of some method that returns a value.
      Specified by:
      addRequestCall in interface MatsTrace<Z>
      Parameters:
      from - which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.
      to - which endpoint that should get the request.
      toMessagingModel - the MatsTrace.Call.MessagingModel of 'to'.
      replyTo - which endpoint that should get the reply from the requested endpoint.
      replyToMessagingModel - the MatsTrace.Call.MessagingModel of 'replyTo'.
      data - the request data, most often a JSON representing the Request Data Transfer Object that the requested service expects to get.
      replyState - the state data for the stageId that gets the reply to this request, that is, the state for the stageId that is at the first element of the replyStack. Most often a JSON representing the State Transfer Object for the multi-stage endpoint.
      initialState - an optional feature, whereby the state can be set for the initial stage of the requested endpoint. Same stuff as replyState.
    • addSendCall

      public MatsTraceFieldImpl<Z> addSendCall(String from, String to, MatsTrace.Call.MessagingModel toMessagingModel, Z data, Z initialState)
      Description copied from interface: MatsTrace
      Adds a SEND Call, meaning a "request" which do not expect a Reply: Envision an invocation of a void-method. Or an invocation of some method that returns the value, but where you invoke it as a void-method (i.e. not storing the result, e.g. the method map.remove("test") returns the removed value, but is often invoked without storing this.).
      Specified by:
      addSendCall in interface MatsTrace<Z>
      Parameters:
      from - which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.
      to - which endpoint that should get the message.
      toMessagingModel - the MatsTrace.Call.MessagingModel of 'to'.
      data - the request data, most often a JSON representing the Request Data Transfer Object that the receiving service expects to get.
      initialState - an optional feature, whereby the state can be set for the initial stage of the requested endpoint.
    • addNextCall

      public MatsTraceFieldImpl<Z> addNextCall(String from, String to, Z data, Z state)
      Description copied from interface: MatsTrace
      Adds a NEXT Call, which is a "skip call" to the next stage in a multistage service, as opposed to the normal request out to a service expecting a reply. The functionality is functionally identical to MatsTrace.addSendCall(String, String, MessagingModel, Object, Object) addSendCall(...)}, but has its own CallType enum value NEXT.

      Note: Cannot specify MatsTrace.Call.MessagingModel here, as one cannot fathom where that would make sense: It must be QUEUE.

      Specified by:
      addNextCall in interface MatsTrace<Z>
      Parameters:
      from - which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.
      to - which endpoint that should get the message - the next stage in a multi-stage service.
      data - the request data, most often a JSON representing the Request Data Transfer Object that the next stage expects to get.
      state - the state data for the next stage.
    • addReplyCall

      public MatsTraceFieldImpl<Z> addReplyCall(String from, Z data)
      Description copied from interface: MatsTrace
      Adds a REPLY Call, which happens when a requested service is finished with its processing and have some Reply to return. This method pops the stack (takes the last element) from the (previous) current call, sets this as the "to" parameter, and uses the rest of the list as the stack for the next Call.
      Specified by:
      addReplyCall in interface MatsTrace<Z>
      Parameters:
      from - which stageId this request is for. This is solely meant for monitoring and debugging - the protocol does not need the from specifier, as this is not where any replies go to.
      data - the request data, most often a JSON representing the Request Data Transfer Object that the requesting service expects to get.
    • addGotoCall

      public MatsTrace<Z> addGotoCall(String from, String to, Z data, Z initialState)
      Specified by:
      addGotoCall in interface MatsTrace<Z>
      data - the request data, most often a JSON representing the Request Data Transfer Object that the passed-to endpoint expects to get.
      initialState - an optional feature, whereby the state can be set for the initial stage of the requested endpoint.
    • setOutgoingTimestamp

      public void setOutgoingTimestamp(long timestamp)
      Description copied from interface: MatsTrace
      Shall be invoked after adding the outgoing call, immediately before serializing the outgoing MatsTrace.
      • Sets the outgoing Call's MatsTrace.Call.getCalledTimestamp() to be more closely aligned to the exact sending time. (For example, the message may have been constructed, then a massive SQL query was performed, and then a new message is constructed, and then the messages are actually turned into JMS messages and committed on the wire. This means that the first message will have a much earlier timestamp than the second.) Using this method, all outgoing messages can have the Called Timestamp set right before it is serialized and JMS-constructed and committed.
      • If the MatsTrace.getCurrentCall() is a REQUEST, SEND, GOTO or PUBLISH (anything else than REPLY), it also sets the same-height-called-timestamp, recorded on the stackframe below it, or on the MatsTrace itself if there is no stackframe below (initial SEND). This is to be able to calculate the "time between stages" for the e.g. time between stage1 and stage2 of a multi-stage endpoint, noting that this might entail multiple levels of Request and Replies (thus it must reside on the stack).
      Specified by:
      setOutgoingTimestamp in interface MatsTrace<Z>
    • getSameHeightOutgoingTimestamp

      public long getSameHeightOutgoingTimestamp()
      Specified by:
      getSameHeightOutgoingTimestamp in interface MatsTrace<Z>
      Returns:
      the timestamp set by MatsTrace.setOutgoingTimestamp(long) for the preceding call on the same stack height. Used to calculate the "time between stages" for the different stages on an endpoint. It does not make sense to get this for the initial stage of an Endpoint if the incoming is a REQUEST, and the return value will then be -1.
    • setStageEnteredTimestamp

      public void setStageEnteredTimestamp(long timestamp)
      Description copied from interface: MatsTrace
      Invoke this as early as possible on the reception of a message. Used to calculate the "total endpoint time", through all stages (including intermediate request/replies): Time from entry on the Initial Stage, to when the endpoint Replies, or stops (no outgoing message).
      Specified by:
      setStageEnteredTimestamp in interface MatsTrace<Z>
    • getSameHeightEndpointEnteredTimestamp

      public long getSameHeightEndpointEnteredTimestamp()
      Specified by:
      getSameHeightEndpointEnteredTimestamp in interface MatsTrace<Z>
      Returns:
      the value of MatsTrace.setStageEnteredTimestamp(long) for the stages of the same endpoint. Used to calculate the "total endpoint time", through all stages, when the endpoint Replies, or stops (no outgoing message).
    • getCurrentSpanId

      public long getCurrentSpanId()
      Specified by:
      getCurrentSpanId in interface MatsTrace<Z>
      Returns:
      this MatsTrace's SpanId. If it is still on the initiator side, before having had a call added to it, or on the terminator side, when the stack again is empty, the SpanId is derived from the FlowId. Otherwise, it is the topmost element of an internal stack, in the same way as MatsTrace.getCurrentCall().MatsTrace.Call.getReplyStack().
    • getCurrentCall

      public MatsTraceFieldImpl.CallImpl<Z> getCurrentCall()
      Specified by:
      getCurrentCall in interface MatsTrace<Z>
      Returns:
      the Call which should be processed by the stage receiving this MatsTrace (which should be the stageId specified in getCurrentCall().getTo()). Returns null if not call has yet been added to the trace.
    • getCallFlow

      public List<MatsTrace.Call<Z>> getCallFlow()
      Specified by:
      getCallFlow in interface MatsTrace<Z>
      Returns:
      the flow of calls, from the first REQUEST (or SEND), to the current call - unless KeepTrace is MINIMAL, in which case only the current call is present in the list.
    • getCurrentState

      public Optional<MatsTrace.StackState<Z>> getCurrentState()
      Description copied from interface: MatsTrace
      Returns the MatsTrace.StackState for the MatsTrace.getCurrentCall(), if present.

      Searches in the 'State Flow' from the back (most recent) for the first element that is at the current stack height, as defined by MatsTrace.getCurrentCall().MatsTrace.Call.getReplyStackHeight(). If a more shallow stackDepth than the specified is encountered, or the list is exhausted without the Stack Height being found, the search is terminated with null. This happens for the initial stage for an endpoint, unless the 'initialState' was set on the SEND or REQUEST.

      The point of the 'State Flow' is the same as for the Call list: Monitoring and debugging, by keeping a history of all calls in the processing, along with the states that was present at each call point.

      If "condensing" is on (COMPACT or MINIMAL), the stack-state-list is - by the condensing algorithm - turned in to a pure stack (as available via MatsTrace.getStateStack()), with the StackState for the earliest stack element at position 0, while the latest (current) at end of list. The above-specified search algorithm still works, as it now will either find the element with the correct stack depth at the end of the list, or it is not there.

      NOTE: The StateStack (mostly) includes a frame for the current call, as opposed to the MatsTrace.Call.getReplyStack() (reply stack), which only includes frames below us. Note that as a matter of avoiding space use, on a REQUEST call, the StackState is not added for the actual REQUEST message's state stack, unless the "initial incoming state" is supplied (which is uncommon - a service invocation typically starts with an empty state). However, on REPLY messages, it will always be present, and hence the state stack is typically one level higher (includes current frame) than the reply stack (only includes frames below).

      NOTE: As further info on how the state stack relates to the reply stack height: When a REPLY comes to a terminator, there are 0 more frames below. However, the terminator needs its state, which is at state stack height 0.

      Specified by:
      getCurrentState in interface MatsTrace<Z>
      Returns:
      the MatsTrace.StackState for the MatsTrace.getCurrentCall() if it exists, null otherwise, as is typical when entering initial stage of an endpoint.
    • getStateFlow

      public List<MatsTrace.StackState<Z>> getStateFlow()
      Specified by:
      getStateFlow in interface MatsTrace<Z>
      Returns:
      the entire list of states as they have changed throughout the call flow. If MatsTrace.KeepMatsTrace is COMPACT or MINIMAL, then it will be a pure stack (as returned with MatsTrace.getStateStack(), with the last element being the most recent stack frame. NOTICE: The index position in this list has little to do with which stack level the state refers to. This must be gotten from MatsTrace.StackState.getHeight().
      See Also:
    • getStateStack

      public List<MatsTrace.StackState<Z>> getStateStack()
      Specified by:
      getStateStack in interface MatsTrace<Z>
      Returns:
      the stack of the states for the current stack: getCurrentCall().getStack().
      See Also:
    • getStateStack_internal

      public List<io.mats3.serial.impl.MatsTraceFieldImpl.StackStateImpl<Z>> getStateStack_internal()
    • cloneForNewCall

      protected MatsTraceFieldImpl<Z> cloneForNewCall()
      Takes into account the KeepMatsTrace value.
    • toString

      public String toString()
      MatsTraceStringImpl.toString().
      Overrides:
      toString in class Object