camel-quarkus
camel-quarkus copied to clipboard
How to use cache in Apache Camel Quarkus
Good morning
I am currently working with camel in quarkus and I want to implement cache when making calls to other APIs, however, I have doubts when implementing it in my ResRoute classes:
Class ResRoute
@ApplicationScoped
public class ResRoute extends RouteBuilder {
@ConfigProperty(name = "client.findIndividualCustomerByDocId")
String findIndividualCustomerByDocId;
@ConfigProperty(name = "client.findOrganizacionCustomerByDocId")
String findOrganizacionCustomerByDocId;
@ConfigProperty(name = "path.openapi")
String pathOpenapi;
@ConfigProperty(name = "descripcion.servicio")
String descripcionServicio;
private ConfigureSsl configureSsl;
private static final String SALIDA_BSS_EXCEPTION = "Salida del microservicio BSS FindCustomerByDocId ${exchangeProperty[bodyRs]}";
private static final String MSG_EXCEPTION = "Descripcion de la Exception: ${exception.message}";
public ResRoute() {
configureSsl = new ConfigureSsl();
}
@Override
public void configure() throws Exception {
BeanDate beanDate= new BeanDate();
getContext().getRegistry().bind("BeanDate",beanDate);
restConfiguration()
.bindingMode(RestBindingMode.json)
.dataFormatProperty("json.in.disableFeatures", "FAIL_ON_UNKNOWN_PROPERTIES")
.apiContextPath(pathOpenapi)
.apiProperty("api.title", "FindCustomerByDocId")
.apiProperty("api.description", descripcionServicio)
.apiProperty("api.version", "1.0.0")
.apiProperty("cors", "true");
rest("customerInformation/v1.4.0/users/")
.get("/{user_id}/customers").to("direct:/{user_id}/customers")
.outType(Customer.class)
.param().name("FindCustomerByDocIdResponse").type(body).description("parametro de salida").required(true)
.endParam()
.to("direct:pipeline");
from("direct:pipeline")
.doTry()
.process(new FindCustomerByDocIdProcessorReq())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"User ID: ${exchangeProperty[userId]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Correlator ID: ${exchangeProperty[correlatorId]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Tipo de Documento (Num): ${exchangeProperty[documentTypeNum]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Tipo de Cliente: ${exchangeProperty[customerType]}")
.choice()
.when(simple("${exchangeProperty[customerType]} == 'NATURAL'"))
.process(new FindIndividualCustomerByDocIdProcessorReq())
.to(configureSsl.setupSSLContext(getCamelContext(), findIndividualCustomerByDocId))
.process(new FindIndividualCustomerByDocIdProcessorRes())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio FindIndividualCustomerByDocId ${exchangeProperty[findIndividualCustomerByDocIdResponse]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio BSS FindCustomerByDocId ${exchangeProperty[findCustomerByDocIdResponse]}")
.when(simple("${exchangeProperty[customerType]} == 'JURIDICO'"))
.process(new FindOrganizationCustomerByDocIdProcessorReq())
/*.log("\n["+getCurrentDate()+"]"+"Entrada del microservicio FindOrganizationCustomerByDocId ${exchangeProperty[findOrganizationCustomerByDocIdRequest]}") */
.to(configureSsl.setupSSLContext(getCamelContext(), findOrganizacionCustomerByDocId))
.process(new FindOrganizationCustomerByDocIdProcessorRes())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio FindOrganizationCustomerByDocId ${exchangeProperty[findOrganizationCustomerByDocIdResponse]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio BSS FindCustomerByDocId ${exchangeProperty[findCustomerByDocIdResponse]}")
.endChoice()
.endDoTry()
.doCatch(RequiredValueException.class)
.process(new FindCustomerByDocIdProcessorInvalidFormatException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(HttpHostConnectException.class)
.process(new FindCustomerByDocIdProcessorHttpHostConectionException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(NotFoundDataException.class)
.process(new FindCustomerByDocIdProcessorInformationSubscriber())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(UnknownHostException.class)
.process(new FindCustomerByDocIdProcessorHttpHostConectionException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(NoHttpResponseException.class)
.process(new FindCustomerByDocIdProcessorHttpHostConectionException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(Exception.class)
.process(new FindCustomerByDocIdProcessorException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION);
}
}
In this part he called one of the microservices:
.when(simple("${exchangeProperty[customerType]} == 'NATURAL'"))
.process(new FindIndividualCustomerByDocIdProcessorReq())
.to(configureSsl.setupSSLContext(getCamelContext(), findIndividualCustomerByDocId))
.process(new FindIndividualCustomerByDocIdProcessorRes())
In the FindIndividualCustomerByDocIdProcessorReq class I create the Request for the call:
@Slf4j
public class FindIndividualCustomerByDocIdProcessorReq implements Processor {
private IFindIndividualCustomerByDocIdMapping findIndividualCustomerByDocIdMapping;
private ObjectMapper objectMapper;
public FindIndividualCustomerByDocIdProcessorReq() {
findIndividualCustomerByDocIdMapping = new FindIndividualCustomerByDocumentRequestMappingImpl();
objectMapper = new ObjectMapper();
}
@Override
public void process(Exchange exchange) throws Exception {
String documentType = exchange.getProperty("documentTypeNum").toString();
String documentNumber = exchange.getProperty("documentNumber").toString();
String userId=exchange.getProperty("userId").toString();
FindIndividualCustomerByDocIdInput findIndividualCustomerByDocIdInput;
findIndividualCustomerByDocIdInput = findIndividualCustomerByDocIdMapping.toRequest(documentType,documentNumber,userId);
String jsonFindIndividualCustomerByDocIdRq = objectMapper.writeValueAsString(findIndividualCustomerByDocIdInput);
exchange.setProperty("findIndividualCustomerByDocIdRq", findIndividualCustomerByDocIdInput);
exchange.setProperty("findIndividualCustomerByDocIdRequest", jsonFindIndividualCustomerByDocIdRq);
exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getOut().setHeader(Exchange.HTTP_METHOD, "POST");
exchange.getOut().setBody(jsonFindIndividualCustomerByDocIdRq);
}
}
The request that is created is like the following:
{
"FindIndividualCustomerByDocId": {
"Header": {
"country": "VE",
"lang": "ES",
"entity": "TMVE",
"system": "97",
"subsystem": "APP",
"origin": "VE:TMVE:97:APP",
"userId": "4242374781",
"operation": "FindOrganizationCustomerByDocId",
"destiny": "VE:TMVE:93:RSB",
"timestamp": "2021-01-20T10:23:23.233-04:00",
"msgType": "REQUEST"
},
"Body": {
"findIndividualCustomerByDocIdRequest": {
"documentType": "1",
"documentNumber": "2056133",
"idCountry": "1"
}
}
}
}
If I have 2 fields that must be mandatory (documentType and documentNumber), would it be a key with both fields or can it be just one?
In the FindIndividualCustomerByDocIdProcessorRes class I create the Response for the service response:
@Slf4j
@ApplicationScoped
public class FindIndividualCustomerByDocIdProcessorRes implements Processor {
public ObjectMapper objectMapper;
public IContactMediaMapping contactMediaMapping;
public FindIndividualCustomerByDocIdProcessorRes() {
objectMapper = new ObjectMapper();
contactMediaMapping=new ContactMediaMapping();
}
@Override
public void process(Exchange exchange) throws Exception {
String bodyResponse=exchange.getIn().getBody(String.class);
FindIndividualCustomerByDocIdOutput findIndividualCustomerByDocIdRs=objectMapper.readValue(bodyResponse,FindIndividualCustomerByDocIdOutput.class);
String jsonFindIndividualCustomerByDocIdRs = objectMapper.writeValueAsString(findIndividualCustomerByDocIdRs);
exchange.setProperty("findIndividualCustomerByDocIdResponse", jsonFindIndividualCustomerByDocIdRs);
String msgType=findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getHeaderResponse().getMsgType();
String documentType= (String) exchange.getProperty("documentType");
String documentNumber= (String) exchange.getProperty("documentNumber");
String userId= (String) exchange.getProperty("userId");
if(msgType.equals("ERROR")) {
try {
String msgError = findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponseFault()
.getExceptionCode();
log.info("Código Error Microservice FindIndividualCustomerByDocId: "+findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponseFault().getExceptionCode());
log.info("Mensaje Error MicroserviceFindIndividualCustomerByDocId: "+findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponseFault().getExceptionMessage());
if (msgError.equals("MSG001") || msgError.equals("MSG002") ) {
throw new InvalidFormatException("Error al validar parametros de entradas");
} else if (msgError.equals("MSG062")) {
throw new NotFoundDataException("No se encontro informacion asociado al cliente");
} else if(msgError.equals("MSG019") || msgError.equals("MSG162") || msgError.equals("MSG020")){
throw new Exception("Ha ocurrido un error al realizar la operacion");
}
} catch (UnknownHostException e) {
throw new UnknownHostException("Error de comunicacion con Host Receptor");
}
}
Document document=new Document("VE",documentType,documentNumber);
ArrayList<ContactMedia> contactMedia=new ArrayList<>();
String contactMediaFavorite=findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponse().getPreferredContactMedium();
String email=findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponse().getEmailAddress();
String phoneNumber=findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponse().getTelephoneNumber();
contactMedia=contactMediaMapping.toRequest(email,phoneNumber,contactMediaFavorite);
String name=findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponse().getName()+" "+findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponse().getLastName();
String customerSince= String.valueOf(findIndividualCustomerByDocIdRs.getFindIndividualCustomerByDocIdResponseHB().getFindIndividualCustomerByDocIdBodyResponse().getFindIndividualCustomerByDocIdResponse().getCustomerSince());
Customer customer=new Customer(userId,name,document,contactMedia, Segment.CONSUMER.getType(), customerSince);
String jsonFindCustomerByDocIdRs = objectMapper.writeValueAsString(customer);
exchange.setProperty("findCustomerByDocIdRs", customer);
exchange.setProperty("findCustomerByDocIdResponse", jsonFindCustomerByDocIdRs);
exchange.getMessage().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, "200");
exchange.getMessage().setBody(customer);
}
}
My question is how can I edit my code to add cache to my calls?
I tried the following way, but it gives me an error code http 500:
@ApplicationScoped
public class ResRoute extends RouteBuilder {
@ConfigProperty(name = "client.findIndividualCustomerByDocId")
String findIndividualCustomerByDocId;
@ConfigProperty(name = "client.findOrganizacionCustomerByDocId")
String findOrganizacionCustomerByDocId;
@ConfigProperty(name = "path.openapi")
String pathOpenapi;
@ConfigProperty(name = "descripcion.servicio")
String descripcionServicio;
private ConfigureSsl configureSsl;
private static final String SALIDA_BSS_EXCEPTION = "Salida del microservicio BSS FindCustomerByDocId ${exchangeProperty[bodyRs]}";
private static final String MSG_EXCEPTION = "Descripcion de la Exception: ${exception.message}";
public ResRoute() {
configureSsl = new ConfigureSsl();
}
@Override
public void configure() throws Exception {
BeanDate beanDate= new BeanDate();
getContext().getRegistry().bind("BeanDate",beanDate);
restConfiguration()
.bindingMode(RestBindingMode.json)
.dataFormatProperty("json.in.disableFeatures", "FAIL_ON_UNKNOWN_PROPERTIES")
.apiContextPath(pathOpenapi)
.apiProperty("api.title", "FindCustomerByDocId")
.apiProperty("api.description", descripcionServicio)
.apiProperty("api.version", "1.0.0")
.apiProperty("cors", "true");
rest("customerInformation/v1.4.0/users/")
.get("/{user_id}/customers").to("direct:/{user_id}/customers")
.outType(Customer.class)
.param().name("FindCustomerByDocIdResponse").type(body).description("parametro de salida").required(true)
.endParam()
.to("direct:pipeline");
from("direct:pipeline")
.doTry()
.process(new FindCustomerByDocIdProcessorReq())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"User ID: ${exchangeProperty[userId]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Correlator ID: ${exchangeProperty[correlatorId]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Tipo de Documento (Num): ${exchangeProperty[documentTypeNum]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Tipo de Cliente: ${exchangeProperty[customerType]}")
.choice()
.when(simple("${exchangeProperty[customerType]} == 'NATURAL'"))
.process(new FindIndividualCustomerByDocIdProcessorReq())
/* .log("\n["+getCurrentDate()+"]"+"Entrada del microservicio FindIndividualCustomerByDocId ${exchangeProperty[findIndividualCustomerByDocIdRequest]}") */
.to(configureSsl.setupSSLContext(getCamelContext(), findIndividualCustomerByDocId))
.process(new FindIndividualCustomerByDocIdProcessorRes())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio FindIndividualCustomerByDocId ${exchangeProperty[findIndividualCustomerByDocIdResponse]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio BSS FindCustomerByDocId ${exchangeProperty[findCustomerByDocIdResponse]}")
.when(simple("${exchangeProperty[customerType]} == 'JURIDICO'"))
.process(new FindOrganizationCustomerByDocIdProcessorReq())
.setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_GET))
.setHeader(CaffeineConstants.KEY, header("$exchangeProperty[userId]"))
.toF("caffeine-cache://%s", "OrganizationCache")
.log("Has Result ${header.CamelCaffeineActionHasResult} ActionSucceeded ${header.CamelCaffeineActionSucceeded}")
.choice().when(header(CaffeineConstants.ACTION_HAS_RESULT).isEqualTo(Boolean.FALSE))
.to(configureSsl.setupSSLContext(getCamelContext(), findOrganizacionCustomerByDocId))
.setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT))
.setHeader(CaffeineConstants.KEY, header("$exchangeProperty[userId]"))
.toF("caffeine-cache://%s", "OrganizationCache")
.process(new FindOrganizationCustomerByDocIdProcessorRes())
.otherwise()
.log("Cache is working")
/*.log("\n["+getCurrentDate()+"]"+"Entrada del microservicio FindOrganizationCustomerByDocId ${exchangeProperty[findOrganizationCustomerByDocIdRequest]}") */
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio FindOrganizationCustomerByDocId ${exchangeProperty[findOrganizationCustomerByDocIdResponse]}")
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+"Salida del microservicio BSS FindCustomerByDocId ${exchangeProperty[findCustomerByDocIdResponse]}")
.endChoice()
.endDoTry()
.doCatch(RequiredValueException.class)
.process(new FindCustomerByDocIdProcessorInvalidFormatException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(HttpHostConnectException.class)
.process(new FindCustomerByDocIdProcessorHttpHostConectionException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(NotFoundDataException.class)
.process(new FindCustomerByDocIdProcessorInformationSubscriber())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(UnknownHostException.class)
.process(new FindCustomerByDocIdProcessorHttpHostConectionException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION)
.doCatch(NoHttpResponseException.class)
.process(new FindCustomerByDocIdProcessorHttpHostConectionException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION);
.doCatch(Exception.class)
.process(new FindCustomerByDocIdProcessorException())
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+MSG_EXCEPTION)
.log("\n[${bean:BeanDate.getCurrentDateTime()}] "+SALIDA_BSS_EXCEPTION);
}
}
The error it gives me is the following, it seems to me that it is not correctly taking the value of the key:
Failed delivery for (MessageId: 1089E8B0FF423A6-0000000000000000 on ExchangeId: 1089E8B0FF423A6-0000000000000000). Exhausted after delivery attempt: 1 caught: org.apache.camel.CamelExchangeException: No value provided in header or as default value (CamelCaffeineKey). Exchange[1089E8B0FF423A6-0000000000000000]
Thanks for the support in advance