KNOX-2144 - Alias API KnoxShell support should provide response types better than raw JSON (#211)

diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AbstractAliasRequest.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AbstractAliasRequest.java
index 39da1bd..f19ebb1 100644
--- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AbstractAliasRequest.java
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AbstractAliasRequest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.knox.gateway.shell.alias;
 
+import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
@@ -76,7 +77,7 @@
     return () -> {
       httpRequest = createRequest();
       try {
-        return new AliasResponse(execute(httpRequest));
+        return createResponse(execute(httpRequest));
       } catch (ErrorResponse e) {
         return new AliasResponse(e.getResponse());
       }
@@ -123,4 +124,8 @@
     return request;
   }
 
+  protected AliasResponse createResponse(HttpResponse response) {
+    return new AliasResponse(response);
+  }
+
 }
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AddAliasResponse.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AddAliasResponse.java
new file mode 100644
index 0000000..bad2d12
--- /dev/null
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AddAliasResponse.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.knox.gateway.shell.alias;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import java.util.Map;
+
+public class AddAliasResponse extends AliasResponse {
+
+  private String alias;
+
+  AddAliasResponse(HttpResponse response) {
+    super(response);
+
+    if (parsedResponse.containsKey("created")) {
+      Map<String, String> created = (Map<String, String>) parsedResponse.get("created");
+      if (created != null) {
+        cluster = created.get("topology");
+        alias = created.get("alias");
+      }
+    }
+  }
+
+  @Override
+  protected boolean isExpectedResponseStatus() {
+    return (response().getStatusLine().getStatusCode() == HttpStatus.SC_CREATED);
+  }
+
+  public String getAlias() {
+    return alias;
+  }
+
+}
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AliasResponse.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AliasResponse.java
index 544764f..1b7ca19 100644
--- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AliasResponse.java
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/AliasResponse.java
@@ -16,13 +16,67 @@
  */
 package org.apache.knox.gateway.shell.alias;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.util.EntityUtils;
 import org.apache.knox.gateway.shell.BasicResponse;
+import org.apache.knox.gateway.shell.KnoxShellException;
+
+import java.util.Map;
 
 public class AliasResponse extends BasicResponse {
 
+  private static final String CONTENT_TYPE = "application/json";
+
+  private String responseContent;
+
+  protected Map<String, Object> parsedResponse;
+
+  protected String cluster;
+
+
   AliasResponse(HttpResponse response) {
     super(response);
+    parseResponseEntity();
+  }
+
+  private void parseResponseEntity() {
+    if (!isExpectedResponseStatus()) {
+      throw new KnoxShellException("Unexpected response: " + response().getStatusLine().getReasonPhrase());
+    }
+
+    HttpEntity entity = response().getEntity();
+    if (entity == null) {
+      throw new KnoxShellException("Missing expected response content");
+    }
+
+    String contentType = entity.getContentType().getValue();
+    if (!CONTENT_TYPE.equals(contentType)) {
+      throw new KnoxShellException("Unexpected response content type: " + contentType);
+    }
+
+    try {
+      responseContent = EntityUtils.toString(entity);
+      parsedResponse =
+          (new ObjectMapper()).readValue(responseContent, new TypeReference<Map<String, Object>>() {});
+    } catch (Exception e) {
+      throw new KnoxShellException("Unable to process response content", e);
+    }
+  }
+
+  protected boolean isExpectedResponseStatus() {
+    return (response().getStatusLine().getStatusCode() == HttpStatus.SC_OK);
+  }
+
+  public String getCluster() {
+    return cluster;
+  }
+
+  public String getResponseContent() {
+    return responseContent;
   }
 
 }
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/DeleteRequest.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/DeleteRequest.java
index 28101c0..f258301 100644
--- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/DeleteRequest.java
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/DeleteRequest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.knox.gateway.shell.alias;
 
+import org.apache.http.HttpResponse;
 import org.apache.knox.gateway.shell.KnoxSession;
 
 import java.util.List;
