Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caffeine time based eviction policy does not work in native mode #6224

Closed
cesarjv opened this issue Jun 25, 2024 · 7 comments
Closed

Caffeine time based eviction policy does not work in native mode #6224

cesarjv opened this issue Jun 25, 2024 · 7 comments
Assignees
Labels
Milestone

Comments

@cesarjv
Copy link

cesarjv commented Jun 25, 2024

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

@jamesnetherton
Copy link
Contributor

jamesnetherton commented Jun 25, 2024

It may be related how you set the cache key header. Instead of:

.setHeader(CaffeineConstants.KEY, header("$exchangeProperty[userId]"))

Try:

.setHeader("CaffeineConstants.KEY").exchangeProperty("userId")

@cesarjv
Copy link
Author

cesarjv commented Jun 25, 2024

@jamesnetherton Ready I managed to solve, now I am enabling the elimination of the cache after a certain time, but I cannot eliminate it, that is, use the properties camel.component.caffeine-cache.expire-after-access-time and camel.component.caffeine-cache .expire-after-write-time, however, I am testing and after setting a time to 60 seconds, the query is still being done in the cache:

#cache
camel.component.caffeine-cache.expire-after-write-time=60
camel.component.caffeine-cache.expire-after-access-time=60

Test number 1 at 2:00 PM

Screenshot 2024-06-25 140040

Query the cache:

CamelCaffeineActionHasResult =true

Screenshot 2024-06-25 140143

Test number 2 at 2:04 PM, in this chaos 240 seconds have already passed since it was cached:

prueba 4 minutos despues

Keep consulting the cache:

CamelCaffeineActionHasResult =true

Screenshot 2024-06-25 140535

What could be the cause of this behavior? Shouldn't it be possible to consult the service again outside the cache after the expiration time (60sec)?

