Event.java
package org.amcp.core;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
/**
* Represents an event in the AMCP mesh.
*
* Events are the primary means of communication between agents.
* They contain a topic, payload, and metadata for routing and processing.
*
* @author AMCP Development Team
* @version 1.5.0
* @since 1.0.0
*/
public final class Event {
private static final ObjectMapper objectMapper = new ObjectMapper();
private final String id;
private final String topic;
private final Object payload;
private final String sender;
private final String correlationId;
private final Instant timestamp;
private final Map<String, String> metadata;
private final EventPriority priority;
@JsonCreator
private Event(
@JsonProperty("id") String id,
@JsonProperty("topic") String topic,
@JsonProperty("payload") Object payload,
@JsonProperty("sender") String sender,
@JsonProperty("correlationId") String correlationId,
@JsonProperty("timestamp") Instant timestamp,
@JsonProperty("metadata") Map<String, String> metadata,
@JsonProperty("priority") EventPriority priority) {
this.id = id != null ? id : UUID.randomUUID().toString();
this.topic = Objects.requireNonNull(topic, "Topic cannot be null");
this.payload = payload;
this.sender = sender;
this.correlationId = correlationId;
this.timestamp = timestamp != null ? timestamp : Instant.now();
this.metadata = metadata != null ? new HashMap<>(metadata) : new HashMap<>();
this.priority = priority != null ? priority : EventPriority.NORMAL;
}
/**
* Gets the unique identifier of this event.
*
* @return the event ID
*/
public String getId() {
return id;
}
/**
* Gets the topic of this event.
*
* @return the topic
*/
public String getTopic() {
return topic;
}
/**
* Gets the payload of this event.
*
* @return the payload
*/
public Object getPayload() {
return payload;
}
/**
* Gets the payload as the specified type.
*
* @param <T> the payload type
* @param type the payload class
* @return the payload cast to the specified type
* @throws ClassCastException if the payload cannot be cast to the specified type
*/
@SuppressWarnings("unchecked")
public <T> T getPayload(Class<T> type) {
if (payload == null) {
return null;
}
if (type.isInstance(payload)) {
return (T) payload;
}
// Try to convert using Jackson
try {
return objectMapper.convertValue(payload, type);
} catch (Exception e) {
throw new ClassCastException("Cannot convert payload to " + type.getSimpleName() + ": " + e.getMessage());
}
}
/**
* Gets the sender of this event.
*
* @return the sender agent ID
*/
public String getSender() {
return sender;
}
/**
* Gets the source of this event (alias for getSender).
*
* @return the source agent ID
*/
public String getSource() {
return sender;
}
/**
* Gets the target of this event from metadata.
*
* @return the target agent ID, or null if not specified
*/
public String getTarget() {
return metadata.get("target");
}
/**
* Gets the correlation ID of this event.
*
* @return the correlation ID
*/
public String getCorrelationId() {
return correlationId;
}
/**
* Gets the timestamp of this event.
*
* @return the timestamp
*/
public Instant getTimestamp() {
return timestamp;
}
/**
* Gets the metadata of this event.
*
* @return a copy of the metadata map
*/
public Map<String, String> getMetadata() {
return new HashMap<>(metadata);
}
/**
* Gets a metadata value.
*
* @param key the metadata key
* @return the metadata value, or null if not found
*/
public String getMetadata(String key) {
return metadata.get(key);
}
/**
* Gets the priority of this event.
*
* @return the priority
*/
public EventPriority getPriority() {
return priority;
}
/**
* Creates a new builder for constructing events.
*
* @return a new event builder
*/
public static Builder builder() {
return new Builder();
}
/**
* Creates a new builder initialized with this event's values.
*
* @return a new event builder
*/
public Builder toBuilder() {
return new Builder()
.id(id)
.topic(topic)
.payload(payload)
.sender(sender)
.correlationId(correlationId)
.timestamp(timestamp)
.metadata(metadata)
.priority(priority);
}
@Override
public String toString() {
return String.format("Event{id='%s', topic='%s', sender='%s', timestamp=%s}",
id, topic, sender, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Event event = (Event) obj;
return Objects.equals(id, event.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
/**
* Builder for constructing Event instances.
*/
public static final class Builder {
private String id;
private String topic;
private Object payload;
private String sender;
private String correlationId;
private Instant timestamp;
private Map<String, String> metadata = new HashMap<>();
private EventPriority priority;
private Builder() {}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder topic(String topic) {
this.topic = topic;
return this;
}
public Builder payload(Object payload) {
this.payload = payload;
return this;
}
public Builder sender(String sender) {
this.sender = sender;
return this;
}
public Builder source(String source) {
this.sender = source;
return this;
}
public Builder target(String target) {
this.metadata.put("target", target);
return this;
}
public Builder correlationId(String correlationId) {
this.correlationId = correlationId;
return this;
}
public Builder timestamp(Instant timestamp) {
this.timestamp = timestamp;
return this;
}
public Builder metadata(String key, String value) {
this.metadata.put(key, value);
return this;
}
public Builder metadata(Map<String, String> metadata) {
this.metadata.putAll(metadata);
return this;
}
public Builder priority(EventPriority priority) {
this.priority = priority;
return this;
}
public Builder from(Event event) {
this.id = event.id;
this.topic = event.topic;
this.payload = event.payload;
this.sender = event.sender;
this.correlationId = event.correlationId;
this.timestamp = event.timestamp;
this.metadata.putAll(event.metadata);
this.priority = event.priority;
return this;
}
public Event build() {
return new Event(id, topic, payload, sender, correlationId,
timestamp, metadata, priority);
}
}
}