@@ -54,4 +55,8 @@
     return elements;
   }
 
+  @Override
+  protected AliasResponse createResponse(HttpResponse response) {
+    return new RemoveAliasResponse(response);
+  }
 }
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/ListAliasResponse.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/ListAliasResponse.java
new file mode 100644
index 0000000..f6226f8
--- /dev/null
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/ListAliasResponse.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.knox.gateway.shell.alias;
+
+import org.apache.http.HttpResponse;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ListAliasResponse extends AliasResponse {
+
+  private List<String> aliases = new ArrayList<>();
+
+  ListAliasResponse(HttpResponse response) {
+    super(response);
+    cluster = (String) parsedResponse.get("topology");
+    List<String> values = (List<String>)parsedResponse.get("aliases");
+    aliases.addAll(values);
+  }
+
+  public List<String> getAliases() {
+    return aliases;
+  }
+
+}
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/ListRequest.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/ListRequest.java
index 7b0f33d..415bfa2 100644
--- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/ListRequest.java
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/ListRequest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.knox.gateway.shell.alias;
 
+import org.apache.http.HttpResponse;
 import org.apache.knox.gateway.shell.KnoxSession;
 
 public class ListRequest extends AbstractAliasRequest {
@@ -38,4 +39,9 @@
     return RequestType.GET;
   }
 
+  @Override
+  protected AliasResponse createResponse(HttpResponse response) {
+    return new ListAliasResponse(response);
+  }
+
 }
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/PostRequest.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/PostRequest.java
index 11af9c1..6e3b2ba 100644
--- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/PostRequest.java
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/PostRequest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.knox.gateway.shell.alias;
 
+import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpPost;
@@ -75,4 +76,9 @@
     return request;
   }
 
