// // 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 create 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 create 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 update object : " + errorMessage); throw new NeutronRestApiException("Failed to create 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(); } }