com.tesobe.obp.transport.spi.MockResponder.java Source code

Java tutorial

Introduction

Here is the source code for com.tesobe.obp.transport.spi.MockResponder.java

Source

/*
 * Copyright (c) TESOBE Ltd.  2017. All rights reserved.
 *
 * Use of this source code is governed by a GNU AFFERO license that can be found in the LICENSE file.
 *
 */
package com.tesobe.obp.transport.spi;

import com.tesobe.obp.transport.Decoder;
import com.tesobe.obp.transport.Response;
import com.tesobe.obp.transport.Transport;
import com.tesobe.obp.transport.nov2016.Account;
import com.tesobe.obp.transport.nov2016.Bank;
import com.tesobe.obp.transport.nov2016.ChallengeThreshold;
import com.tesobe.obp.transport.nov2016.Transaction;
import com.tesobe.obp.transport.nov2016.User;
import org.json.JSONArray;
import org.json.JSONObject;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;

import static com.tesobe.obp.util.Utils.merge;
import static java.lang.String.format;
import static java.time.ZoneOffset.UTC;
import static java.util.Collections.synchronizedMap;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

/**
 * Example implementation of a south.
 *
 * @since 2016.11
 */
@SuppressWarnings("WeakerAccess")
public class MockResponder extends DefaultResponder {
    @Override
    public JSONObject describe(JSONObject json) {
        JSONObject nov2016 = new JSONObject();
        JSONObject get = new JSONObject();
        JSONObject put = new JSONObject();
        JSONObject transaction = new JSONObject();
        JSONObject types = new JSONObject();

        //  Do not know how to handle types yet. So all it's strings.
        //    JSONObject account = Account.FIELDS.stream()
        //      .collect(JSONObject::new, (a, k) -> a.put(k, "String"),
        //        (a1, a2) -> a2.keySet().forEach(k -> a1.put(k, a2.get(k))));

        get.put(Transport.Target.account.toString(), Account.FIELDS);
        get.put(Transport.Target.bank.toString(), Bank.FIELDS);
        get.put(Transport.Target.transaction.toString(), Transaction.FIELDS);
        get.put(Transport.Target.user.toString(), User.FIELDS);
        get.put(Transport.Target.challengeThreshold.toString(), ChallengeThreshold.FIELDS);

        put.put(Transport.Target.transaction.toString(), transaction);

        transaction.put("types", types);
        types.put("pain.001.001.03db", Transaction.FIELDS);

        nov2016.put("get", get);
        nov2016.put("put", put);

        json.put("versions", new JSONArray().put(Transport.Version.Nov2016));
        json.put(Transport.Version.Nov2016.toString(), nov2016);

        return json;
    }

    @Override
    public Response next(String state, Decoder.Pager p) {
        List<? extends Map<String, ?>> data = state != null ? cache.get(state) : null;

        return new DefaultResponse(data);
    }

    @Override
    protected Response account(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = ps.accountId().map(this::account).map(Collections::singletonList)
                .orElseGet(Collections::emptyList);

        return new DefaultResponse(data);
    }

    protected Map<String, Object> account(String id) {
        return entity(Account.accountId, id);
    }

    @Override
    protected Response accounts(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = ps.bankId()
                .map(bankId -> Stream.of("accountId-0", "accountId-1").map(this::account)
                        .map(a -> merge(a, Account.bankId, bankId)).collect(toList()))
                .orElseGet(Collections::emptyList);

        return new DefaultResponse(data);
    }

    @Override
    protected Response bank(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = ps.bankId().map(this::bank).map(Collections::singletonList)
                .orElseGet(Collections::emptyList);

        return new DefaultResponse(data);
    }

    protected Map<String, Object> bank(String id) {
        return entity(Bank.bankId, id);
    }

    @Override
    protected Response banks(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = Stream.of("bankId-0", "bankId-1").map(this::bank).collect(toList());

        return new DefaultResponse(data);
    }

    @Override
    protected Response challengeThreshold(String state, Decoder.Pager p, Decoder.Parameters ps) {
        assertThat(ps.accountId().get(), is("account-x"));
        assertThat(ps.userId().get(), is("user-x"));
        assertThat(ps.get("type").get(), is("type-x"));
        assertThat(ps.get("currency").get(), is("currency-x"));

        HashMap<String, String> data = new HashMap<>();

        data.put(ChallengeThreshold.amount, "amount-x");
        data.put(ChallengeThreshold.currency, "currency-x");

        return DefaultResponse.fromData(data);
    }