This is how I ended up configuring my 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())
                .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_GET))
                .setHeader(CaffeineConstants.KEY).exchangeProperty("documentNumber")
                .toF("caffeine-cache://%s", "IndividualCache")
                .log("Hay Resultado en Cache de la consulta asociado al siguiente documento: ${exchangeProperty[userId]} ${header.CamelCaffeineActionHasResult}}")
                .log("CamelCaffeineActionSucceeded: ${header.CamelCaffeineActionSucceeded}")
                .choice().when(header(CaffeineConstants.ACTION_HAS_RESULT).isEqualTo(Boolean.FALSE))
                    .to(configureSsl.setupSSLContext(getCamelContext(), findIndividualCustomerByDocId))
                    .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT))
                    .setHeader(CaffeineConstants.KEY).exchangeProperty("documentNumber")
                    .toF("caffeine-cache://%s", "IndividualCache")
                    .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]}")
                .otherwise()
                    .log("Cache is working")
                    .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())
                .to(configureSsl.setupSSLContext(getCamelContext(), findOrganizacionCustomerByDocId))
                .process(new FindOrganizationCustomerByDocIdProcessorRes())
                /*.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);
    }
}

@jamesnetherton
Copy link
Contributor

jamesnetherton commented Jun 26, 2024

You need to set:

camel.component.caffeine-cache.eviction-type = TIME_BASED

Otherwise expire-after-access-time& expire-after-write-time has no effect since the default eviction-type is based on the cache size.

Also:

https://stackoverflow.com/questions/78669211/configuring-cache-expiration-time-in-apache-camel-quarkus

@jamesnetherton jamesnetherton added the question Further information is requested label Jun 26, 2024
@cesarjv
Copy link
Author

cesarjv commented Jun 26, 2024

Thank you so much @jamesnetherton

Everything works great for me locally, but I have the following problem once I do the native compilation, what could be happening?

12:04:05 ERROR traceId=, parentId=, spanId=, sampled= [or.ap.ca.im.en.AbstractCamelContext] (main) Error starting CamelContext (camel-1) due to exception thrown: Failed to start route route2 because of null: org.apache.camel.FailedToStartRouteException: Failed to start route route2 because of null
	at org.apache.camel.impl.engine.RouteService.warmUp(RouteService.java:123)
	at org.apache.camel.impl.engine.InternalRouteStartupManager.doWarmUpRoutes(InternalRouteStartupManager.java:306)
	at org.apache.camel.impl.engine.InternalRouteStartupManager.safelyStartRouteServices(InternalRouteStartupManager.java:189)
	at org.apache.camel.impl.engine.InternalRouteStartupManager.doStartOrResumeRoutes(InternalRouteStartupManager.java:147)
	at org.apache.camel.impl.engine.AbstractCamelContext.doStartCamel(AbstractCamelContext.java:3425)
	at org.apache.camel.impl.engine.AbstractCamelContext.doStartContext(AbstractCamelContext.java:3094)
	at org.apache.camel.impl.engine.AbstractCamelContext.doStart(AbstractCamelContext.java:3049)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.impl.engine.AbstractCamelContext.start(AbstractCamelContext.java:2698)
	at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:262)
	at org.apache.camel.quarkus.main.CamelMain.doStart(CamelMain.java:94)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.quarkus.main.CamelMain.startEngine(CamelMain.java:140)
	at org.apache.camel.quarkus.main.CamelMainRuntime.start(CamelMainRuntime.java:49)
	at org.apache.camel.quarkus.core.CamelBootstrapRecorder.start(CamelBootstrapRecorder.java:45)
	at io.quarkus.deployment.steps.CamelBootstrapProcessor$boot173480958.deploy_0(Unknown Source)
	at io.quarkus.deployment.steps.CamelBootstrapProcessor$boot173480958.deploy(Unknown Source)
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:108)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
	at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Caused by: java.lang.IllegalStateException: com.github.benmanes.caffeine.cache.SSAW
	at com.github.benmanes.caffeine.cache.LocalCacheFactory.loadFactory(LocalCacheFactory.java:90)
	at com.github.benmanes.caffeine.cache.LocalCacheFactory.newBoundedLocalCache(LocalCacheFactory.java:40)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCache.<init>(BoundedLocalCache.java:3687)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCache.<init>(BoundedLocalCache.java:3683)
	at com.github.benmanes.caffeine.cache.Caffeine.build(Caffeine.java:1035)
	at org.apache.camel.component.caffeine.cache.CaffeineCacheComponent.lambda$getOrCreateCache$0(CaffeineCacheComponent.java:68)
	at [email protected]/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
	at org.apache.camel.component.caffeine.cache.CaffeineCacheComponent.getOrCreateCache(CaffeineCacheComponent.java:65)
	at org.apache.camel.component.caffeine.cache.CaffeineCacheEndpoint.doStart(CaffeineCacheEndpoint.java:72)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.processor.SendProcessor.doStart(SendProcessor.java:242)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.impl.engine.DefaultChannel.doStart(DefaultChannel.java:126)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:116)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.processor.Pipeline.doStart(Pipeline.java:207)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.processor.DelegateAsyncProcessor.doStart(DelegateAsyncProcessor.java:89)
	at org.apache.camel.processor.FilterProcessor.doStart(FilterProcessor.java:150)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:116)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.processor.ChoiceProcessor.doStart(ChoiceProcessor.java:185)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.impl.engine.DefaultChannel.doStart(DefaultChannel.java:126)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:116)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.processor.Pipeline.doStart(Pipeline.java:207)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.processor.TryProcessor.doStart(TryProcessor.java:139)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.impl.engine.DefaultChannel.doStart(DefaultChannel.java:126)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:116)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:130)
	at org.apache.camel.processor.Pipeline.doStart(Pipeline.java:207)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.support.processor.DelegateAsyncProcessor.doStart(DelegateAsyncProcessor.java:89)
	at org.apache.camel.support.service.BaseService.start(BaseService.java:119)
	at org.apache.camel.support.service.ServiceHelper.startService(ServiceHelper.java:113)
	at org.apache.camel.impl.engine.RouteService.startChildServices(RouteService.java:396)
	at org.apache.camel.impl.engine.RouteService.doWarmUp(RouteService.java:193)
	at org.apache.camel.impl.engine.RouteService.warmUp(RouteService.java:121)
	... 23 more
Caused by: java.lang.ClassNotFoundException: com.github.benmanes.caffeine.cache.SSAW
	at [email protected]/java.lang.Class.forName(DynamicHub.java:1132)
	at [email protected]/java.lang.Class.forName(DynamicHub.java:1105)
	at com.github.benmanes.caffeine.cache.LocalCacheFactory.loadFactory(LocalCacheFactory.java:84)
	... 82 more

I attach my pom.xml

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.tmve.customer</groupId>
  <artifactId>find-customer-by-doc-id</artifactId>
  <version>1.0.2-DEV</version>
  <properties>
    <compiler-plugin.version>3.10.1</compiler-plugin.version>
    <maven.compiler.release>17</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
    <quarkus.platform.version>2.16.7.Final</quarkus.platform.version>
    <skipITs>true</skipITs>
    <surefire-plugin.version>3.0.0-M7</surefire-plugin.version>
    <jacoco.version>0.8.7</jacoco.version>
    <sonar.coverage.jacoco.xmlReportPaths>${project.build.directory}/jacoco-report/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-camel-bom</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-rest-openapi</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-bean</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-direct</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-http</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-jaxb</artifactId>
    </dependency>

    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-log</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-rest</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jsonb</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.22</version>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-openapi-java</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-openapi</artifactId>
    </dependency>
    <dependency>
      <groupId>org.webjars</groupId>
      <artifactId>swagger-ui</artifactId>
      <version>4.11.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.camel.quarkus</groupId>
      <artifactId>camel-quarkus-opentelemetry</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-opentelemetry-exporter-otlp</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jacoco</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-caffeine</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.platform.version}</version>
        <extensions>true</extensions>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
              <goal>generate-code</goal>
              <goal>generate-code-tests</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
        <configuration>
          <compilerArgs>
            <arg>-parameters</arg>
          </compilerArgs>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemPropertyVariables>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
            <maven.home>${maven.home}</maven.home>
          </systemPropertyVariables>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>verify</goal>
            </goals>
            <configuration>
              <systemPropertyVariables>
                <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                <maven.home>${maven.home}</maven.home>
              </systemPropertyVariables>
            </configuration>
          </execution>
          <execution>
            <id>integration-tests</id>
            <phase>integration-test</phase>
            <configuration>
              <excludedGroups>!integration</excludedGroups>
              <groups>integration</groups>
              <systemPropertyVariables>
                <jacoco-agent.destfile>${project.build.directory}/jacoco-quarkus.exec</jacoco-agent.destfile>
              </systemPropertyVariables>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco.version}</version>
        <executions>
          <execution>
            <id>default-prepare-agent</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
            <configuration>
              <exclClassLoaders>*QuarkusClassLoader</exclClassLoaders>
              <destFile>${project.build.directory}/jacoco-quarkus.exec</destFile>
              <append>true</append>
              <excludes>
              </excludes>
            </configuration>
          </execution>
          <execution>
            <id>report</id>
            <phase>post-integration-test</phase>
            <goals>
              <goal>report</goal>
            </goals>
            <configuration>
              <dataFile>${project.build.directory}/jacoco-quarkus.exec</dataFile>
              <outputDirectory>${project.build.directory}/jacoco-report</outputDirectory>
            </configuration>
          </execution>
          <execution>
            <id>jacoco-check</id>
            <goals>
              <goal>check</goal>
            </goals>
            <phase>post-integration-test</phase>
            <configuration>
              <dataFile>${project.build.directory}/jacoco-quarkus.exec</dataFile>
              <rules>
                <rule>
                  <element>BUNDLE</element>
                  <limits>
                    <limit>
                      <counter>LINE</counter>
                      <value>COVEREDRATIO</value>
                      <minimum>0.5</minimum>
                    </limit>
                    <limit>
                      <counter>BRANCH</counter>
                      <value>COVEREDRATIO</value>
                      <minimum>0.5</minimum>
                    </limit>
                  </limits>
                </rule>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <properties>
        <skipITs>false</skipITs>
        <quarkus.package.type>native</quarkus.package.type>
      </properties>
    </profile>
  </profiles>
</project>

ResRoute

package org.tmve.customer.ms.route;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.caffeine.CaffeineConstants;
import org.apache.camel.model.rest.RestBindingMode;
import org.apache.http.NoHttpResponseException;
import org.apache.http.conn.HttpHostConnectException;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.tmve.customer.ms.beans.Customer;
import org.tmve.customer.ms.exceptions.RequiredValueException;
import org.tmve.customer.ms.exceptions.NotFoundDataException;
import org.tmve.customer.ms.processor.*;
import org.tmve.customer.ms.utilities.BeanDate;

import javax.enterprise.context.ApplicationScoped;
import java.net.UnknownHostException;

import static org.apache.camel.model.rest.RestParamType.body;

@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())
                    .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_GET))
                    .setHeader(CaffeineConstants.KEY).exchangeProperty("documentNumber")
                    .toF("caffeine-cache://%s", "IndividualCache")
                    .log("Hay Resultado en Cache de la consulta asociado al siguiente documento: ${exchangeProperty[userId]} ${header.CamelCaffeineActionHasResult}}")
                    .log("CamelCaffeineActionSucceeded: ${header.CamelCaffeineActionSucceeded}")
                    .choice().when(header(CaffeineConstants.ACTION_HAS_RESULT).isEqualTo(Boolean.FALSE))
                        .to(configureSsl.setupSSLContext(getCamelContext(), findIndividualCustomerByDocId))
                        .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT))
                        .setHeader(CaffeineConstants.KEY).exchangeProperty("documentNumber")
                        .toF("caffeine-cache://%s", "IndividualCache")
                        .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]}")
                    .otherwise()
                        .log("Cache is working")
                        .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]}")
                    .endChoice()
                .when(simple("${exchangeProperty[customerType]} == 'JURIDICO'"))
                    .process(new FindOrganizationCustomerByDocIdProcessorReq())
                    .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_GET))
                    .setHeader(CaffeineConstants.KEY).exchangeProperty("documentNumber")
                    .toF("caffeine-cache://%s", "OrganizationCache")
                    .log("Hay Resultado en Cache de la consulta asociado al siguiente documento: ${exchangeProperty[userId]} ${header.CamelCaffeineActionHasResult}}")
                    .log("CamelCaffeineActionSucceeded: ${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).exchangeProperty("documentNumber")
                        .toF("caffeine-cache://%s", "OrganizationCache")
                        .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]}")
                    .otherwise()
                        .log("Cache is working")
                        .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()
                .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);
    }
}

application.properties

#https
quarkus.ssl.native=true
quarkus.http.ssl-port=${PORT-SSl:8080}
quarkus.http.read-timeout=${SERVICE_READ_TIMEOUT:30s}
quarkus.http.connect-timeout=${SERVICE_CONNECT_TIMEOUT:30s}
quarkus.http.timeout=${SERVICE_TIMEOUT:30s}
quarkus.http.insecure-requests=disabled
quarkus.http.ssl.certificate.key-store-file=${UBICATION_CERTIFICATE_SSL:META-INF/resources/srvdevrma1.jks}
quarkus.http.ssl.certificate.key-store-file-type=JKS
quarkus.http.ssl.certificate.key-store-password=${PASSWORD_CERTIFICATE_SSL:service123}
quarkus.http.ssl.certificate.key-store-key-alias=${ALIAS_CERTIFICATE_SSL:srvdevrma1}
quarkus.http.cors=true
path=/customerInformation/v1.4.0/users/.*/customers