+  @Override
+  protected AliasResponse createResponse(HttpResponse response) {
+    return new AddAliasResponse(response);
+  }
+
 }
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/RemoveAliasResponse.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/RemoveAliasResponse.java
new file mode 100644
index 0000000..d12be77
--- /dev/null
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/alias/RemoveAliasResponse.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.knox.gateway.shell.alias;
+
+import org.apache.http.HttpResponse;
+import java.util.Map;
+
+public class RemoveAliasResponse extends AliasResponse {
+
+  private String alias;
+
+  RemoveAliasResponse(HttpResponse response) {
+    super(response);
+
+    if (parsedResponse.containsKey("deleted")) {
+      Map<String, String> deleted = (Map<String, String>) parsedResponse.get("deleted");
+      if (deleted != null) {
+        cluster = deleted.get("topology");
+        alias = deleted.get("alias");
+      }
+    }
+  }
+
+  public String getAlias() {
+    return alias;
+  }
+
+}
diff --git a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/AbstractResponseTest.java b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/AbstractResponseTest.java
new file mode 100644
index 0000000..44d2d3f
--- /dev/null
+++ b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/AbstractResponseTest.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.knox.gateway.shell.alias;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.StatusLine;
+import org.apache.http.entity.StringEntity;
+import org.apache.knox.gateway.shell.KnoxShellException;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public abstract class AbstractResponseTest<T extends AliasResponse> {
+
+  @Test
+  public void testInvalidResponseStatus() {
+    // Anything other than the expected response status
+    HttpResponse httpResponse =
+        createTestResponse(createTestStatusLine(HttpStatus.SC_BAD_REQUEST, "Bad Request"), null);
+
+    try {
+      createResponse(httpResponse);
+    } catch (KnoxShellException e) {
+      // Expected
+      assertEquals("Unexpected response: " + httpResponse.getStatusLine().getReasonPhrase(), e.getMessage());
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+  }
+
+  @Test
+  public void testMissingResponseEntity() {
+    HttpResponse httpResponse = createTestResponse(createTestStatusLine(getExpectedResponseStatusCode()), null);
+
+    try {
+      createResponse(httpResponse);
+    } catch (KnoxShellException e) {
+      // Expected
+      assertEquals("Missing expected response content", e.getMessage());
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+  }
+
+  @Test
+  public void testInvalidResponseJSON() {
+    StringEntity entity = null;
+    try {
+      entity = new StringEntity("{ \"topology\": \"testInvalidJSONCluster\", \"aliases\" : [ ");
+      entity.setContentType("application/json");
+    } catch (UnsupportedEncodingException e) {
+      fail(e.getMessage());
+    }
+
+    HttpResponse httpResponse = createTestResponse(createTestStatusLine(getExpectedResponseStatusCode()), entity);
+
+    try {
+      createResponse(httpResponse);
+    } catch (KnoxShellException e) {
+      // Expected
+      assertEquals("Unable to process response content", e.getMessage());
+      assertTrue(e.getCause().getMessage().contains("Unexpected end-of-input"));
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+  }
+
+  @Test
+  public void testInvalidResponseContentType() {
+    StringEntity entity = null;
+    try {
+      entity = new StringEntity("{ \"topology\": \"testInvalidJSONCluster\", \"aliases\" : [ ");
+    } catch (UnsupportedEncodingException e) {
+      fail(e.getMessage());
+    }
+
+    HttpResponse httpResponse = createTestResponse(createTestStatusLine(getExpectedResponseStatusCode()), entity);
+
+    try {
+      createResponse(httpResponse);
+    } catch (KnoxShellException e) {
+      // Expected
+      assertTrue(e.getMessage().startsWith("Unexpected response content type: "));
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+  }
+
+
+  abstract StringEntity createTestEntity(String cluster, List<String> aliases) throws Exception;
+
+
+  abstract T createResponse(HttpResponse httpResponse);
+
+
+  int getExpectedResponseStatusCode() {
+    return HttpStatus.SC_OK;
+  }
+
+
+  HttpResponse createTestResponse(final StatusLine   statusLine,
+                                  final String       cluster,
+                                  final List<String> aliases) {
+    StringEntity entity = null;
+    try {
+      entity = createTestEntity(cluster, aliases);
+      entity.setContentType("application/json");
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+    return createTestResponse(statusLine, entity);
+  }
+
+
+  HttpResponse createTestResponse(final StatusLine statusLine, final StringEntity entity) {
+    HttpResponse httpResponse = EasyMock.createNiceMock(HttpResponse.class);
+    EasyMock.expect(httpResponse.getStatusLine()).andReturn(statusLine).anyTimes();
+    EasyMock.expect(httpResponse.getEntity()).andReturn(entity).anyTimes();
+    EasyMock.replay(httpResponse);
+    return httpResponse;
+  }
+
+
+  StatusLine createTestStatusLine(int statusCode) {
+    return createTestStatusLine(statusCode, null);
+  }
+
+
+  StatusLine createTestStatusLine(int statusCode, final String reasonPhrase) {
+    StatusLine statusLine = EasyMock.createNiceMock(StatusLine.class);
+    EasyMock.expect(statusLine.getStatusCode()).andReturn(statusCode).anyTimes();
+    EasyMock.expect(statusLine.getReasonPhrase()).andReturn(reasonPhrase).anyTimes();
+    EasyMock.replay(statusLine);
+    return statusLine;
+  }
+
+}
diff --git a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/AddAliasResponseTest.java b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/AddAliasResponseTest.java
new file mode 100644
index 0000000..0a2eff9
--- /dev/null
+++ b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/AddAliasResponseTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.knox.gateway.shell.alias;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.StringEntity;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class AddAliasResponseTest extends AbstractResponseTest<AddAliasResponse> {
+
+  @Test
+  public void testAddAliasResponse() {
+    final String CLUSTER = "testValidCluster";
+    final String TEST_ALIAS = "alias1";
+
+    HttpResponse httpResponse = createTestResponse(createTestStatusLine(HttpStatus.SC_CREATED),
+                                                   CLUSTER,
+                                                   Collections.singletonList(TEST_ALIAS));
+
+    AddAliasResponse response = null;
+    try {
+      response = createResponse(httpResponse);
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+    assertEquals(CLUSTER, response.getCluster());
+    assertEquals(TEST_ALIAS, response.getAlias());
+  }
+
+  @Override
+  int getExpectedResponseStatusCode() {
+    return HttpStatus.SC_CREATED;
+  }
+
+  @Override
+  AddAliasResponse createResponse(HttpResponse httpResponse) {
+    return new AddAliasResponse(httpResponse);
+  }
+
+  @Override
+  StringEntity createTestEntity(String cluster, List<String> aliases) throws Exception {
+    String content = "{ \"created\" : { \"topology\" : \"" + cluster + "\", \"alias\" : \"" + aliases.get(0) + "\" } }";
+    return new StringEntity(content);
+  }
+
+}
diff --git a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/ListAliasResponseTest.java b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/ListAliasResponseTest.java
new file mode 100644
index 0000000..389b69a
--- /dev/null
+++ b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/ListAliasResponseTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.knox.gateway.shell.alias;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.StringEntity;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class ListAliasResponseTest extends AbstractResponseTest<ListAliasResponse> {
+
+  @Test
+  public void testListAliasResponse() {
+    final String CLUSTER = "testValidCluster";
+    final List<String> TEST_ALIASES = Arrays.asList("alias1", "alias2", "alias3");
+
+    HttpResponse httpResponse = createTestResponse(createTestStatusLine(HttpStatus.SC_OK), CLUSTER, TEST_ALIASES);
+
+    ListAliasResponse response = null;
+    try {
+      response = createResponse(httpResponse);
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+    assertEquals(CLUSTER, response.getCluster());
+    assertEquals(TEST_ALIASES, response.getAliases());
+  }
+
+  @Override
+  ListAliasResponse createResponse(HttpResponse httpResponse) {
+    return new ListAliasResponse(httpResponse);
+  }
+
+  @Override
+  StringEntity createTestEntity(final String cluster, final List<String> aliases) throws Exception {
+    StringBuilder sb = new StringBuilder(48);
+    sb.append("{ \"topology\": \"")
+      .append(cluster)
+      .append("\", \"aliases\" : [ ");
+
+    Iterator<String> iter = aliases.iterator();
+    while (iter.hasNext()) {
+      sb.append('\"')
+        .append(iter.next())
+        .append('\"');
+      if (iter.hasNext()) {
+        sb.append(", ");
+      }
+    }
+    sb.append(" ] }");
+
+    return new StringEntity(sb.toString());
+  }
+
+}
diff --git a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/RemoveAliasResponseTest.java b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/RemoveAliasResponseTest.java
new file mode 100644
index 0000000..859a0ec
--- /dev/null
+++ b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/alias/RemoveAliasResponseTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.knox.gateway.shell.alias;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.StringEntity;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class RemoveAliasResponseTest extends AbstractResponseTest<RemoveAliasResponse> {
+
+  @Test
+  public void testRemoveAliasResponse() {
+    final String CLUSTER = "testValidCluster";
+    final String TEST_ALIAS = "alias1";
+
+    HttpResponse httpResponse = createTestResponse(createTestStatusLine(HttpStatus.SC_OK),
+                                                   CLUSTER,
+                                                   Collections.singletonList(TEST_ALIAS));
+
+    RemoveAliasResponse response = null;
+    try {
+      response = createResponse(httpResponse);
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+    assertEquals(CLUSTER, response.getCluster());
+    assertEquals(TEST_ALIAS, response.getAlias());
+  }
+
+  @Override
+  RemoveAliasResponse createResponse(HttpResponse httpResponse) {
+    return new RemoveAliasResponse(httpResponse);
+  }
+
+  @Override
+  StringEntity createTestEntity(String cluster, List<String> aliases) throws Exception {
+    String content = "{ \"deleted\" : { \"topology\" : \"" + cluster + "\", \"alias\" : \"" + aliases.get(0) + "\" } }";
+    return new StringEntity(content);
+  }
+
+}