# Java

<details>

<summary>Without Router - Current Approach</summary>

```java
// 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();
    }
}

```

</details>

<details>

<summary>With Router Integration - Request</summary>

```java
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 baseurl + 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 + baseurl
            Map<String, Object> headerResponse = routerIntegrationHelper(route, rebitRequestBody);

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

            // Build new Router URL dynamically
            String newUrl = baseurl + 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:
     * - baseurl
     * - 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);
    }
}


```

</details>

<details>

<summary>With Router Integration - Response</summary>

```java
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, baseurl, 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;
	}
}


```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.sahamati.org.in/sahamatinet-mvp/integration-steps/integration-with-router/sample-code-snippets/java.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
