Я определяю интерфейс для всех моих компонентов mapper, которые извлекают значения, используя xpath из полей xml. В качестве входных данных используется полезная нагрузка, преобразованная в качестве документа, а также обернутая торговая модель, возвращающая то же самое с заполненным полем:
interface Mapper {
Model<Trade> map(Document document, Model<Trade> model);
}
Я определяю один родительский класс как абстракцию для дочерних классов, чтобы предоставить выражение xpath:
abstract class TradeMapper implements Mapper {
abstract String getXpathExpression();
}
Реализация одного из картографов как компонента Spring:
@Component
class QuantityMapper extends TradeMapper {
@Override
public Model<Trade> map(Document document, Model<Trade> model) {
//implementation logic to get qty and populate the trade model
//return the same trade model with qty field populates
return model(model)
.quantity(qty);
.build();
}
@Override
String getXpathExpression() {
return "XXX";
}
}
@Component
class IdMapper extends TradeMapper {
@Override
public Model<Trade> map(Document document, Model<Trade> model) {
//implementation logic to get id and populate the trade model
}
}
В моем приложении я получаю два типа сделок. Допустим, initial
и actual
. Оба они должны быть преобразованы в модель Trade
в определенный момент жизненного цикла события. Для initial
я передаю Message
, который затем преобразуется в строковое сообщение -> в тип документа ->, а затем с помощью картографов строит объект Trade для дальнейшей обработки. Это все хорошо.
@Service
class TradeRequestService {
@Autowired
private List<TradeMapper> mappers;
void callback(Model<Message> model) {
String message = model.getPayload(model);
Document document = getDocument(message);
mappers.forEach(tradeMapper -> tradeMapper.map(document, model));
}
private Document getDocument(String message) {
return XmlUtils.toDoc(message);
}
}
Моя проблема в точке входа и для сообщения типа actual
.
/**
* Message Entry Point
*/
@Service
class MessageReceiver {
@Autowired
private List<TradeMapper> mappers;
void callback(String message) {
if (message.contains("initial")) {
return model.withPayload(new Message(message)); //callback in TradeRequestService then receives this model for conversion
} else if (message.contains("actual")) {
// derive id from String
} else {
return null;
}
}
}
В моем приложении мне нужно уже получить сообщение типа Id
для actual
, используя IdMapper
на уровне обслуживания MessageReceiver
перед модельюпередается в TradeRequestService
обратный вызов. id
требуется в точке входа для получения некоторой метаинформации перед обработкой последующих обратных вызовов событий.
Я изо всех сил пытаюсь преобразовать сообщение типа actual
в точке входа в Document
и с помощью IdMapper
вывести Id в виде строки, а контракт - Document. Как я могу реструктурировать код, чтобы получить Id из полезной нагрузки String
в точке входа? Должно ли преобразование в Document и Id mapping перейти на общий интерфейс? Будем весьма благодарны за некоторые идеи или предложения о том, какой шаблон я могу использовать в этом примере или в примерах кода.