引言
在第一篇博客里面提到了如何拼接出一个调用Open API的URL。
https://yq.aliyun.com/articles/225094?spm=5176.8091938.0.0.88lzXf
具备这个能力后,可以做很多事情。比如说可灵活定制的批量处理操作、或可灵活定制的监控查询动作。
这篇文章介绍一个批量添加EIP到共享带宽。这个功能后续会在控制台上线,在没上线之前可以用本文的方法批量添加多个IP到共享带宽。
源代码
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Arrays;
import org.apache.commons.codec.binary.Base64;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.SimpleTimeZone;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.*;
import javax.swing.*;import java.awt.event.*;
public class ApiDemo extends JFrame {
private static final String ENCODING = "UTF-8";
private static final String ALGORITHM = "HmacSHA1";
private static final String HTTP_METHOD = "GET";
//不同的产品API version不一样
private static final String urlAPIVersion = "2016-04-28";
private static final String urlSecALG = "HMAC-SHA1";
private static final String urlSecVer = "1.0";
private String urlAccKeyID = "";
private String ulrSeckey = "";
private static String urlSecNonce = UUID.randomUUID().toString();
private static final String urlFromat = "xml";
private String ulrTimeStamp =formatIso8601Date(new Date());
private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static String formatIso8601Date(Date date) {
SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
df.setTimeZone(new SimpleTimeZone(0, "GMT"));
return df.format(date);
}
public void AddIpToCbwp(String strAccKeyID,String strSeckey,String StrRegion,String StrCbwpid,String strIps) throws Exception {
String strcmd ="";
String Ips= strIps;
String[] splitAddress=Ips.split(";"); //如果以竖线为分隔符,则split的时候需要加上两个斜杠【\\】进行转义
for (int i = 0; i < splitAddress.length; i++) {
System.out.println();
strcmd = "Action=AddCommonBandwidthPackageIp;RegionId=";
strcmd += StrRegion;
strcmd += ";BandwidthPackageId=";
strcmd += StrCbwpid;
strcmd += ";IpInstanceId=";
strcmd += splitAddress[i];
try {
String strUR1 = CreatApiURL(strAccKeyID,strSeckey,strcmd);
new URL(strUR1).openStream();
System.out.println(" "+splitAddress[i] + " 添加成功");
} catch (Exception e2) {
// TODO Auto-generated catch block
//e2.printStackTrace();
System.out.println(" "+splitAddress[i] + " 添加失败:已添加或不是后付费类型EIP");
}
}
try{
Thread thread = Thread.currentThread();
thread.sleep(100);//暂停0.1秒后程序继续执行
}catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public String CreatApiURL(String strAccKeyID,String strSeckey,String strcmd) throws Exception {
urlAccKeyID=strAccKeyID;
ulrSeckey =strSeckey;
ulrSeckey = ulrSeckey+"&";
String urlNonce = UUID.randomUUID().toString();
String phrase =strcmd;
Date date = new Date();
SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
df.setTimeZone(new SimpleTimeZone(0, "GMT"));
ulrTimeStamp = df.format(date);
Map<String, String> parameters = new HashMap<String, String>();
// 加入公共请求参数
parameters.put("Format", urlFromat);
parameters.put("Version", urlAPIVersion);
parameters.put("SignatureMethod", urlSecALG);
parameters.put("SignatureNonce", urlNonce);
parameters.put("SignatureVersion", urlSecVer);
parameters.put("AccessKeyId", urlAccKeyID);
parameters.put("Timestamp", ulrTimeStamp);
String delims1 = ";";
String[] tokens1 = phrase.split(delims1);
for (int i = 0; i < tokens1.length; i++)
{
String delims2 = "=";
String[] tokens2 = tokens1[i].split(delims2);
parameters.put(tokens2[0], tokens2[1]);
}
// 对参数进行排序
String[] sortedKeys = parameters.keySet().toArray(new String[]{});
Arrays.sort(sortedKeys);
final String SEPARATOR = "&";
// 生成stringToSign字符串
StringBuilder stringToSign = new StringBuilder();
stringToSign.append(HTTP_METHOD).append(SEPARATOR);
String value = "/";
try {
value = URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") ;
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
stringToSign.append(value).append(SEPARATOR);
StringBuilder canonicalizedQueryString = new StringBuilder();
for(String key : sortedKeys) {
// 这里注意对key和value进行编码
String value1 = key;
try {
value1 = URLEncoder.encode(value1, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") ;
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String value2 = parameters.get(key);
try {
value2 = URLEncoder.encode(value2, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") ;
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
canonicalizedQueryString.append("&")
.append(value1).append("=")
.append(value2);
}
// 这里注意对canonicalizedQueryString进行编码
String value3 = canonicalizedQueryString.toString().substring(1);
try {
value3 = URLEncoder.encode(value3, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") ;
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
stringToSign.append(value3);
Mac mac = null;
try {
mac = Mac.getInstance(ALGORITHM);
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
mac.init(new SecretKeySpec(ulrSeckey.getBytes(ENCODING), ALGORITHM));
} catch (InvalidKeyException | UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] signData = null;
try {
signData = mac.doFinal(stringToSign.toString().getBytes(ENCODING));
} catch (IllegalStateException | UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String signature = new String(Base64.encodeBase64(signData));
value = signature;
try {
value = URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") ;
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String urlSignature = value;
StringBuilder urlReq = new StringBuilder();
//vpc的调用入口,如果是云监控的入口,则是http://metrics.cn-beijing.aliyuncs.com/的形式
urlReq.append("https://vpc.aliyuncs.com");
urlReq.append("?Signature=");
urlReq.append(urlSignature);
for(String key : sortedKeys) {
urlReq.append("&")
.append(key)
.append("=")
.append(parameters.get(key));
}
System.out.println(urlReq.toString());
return urlReq.toString();
}
public ApiDemo() throws Exception {
setSize(500,800);
setLayout(new FlowLayout(FlowLayout.CENTER,10,30));
JPanel panel=new JPanel();
JTextField textField_AccID=new JTextField(30);
JTextField textField_Acckey=new JTextField(30);
JTextField textField_region=new JTextField(30);
JTextField textField_cbwpid=new JTextField(30);
JTextArea textArea_ip=new JTextArea(10,30);
JButton button=new JButton(" 批量添加IP到共享带宽 ");
JLabel AccID=new JLabel("请输入Access Key ID:");
JLabel AccKey=new JLabel("请输入Access Key Secret:");
JLabel Region=new JLabel("请输入共享带宽包region,如 cn-beijing ");
JLabel Cbwpid=new JLabel("请输入带宽包实例ID:如 cbwp-2zetu1kb5ek9lwjspo3yl ");
JLabel Ips=new JLabel("请输入要加入共享带宽的IP实例ID,如有多个请用英文分号;分隔");
JLabel Ips2=new JLabel("如eip-2zexs2h1lscs4ljccpigh;eip-2zew4iuvcnvr0e7cew7rx ");
// JLabel URLResult=new JLabel(" Open API URL生成结果: ");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
urlAccKeyID=textField_AccID.getText();
ulrSeckey =textField_Acckey.getText();
String strRegion = textField_region.getText();
String strCbwpid = textField_cbwpid.getText();
String strIPs = textArea_ip.getText();
try {
AddIpToCbwp(urlAccKeyID,ulrSeckey,strRegion,strCbwpid,strIPs);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
getContentPane().add(panel);
getContentPane().add(AccID);
getContentPane().add(textField_AccID);
getContentPane().add(AccKey);
getContentPane().add(textField_Acckey);
getContentPane().add(Region);
getContentPane().add(textField_region);
getContentPane().add(Cbwpid);
getContentPane().add(textField_cbwpid);
getContentPane().add(Ips);
getContentPane().add(Ips2);
getContentPane().add(textArea_ip);
getContentPane().add(button);
// getContentPane().add(URLResult);
//getContentPane().add(textField_URL);
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(3);
}
public static void main(String[] args) throws Exception {
ApiDemo API_GEN = new ApiDemo();
}
}
程序界面
这个是一个以图形化界面来展示拼接URL的小程序
程序界面
附件提供可运行的程序。
通过命令行终端启动可以看到debug信息。