Search in sources :

Example 11 with JsonObject

use of org.apache.camel.util.json.JsonObject in project ph-ee-connector-mpesa by openMF.

the class SafaricomRoutesBuilder method configure.

@Override
public void configure() {
    /*
         * Use this endpoint for getting the mpesa transaction status
         * The request parameter is same as the safaricom standards
         */
    from("rest:POST:/buygoods/transactionstatus").id("buy-goods-transaction-status").process(exchange -> {
        String body = exchange.getIn().getBody(String.class);
        TransactionStatusRequestDTO transactionStatusRequestDTO = objectMapper.readValue(body, TransactionStatusRequestDTO.class);
        exchange.setProperty(BUY_GOODS_TRANSACTION_STATUS_BODY, transactionStatusRequestDTO);
        logger.info(body);
    }).to("direct:lipana-transaction-status");
    /*
           Use this endpoint for receiving the callback form safaricom mpesa endpoint
         */
    from("rest:POST:/buygoods/callback").id("buy-goods-callback").log(LoggingLevel.INFO, "Callback body \n\n..\n\n..\n\n.. ${body}").unmarshal().json(JsonLibrary.Jackson, JsonObject.class).to("direct:callback-handler");
    from("direct:callback-handler").id("callback-handler").log(LoggingLevel.INFO, "Handling callback body").process(exchange -> {
        JsonObject response = exchange.getIn().getBody(JsonObject.class);
        StkCallback callback = SafaricomUtils.getStkCallback(response);
        String checkoutRequestId = callback.getCheckoutRequestId();
        String clientCorrelationId = correlationIDStore.getClientCorrelation(checkoutRequestId);
        exchange.setProperty(TRANSACTION_ID, clientCorrelationId);
        exchange.setProperty(SERVER_TRANSACTION_ID, checkoutRequestId);
        logger.info("\n\n StkCallback " + callback + "\n");
        logger.info("\n\n Correlation Key " + clientCorrelationId + "\n\n");
        if (callback.getResultCode() == 0) {
            exchange.setProperty(TRANSACTION_FAILED, false);
            exchange.setProperty(SERVER_TRANSACTION_RECEIPT_NUMBER, SafaricomUtils.getTransactionId(response));
        } else {
            exchange.setProperty(ERROR_CODE, callback.getResultCode().toString());
            exchange.setProperty(ERROR_INFORMATION, exchange.getIn().getBody(String.class));
            exchange.setProperty(ERROR_DESCRIPTION, callback.getResultDesc());
        }
    }).choice().when(exchangeProperty(ERROR_CODE).isNotNull()).to("direct:filter-by-error-code").choice().when(exchangeProperty(IS_ERROR_RECOVERABLE).isEqualTo(false)).process(exchange -> exchange.setProperty(TRANSACTION_FAILED, true)).process(collectionResponseProcessor).otherwise().log("Current resultCode is recoverable hence waiting for getting transaction status").endChoice().otherwise().process(collectionResponseProcessor);
    /*
          Rest endpoint to initiate payment for buy goods

          Sample request body: {
              "BusinessShortCode": 174379,
              "Amount": 1,
              "PartyA": 254708374149,
              "PartyB": 174379,
              "PhoneNumber": 254708374149,
              "CallBackURL": "https://mydomain.com/path",
              "AccountReference": "CompanyXLTD",
              "TransactionDesc": "Payment of X"
            }
         */
    from("rest:POST:/buygoods").id("buy-goods-online").process(exchange -> {
        String body = exchange.getIn().getBody(String.class);
        BuyGoodsPaymentRequestDTO buyGoodsPaymentRequestDTO = objectMapper.readValue(body, BuyGoodsPaymentRequestDTO.class);
        exchange.setProperty(BUY_GOODS_REQUEST_BODY, buyGoodsPaymentRequestDTO);
        logger.info(body);
        logger.info(buyGoodsPaymentRequestDTO.toString());
    }).to("direct:buy-goods-base");
    /*
         * Starts the payment flow
         *
         * Step1: Authenticate the user by initiating [get-access-token] flow
         * Step2: On successful [Step1], directs to [lipana-buy-goods] flow
         */
    from("direct:buy-goods-base").id("buy-goods-base").log(LoggingLevel.INFO, "Starting buy goods flow").to("direct:get-access-token").process(exchange -> exchange.setProperty(ACCESS_TOKEN, accessTokenStore.getAccessToken())).log(LoggingLevel.INFO, "Got access token, moving on to API call.").to("direct:lipana-buy-goods").log(LoggingLevel.INFO, "Status: ${header.CamelHttpResponseCode}").log(LoggingLevel.INFO, "Transaction API response: ${body}").to("direct:transaction-response-handler");
    /*
         * Starts the payment flow
         *
         * Step1: Authenticate the user by initiating [get-access-token] flow
         * Step2: On successful [Step1], directs to [lipana-buy-goods] flow
         */
    from("direct:get-transaction-status-base").id("buy-goods-get-transaction-status-base").log(LoggingLevel.INFO, "Starting buy goods transaction status flow").choice().when(exchangeProperty(SERVER_TRANSACTION_STATUS_RETRY_COUNT).isLessThanOrEqualTo(maxRetryCount)).to("direct:get-access-token").process(exchange -> exchange.setProperty(ACCESS_TOKEN, accessTokenStore.getAccessToken())).log(LoggingLevel.INFO, "Got access token, moving on to API call.").to("direct:lipana-transaction-status").log(LoggingLevel.INFO, "Status: ${header.CamelHttpResponseCode}").log(LoggingLevel.INFO, "Transaction API response: ${body}").to("direct:transaction-status-response-handler").otherwise().process(exchange -> {
        exchange.setProperty(IS_RETRY_EXCEEDED, true);
        exchange.setProperty(TRANSACTION_FAILED, true);
    }).process(collectionResponseProcessor);
    /*
         * Route to handle async transaction status API responses
         */
    from("direct:transaction-status-response-handler").id("transaction-status-response-handler").log(LoggingLevel.INFO, "## Staring transaction status handler route").choice().when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo("200")).log(LoggingLevel.INFO, "Transaction status request successful").process(exchange -> {
        String body = exchange.getIn().getBody(String.class);
        JSONObject jsonObject = new JSONObject(body);
        exchange.setProperty(LAST_RESPONSE_BODY, body);
        String server_id = jsonObject.getString("CheckoutRequestID");
        String resultCode = jsonObject.getString("ResultCode");
        String resultDescription = jsonObject.getString("ResultDesc");
        Object correlationId = exchange.getProperty(CORRELATION_ID);
        if (resultCode.equals("0")) {
            exchange.setProperty(TRANSACTION_FAILED, false);
        } else {
            exchange.setProperty(ERROR_CODE, resultCode);
            exchange.setProperty(ERROR_INFORMATION, exchange.getIn().getBody(String.class));
            exchange.setProperty(ERROR_DESCRIPTION, resultDescription);
        }
        exchange.setProperty(SERVER_TRANSACTION_ID, server_id);
        exchange.setProperty(TRANSACTION_ID, correlationId);
    }).choice().when(exchange -> exchange.getProperty(ERROR_CODE) != null).to("direct:filter-by-error-code").process(exchange -> {
        boolean isRecoverableError = exchange.getProperty(IS_ERROR_RECOVERABLE, Boolean.class);
        if (isRecoverableError) {
            exchange.setProperty(IS_TRANSACTION_PENDING, true);
        } else {
            exchange.setProperty(TRANSACTION_FAILED, true);
        }
    }).endChoice().process(collectionResponseProcessor).when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo("500")).process(exchange -> {
        logger.info("Handling 500 transaction status case");
        String body = exchange.getIn().getBody(String.class);
        JSONObject jsonObject = new JSONObject(body);
        exchange.setProperty(LAST_RESPONSE_BODY, body);
        String errorCode = jsonObject.getString("errorCode");
        String errorDescription = jsonObject.getString("errorMessage");
        exchange.setProperty(ERROR_CODE, errorCode);
        exchange.setProperty(ERROR_INFORMATION, exchange.getIn().getBody(String.class));
        exchange.setProperty(ERROR_DESCRIPTION, errorDescription);
        Object correlationId = exchange.getProperty(CORRELATION_ID);
        exchange.setProperty(TRANSACTION_ID, correlationId);
        exchange.setProperty(IS_TRANSACTION_PENDING, true);
    }).process(collectionResponseProcessor).otherwise().log(LoggingLevel.ERROR, "Transaction status request unsuccessful").process(exchange -> {
        Object correlationId = exchange.getProperty(CORRELATION_ID);
        exchange.setProperty(TRANSACTION_ID, correlationId);
    }).setProperty(TRANSACTION_FAILED, constant(true)).process(collectionResponseProcessor);
    /*
         * Route to handle async API responses
         */
    from("direct:transaction-response-handler").id("transaction-response-handler").choice().when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo("200")).log(LoggingLevel.INFO, "Collection request successful").process(exchange -> {
        JSONObject jsonObject = new JSONObject(exchange.getIn().getBody(String.class));
        String server_id = jsonObject.getString("CheckoutRequestID");
        Object correlationId = exchange.getProperty(CORRELATION_ID);
        exchange.setProperty(SERVER_TRANSACTION_ID, server_id);
        exchange.setProperty(TRANSACTION_ID, correlationId);
        correlationIDStore.addMapping(server_id, (String) correlationId);
        logger.info("Saved correlationId mapping \n\n {" + server_id + " : " + correlationId + "}");
    }).process(transactionResponseProcessor).otherwise().log(LoggingLevel.ERROR, "Collection request unsuccessful").process(exchange -> {
        Object correlationId = exchange.getProperty(CORRELATION_ID);
        exchange.setProperty(TRANSACTION_ID, correlationId);
    }).setProperty(TRANSACTION_FAILED, constant(true)).process(transactionResponseProcessor);
    /*
         * Takes the access toke and payment request and forwards the requests to lipana API.
         * [Password] and [TransactionType] are set in runtime and request is forwarded to lipana endpoint.
         */
    from("direct:lipana-buy-goods").removeHeader("*").setHeader(Exchange.HTTP_METHOD, constant("POST")).setHeader("Content-Type", constant("application/json")).setHeader("Authorization", simple("Bearer ${exchangeProperty." + ACCESS_TOKEN + "}")).setBody(exchange -> {
        BuyGoodsPaymentRequestDTO buyGoodsPaymentRequestDTO = (BuyGoodsPaymentRequestDTO) exchange.getProperty(BUY_GOODS_REQUEST_BODY);
        String password = safaricomUtils.getPassword("" + buyGoodsPaymentRequestDTO.getBusinessShortCode(), passKey, "" + buyGoodsPaymentRequestDTO.getTimestamp());
        buyGoodsPaymentRequestDTO.setPassword(password);
        buyGoodsPaymentRequestDTO.setTransactionType(MPESA_BUY_GOODS_TRANSACTION_TYPE);
        logger.info("BUY GOODS BODY: \n\n..\n\n..\n\n.. " + buyGoodsPaymentRequestDTO);
        logger.info(accessTokenStore.getAccessToken());
        return buyGoodsPaymentRequestDTO;
    }).marshal().json(JsonLibrary.Jackson).toD(buyGoodsHost + buyGoodsLipanaUrl + "?bridgeEndpoint=true&throwExceptionOnFailure=false").process(mpesaGenericProcessor).log(LoggingLevel.INFO, "MPESA API called, response: \n\n ${body}");
    /*
         * Takes the request for transaction status and forwards in to the lipana transaction status endpoint
         */
    from("direct:lipana-transaction-status").removeHeader("*").setHeader(Exchange.HTTP_METHOD, constant("POST")).setHeader("Content-Type", constant("application/json")).setHeader("Authorization", simple("Bearer ${exchangeProperty." + ACCESS_TOKEN + "}")).setBody(exchange -> {
        TransactionStatusRequestDTO transactionStatusRequestDTO = new TransactionStatusRequestDTO();
        BuyGoodsPaymentRequestDTO buyGoodsPaymentRequestDTO = (BuyGoodsPaymentRequestDTO) exchange.getProperty(BUY_GOODS_REQUEST_BODY);
        logger.info("BUY GOODS REQUEST: \n\n..\n\n..\n\n.." + buyGoodsPaymentRequestDTO);
        transactionStatusRequestDTO.setBusinessShortCode(buyGoodsPaymentRequestDTO.getBusinessShortCode());
        transactionStatusRequestDTO.setTimestamp("" + safaricomUtils.getTimestamp());
        transactionStatusRequestDTO.setCheckoutRequestId(exchange.getProperty(SERVER_TRANSACTION_ID, String.class));
        transactionStatusRequestDTO.setPassword(safaricomUtils.getPassword("" + transactionStatusRequestDTO.getBusinessShortCode(), passKey, transactionStatusRequestDTO.getTimestamp()));
        logger.info("TRANSACTION STATUS REQUEST DTO \n\n..\n\n..\n\n.." + transactionStatusRequestDTO);
        return transactionStatusRequestDTO;
    }).marshal().json(JsonLibrary.Jackson).toD(buyGoodsHost + transactionStatusUrl + "?bridgeEndpoint=true&throwExceptionOnFailure=false").process(mpesaGenericProcessor).log(LoggingLevel.INFO, "MPESA STATUS called, response: \n\n ${body}");
}
Also used : LoggingLevel(org.apache.camel.LoggingLevel) MPESA_BUY_GOODS_TRANSACTION_TYPE(org.mifos.connector.mpesa.safaricom.config.SafaricomProperties.MPESA_BUY_GOODS_TRANSACTION_TYPE) TransactionResponseProcessor(org.mifos.connector.mpesa.flowcomponents.transaction.TransactionResponseProcessor) Logger(org.slf4j.Logger) JsonObject(org.apache.camel.util.json.JsonObject) SafaricomUtils(org.mifos.connector.mpesa.utility.SafaricomUtils) TRANSACTION_ID(org.mifos.connector.mpesa.zeebe.ZeebeVariables.TRANSACTION_ID) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) LoggerFactory(org.slf4j.LoggerFactory) Exchange(org.apache.camel.Exchange) ZeebeVariables(org.mifos.connector.mpesa.zeebe.ZeebeVariables) BuyGoodsPaymentRequestDTO(org.mifos.connector.mpesa.dto.BuyGoodsPaymentRequestDTO) CamelProperties(org.mifos.connector.mpesa.camel.config.CamelProperties) Value(org.springframework.beans.factory.annotation.Value) JsonLibrary(org.apache.camel.model.dataformat.JsonLibrary) Component(org.springframework.stereotype.Component) JSONObject(org.json.JSONObject) AccessTokenStore(org.mifos.connector.mpesa.auth.AccessTokenStore) CollectionResponseProcessor(org.mifos.connector.mpesa.flowcomponents.transaction.CollectionResponseProcessor) RouteBuilder(org.apache.camel.builder.RouteBuilder) TransactionStatusRequestDTO(org.mifos.connector.mpesa.dto.TransactionStatusRequestDTO) MpesaGenericProcessor(org.mifos.connector.mpesa.flowcomponents.mpesa.MpesaGenericProcessor) StkCallback(org.mifos.connector.mpesa.dto.StkCallback) CorrelationIDStore(org.mifos.connector.mpesa.flowcomponents.CorrelationIDStore) StkCallback(org.mifos.connector.mpesa.dto.StkCallback) BuyGoodsPaymentRequestDTO(org.mifos.connector.mpesa.dto.BuyGoodsPaymentRequestDTO) JSONObject(org.json.JSONObject) JsonObject(org.apache.camel.util.json.JsonObject) JsonObject(org.apache.camel.util.json.JsonObject) JSONObject(org.json.JSONObject) TransactionStatusRequestDTO(org.mifos.connector.mpesa.dto.TransactionStatusRequestDTO)

