0

We're trying to create a stack using REST api from a Java class, but we're getting the response code as 400. It'll be of great help if you can say us where what we're doing wrong.

Here's the java class Note: Please, replace TOKEN_ID and TENANT_ID with the correct one in the class.

import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;

public class StackOrchestration {
private static final String TOKEN_ID = "xananananana";
private static final String TENANT_ID = "?????";

public static void createStack()
{
    HttpURLConnection connection = null;
    BufferedReader br = null;
    try {
        URL url = new URL("https://hkg.orchestration.api.rackspacecloud.com/v1/"+TENANT_ID+"/stacks");
        connection = (HttpURLConnection) url.openConnection();
        String line;
        StringBuffer jsonString = new StringBuffer();

        String payload = "{ \"stack_name\": \"Single-Server-Stack\", \"disable_rollback\": true, \"parameters\": {}, \"template\": \"heat_template_version: 2014-10-16\n \nresources:\n  compute_instance:  \n    type: \"OS::Nova::Server\"\n    properties:\n      flavor: 1 GB Performance\n      image: CentOS 5 (PV)\n      name: Single Server Stack\n       \noutputs:\n  public_ip:\n    description: public IP address of the deployed compute instance\n    value: { get_attr: [compute_instance, accessIPv4] }      \n\n\n\", \"timeout_mins\": 60 }";

        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("X-Auth-Token", TOKEN_ID);
        connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setRequestProperty("Accept", "application/json");

        OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
        writer.write(payload);
        writer.close();
        br = new BufferedReader(new InputStreamReader(connection.getInputStream()));

        while ((line = br.readLine()) != null) {
            System.out.println("-- "+line);
        }
        br.close();
        connection.disconnect();
    } catch (Exception e) {
        InputStream error = ((HttpURLConnection) connection).getErrorStream();
        br = new BufferedReader(new InputStreamReader(error));

        String nachricht;
        String response = "";
        try {
            while ((nachricht = br.readLine()) != null){
                  response += nachricht;
            }
            System.out.println("+++ " + response);
        } catch (Exception ex) {
        }
        //e.printStackTrace();

        return;
    }
}

public static void main (String args[])
{
    try {
        createStack();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

Java output::

+++ 400 Bad RequestThe server could not comply with the request since it is either malformed or otherwise incorrect. Invalid control character at: line 1 column 129 (char 129)

When we're trying to create a stack using 'curl' at that time we're able to do with the same template attribute which we're passing as the payload to the above Java code. Below is the curl execution:

curl -i -X POST -H 'Accept: application/json' -H 'Content-Type: application/json'  -H  "X-Auth-Token: $OS_AUTH_TOKEN" -d \
'{
    "stack_name": "Single-Server-Stack",
    "disable_rollback": true,
    "parameters": {},
    "template": "heat_template_version: 2014-10-16\n \nresources:\n         compute_instance:  \n    type: \"OS::Nova::Server\"\n    properties:\n      flavor: 1 GB Performance\n      image: CentOS 5 (PV)\n      name: Single Server Stack\n       \noutputs:\n  public_ip:\n    description: public IP address of the deployed compute instance\n    value: { get_attr: [compute_instance, accessIPv4] }      \n\n\n", 
    "timeout_mins": 60
 }' \
 https://hkg.orchestration.api.rackspacecloud.com/v1/$OS_TENANT_ID/stacks     

Curl Output::

HTTP/1.1 201 Created
Server: nginx/1.2.1
Date: Fri, 16 Jan 2015 11:27:59 GMT
Content-Type: application/json
Content-Length: 219
Connection: keep-alive
Location:         https://hkg.orchestration.api.rackspacecloud.com/v1/$OS_TENANT_ID/stacks/Single-Server-Stack/f1d5cc09-f4f8-4226-b5ce-62b9b26d111d
Via: 1.0 Repose (Repose/6.0.2)
{"stack": {"id": "f1d5cc09-f4f8-4226-b5ce-62b9b26d111d", "links":[{"href": "https://hkg.orchestration.api.rackspacecloud.com/v1/$OS_TENANT_ID/stacks/Single-Server-Stack/f1d5cc09-f4f8-4226-b5ce-62b9b26d111d", "rel": "self"}]}}

Update: The problem was because of not adding escape characters. This is how the payload has to be sent:

String payload = "{ \"stack_name\": \"Single-Server-Stack\", \"disable_rollback\": true, \"parameters\": {}, \"template\": \"heat_template_version: 2014-10-16\\n \\nresources:\\n compute_instance: \\n type: \\\"OS::Nova::Server\\\"\\n properties:\\n flavor: 1 GB Performance\\n image: CentOS 5 (PV)\\n name: Single Server Stack\\n \\noutputs:\\n public_ip:\\n description: public IP address of the deployed compute instance\\n value: { get_attr: [compute_instance, accessIPv4] } \\n\\n\\n\", \"timeout_mins\": 60 }";

devd
  • 370
  • 10
  • 28
  • Have you tried double-escaping the newline characters inside the template? So, instead of `\n`, you would use `\\\n`. – Shaunak Kashyap Jan 16 '15 at 14:00
  • Instead of double-escaping I added single escape like this `\\n`. So, now the "Invalid control character at" error is not coming but "Expecting , delimiter:" is coming. – devd Jan 19 '15 at 07:38

0 Answers0