我正在使用Order请求的Collection,每个请求都有一个标识符和order_id列表(例如abc123,def456、789ghl..so等)。基本上,集合可以包含4种类型的订单,我有4个API分别获取它们的“订单状态”。我的要求是实现队列机制,并将这些请求发送到相应的API,然后使用Spring Boot将响应发送回调用方。共有4个约束:
我正在为此目的实现Spring amqp和RabbitMq。
任何人都可以建议该方法或如何实施此方法吗?我无法实现第二,第三和第四约束。
@服务 公共类ShipmentListener {
private static final Logger log = LoggerFactory.getLogger(ShipmentListener.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private ApplicationConfigReader appConfigReader;
@Autowired
ApiMessageRequestBufferGenerator shipmentBuffer;
private final CountDownLatch latch = new CountDownLatch(5);
@RabbitListener(queues = "${shipment.queue.name}")
public Map<String, List<String>> shipmentConsumer(final MessageRequest message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
log.info("Received message: {} from shipment queue.", message);
Optional<List<MessageRequest>> optMessageRequest = shipmentBuffer.getMessageRequestBuffer().add(message);
if (optMessageRequest.isPresent()) {
Map<String, List<String>> test = new HashMap<String, List<String>>();
List<MessageRequest> listRequest = optMessageRequest.get();
for (List<String> request : createApiBulkRequestData(listRequest)) {
test.putAll(callShipmentAPI(request));
}
return test;
}
channel.basicAck(tag, false);
latch.countDown();
return null;
}
private List<List<String>> createApiBulkRequestData(List<MessageRequest> listOfRequest) {
List<List<String>> listOLists = new ArrayList<List<String>>();
List<String> allQueryParam = listOfRequest.stream()
.map(value -> value.getQueryParam())
.map(map -> map.entrySet())
.flatMap(each -> each.stream())
.map(m -> m.getKey())
.collect(Collectors.toList());
int counter = 1;
List<String> values = new ArrayList<>();
while (counter < allQueryParam.size()) {
values.add(allQueryParam.get(counter++));
if (counter % 5 == 0) {
listOLists.add(values);
values = new ArrayList<>();
}
}
if(values.size() < 0 && values.size() < 5) {
listOLists.add(values);
}
return listOLists;
}
private Map<String, List<String>> callShipmentAPI(List<String> message) {
ParameterizedTypeReference<Map<String, List<String>>> typeRef = null;
ResponseEntity<Map<String, List<String>>> response = null;
HttpEntity<String> requestEntity = new HttpEntity<>(buildRequestHeaders());
String shipmentUrl = String.valueOf(buildShipmentUrl(message));
try {
typeRef = new ParameterizedTypeReference<Map<String, List<String>>>() {
};
log.info("Making REST call to the API >>");
response = restTemplate.exchange(shipmentUrl, HttpMethod.GET, requestEntity, typeRef);
if (response.getStatusCode().is2xxSuccessful()) {
log.info("<<<<<<<<<<<<<<<<<<<<DATA RECEIVED>>>>>>>>>>>>>>>>>>>");
log.info("Data recieved \n" + response.getBody());
}
log.info("<< Exiting callShipmentApi() after API call.");
} catch (HttpClientErrorException ex) {
if (ex.getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE) {
throw new AmqpRejectAndDontRequeueException(ex);
}
} catch (Exception e) {
log.error("Internal server error occurred in API call. Bypassing message requeue {}", e);
throw new AmqpRejectAndDontRequeueException(e);
}
return response.getBody();
}