Example 12 with JsonObject

use of org.apache.camel.util.json.JsonObject in project ph-ee-connector-mpesa by openMF.

the class TransactionResponseProcessor method getErrorDescription.

/**
 * Sample Error Json payload
 * {
 *    "requestId":"22749-38515563-2",
 *    "errorCode":"404.001.03",
 *    "errorMessage":"Invalid Access Token"
 * }
 * @param errorJson
 * @return errorDescription
 */
private String getErrorDescription(String errorJson) {
    String errorDescription;
    JsonObject jsonObject = (new Gson()).fromJson(errorJson, JsonObject.class);
    errorDescription = jsonObject.getString("errorMessage");
    return errorDescription;
}
Also used : JsonObject(org.apache.camel.util.json.JsonObject) Gson(com.google.gson.Gson)

Example 13 with JsonObject

use of org.apache.camel.util.json.JsonObject in project camel-kafka-connector by apache.

the class CamelKafkaConnectorCatalog method createModel.

private CamelKafkaConnectorModel createModel(String json) {
    CamelKafkaConnectorModel model = new CamelKafkaConnectorModel();
    JsonObject obj = JsonMapper.deserialize(json);
    JsonObject wrapper = (JsonObject) obj.get("connector");
    model.setConnectorClass((String) wrapper.get("class"));
    model.setArtifactId((String) wrapper.get("artifactId"));
    model.setGroupId((String) wrapper.get("groupId"));
    model.setType((String) wrapper.get("type"));
    model.setVersion((String) wrapper.get("version"));
    model.setDescription((String) wrapper.get("description"));
    model.setOptions(getConnectorOptionModel(obj));
    if (obj.get("aggregationStrategies") != null) {
        model.setAggregationStrategies((List<String>) obj.get("aggregationStrategies"));
    }
    if (obj.get("converters") != null) {
        model.setConverters((List<String>) obj.get("converters"));
    }
    if (obj.get("transforms") != null) {
        model.setTransforms((List<String>) obj.get("transforms"));
    }
    return model;
}
Also used : CamelKafkaConnectorModel(org.apache.camel.kafkaconnector.model.CamelKafkaConnectorModel) JsonObject(org.apache.camel.util.json.JsonObject)

Example 14 with JsonObject

use of org.apache.camel.util.json.JsonObject in project camel-kafka-connector by apache.

the class JsonMapperKafkaConnector method asJsonObject.

public static JsonObject asJsonObject(List<CamelKafkaConnectorOptionModel> options) {
    JsonObject json = new JsonObject();
    options.forEach(option -> json.put(option.getName(), asJsonObject(option)));
    return json;
}
Also used : JsonObject(org.apache.camel.util.json.JsonObject)

Example 15 with JsonObject

use of org.apache.camel.util.json.JsonObject in project camel-kafka-connector by apache.

the class JsonMapperKafkaConnector method asJsonObject.

public static JsonObject asJsonObject(CamelKafkaConnectorOptionModel model) {
    JsonObject obj = new JsonObject();
    obj.put("name", model.getName());
    obj.put("description", model.getDescription());
    if (model.getDefaultValue() != null) {
        obj.put("defaultValue", model.getDefaultValue());
    }
    obj.put("priority", model.getPriority());
    obj.put("required", model.getRequired());
    List<String> possibleEnumValues = model.getPossibleEnumValues();
    if (possibleEnumValues != null && !possibleEnumValues.isEmpty()) {
        obj.put("enum", possibleEnumValues);
    }
    return obj;
}
Also used : JsonObject(org.apache.camel.util.json.JsonObject)

Aggregations

JsonObject (org.apache.camel.util.json.JsonObject)15 CamelKafkaConnectorModel (org.apache.camel.kafkaconnector.model.CamelKafkaConnectorModel)3 Gson (com.google.gson.Gson)2 File (java.io.File)2 StkCallback (org.mifos.connector.mpesa.dto.StkCallback)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 CamelCatalogService (com.github.cameltooling.idea.service.CamelCatalogService)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 GET (javax.ws.rs.GET)1 Path (javax.ws.rs.Path)1 Produces (javax.ws.rs.Produces)1 Exchange (org.apache.camel.Exchange)1 LoggingLevel (org.apache.camel.LoggingLevel)1 RouteBuilder (org.apache.camel.builder.RouteBuilder)1 CamelCatalog (org.apache.camel.catalog.CamelCatalog)1 HttpOperationFailedException (org.apache.camel.http.base.HttpOperationFailedException)1