blob: 0038ffdb517528fa7c659f3f95718bc82fd6d72f [file] [log] [blame]
//
// 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.cloudstack.network.opendaylight.api.resources;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.cloudstack.network.opendaylight.api.NeutronInvalidCredentialsException;
import org.apache.cloudstack.network.opendaylight.api.NeutronRestApi;
import org.apache.cloudstack.network.opendaylight.api.NeutronRestApiException;
import org.apache.cloudstack.network.opendaylight.api.NeutronRestFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.log4j.Logger;
public abstract class Action {
private static final Logger s_logger = Logger.getLogger(Action.class);
private static final int BODY_RESP_MAX_LEN = 1024;
// private static final String DEFAULT
protected static final String TEXT_HTML_CONTENT_TYPE = "text/html";
protected static final String JSON_CONTENT_TYPE = "application/json";
protected static final String CONTENT_TYPE = "Content-Type";
private final URL url;
private final String username;
private final String password;
public Action(final URL url, final String username, final String password) {
this.url = url;
this.username = username;
this.password = password;
}
public String executeGet(final String uri, final Map<String, String> parameters) throws NeutronRestApiException {
try {
validateCredentials();
} catch (NeutronInvalidCredentialsException e) {
throw new NeutronRestApiException("Invalid credentials!", e);
}
NeutronRestFactory factory = NeutronRestFactory.getInstance();
NeutronRestApi neutronRestApi = factory.getNeutronApi(GetMethod.class);
GetMethod getMethod = (GetMethod) neutronRestApi.createMethod(url, uri);
try {
getMethod.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE);
String encodedCredentials = encodeCredentials();
getMethod.setRequestHeader("Authorization", "Basic " + encodedCredentials);
if (parameters != null && !parameters.isEmpty()) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(parameters.size());
for (Entry<String, String> e : parameters.entrySet()) {
nameValuePairs.add(new NameValuePair(e.getKey(), e.getValue()));
}
getMethod.setQueryString(nameValuePairs.toArray(new NameValuePair[0]));
}
neutronRestApi.executeMethod(getMethod);
if (getMethod.getStatusCode() != HttpStatus.SC_OK) {
String errorMessage = responseToErrorMessage(getMethod);
getMethod.releaseConnection();
s_logger.error("Failed to retrieve object : " + errorMessage);
throw new NeutronRestApiException("Failed to retrieve object : " + errorMessage);
}
return getMethod.getResponseBodyAsString();
} catch (NeutronRestApiException e) {
s_logger.error("NeutronRestApiException caught while trying to execute HTTP Method on the Neutron Controller", e);
throw new NeutronRestApiException("API call to Neutron Controller Failed", e);
} catch (IOException e) {
throw new NeutronRestApiException(e);
} finally {
getMethod.releaseConnection();
}
}
protected String executePost(final String uri, final StringRequestEntity entity) throws NeutronRestApiException {
try {
validateCredentials();
} catch (NeutronInvalidCredentialsException e) {
throw new NeutronRestApiException("Invalid credentials!", e);
}
NeutronRestFactory factory = NeutronRestFactory.getInstance();
NeutronRestApi neutronRestApi = factory.getNeutronApi(PostMethod.class);
PostMethod postMethod = (PostMethod) neutronRestApi.createMethod(url, uri);
try {
postMethod.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE);
postMethod.setRequestEntity(entity);
String encodedCredentials = encodeCredentials();
postMethod.setRequestHeader("Authorization", "Basic " + encodedCredentials);
neutronRestApi.executeMethod(postMethod);
if (postMethod.getStatusCode() != HttpStatus.SC_CREATED) {
String errorMessage = responseToErrorMessage(postMethod);
postMethod.releaseConnection();
s_logger.error("Failed to create object : " + errorMessage);
throw new NeutronRestApiException("Failed to create object : " + errorMessage);
}
return postMethod.getResponseBodyAsString();
} catch (NeutronRestApiException e) {
s_logger.error("NeutronRestApiException caught while trying to execute HTTP Method on the Neutron Controller", e);
throw new NeutronRestApiException("API call to Neutron Controller Failed", e);
} catch (IOException e) {
throw new NeutronRestApiException("Failed to load json response body", e);
} finally {
postMethod.releaseConnection();
}
}
protected void executePut(final String uri, final StringRequestEntity entity) throws NeutronRestApiException {
try {
validateCredentials();
} catch (NeutronInvalidCredentialsException e) {
throw new NeutronRestApiException("Invalid credentials!", e);
}
NeutronRestFactory factory = NeutronRestFactory.getInstance();
NeutronRestApi neutronRestApi = factory.getNeutronApi(PutMethod.class);
PutMethod putMethod = (PutMethod) neutronRestApi.createMethod(url, uri);
try {
putMethod.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE);
putMethod.setRequestEntity(entity);
String encodedCredentials = encodeCredentials();
putMethod.setRequestHeader("Authorization", "Basic " + encodedCredentials);
neutronRestApi.executeMethod(putMethod);
if (putMethod.getStatusCode() != HttpStatus.SC_OK) {
String errorMessage = responseToErrorMessage(putMethod);
putMethod.releaseConnection();
s_logger.error("Failed to update object : " + errorMessage);
throw new NeutronRestApiException("Failed to update object : " + errorMessage);
}
} catch (NeutronRestApiException e) {
s_logger.error("NeutronRestApiException caught while trying to execute HTTP Method on the Neutron Controller", e);
throw new NeutronRestApiException("API call to Neutron Controller Failed", e);
} finally {
putMethod.releaseConnection();
}
}
protected String executePut(final String uri) throws NeutronRestApiException {
try {
validateCredentials();
} catch (NeutronInvalidCredentialsException e) {
throw new NeutronRestApiException("Invalid credentials!", e);
}
NeutronRestFactory factory = NeutronRestFactory.getInstance();
NeutronRestApi neutronRestApi = factory.getNeutronApi(PutMethod.class);
PutMethod putMethod = (PutMethod) neutronRestApi.createMethod(url, uri);
try {
String encodedCredentials = encodeCredentials();
putMethod.setRequestHeader("Authorization", "Basic " + encodedCredentials);
neutronRestApi.executeMethod(putMethod);
if (putMethod.getStatusCode() != HttpStatus.SC_OK) {
String errorMessage = responseToErrorMessage(putMethod);
putMethod.releaseConnection();
s_logger.error("Failed to update object : " + errorMessage);
throw new NeutronRestApiException("Failed to update object : " + errorMessage);
}
return putMethod.getResponseBodyAsString();
} catch (NeutronRestApiException e) {
s_logger.error("NeutronRestApiException caught while trying to execute HTTP Method on the Neutron Controller", e);
throw new NeutronRestApiException("API call to Neutron Controller Failed", e);
} catch (IOException e) {
throw new NeutronRestApiException("Failed to load json response body", e);
} finally {
putMethod.releaseConnection();
}
}
protected void executeDelete(final String uri) throws NeutronRestApiException {
try {
validateCredentials();
} catch (NeutronInvalidCredentialsException e) {
throw new NeutronRestApiException("Invalid credentials!", e);
}
NeutronRestFactory factory = NeutronRestFactory.getInstance();
NeutronRestApi neutronRestApi = factory.getNeutronApi(DeleteMethod.class);
DeleteMethod deleteMethod = (DeleteMethod) neutronRestApi.createMethod(url, uri);
try {
deleteMethod.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE);
String encodedCredentials = encodeCredentials();
deleteMethod.setRequestHeader("Authorization", "Basic " + encodedCredentials);
neutronRestApi.executeMethod(deleteMethod);
if (deleteMethod.getStatusCode() != HttpStatus.SC_NO_CONTENT) {
String errorMessage = responseToErrorMessage(deleteMethod);
deleteMethod.releaseConnection();
s_logger.error("Failed to delete object : " + errorMessage);
throw new NeutronRestApiException("Failed to delete object : " + errorMessage);
}
} catch (NeutronRestApiException e) {
s_logger.error("NeutronRestApiException caught while trying to execute HTTP Method on the Neutron Controller", e);
throw new NeutronRestApiException("API call to Neutron Controller Failed", e);
} finally {
deleteMethod.releaseConnection();
}
}
private void validateCredentials() throws NeutronInvalidCredentialsException {
if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
throw new NeutronInvalidCredentialsException("Credentials are null or empty");
}
}
private String encodeCredentials() {
String authString = username + ":" + password;
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
return authStringEnc;
}
private String responseToErrorMessage(final HttpMethodBase method) {
assert method.isRequestSent() : "no use getting an error message unless the request is sent";
final Header contentTypeHeader = method.getResponseHeader(CONTENT_TYPE);
if (contentTypeHeader != null && TEXT_HTML_CONTENT_TYPE.equals(contentTypeHeader.getValue())) {
// The error message is the response content
// Safety margin of 1024 characters, anything longer is probably
// useless and will clutter the logs
try {
return method.getResponseBodyAsString(BODY_RESP_MAX_LEN);
} catch (IOException e) {
s_logger.debug("Error while loading response body", e);
}
}
// The default
return method.getStatusText();
}
}