package tc.oc.api.queue;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.BasicProperties;
import java.time.Duration;
import java.time.Instant;
import tc.oc.api.config.ApiConstants;
public class Metadata extends AMQP.BasicProperties {
// Custom headers
public static final String PROTOCOL_VERSION = "protocol_version";
public static final String MODEL_NAME = "model_name";
public static Map<String, Object> nonNullHeaders(Map<String, Object> headers) {
return headers != null ? headers : Collections.<String, Object>emptyMap();
}
public static Map<String, Object> getHeaders(AMQP.BasicProperties props) {
return nonNullHeaders(props.getHeaders());
}
@Override
public Map<String, Object> getHeaders() {
return nonNullHeaders(super.getHeaders());
}
public static @Nullable String getHeaderString(AMQP.BasicProperties props, String name) {
// Header values are some kind of spooky fake string object
// called LongStringHelper.ByteArrayLongString
Object o = getHeaders(props).get(name);
return o == null ? null : o.toString();
}
public @Nullable String getHeaderString(String name) {
return getHeaderString(this, name);
}
public static int getHeaderInt(AMQP.BasicProperties props, String name, int def) {
final String text = getHeaderString(props, name);
return text == null ? def : Integer.parseInt(text);
}
public int getHeaderInt(String name, int def) {
return getHeaderInt(this, name, def);
}
public static int protocolVersion(AMQP.BasicProperties props) {
return getHeaderInt(props, PROTOCOL_VERSION, ApiConstants.PROTOCOL_VERSION);
}
public int protocolVersion() {
return protocolVersion(this);
}
public static Optional<String> modelName(AMQP.BasicProperties props) {
return Optional.ofNullable(getHeaderString(props, MODEL_NAME));
}
public Optional<String> modelName() {
return modelName(this);
}
public @Nullable Duration expiration() {
final String expiration = getExpiration();
return expiration == null ? null : Duration.ofMillis(Long.parseLong(expiration));
}
public @Nullable Instant timestamp() {
final Date timestamp = getTimestamp();
return timestamp == null ? null : timestamp.toInstant();
}
public @Nullable Instant expiresAt() {
final Instant timestamp = timestamp();
final Duration expiration = expiration();
if(timestamp != null && expiration != null) {
return timestamp.plus(expiration);
}
return null;
}
public Metadata(String contentType, String contentEncoding, Map<String, Object> headers, Integer deliveryMode, Integer priority, String correlationId, String replyTo, String expiration, String messageId, Date timestamp, String type, String userId, String appId) {
super(contentType, contentEncoding, headers, deliveryMode, priority, correlationId, replyTo, expiration, messageId, timestamp, type, userId, appId, null);
}
public Metadata(BasicProperties p) {
this(p.getContentType(), p.getContentEncoding(), p.getHeaders(), p.getDeliveryMode(), p.getPriority(), p.getCorrelationId(), p.getReplyTo(), p.getExpiration(), p.getMessageId(), p.getTimestamp(), p.getType(), p.getUserId(), p.getAppId());
}
public static class Builder {
private String contentType;
private String contentEncoding;
private Map<String,Object> headers;
private Integer deliveryMode;
private Integer priority;
private String correlationId;
private String replyTo;
private String expiration;
private String messageId;
private Date timestamp;
private String type;
private String userId;
private String appId;
public Builder() {};
public Builder(@Nullable BasicProperties p) {
if(p == null) return;
this.contentType = p.getContentType();
this.contentEncoding = p.getContentEncoding();
this.headers = p.getHeaders();
this.deliveryMode = p.getDeliveryMode();
this.priority = p.getPriority();
this.correlationId = p.getCorrelationId();
this.replyTo = p.getReplyTo();
this.expiration = p.getExpiration();
this.timestamp = p.getTimestamp();
this.type = p.getType();
this.userId = p.getUserId();
this.appId = p.getAppId();
};
public Builder expiration(Duration expiration) {
return expiration(String.valueOf(expiration.toMillis()));
}
public Builder persistent(boolean persistent) {
return deliveryMode(persistent ? 2 : 1);
}
public Builder timestamp(Instant timestamp) {
return timestamp(Date.from(timestamp));
}
public Builder replyTo(Queue queue) {
return replyTo(queue.name());
}
public Builder header(String key, String value) {
if(headers == null) {
headers = new HashMap<>();
}
headers.put(key, value);
return this;
}
public Builder header(String key, int value) {
return header(key, String.valueOf(value));
}
public Builder protocolVersion(int version) {
return header("protocol_version", version);
}
// Commence copypasta
public Builder contentType(String contentType)
{ this.contentType = contentType; return this; }
public Builder contentEncoding(String contentEncoding)
{ this.contentEncoding = contentEncoding; return this; }
public Builder headers(Map<String,Object> headers)
{ this.headers = headers; return this; }
public Builder deliveryMode(Integer deliveryMode)
{ this.deliveryMode = deliveryMode; return this; }
public Builder priority(Integer priority)
{ this.priority = priority; return this; }
public Builder correlationId(String correlationId)
{ this.correlationId = correlationId; return this; }
public Builder replyTo(String replyTo)
{ this.replyTo = replyTo; return this; }
public Builder expiration(String expiration)
{ this.expiration = expiration; return this; }
public Builder messageId(String messageId)
{ this.messageId = messageId; return this; }
public Builder timestamp(Date timestamp)
{ this.timestamp = timestamp; return this; }
public Builder type(String type)
{ this.type = type; return this; }
public Builder userId(String userId)
{ this.userId = userId; return this; }
public Builder appId(String appId)
{ this.appId = appId; return this; }
public Metadata build() {
return new Metadata
( contentType
, contentEncoding
, headers
, deliveryMode
, priority
, correlationId
, replyTo
, expiration
, messageId
, timestamp
, type
, userId
, appId
);
}
}
}