CloudStack API URLをJavaで生成するコード
Androidから使いたいため、Base64.encodeBase64String();は利用しないやり方です。
お勉強中なので確認用出力コードもそのまま記載、自分と同じように勉強中の方のお役に立てば幸いです。
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.util.TreeMap;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import android.util.Base64; //←Androidから使う場合はこちらを利用
//import java.util.Base64; ←通常のJavaから使う場合はこちらを利用
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
String queryString = "";
String host = "http://<yourCloudStackHost>/client/api";
String apiUrl = "";
String apiKey = "yourApiKey";
Key secKey = new SecretKeySpec("yourSecretKey".getBytes(),"HmacSHA1");
TreeMap<String,String> params = new TreeMap<>();
params.put("response","json");
params.put("command","listZones");
params.put("apikey",apiKey);
for(String key:params.keySet()){
if(queryString.isEmpty()){
queryString = key + "=" + params.get(key);
}else{
queryString = queryString + "&" + key + "=" + params.get(key);
}
//System.out.println(key + "=" + params.get(key));
System.out.println(queryString);
}
String queryStringLow = queryString.toLowerCase();
System.out.println(queryStringLow);
//シークレットキーを利用して、HMAC SHA1でハッシュする
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secKey);
byte[] digest = mac.doFinal(queryStringLow.getBytes());
//BASE64エンコード
String b64 = Base64.getEncoder().encodeToString(digest);
//URLエンコード
String signature = URLEncoder.encode(b64);
signature = signature.replaceAll("%0A",""); //改行コード除去
//URL生成
apiUrl = host + "?" + queryString + "&signature=" + signature;
//デバッグ用
System.out.println(digest);
System.out.println(b64);
System.out.println(signature);
System.out.println(queryString + "&signature=" + signature);
System.out.println(apiUrl);
}
}
apiURLに、
http://<yourCloudStackHost>/client/api?apikey=<yourApiKey>&command=listZones&response=json&signature=<yourSignature>
と入ってくるはずなので、こちらをコピーしターミナル等でアクセスしてみます。
curl -s 'http://<yourCloudStackHost>/client/api?apikey=<yourApiKey>&command=listZones&response=json&signature=<yourSignature>' | jq -C
応答結果
{
"listzonesresponse": {
"count": 3,
"zone": [
{
"id": "e8ebfccb-eb38-43ed-8abf-XXXX",
"name": "weber",
"networktype": "Advanced",
"securitygroupsenabled": false,
"allocationstate": "Enabled",
"zonetoken": "42101a12-6299-32c7-a324-XXXX",
"dhcpprovider": "VirtualRouter",
"localstorageenabled": true,
"tags": []
},
{
"id": "95c8746d-57b3-421f-9375-XXXX",
"name": "lux",
"networktype": "Advanced",
"securitygroupsenabled": false,
"allocationstate": "Enabled",
"zonetoken": "de9e9a4f-696d-39f4-bb3e-XXXX",
"dhcpprovider": "VirtualRouter",
"localstorageenabled": true,
"tags": []
},
{
"id": "f4583787-7bff-461a-b026-XXXX",
"name": "farad",
"networktype": "Advanced",
"securitygroupsenabled": false,
"allocationstate": "Enabled",
"zonetoken": "a53d8e78-3c77-3352-8a04-XXXX",
"dhcpprovider": "VirtualRouter",
"localstorageenabled": true,
"tags": []
}
]
}
}
signature等が間違っている場合の応答結果
{
"listzonesresponse": {
"errorcode": 401,
"errortext": "unable to verify user credentials and/or request signature"
}
}