| // 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 |
| // 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 com.cloud.api; |
| |
| import com.cloud.utils.exception.CloudRuntimeException; |
| import com.google.gson.Gson; |
| import org.apache.cloudstack.api.response.SuccessResponse; |
| |
| import java.io.BufferedReader; |
| import java.io.EOFException; |
| import java.io.InputStreamReader; |
| import java.math.BigInteger; |
| import java.net.HttpURLConnection; |
| import java.net.URL; |
| import java.net.URLEncoder; |
| import java.security.MessageDigest; |
| import java.security.NoSuchAlgorithmException; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| |
| /** |
| * Base class for API Test |
| * |
| */ |
| public abstract class APITest { |
| |
| protected String rootUrl = "http://localhost:8080/client/api"; |
| protected String sessionKey = null; |
| protected String cookieToSent = null; |
| |
| /** |
| * Sending an api request through Http GET |
| * @param command command name |
| * @param params command query parameters in a HashMap |
| * @return http request response string |
| */ |
| protected String sendRequest(String command, HashMap<String, String> params) { |
| try { |
| // Construct query string |
| StringBuilder sBuilder = new StringBuilder(); |
| sBuilder.append("command="); |
| sBuilder.append(command); |
| if (params != null && params.size() > 0) { |
| Iterator<String> keys = params.keySet().iterator(); |
| while (keys.hasNext()) { |
| String key = keys.next(); |
| sBuilder.append("&"); |
| sBuilder.append(key); |
| sBuilder.append("="); |
| sBuilder.append(URLEncoder.encode(params.get(key), "UTF-8")); |
| } |
| } |
| |
| // Construct request url |
| String reqUrl = rootUrl + "?" + sBuilder.toString(); |
| |
| // Send Http GET request |
| URL url = new URL(reqUrl); |
| HttpURLConnection conn = (HttpURLConnection)url.openConnection(); |
| conn.setRequestMethod("GET"); |
| |
| if (!command.equals("login") && cookieToSent != null) { |
| // add the cookie to a request |
| conn.setRequestProperty("Cookie", cookieToSent); |
| } |
| conn.connect(); |
| |
| if (command.equals("login")) { |
| // if it is login call, store cookie |
| String headerName = null; |
| for (int i = 1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) { |
| if (headerName.equals("Set-Cookie")) { |
| String cookie = conn.getHeaderField(i); |
| cookie = cookie.substring(0, cookie.indexOf(";")); |
| String cookieName = cookie.substring(0, cookie.indexOf("=")); |
| String cookieValue = cookie.substring(cookie.indexOf("=") + 1, cookie.length()); |
| cookieToSent = cookieName + "=" + cookieValue; |
| } |
| } |
| } |
| |
| // Get the response |
| StringBuilder response = new StringBuilder(); |
| BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); |
| String line; |
| try { |
| while ((line = rd.readLine()) != null) { |
| response.append(line); |
| } |
| } catch (EOFException ex) { |
| // ignore this exception |
| System.out.println("EOF exception due to java bug"); |
| } |
| rd.close(); |
| |
| return response.toString(); |
| |
| } catch (Exception e) { |
| throw new CloudRuntimeException("Problem with sending api request", e); |
| } |
| } |
| |
| protected String createMD5String(String password) { |
| MessageDigest md5; |
| try { |
| md5 = MessageDigest.getInstance("MD5"); |
| } catch (NoSuchAlgorithmException e) { |
| throw new CloudRuntimeException("Error", e); |
| } |
| |
| md5.reset(); |
| BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes())); |
| |
| // make sure our MD5 hash value is 32 digits long... |
| StringBuffer sb = new StringBuffer(); |
| String pwStr = pwInt.toString(16); |
| int padding = 32 - pwStr.length(); |
| for (int i = 0; i < padding; i++) { |
| sb.append('0'); |
| } |
| sb.append(pwStr); |
| return sb.toString(); |
| } |
| |
| protected Object fromSerializedString(String result, Class<?> repCls) { |
| try { |
| if (result != null && !result.isEmpty()) { |
| // get real content |
| int start; |
| int end; |
| if (repCls == LoginResponse.class || repCls == SuccessResponse.class) { |
| |
| start = result.indexOf('{', result.indexOf('{') + 1); // find |
| // the |
| // second |
| // { |
| |
| end = result.lastIndexOf('}', result.lastIndexOf('}') - 1); // find |
| // the |
| // second |
| // } |
| // backwards |
| |
| } else { |
| // get real content |
| start = result.indexOf('{', result.indexOf('{', result.indexOf('{') + 1) + 1); // find |
| // the |
| // third |
| // { |
| end = result.lastIndexOf('}', result.lastIndexOf('}', result.lastIndexOf('}') - 1) - 1); // find |
| // the |
| // third |
| // } |
| // backwards |
| } |
| if (start < 0 || end < 0) { |
| throw new CloudRuntimeException("Response format is wrong: " + result); |
| } |
| String content = result.substring(start, end + 1); |
| Gson gson = ApiGsonHelper.getBuilder().create(); |
| return gson.fromJson(content, repCls); |
| } |
| return null; |
| } catch (RuntimeException e) { |
| throw new CloudRuntimeException("Caught runtime exception when doing GSON deserialization on: " + result, e); |
| } |
| } |
| |
| /** |
| * Login call |
| * @param username user name |
| * @param password password (plain password, we will do MD5 hash here for you) |
| * @return login response string |
| */ |
| protected void login(String username, String password) { |
| //String md5Psw = createMD5String(password); |
| // send login request |
| HashMap<String, String> params = new HashMap<String, String>(); |
| params.put("response", "json"); |
| params.put("username", username); |
| params.put("password", password); |
| String result = this.sendRequest("login", params); |
| LoginResponse loginResp = (LoginResponse)fromSerializedString(result, LoginResponse.class); |
| sessionKey = loginResp.getSessionkey(); |
| |
| } |
| } |