Java

Without Router - Current Approach
// Assuming this as previous logic without Router
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;

public class EntityRequest {
    private static final String BASE_URL = "http://fip-1.dev.sahamati.org.in/fip-simulate";
    private static final String RECIPIENT_ID = "FIP-SIMULATOR";

    public static void main(String[] args) {
        try {
            String response = executeDiscoveryRequest();
            performAnotherOperations(response);
            System.out.println("Account discovery successful.");
        } catch (Exception e) {
            System.out.println("Account discovery failed. Error: " + e.getMessage());
        } finally {
            System.out.println("Account discovery completed.");
        }
    }

    private static String executeDiscoveryRequest() throws Exception {
        String route = "/v2/Accounts/discover";
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = getHttpConfig(BASE_URL, route, new HashMap<>(), new HashMap<>(), "POST");
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    private static HttpRequest getHttpConfig(String baseUrl, String route, Map<String, String> headers, Map<String, Object> data, String methodType) {
        String url = baseUrl + route;
        String jsonData = mapToJson(data);
        
        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .POST(HttpRequest.BodyPublishers.ofString(jsonData))
                .header("Content-Type", "application/json");
        
        headers.forEach(builder::header);
        return builder.build();
    }

    private static void performAnotherOperations(String accountDiscoverResponse) {
        System.out.println("Perform another operations with the response: " + accountDiscoverResponse);
    }

    private static String mapToJson(Map<String, ?> data) {
        StringBuilder jsonData = new StringBuilder("{");
        for (Map.Entry<String, ?> entry : data.entrySet()) {
            jsonData.append("\"").append(entry.getKey()).append("\": \"").append(entry.getValue()).append("\",");
        }
        if (!data.isEmpty()) {
            jsonData.deleteCharAt(jsonData.length() - 1);  
        }
        jsonData.append("}");
        return jsonData.toString();
    }
}

With Router Integration - Request
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Example flow for calling Sahamati Router with account discovery.
 * - Step 1: Build initial request.
 * - Step 2: Enrich it with adding headers.
 * - Step 3: Send the request.
 */
public class EntityRequest {
    private static final String BASE_URL = "http://fip-1.sandbox.sahamati.org.in/fip-simulate";
    private static final String RECIPIENT_ID = "FIP-SIMULATOR";
    private static final String ROUTER_INTEGRATION_HELPER_URL = "https://api.sandbox.sahamati.org.in/router-helper/v1/request/header";

    private static final HttpClient client = HttpClient.newHttpClient();
    private static final ObjectMapper mapper = new ObjectMapper();

    public static void main(String[] args) {
        try {
            // Execute account discovery
            String response = executeDiscoveryRequest();
            System.out.println("Account discovery successful: " + response);

            // Do something with response
            performAnotherOperations(response);

        } catch (Exception e) {
            System.out.println("Account discovery failed. Error: " + e.getMessage());
        }
    }

    /**
     * Runs account discovery by calling BASE_URL + /Accounts/discover
     */
    private static String executeDiscoveryRequest() throws Exception {
        String route = "/Accounts/discover";
        String url = BASE_URL + route;
        rebitRequestBody = {} // Rebit Defined request body
        // Initial request
        HttpRequest request = buildHttpRequest(url, new HashMap<>(), rebitRequestBody);

        // New code starts here
        request = addSahamatiConfiguration(request, route, new HashMap<>());
        // New code ends here

        // Execute the request
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    /**
     * Builds a basic POST request with headers + JSON data.
     */
    private static HttpRequest buildHttpRequest(String url, Map<String, String> headers, Map<String, Object> data) throws Exception {
        String jsonData = mapper.writeValueAsString(data);

        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonData));

        headers.forEach(builder::header);
        return builder.build();
    }

    private static void performAnotherOperations(String accountDiscoverResponse) {
        System.out.println("Next steps with response: " + accountDiscoverResponse);
    }

    /**
     * Adds Sahamati Router headers by calling the Router Integration Helper API.
     * - Fetches targetHost + x-request-meta from helper service.
     * - Rebuilds request with updated URL and headers.
     */
    private static HttpRequest addSahamatiConfiguration(HttpRequest request, String route, Map<String, Object> rebitRequestBody) {
        try {
            // Call Router Integration Helper to get x-request-meta + targetHost
            Map<String, Object> headerResponse = routerIntegrationHelper(route, rebitRequestBody);

            String targetHost = (String) headerResponse.getOrDefault("targetHost", ""); // Get the targetHost URL (router URL if integrated, else entity target URL)
            String xRequestMeta = (String) headerResponse.getOrDefault("x-request-meta", ""); // Request metadata generated by router helper

            // Build new Router URL dynamically
            String newUrl = targetHost + route;

            // Rebuild request with original body + headers
            HttpRequest.Builder builder = HttpRequest.newBuilder()
                    .uri(URI.create(newUrl))
                    .method(request.method(), request.bodyPublisher().orElse(HttpRequest.BodyPublishers.noBody()));

            // Copy existing headers
            request.headers().map().forEach((key, values) -> values.forEach(value -> builder.header(key, value)));

            // Add x-request-meta header, if exist in the response
            if(!xRequestMeta.isEmpty()){
                builder.header("x-request-meta", xRequestMeta);
            }
            return builder.build();

        } catch (Exception e) {
            throw new RuntimeException("Failed to configure Sahamati Router headers", e);
        }
    }