client.file=${CLIENT-FILE:META-INF/resources/srvdevrma1.jks}
client.password=${CLIENT-PASSWORD:service123}
quarkus.native.additional-build-args=-H:IncludeResources=.*\\.jks
quarkus.native.resources.includes=*.jks
#GlobalVariables
server.variables.msgType=RESPONSE
server.variables.msgTypeError=ERROR

error.400.code=INVALID_ARGUMENT
error.400.message=Client specified an invalid argument, request body or query param

error.403.code=PERMISSION_DENIED
error.403.message=Authenticated user has no permission to access the requested resource

error.404.code=NOT_FOUND
error.404.message=A specified resource is not found

error.500.code=INTERNAL
error.500.message=Server error

error.503.code=UNAVAILABLE
error.503.message=Service unavailable

error.504.code=TIMEOUT
error.504.message=Request timeout exceeded. Try it later

descripcion.servicio=MicroServicio que permite orquestar la busqueda de informacion asociados a clientes Naturales y Juridicos

#endpoints_ms- local
client.findIndividualCustomerByDocId=${UBICATION-URL-FIND-INDIVIDUAL-CUSTOMER-BY-DOC-ID:https://10.162.128.94:30000/api/FindIndividualCustomerByDocId}
client.findOrganizacionCustomerByDocId=${UBICATION-URL-FIND-ORGANIZATION-CUSTOMER-BY-DOC-ID:https://10.162.128.94:30000/api/FindOrganizationCustomerByDocId}
#timeZone
quarkus.jackson.timezone=${TIME_ZONE:GMT-4}

#Ruta OpenApi
path.openapi=customerInformation/v1.4.0/users/.*/customers/openapi/swagger-ui/
quarkus.camel.openapi.expose.enabled=true
#camel.rest.api-context-path = /openapi.yaml
#quarkus.swagger-ui.urls.camel = /openapi.yaml
#openapi
quarkus.smallrye-openapi.path=/api/FindCustomerByDocId/swagger
#quarkus.swagger-ui.path= /api/FindCustomerByDocId/swagger-ui/
quarkus.swagger-ui.always-include=true

#cache
camel.component.caffeine-cache.expire-after-write-time=${CACHE_EXPIRE_WRITE_ACCESS_TIME:60}
camel.component.caffeine-cache.expire-after-access-time=${CACHE_EXPIRE_AFTER_ACCESS_TIME:60}
camel.component.caffeine-cache.eviction-type=${CACHE_EVICTION_TIME:TIME_BASED}
#opentelemetry
quarkus.application.name=FindCustomerByDocId
quarkus.opentelemetry.enabled=true
quarkus.opentelemetry.tracer.exporter.otlp.endpoint=${URL_JAEGER:http://172.28.2.107:4317}
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n
quarkus.http.header."X-Content-Type-Options".value=nosniff
quarkus.http.header."X-Frame-Options".value=DENY
quarkus.http.header."Content-Security-Policy".value=default-src
quarkus.http.header."X-XSS-Protection".value=1; mode=block
quarkus.http.header."Expect-CT".value=report-only
quarkus.http.header."Permissions-Policy".value=geolocation=*, fullscreen=*
quarkus.http.header."Cache-Control".value=no-cache
#jacoco report
#quarkus.jacoco.excludes=com/tmve/findaccountinvoicedetail/beans/*, com/tmve/findaccountinvoicedetail/ms/processor/exceptions/*,

That could be happening?

@jamesnetherton
Copy link
Contributor

To work around the problem, try adding a configuration property like:

quarkus.camel.native.reflection.include-patterns = com.github.benmanes.caffeine.cache.SSAW

@jamesnetherton
Copy link
Contributor

To work around the problem, try adding a configuration property like:

quarkus.camel.native.reflection.include-patterns = com.github.benmanes.caffeine.cache.SSAW

This will get fixed permanently in Quarkus 3.13.0 (maybe 3.12.1).

@cesarjv
Copy link
Author

cesarjv commented Jun 27, 2024

@jamesnetherton Thank you very much, in the end I had to add the annotation with 2 values:

quarkus.camel.native.reflection.include-patterns = com.github.benmanes.caffeine.cache.SSAW, com.github.benmanes.caffeine.cache.PSAW

@jamesnetherton jamesnetherton self-assigned this Jul 22, 2024
@jamesnetherton jamesnetherton added this to the 3.13.0 milestone Jul 22, 2024
@jamesnetherton jamesnetherton changed the title How to use cache in Apache Camel Quarkus Caffeine time based eviction policy does not work in native mode Jul 24, 2024
@jamesnetherton jamesnetherton added bug Something isn't working and removed question Further information is requested labels Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants