org.fineract.module.stellar.StellarBridgeTestHelpers.java Source code

Java tutorial

Introduction

Here is the source code for org.fineract.module.stellar.StellarBridgeTestHelpers.java

Source

/**
 * Copyright 2016 Myrle Krantz
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.fineract.module.stellar;

import com.google.gson.Gson;
import com.jayway.restassured.internal.mapper.ObjectMapperType;
import com.jayway.restassured.response.Header;
import com.jayway.restassured.response.Response;
import org.fineract.module.stellar.restdomain.*;
import org.junit.Assert;
import org.springframework.http.HttpStatus;
import org.stellar.sdk.federation.FederationResponse;

import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Optional;

import static com.jayway.restassured.RestAssured.given;
import static org.fineract.module.stellar.AccountBalanceMatcher.balanceMatches;

public class StellarBridgeTestHelpers {
    public static final String API_KEY_HEADER_LABEL = "X-Stellar-Bridge-API-Key";
    public static final String TENANT_ID_HEADER_LABEL = "X-Mifos-Platform-TenantId";
    public static final String ENTITY_HEADER_LABEL = "X-Mifos-Entity";
    public static final String ENTITY_HEADER_VALUE = "JOURNALENTRY";
    public static final String ACTION_HEADER_LABEL = "X-Mifos-Action";
    public static final String ACTION_HEADER_VALUE = "CREATE";
    public static final Header CONTENT_TYPE_HEADER = new Header("Content-Type", "application/json");
    public static final String TEST_ADDRESS_DOMAIN = "test.org";
    public static final String STELLAR_ROUTING_CODE = "STELLAR";

    /**
     * @return the api key used when accessing the tenantName
     */
    public static String createAndDestroyBridge(final String tenantName, final Cleanup testCleanup,
            final String endpoint) {
        final String apiKey = createBridge(tenantName, endpoint);
        testCleanup.addStep(() -> deleteBridge(tenantName, apiKey));
        return apiKey;
    }

    public static String createBridge(final String tenantName, final String mifosAddress) {
        final AccountBridgeConfiguration newAccount = new AccountBridgeConfiguration(tenantName,
                getTenantToken(tenantName, mifosAddress), mifosAddress);
        final Response creationResponse = given().header(CONTENT_TYPE_HEADER).body(newAccount)
                .post("/modules/stellarbridge");

        creationResponse.then().assertThat().statusCode(HttpStatus.CREATED.value());

        return creationResponse.getBody().as(String.class, ObjectMapperType.GSON);
    }

    public static String getTenantToken(final String tenantName, final String mifosAddress) {
        //TODO: Comment the real code back in once you have a multi-tenant docker image.
        /*final String encodedTenantName;
        try {
          encodedTenantName = URLEncoder.encode(tenantName, "UTF-8");
        } catch (UnsupportedEncodingException ignore) {
          throw new RuntimeException("unexpected error.");
        }
        final String LOGIN_URL = "/fineract-provider/api/v1/authentication?username=mifos&password=password&tenantIdentifier=" + encodedTenantName;
            
        final String json = given().baseUri(mifosAddress).post(LOGIN_URL).asString();
            
        assertThat("Failed to login into fineract platform", StringUtils.isBlank(json), is(false));
        final String ret = JsonPath.with(json).get("base64EncodedAuthenticationKey");
        assertThat("Failed to acquire a tenant token", StringUtils.isBlank(ret), is(false));
        return ret;
        */

        return mifosAddress + "+" + tenantName;
    }

    public static void deleteBridge(final String tenantName, final String apiKey) {
        final Response deletionResponse = given().header(StellarBridgeTestHelpers.API_KEY_HEADER_LABEL, apiKey)
                .header(StellarBridgeTestHelpers.TENANT_ID_HEADER_LABEL, tenantName)
                .delete("/modules/stellarbridge");

        deletionResponse.then().assertThat().statusCode(HttpStatus.OK.value());
    }

    public static void setVaultSize(final String tenantName, final String apiKey, final String assetCode,
            final BigDecimal balance) {
        final AmountConfiguration amount = new AmountConfiguration(balance);

        given().header(CONTENT_TYPE_HEADER).header(StellarBridgeTestHelpers.API_KEY_HEADER_LABEL, apiKey)
                .header(StellarBridgeTestHelpers.TENANT_ID_HEADER_LABEL, tenantName)
                .pathParameter("assetCode", assetCode).body(amount).put("/modules/stellarbridge/vault/{assetCode}/")
                .then().assertThat().statusCode(HttpStatus.OK.value()).content(balanceMatches(balance));
    }

    public static void createAndDestroyTrustLine(final String fromTenant, final String fromTenantApiKey,
            final String toStellarAddress, final String assetCode, final BigDecimal amount,
            final Cleanup testCleanup) {
        createTrustLine(fromTenant, fromTenantApiKey, toStellarAddress, assetCode, amount);
        testCleanup.addStep(() -> deleteTrustLine(fromTenant, fromTenantApiKey, toStellarAddress, assetCode));
    }

    public static void createTrustLine(final String fromTenant, final String fromTenantApiKey,
            final String toStellarAddress, final String assetCode, final BigDecimal amount) {
        final TrustLineConfiguration trustLine = new TrustLineConfiguration(amount);

        String issuer = "";
        try {
            issuer = URLEncoder.encode(toStellarAddress, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            Assert.fail();
        }

        given().header(StellarBridgeTestHelpers.CONTENT_TYPE_HEADER)
                .header(StellarBridgeTestHelpers.API_KEY_HEADER_LABEL, fromTenantApiKey)
                .header(StellarBridgeTestHelpers.TENANT_ID_HEADER_LABEL, fromTenant)
                .pathParameter("assetCode", assetCode).pathParameter("issuer", issuer).body(trustLine)
                .put("/modules/stellarbridge/trustlines/{assetCode}/{issuer}/").then().assertThat()
                .statusCode(HttpStatus.OK.value());
    }

    public static void deleteTrustLine(final String fromTenant, final String fromTenantApiKey,
            final String toStellarAddress, final String assetCode) {
        String issuer = "";
        try {
            issuer = URLEncoder.encode(toStellarAddress, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            Assert.fail();
        }

        given().header(StellarBridgeTestHelpers.CONTENT_TYPE_HEADER)
                .header(StellarBridgeTestHelpers.API_KEY_HEADER_LABEL, fromTenantApiKey)
                .header(StellarBridgeTestHelpers.TENANT_ID_HEADER_LABEL, fromTenant)
                .pathParam("assetCode", assetCode).pathParam("issuer", issuer)
                .body(new TrustLineConfiguration(BigDecimal.ZERO))
                .put("/modules/stellarbridge/trustlines/{assetCode}/{issuer}/").then().assertThat()
                .statusCode(HttpStatus.OK.value());
    }

    public static void makePayment(final String fromTenant, final String fromTenantApiKey, final String toTenant,
            final String assetCode, final BigDecimal transferAmount) {
        makePaymentExpectStatus(fromTenant, fromTenantApiKey, toTenant, assetCode, transferAmount,
                HttpStatus.ACCEPTED);
    }

    public static void makePaymentExpectStatus(final String fromTenant, final String fromTenantApiKey,
            final String toTenant, final String assetCode, final BigDecimal transferAmount,
            final HttpStatus expectStatus) {
        final String payment = getPaymentPayload(assetCode, transferAmount, TEST_ADDRESS_DOMAIN, toTenant);

        given().header(CONTENT_TYPE_HEADER).header(API_KEY_HEADER_LABEL, fromTenantApiKey)
                .header(TENANT_ID_HEADER_LABEL, fromTenant).header(ENTITY_HEADER_LABEL, ENTITY_HEADER_VALUE)
                .header(ACTION_HEADER_LABEL, ACTION_HEADER_VALUE).body(payment)
                .post("/modules/stellarbridge/payments/").then().assertThat().statusCode(expectStatus.value());
    }

    public static void checkBalance(final String tenant, final String tenantApiKey, final String assetCode,
            final String issuingStellarAddress, final BigDecimal amount) {
        String issuer = "";
        try {
            issuer = URLEncoder.encode(issuingStellarAddress, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            Assert.fail();
        }

        given().header(CONTENT_TYPE_HEADER).header(API_KEY_HEADER_LABEL, tenantApiKey)
                .header(TENANT_ID_HEADER_LABEL, tenant).pathParam("assetCode", assetCode)
                .pathParam("issuer", issuer).get("/modules/stellarbridge/balances/{assetCode}/{issuer}/").then()
                .assertThat().statusCode(HttpStatus.OK.value()).content(balanceMatches(amount));
    }

    public static void checkBalanceDoesntExist(final String tenant, final String tenantApiKey,
            final String assetCode, final String issuingStellarAddress) {
        String issuer = "";
        try {
            issuer = URLEncoder.encode(issuingStellarAddress, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            Assert.fail();
        }

        given().header(CONTENT_TYPE_HEADER).header(API_KEY_HEADER_LABEL, tenantApiKey)
                .header(TENANT_ID_HEADER_LABEL, tenant).pathParam("assetCode", assetCode)
                .pathParam("issuer", issuer).get("/modules/stellarbridge/balances/{assetCode}/{issuer}/").then()
                .assertThat().statusCode(HttpStatus.NOT_FOUND.value());
    }

    public static String tenantVaultStellarAddress(final String tenantId) {
        return tenantId + ":vault" + "*" + TEST_ADDRESS_DOMAIN;
    }

    public static String tenantStellarAddress(final String tenantId) {

        return tenantId + "*" + TEST_ADDRESS_DOMAIN;
    }

    public static Optional<String> getStellarAccountIdForTenantId(@NotNull final String tenantId) {

        final String tenantStellarAddress = tenantStellarAddress(tenantId);

        return getStellarAccountIdForStellarAddress(tenantStellarAddress);
    }

    public static Optional<String> getStellarVaultAccountIdForTenantId(@NotNull final String tenantId) {
        final String tenantVaultStellarAddress = tenantVaultStellarAddress(tenantId);

        return getStellarAccountIdForStellarAddress(tenantVaultStellarAddress);
    }

    public static Optional<String> getStellarAccountIdForStellarAddress(
            @NotNull final String tenantStellarAddress) {
        final Response restResponse = given().queryParam("type", "name").queryParam("q", tenantStellarAddress)
                .get("/federation/");

        int statusCode = restResponse.getStatusCode();
        if (statusCode != HttpStatus.OK.value()) {
            return Optional.empty();
        }

        final FederationResponse response = restResponse.getBody().as(FederationResponse.class,
                ObjectMapperType.GSON);

        if (response == null)
            return Optional.empty();

        return Optional.of(response.getAccountId());
    }

    private static String getPaymentPayload(final String assetCode, final BigDecimal amount, final String toDomain,
            final String toTenant) {
        final JournalEntryData payment = new JournalEntryData();
        payment.currency = new CurrencyData();
        payment.currency.inMultiplesOf = 1;
        payment.currency.code = assetCode;
        payment.amount = amount;
        payment.transactionDetails = new TransactionDetailData();
        payment.transactionDetails.paymentDetails = new PaymentDetailData();
        payment.transactionDetails.paymentDetails.bankNumber = toDomain;
        payment.transactionDetails.paymentDetails.accountNumber = toTenant;
        payment.transactionDetails.paymentDetails.routingCode = STELLAR_ROUTING_CODE;

        return new Gson().toJson(payment);
    }
}