    /**
     * Calls Router Integration Helper Service to get:
     * - targetHost
     * - x-request-meta
     */
    private static Map<String, Object> routerIntegrationHelper(String rebitAPIEndpoint, Map<String, Object> rebitRequestBody) throws Exception {
        // Build payload
        Map<String, Object> payload = new HashMap<>();
        payload.put("rebitAPIEndpoint", rebitAPIEndpoint);
        payload.put("recipientId", RECIPIENT_ID);
        payload.put("customerId", "9766334467@aa_simulator");
        payload.put("requestBody", rebitRequestBody);

        // Convert payload to JSON
        String requestJson = mapper.writeValueAsString(payload);

        // Call Router Integration Helper Service
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(ROUTER_INTEGRATION_HELPER_URL))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(requestJson))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // Convert JSON response into Map
        return mapper.readValue(response.body(), Map.class);
    }
}

With Router Integration - Response
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Structured example for FIP-SIMULATOR: Handles incoming account discovery request,
 * calls /response/header to get x-response-meta, and adds it to the outgoing response headers.
 */
public class FipSimulatorResponseMeta {
	private static final String ROUTER_RESPONSE_HEADER_URL = "https://api.sandbox.sahamati.org.in/router-helper/v1/response/header";
	private static final String RECIPIENT_ID = "AA-SIMULATOR";
	private static final HttpClient client = HttpClient.newHttpClient();
	private static final ObjectMapper mapper = new ObjectMapper();

	/**
	 * Servlet/controller handler for account discovery.
	 */
	public void handleAccountDiscovery(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		// Parse incoming request body (pseudo-code, adapt as per your framework)
		// Example: Map<String, Object> incomingRequestBody = ...
		Map<String, Object> incomingRequestBody = new HashMap<>(); // Replace with actual parsing logic

		// Fetch account details from the incoming request
		Map<String, Object> discoveredAccount = fetchAccountFromRequestBody(incomingRequestBody);
		if (discoveredAccount == null) {
			resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
			resp.setContentType("application/json");
			resp.getWriter().write("{\"error\":\"Account not found\"}");
			return;
		}

		// Build the account discovery response body
		Map<String, Object> responseBody = new HashMap<>();
		responseBody.put("ver", "2.0.0");
		responseBody.put("timestamp", System.currentTimeMillis().toString()); // Use current timestamp
		responseBody.put("txnid", "f35761ac-4a18-11e8-96ff-0277a9fbfedcs");
		responseBody.put("DiscoveredAccounts", java.util.List.of(discoveredAccount));

		// Prepare the Request Body for /response/header 
		Map<String, Object> responseHeaderRequestBody = new HashMap<>();
		responseHeaderRequestBody.put("rebitAPIEndpoint", "/accounts/discover");
		// Optionally extract customerId from incomingRequestBody if available
		responseHeaderRequestBody.put("customerId", "9977336577@aa_simulator");
		responseHeaderRequestBody.put("recipientId", RECIPIENT_ID);
		responseHeaderRequestBody.put("additionalAttributes", new HashMap<>());
		responseHeaderRequestBody.put("responseBody", responseBody);


		// Call /response/header to get the full response
		Map<String, Object> responseHeaderResp = routerIntegrationHelper(responseHeaderRequestBody);
		Object xResponseMeta = responseHeaderResp.get("x-response-meta");
		if (xResponseMeta != null && xResponseMeta instanceof String && !((String)xResponseMeta).isEmpty()) {
			// Set x-response-meta in outgoing response header only if present
			resp.setHeader("x-response-meta", (String)xResponseMeta);
		}

		// Write the account discovery response body as JSON
		resp.setContentType("application/json");
		resp.getWriter().write(mapper.writeValueAsString(responseBody));
	}

	/**
	 * Calls /response/header to get the full response map (timestamp, x-response-meta, targetHost, etc).
	 */
	private static Map<String, Object> routerIntegrationHelper(Map<String, Object> requestBody) throws Exception {
		String json = mapper.writeValueAsString(requestBody);
		HttpRequest request = HttpRequest.newBuilder()
				.uri(URI.create(ROUTER_RESPONSE_HEADER_URL))
				.header("Content-Type", "application/json")
				.POST(HttpRequest.BodyPublishers.ofString(json))
				.build();
		HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
		// The response is expected to be a JSON with x-response-meta field (and possibly others)
		return mapper.readValue(response.body(), Map.class);
	}

	/**
	 * Fetches account details from the request body by searching for the Customer object
	 * with Identifiers (category: STRONG, type: AADHAAR, value: ...).
	 * Returns a dummy account for demonstration.
	 */
	private Map<String, Object> fetchAccountFromRequestBody(Map<String, Object> requestBody) {
		if (requestBody == null) return null;
		Object customerObj = requestBody.get("Customer");
		if (!(customerObj instanceof Map)) return null;
		Map<String, Object> customer = (Map<String, Object>) customerObj;
		Object identifiersObj = customer.get("Identifiers");
		if (!(identifiersObj instanceof java.util.List)) return null;
		java.util.List<?> identifiers = (java.util.List<?>) identifiersObj;
		for (Object idObj : identifiers) {
			if (idObj instanceof Map) {
				Map<String, Object> idMap = (Map<String, Object>) idObj;
				String category = (String) idMap.getOrDefault("category", "");
				String type = (String) idMap.getOrDefault("type", "");
				String value = (String) idMap.getOrDefault("value", "");
				if ("STRONG".equals(category) && "AADHAAR".equals(type) && value != null && !value.isEmpty()) {
					// Found the matching identifier, return dummy account
					Map<String, Object> account = new HashMap<>();
					account.put("FIType", "DEPOSIT");
					account.put("accType", "SAVINGS");
					account.put("accRefNumber", "BANK11111111");
					account.put("maskedAccNumber", "XXXXXXX3468");
					return account;
				}
			}
		}
		return null;
	}
}

Last updated

Was this helpful?