// 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 org.apache.cloudstack.ratelimit.integration; 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; import com.google.gson.Gson; import org.apache.cloudstack.api.response.SuccessResponse; import com.cloud.api.ApiGsonHelper; import com.cloud.utils.exception.CloudRuntimeException; /** * 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(); } }