    @Override
    protected Response transaction(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = ps.accountId()
                .flatMap(a -> ps.bankId().flatMap(b -> ps.transactionId().map(tid -> transaction(a, b, tid))))
                .map(Collections::singletonList).orElseGet(Collections::emptyList);

        return new DefaultResponse(data);
    }

    protected Map<String, Object> transaction(String accountId, String bankId, String transactionId) {
        return merge(merge(entity(Transaction.transactionId, transactionId), Transaction.accountId, accountId),
                Transaction.bankId, bankId);
    }

    @Override
    protected Response transactions(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = ps.accountId()
                .flatMap(a -> ps.bankId().map(b -> transactions(state, p, a, b))).orElseGet(Collections::emptyList);

        return new DefaultResponse(data);
    }

    /**
     * Return a total of seventeen transactions, posted one per day counting down
     * from January 1st, 1999..
     *
     * @param state local state, can store result set over page requests
     * @param p pager
     * @param accountId account
     * @param bankId bank
     *
     * @return 17 transactions in as many pages, as needed.
     */
    protected List<Map<String, Object>> transactions(String state, Decoder.Pager p, String accountId,
            String bankId) {
        ZonedDateTime completed = ZonedDateTime.of(1999, 1, 31, 0, 0, 0, 0, UTC);
        final List<Map<String, Object>> data = new ArrayList<>(); // todo stream
        int numTransactions = 17;

        for (int i = 0; i < numTransactions; ++i) {
            int dayOfMonth = Math.min(i, 26) + 1; // safe month length
            ZonedDateTime posted = ZonedDateTime.of(1999, 1, dayOfMonth, 0, 0, 0, 0, UTC);

            HashMap<String, Object> t = new HashMap<>();

            t.put(Transaction.accountId, accountId);
            t.put(Transaction.bankId, bankId);
            t.put(Transaction.transactionId, format(Locale.US, "transactionId-%d", i));
            t.put(Transaction.completedDate, completed);
            t.put(Transaction.postedDate, posted);
            t.put(Transaction.counterPartyId, format(Locale.US, "counterPartyId-%d", i));

            data.add(t);
        }

        List<Map<String, Object>> processed = data.stream().filter(filter(p)).sorted(sorter(p)).collect(toList());

        cache.put(state, processed);

        return processed;
    }

    @Override
    protected Response user(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = ps.userId().map(this::user).map(Collections::singletonList)
                .orElseGet(Collections::emptyList);

        return new DefaultResponse(data);
    }

    protected Map<String, Object> user(String id) {
        return entity(User.email, id);
    }

    @Override
    protected Response users(String state, Decoder.Pager p, Decoder.Parameters ps) {
        List<Map<String, Object>> data = Stream.of("userId-0", "userId-1").map(this::user)
                .map(a -> merge(a, User.id, a.get("email"))).collect(toList());

        return new DefaultResponse(data);
    }

    private Map<String, Object> entity(String idName, String idValue) {
        return merge(new HashMap<>(), idName, idValue);
    }

    public Response put(Decoder.Parameters ps, Map<String, ?> fields, Transport.Target t) {
        ps.type().map(type -> {
            assertThat(type, is("pain.001.001.03db"));
            return Void.TYPE;
        }).orElseGet(() -> {
            fail();
            return Void.TYPE;
        });

        assertThat(fields.get(Transaction.accountId), is("account-x"));
        assertThat(fields.get(Transaction.amount), is("10"));
        assertThat(fields.get(Transaction.bankId), is("bank-x"));
        assertThat(fields.get(Transaction.completedDate), is("1999-01-02T00:00:00.000Z"));
        assertThat(fields.get(Transaction.counterPartyId), is("counterPartyId-x"));
        assertThat(fields.get(Transaction.counterPartyName), is("counterPartyName-x"));
        assertThat(fields.get(Transaction.currency), is("currency-x"));
        assertThat(fields.get(Transaction.description), is("description-x"));
        assertThat(fields.get(Transaction.newBalanceAmount), is("123456.78"));
        assertThat(fields.get(Transaction.newBalanceCurrency), is("nbc-x"));
        assertThat(fields.get(Transaction.postedDate), is("1999-01-02T00:00:00.000Z"));
        assertThat(fields.get(Transaction.transactionId), is("transaction-x"));
        assertThat(fields.get(Transaction.type), is("type-x"));
        assertThat(fields.get(Transaction.userId), is("user-x"));

        return DefaultResponse.fromData(entity("transactionId", Objects.toString(fields.get("transactionId"))));
    }

    @Override
    public Response fetch() {
        return DefaultResponse.fromData(merge(new HashMap<>(), "transaction-x", "ACPT"));
    }

    Map<String, List<Map<String, Object>>> cache = synchronizedMap(new HashMap<>());
}