Search code examples
javaamazon-web-serviceshttpsurlconnectionamazon-fsx

How to fetch response from the Amazon Fsx DescribeFileCaches API?


I am trying to fetch the response for DescribeFileCaches API using HttpsURLConnection in Java. When using the AWS SDK, I am able to get the response but when hitting the API using the same headers in Java, I am getting 404 - <UnknownOperationException/> (This is the error response returned).

As I am new to Java HttpsURLConnection, let me know if I am missing anything in my end.

try {
    String url = "https://fsx.us-east-1.amazonaws.com";

    /**
     * Add host without http or https protocol.
     * You can also add other parameters based on your amazon service requirement.
     */
    TreeMap<String, String> awsHeaders = new TreeMap<String, String>();
    awsHeaders.put("content-length", "2");
    awsHeaders.put("content-type", "application/x-amz-json-1.1");
    awsHeaders.put("host", "fsx.us-east-1.amazonaws.com");
    String target = "AWSSimbaAPIService_v20180301.DescribeFileCaches";
    awsHeaders.put("x-amz-target", target);
    
    TreeMap<String, String> queryParameters = new TreeMap<String, String>();            
    
    AWSV4Auth aWSV4Auth = new AWSV4Auth.Builder("", "")
            .regionName("us-east-1")
            .serviceName("fsx") // es - elastic search. use your service name
            .httpMethodName("POST") //GET, PUT, POST, DELETE, etc...
            .canonicalURI("/") //end point
            .queryParametes(queryParameters) //query parameters if any
            .awsHeaders(awsHeaders) //aws header parameters
            .payload("{}") // payload if any
            .debug() // turn on the debug mode
            .build();

    /* Get header calculated for request */
    Map<String, String> header = aWSV4Auth.getHeaders();
    System.out.println(header.toString());
    
    
    URL urlobj = new URL(url);
    HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlobj.openConnection();
    httpsURLConnection.setRequestMethod("POST");
    httpsURLConnection.setDoOutput(true);
    for(String headerName : header.keySet()) {
        httpsURLConnection.setRequestProperty(headerName, header.get(headerName));
    }
    httpsURLConnection.setRequestProperty("Accept", "application/json");
    
    try (DataOutputStream wr = new DataOutputStream(httpsURLConnection.getOutputStream())) {
        wr.write("{}".getBytes());
        wr.flush();
        wr.close();
    }
    //httpsURLConnection.setRequestProperty("Accept", "text/xml");
    if (httpsURLConnection.getResponseCode() != 200) {
            System.out.println("http response code is " + httpsURLConnection.getResponseCode() +" - " + httpsURLConnection.getResponseMessage());
        InputStream errorStream = httpsURLConnection.getErrorStream();
        if (errorStream != null) {
            BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream));
            String errorResponse;
            while ((errorResponse = errorReader.readLine()) != null) {
                System.out.println(errorResponse);
            }
            errorReader.close();
        }
    } else {
        InputStream in = httpsURLConnection.getInputStream();
        InputStreamReader reader = new InputStreamReader(in);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String response = null;
        String line = (response = bufferedReader.readLine());
        while(line != null) {
            line = bufferedReader.readLine();
            if (line != null) {
                response += line;
            }
        }
        System.out.println(response);
    }
} catch (Exception e) {
    e.printStackTrace();
}

I have copied all the headers from the SDK and used it here. No use and I am getting same error response.


Solution

  • After much troubleshooting, I have found the issue. I debugged the SDK and found the missing values because AWS API documentation has no information about the API parameters or headers.

    API Documentation: https://docs.aws.amazon.com/fsx/latest/APIReference/API_DescribeFileCaches.html

    Headers needed:

    "Content-Length": "NUMBER"
    "Content-Type": "application/x-amz-json-1.1"
    "x-amz-target": "AWSSimbaAPIService_v20180301.DescribeFileCaches"
    "x-amz-content-sha256": "HASH" 
    

    I Have reported to AWS to update the documentation.