[framework] TxCore → common-framework (TxContext·MessageCodec) (ACM-FW-001)

This commit is contained in:
forge-bot 2026-07-18 10:06:04 +00:00
parent 03c2999a26
commit 9b43defd7d

View file

@ -0,0 +1,280 @@
package com.klaro.acquirecore.framework;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
/**
* TxCore - Spring Boot equivalent of C txcore.h/txcore.c
* Provides transaction context, buffer, request/response DTOs, and result codes.
*/
public final class TxCore {
private TxCore() {}
// ===== TxResult - equivalent to C tx_result_t enum =====
public enum TxResult {
OK(0), ERROR(-1), TIMEOUT(-2), ROLLBACK(-3), NESTED(-4);
private final int code;
TxResult(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public static TxResult fromCode(int code) {
for (TxResult r : values()) {
if (r.code == code) return r;
}
return ERROR;
}
public boolean isSuccess() {
return this == OK;
}
public String toErrorString() {
return switch (this) {
case OK -> "OK";
case ERROR -> "Error";
case TIMEOUT -> "Timeout";
case ROLLBACK -> "Rollback";
case NESTED -> "Nested transaction not supported";
};
}
}
// ===== TxBuffer - equivalent to C txbuf_t struct =====
public static final class TxBuffer {
private static final int MAX_BUFSIZE = 4096;
private final ByteBuffer buffer;
private final Map<String, Object> data;
public TxBuffer() {
this.buffer = ByteBuffer.allocate(MAX_BUFSIZE);
this.data = new HashMap<>();
}
public TxBuffer(int capacity) {
this.buffer = ByteBuffer.allocate(Math.min(capacity, MAX_BUFSIZE));
this.data = new HashMap<>();
}
public int write(byte[] src) {
if (src == null || buffer.remaining() < src.length) return -1;
buffer.put(src);
return src.length;
}
public int read(byte[] dest) {
if (dest == null || buffer.remaining() < dest.length) return -1;
buffer.get(dest);
return dest.length;
}
public byte[] toByteArray() {
byte[] result = new byte[buffer.position()];
buffer.flip();
buffer.get(result);
return result;
}
public void put(String key, Object value) {
data.put(key, value);
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
return (T) data.get(key);
}
public Map<String, Object> getData() {
return new HashMap<>(data);
}
public void clear() {
buffer.clear();
data.clear();
}
public void rewind() {
buffer.rewind();
}
public int size() {
return buffer.position();
}
public int remaining() {
return buffer.remaining();
}
}
// ===== TxContext - equivalent to C tx_context_t struct =====
public static final class TxContext {
private static final AtomicLong txnCounter = new AtomicLong(0);
private final long txnId;
private final int flags;
private final TxBuffer buffer;
private final Map<String, Object> userData;
public TxContext() {
this(0);
}
public TxContext(int flags) {
this.txnId = txnCounter.incrementAndGet();
this.flags = flags;
this.buffer = new TxBuffer();
this.userData = new HashMap<>();
}
public long getTxnId() {
return txnId;
}
public int getFlags() {
return flags;
}
public TxBuffer getBuffer() {
return buffer;
}
public void setUserData(String key, Object value) {
userData.put(key, value);
}
@SuppressWarnings("unchecked")
public <T> T getUserData(String key) {
return (T) userData.get(key);
}
public void clearUserData() {
userData.clear();
}
public void resetBuffer() {
buffer.clear();
}
@Override
public String toString() {
return "TxContext{txnId=" + txnId + ", flags=" + flags + ", bufferSize=" + buffer.size() + "}";
}
}
// ===== TxRequest - equivalent to C input void* parameter =====
public static final class TxRequest {
private final String serviceName;
private final Map<String, Object> payload;
private final TxContext context;
public TxRequest(String serviceName, Map<String, Object> payload, TxContext context) {
this.serviceName = Objects.requireNonNull(serviceName);
this.payload = payload != null ? Map.copyOf(payload) : Map.of();
this.context = context;
}
public static TxRequest of(String serviceName) {
return new TxRequest(serviceName, Map.of(), null);
}
public static TxRequest of(String serviceName, Map<String, Object> payload) {
return new TxRequest(serviceName, payload, null);
}
public String getServiceName() {
return serviceName;
}
public Map<String, Object> getPayload() {
return payload;
}
public TxContext getContext() {
return context;
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
return (T) payload.get(key);
}
public boolean has(String key) {
return payload.containsKey(key);
}
}
// ===== TxResponse - equivalent to C output void* parameter =====
public static final class TxResponse {
private final TxResult result;
private final Map<String, Object> data;
private final String errorMessage;
private TxResponse(TxResult result, Map<String, Object> data, String errorMessage) {
this.result = Objects.requireNonNull(result);
this.data = data != null ? Map.copyOf(data) : Map.of();
this.errorMessage = errorMessage;
}
public static TxResponse success() {
return new TxResponse(TxResult.OK, Map.of(), null);
}
public static TxResponse success(Map<String, Object> data) {
return new TxResponse(TxResult.OK, data, null);
}
public static TxResponse error(TxResult result) {
return new TxResponse(result, Map.of(), result.toErrorString());
}
public static TxResponse error(TxResult result, String message) {
return new TxResponse(result, Map.of(), message);
}
public static TxResponse error(String message) {
return new TxResponse(TxResult.ERROR, Map.of(), message);
}
public TxResult getResult() {
return result;
}
public Map<String, Object> getData() {
return data;
}
public String getErrorMessage() {
return errorMessage;
}
public boolean isSuccess() {
return result.isSuccess();
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
return (T) data.get(key);
}
public TxResponse with(String key, Object value) {
Map<String, Object> newData = new HashMap<>(this.data);
newData.put(key, value);
return new TxResponse(this.result, newData, this.errorMessage);
}
}
}