diff --git a/examples/LinkingDemo.java b/examples/LinkingDemo.java new file mode 100644 index 000000000..1aea0da88 --- /dev/null +++ b/examples/LinkingDemo.java @@ -0,0 +1,132 @@ +import com.qiniu.common.QiniuException; +import com.qiniu.linking.*; +import com.qiniu.linking.model.*; +import com.qiniu.util.Auth; +import sun.security.tools.jarsigner.TimestampedSigner; + +import java.security.Timestamp; +import java.util.Date; + + +public class LinkingDemo { + + final static String testAk = "ak"; + final static String testSk = "sk"; + final static String testAppid = "appid"; + final static String testHost = "http://linking.qiniuapi.com"; + final static String testDeviceName1 = "test1"; + final static String testDeviceName2 = "test2"; + public static void main(String[] args) { + + Auth auth = Auth.create(testAk,testSk); + LinkingDeviceManager deviceManager = new LinkingDeviceManager(auth,testHost); + try{ + //创建设备 + deviceManager.createDevice(testAppid,testDeviceName1); + } catch (QiniuException e){ + System.out.println(e.error()); + } + + try{ + //添加dak + DeviceKey[] keys = deviceManager.addDeviceKey(testAppid,testDeviceName1); + System.out.println(keys[0].getAccessKey()); + System.out.println(keys[0].getSecretKey()); + }catch (QiniuException e){ + System.out.println(e.error()); + } + + try{ + //查询设备 + DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid,testDeviceName1); + if (keys.length==1){ + throw new QiniuException(new Exception(),"expect one length"); + } + //删除设备 + deviceManager.deleteDeviceKey(testAppid,testDeviceName1,keys[0].getAccessKey()); + keys = deviceManager.queryDeviceKey(testAppid,testDeviceName1); + if (keys.length==0){ + throw new QiniuException(new Exception(),"expect zero length"); + } + }catch (QiniuException e){ + System.out.println(e.error()); + } + + try{ + //列出设备 + DeviceListing deviceslist = deviceManager.listDevice(testAppid,"","", 1,false); + System.out.println(deviceslist.items.length); + }catch (QiniuException e){ + System.out.println(e.error()); + } + + + + try{ + //修改设备字段 + PatchOperation[] operations={new PatchOperation("replace","segmentExpireDays",9)}; + Device device= deviceManager.updateDevice(testAppid,testDeviceName1,operations); + System.out.println(device.getSegmentExpireDays()); + }catch (QiniuException e){ + System.out.println(e.error()); + } + + + try{ + //查询设备在线历史记录 + DeviceHistoryListing history= deviceManager.listDeviceHistory(testAppid,testDeviceName1, + 0,(new Date().getTime())/1000,"",0); + }catch (QiniuException e){ + System.out.println(e.error()); + } + + + + try{ + //删除设备信息 + deviceManager.deleteDevice(testAppid,testDeviceName1); + } catch (QiniuException e){ + System.out.println(e.error()); + } + + try{ + deviceManager.createDevice(testAppid,testDeviceName1); + deviceManager.createDevice(testAppid,testDeviceName2); + + //添加dak + deviceManager.addDeviceKey(testAppid,testDeviceName1); + DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid,testDeviceName1); + String dak = keys[0].getAccessKey(); + + //移动dak + deviceManager.cloneDeviceKey(testAppid,testDeviceName1,testDeviceName2,true, false,dak); + Device device = deviceManager.getDeviceByAccessKey(dak); + device.getDeviceName(); + + deviceManager.deleteDeviceKey(testAppid,testDeviceName2,dak); + + String token; + //生成具有所有功能的token + String[] actions = new String[]{Auth.DTOKEN_ACTION_STATUS,Auth.DTOKEN_ACTION_VOD,Auth.DTOKEN_ACTION_TUTK}; + token = auth.generateLinkingDeviceTokenWithExpires(testAppid,testDeviceName1,1000,actions); + //生成视频相关功能的token + token = auth.generateLinkingDeviceVodTokenWithExpires(testAppid,testDeviceName1,1000,actions); + //生成获取设备状态的token + token = auth.generateLinkingDeviceStatusTokenWithExpires(testAppid,testDeviceName1,1000,actions); + + }catch (QiniuException e){ + System.out.println(e.error()); + }finally { + try{ + deviceManager.deleteDevice(testAppid,testDeviceName1); + }catch (Exception ignored){ + } + try{ + deviceManager.deleteDevice(testAppid,testDeviceName2); + }catch (Exception ignored){ + } + } + + + } +} diff --git a/src/main/java/com/qiniu/http/Client.java b/src/main/java/com/qiniu/http/Client.java index befce526f..88da38a44 100755 --- a/src/main/java/com/qiniu/http/Client.java +++ b/src/main/java/com/qiniu/http/Client.java @@ -236,6 +236,54 @@ public void accept(String key, Object value) { return send(requestBuilder, headers); } + public Response patch(String url, byte[] body, StringMap headers) throws QiniuException { + return patch(url, body, headers, DefaultMime); + } + + public Response patch(String url, String body, StringMap headers) throws QiniuException { + return patch(url, StringUtils.utf8Bytes(body), headers, DefaultMime); + } + + public Response patch(String url, StringMap params, StringMap headers) throws QiniuException { + final FormBody.Builder f = new FormBody.Builder(); + params.forEach(new StringMap.Consumer() { + @Override + public void accept(String key, Object value) { + f.add(key, value.toString()); + } + }); + return patch(url, f.build(), headers); + } + + public Response patch(String url, byte[] body, StringMap headers, String contentType) throws QiniuException { + RequestBody rbody; + if (body != null && body.length > 0) { + MediaType t = MediaType.parse(contentType); + rbody = RequestBody.create(t, body); + } else { + rbody = RequestBody.create(null, new byte[0]); + } + return patch(url, rbody, headers); + } + + public Response patch(String url, byte[] body, int offset, int size, + StringMap headers, String contentType) throws QiniuException { + RequestBody rbody; + if (body != null && body.length > 0) { + MediaType t = MediaType.parse(contentType); + rbody = create(t, body, offset, size); + } else { + rbody = RequestBody.create(null, new byte[0]); + } + return patch(url, rbody, headers); + } + + private Response patch(String url, RequestBody body, StringMap headers) throws QiniuException { + Request.Builder requestBuilder = new Request.Builder().url(url).patch(body); + return send(requestBuilder, headers); + } + + public Response send(final Request.Builder requestBuilder, StringMap headers) throws QiniuException { if (headers != null) { headers.forEach(new StringMap.Consumer() { diff --git a/src/main/java/com/qiniu/linking/LinkingDeviceManager.java b/src/main/java/com/qiniu/linking/LinkingDeviceManager.java new file mode 100644 index 000000000..a33fbffab --- /dev/null +++ b/src/main/java/com/qiniu/linking/LinkingDeviceManager.java @@ -0,0 +1,207 @@ +package com.qiniu.linking; + +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.Response; +import com.qiniu.linking.model.*; +import com.qiniu.util.*; + +public class LinkingDeviceManager { + + + private final Auth auth; + private final String host; + private final Client client; + + + public LinkingDeviceManager(Auth auth) { + this(auth, "http://linking.qiniuapi.com"); + } + + public LinkingDeviceManager(Auth auth, String host) { + this(auth, host, new Client()); + } + + public LinkingDeviceManager(Auth auth, String host, Client client) { + this.auth = auth; + this.host = host; + this.client = client; + } + + public void createDevice(String appid, String deviceName) throws QiniuException { + StringMap params = new StringMap().put("device", deviceName); + String url = String.format("%s/v1/apps/%s/devices", host, appid); + Response res = post(url, params); + res.close(); + } + + public void deleteDevice(String appid, String deviceName) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + String url = String.format("%s/v1/apps/%s/devices/%s", host, appid, encodedDeviceName); + StringMap headers = auth.authorizationV2(url, "DELETE", null, null); + Response res = client.delete(url, headers); + if (!res.isOK()) { + throw new QiniuException(res); + } + res.close(); + } + + public DeviceListing listDevice(String appid, String prefix, + String marker, int limit, boolean online) throws QiniuException { + StringMap map = new StringMap().putNotEmpty("marker", marker) + .putNotEmpty("prefix", prefix).putWhen("limit", limit, limit > 0) + .putWhen("online", online, online); + String queryString = map.formString(); + if (map.size()>0){ + queryString="?"+queryString; + } + String url = String.format("%s/v1/apps/%s/devices%s", host, appid, queryString); + Response res = get(url); + DeviceListing ret = res.jsonToObject(DeviceListing.class); + res.close(); + return ret; + } + + private Response get(String url) throws QiniuException { + StringMap headers = auth.authorizationV2(url, "GET", null, null); + Response res = client.get(url, headers); + if (!res.isOK()) { + throw new QiniuException(res); + } + return res; + } + + public Device getDevice(String appid, String deviceName) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + String url = String.format("%s/v1/apps/%s/devices/%s", host, appid, encodedDeviceName); + Response res = get(url); + Device ret = res.jsonToObject(Device.class); + res.close(); + return ret; + } + + public Device getDeviceByAccessKey(String deviceAccessKey) throws QiniuException { + String url = String.format("%s/v1/keys/%s", host, deviceAccessKey); + Response res = get(url); + Device ret = res.jsonToObject(Device.class); + res.close(); + return ret; + } + + public Device updateDevice(String appid, String deviceName, PatchOperation[] operations) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + StringMap params = new StringMap().put("operations", operations); + String url = String.format("%s/v1/apps/%s/devices/%s", host, appid, encodedDeviceName); + byte[] body = Json.encode(params).getBytes(Constants.UTF_8); + StringMap headers = auth.authorizationV2(url, "PATCH", body, Client.JsonMime); + Response res = client.patch(url, body, headers, Client.JsonMime); + if (!res.isOK()) { + throw new QiniuException(res); + } + Device ret = res.jsonToObject(Device.class); + res.close(); + return ret; + + } + + public DeviceHistoryListing listDeviceHistory(String appid, String deviceName, + long start, long end, String marker, int limit) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + StringMap map = new StringMap().putNotEmpty("marker", marker). + put("start", start).put("end", end).putWhen("limit", limit, limit > 0); + String queryString = map.formString(); + String url = String.format("%s/v1/apps/%s/devices/%s/historyactivity?%s", + host, appid, encodedDeviceName, queryString); + Response res = get(url); + DeviceHistoryListing ret = res.jsonToObject(DeviceHistoryListing.class); + res.close(); + return ret; + + } + + private class DeviceKeyRet { + DeviceKey[] keys; + } + + public DeviceKey[] addDeviceKey(String appid, String deviceName) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + String url = String.format("%s/v1/apps/%s/devices/%s/keys", host, appid, encodedDeviceName); + Response res = post(url, null); + DeviceKeyRet ret = res.jsonToObject(DeviceKeyRet.class); + res.close(); + if (ret != null) { + return ret.keys; + } + return null; + } + + public DeviceKey[] queryDeviceKey(String appid, String deviceName) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + String url = String.format("%s/v1/apps/%s/devices/%s/keys", host, appid, encodedDeviceName); + Response res = get(url); + DeviceKeyRet ret = res.jsonToObject(DeviceKeyRet.class); + res.close(); + if (ret != null) { + return ret.keys; + } + return null; + } + + public void deleteDeviceKey(String appid, String deviceName, String accessKey) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + String url = String.format("%s/v1/apps/%s/devices/%s/keys/%s", host, appid, encodedDeviceName, accessKey); + StringMap headers = auth.authorizationV2(url, "DELETE", null, null); + Response res = client.delete(url, headers); + if (!res.isOK()) { + throw new QiniuException(res); + } + DeviceKeyRet ret = res.jsonToObject(DeviceKeyRet.class); + res.close(); + } + + public void updateDeviceKeyState(String appid, String deviceName, + String accessKey, int state) throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + StringMap params = new StringMap().put("state", state); + String url = String.format("%s/v1/apps/%s/devices/%s/keys/%s/state", host, appid, encodedDeviceName, accessKey); + Response res = post(url, params); + res.close(); + } + + public DeviceKey[] cloneDeviceKey(String appid, String fromDeviceName, + String toDeviceName, boolean cleanSelfKeys, + boolean deleteDevice, String deviceAccessKey) throws QiniuException { + String encodedFromDeviceName = UrlSafeBase64.encodeToString(fromDeviceName); + String encodedToDeviceName = UrlSafeBase64.encodeToString(toDeviceName); + String url = String.format("%s/v1/apps/%s/devices/%s/keys/clone", host, appid, encodedToDeviceName); + StringMap params = new StringMap().put("fromDevice", fromDeviceName).put("cleanSelfKeys", cleanSelfKeys). + put("deleteDevice", deleteDevice).put("deviceAccessKey", deviceAccessKey); + + Response res = post(url, params); + DeviceKeyRet ret = res.jsonToObject(DeviceKeyRet.class); + res.close(); + if (ret != null) { + return ret.keys; + + } + return null; + } + + private Response post(String url, StringMap params) throws QiniuException { + byte[] body; + String contentType = null; + if (params == null) { + body = null; + } else { + contentType = Client.JsonMime; + body = Json.encode(params).getBytes(Constants.UTF_8); + } + StringMap headers = auth.authorizationV2(url, "POST", body, contentType); + Response res = client.post(url, body, headers, Client.JsonMime); + if (!res.isOK()) { + throw new QiniuException(res); + } + return res; + } +} diff --git a/src/main/java/com/qiniu/linking/LinkingVodManager.java b/src/main/java/com/qiniu/linking/LinkingVodManager.java new file mode 100644 index 000000000..7c0644c7a --- /dev/null +++ b/src/main/java/com/qiniu/linking/LinkingVodManager.java @@ -0,0 +1,70 @@ +package com.qiniu.linking; + +import com.qiniu.common.Constants; +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.Response; +import com.qiniu.linking.model.SaveasReply; +import com.qiniu.linking.model.SegmentListing; +import com.qiniu.util.Auth; +import com.qiniu.util.Json; +import com.qiniu.util.StringMap; +import com.qiniu.util.UrlSafeBase64; + +public class LinkingVodManager { + + + private final Auth auth; + private final String host; + private final Client client; + + public LinkingVodManager(Auth auth) { + this(auth, "http://linking.qiniuapi.com"); + } + + public LinkingVodManager(Auth auth, String host) { + this(auth, host, new Client()); + } + + public LinkingVodManager(Auth auth, String host, Client client) { + this.auth = auth; + this.host = host; + this.client = client; + } + + public SegmentListing querySegments(String appid, String deviceName, long start, long end, String marker, int limit) + throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + StringMap map = new StringMap().putNotEmpty("marker", marker). + putWhen("start", start, start > 0).putWhen("end", end, end > 0). + putWhen("limit", limit, limit > 0); + String queryString = map.formString(); + String url = String.format("%s/v1/apps/%s/devices/%s/vod/segments?%s", + host, appid, encodedDeviceName, queryString); + StringMap headers = auth.authorizationV2(url, "GET", null, null); + Response res = client.get(url, headers); + if (!res.isOK()) { + throw new QiniuException(res); + } + SegmentListing ret = res.jsonToObject(SegmentListing.class); + res.close(); + return ret; + } + + public SaveasReply saveAs(String appid, String deviceName, long start, long end, String fname, String format) + throws QiniuException { + String encodedDeviceName = UrlSafeBase64.encodeToString(deviceName); + StringMap map = new StringMap().put("start", start).put("end", end). + putNotEmpty("fname", fname).putNotEmpty("format", format); + String url = String.format("%s/v1/apps/%s/devices/%s/vod/saveas", host, appid, encodedDeviceName); + byte[] body = Json.encode(map).getBytes(Constants.UTF_8); + StringMap headers = auth.authorizationV2(url, "POST", body, Client.JsonMime); + Response res = client.post(url, body, headers, Client.JsonMime); + if (!res.isOK()) { + throw new QiniuException(res); + } + SaveasReply ret = res.jsonToObject(SaveasReply.class); + res.close(); + return ret; + } +} diff --git a/src/main/java/com/qiniu/linking/README.md b/src/main/java/com/qiniu/linking/README.md new file mode 100644 index 000000000..7f112be6e --- /dev/null +++ b/src/main/java/com/qiniu/linking/README.md @@ -0,0 +1,118 @@ +# 七牛社会化监控JAVA SDK + +## Features + +- 设备管理 + - [x] 新建设备: deviceManager.createDevice(appid,deviceName) + - [x] 获取设备列表:deviceManager.listDevice(appid,prefix,marker,limit,online) + - [x] 查询设备: deviceManager.getDevice(appid,deviceName) + - [x] 更新设备信息: deviceManager.updateDevice(appid,deviceName,operations) + - [x] 添加dak: deviceManager.addDeviceKey(appid,deviceName) + - [x] 通过dak查询设备: deviceManager.getDeviceByAccessKey(dak) + - [x] 删除dak: deviceManager.deleteDeviceKey(appid,deviceName,dak) + - [x] 获取设备的dak列表: deviceManager.queryDeviceKey(appid,deviceName1) + - [x] 将dak移到另外的设备上去: deviceManager.cloneDeviceKey(appid,fromDeviceName,toDeviceName,cleanSelfKeys,deleteDevice,dak) +- dtoken生成 + - [x] 生成获取设备状态的token: auth.generateLinkingDeviceStatusTokenWithExpires(appid,deviceName,expires,actions) + - [x] 生成获取视频的token: auth.generateLinkingDeviceVodTokenWithExpires(appid,deviceName,expires) + - [x] 生成具有多种功能的token: auth.generateLinkingDeviceTokenWithExpires(appid,deviceName,expires) + +## Contents + + +- [Usage](#usage) + - [设备管理](#设备管理) + - [新建设备](#新建设备) + - [获取设备列表](#获取设备列表) + - [查询设备](#查询设备) + - [更新设备信息](#更新设备信息) + - [添加dak](#添加dak) + - [通过dak查询设备](#通过dak查询设备) + - [删除dak](#删除dak) + - [获取设备的dak列表](#获取设备的dak列表) + - [将dak移到另外的设备上去](#将dak移到另外的设备上去) + - [dtoken](#dtoken) + - [Instantiate a Pili Hub object](#instantiate-a-pili-hub-object) + - [Create a new Stream](#create-a-new-stream) + + +## Usage + +### Init + +```java +Auth auth = Auth.create(testAk,testSk); +LinkingDeviceManager deviceManager = new LinkingDeviceManager(auth); +``` + +### 设备管理 + +####新建设备 + +```java +deviceManager.createDevice(appid,deviceName); +``` +####获取设备列表 + +```java +DeviceListing deviceslist = deviceManager.listDevice(appid,prefix,marker,limit,online) +Device[] devices = deviceslist.items; +String marker = deviceslist.marker; +``` +####查询设备 + +```java +Device device = deviceManager.getDevice(appid,deviceName); +``` +####更新设备信息 + +```java +PatchOperation[] operations={new PatchOperation("replace","segmentExpireDays",9)}; +Device device= deviceManager.updateDevice(appid,deviceName,operations); +//返回更新后的设备 +``` +####添加dak + +```java +DeviceKey[] keys = deviceManager.addDeviceKey(appid,deviceName); +``` +####通过dak查询设备 + +```java +Device device = deviceManager.getDeviceByAccessKey(dak); +``` +####删除dak + +```java +deviceManager.deleteDeviceKey(appid,deviceName,dak); +``` +####获取设备的dak列表 + +```java +DeviceKey[] keys = deviceManager.queryDeviceKey(appid,deviceName); +``` +####将dak移到另外的设备上去 + +```java +deviceManager.cloneDeviceKey(appid,fromDeviceName,toDeviceName2,true, false,dak) +``` + + +###dtoken + +####生成具有多种功能的token: +```java +String[] = new +String token = auth.generateLinkingDeviceTokenWithExpires(appid,deviceName,expires,actions); +``` + + +####生成获取视频的token: +```java +String token = auth.generateLinkingDeviceVodTokenWithExpires(appid,deviceName,expires) +``` +####生成获取设备状态的token: +```java +String[] actions = new String[]{Auth.DTOKEN_ACTION_STATUS,Auth.DTOKEN_ACTION_VOD,Auth.DTOKEN_ACTION_TUTK}; +String token = auth.generateLinkingDeviceStatusTokenWithExpires(appid,deviceName,expires) +``` \ No newline at end of file diff --git a/src/main/java/com/qiniu/linking/model/Device.java b/src/main/java/com/qiniu/linking/model/Device.java new file mode 100644 index 000000000..6c29023bc --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/Device.java @@ -0,0 +1,94 @@ +package com.qiniu.linking.model; + + +import com.google.gson.annotations.SerializedName; + +public class Device { + + + @SerializedName("device") + private String deviceName; + @SerializedName("loginAt") + private long loginAt; + @SerializedName("remoteIp") + private String remoteIp; + @SerializedName("uploadMode") + private int uploadMode; + @SerializedName("segmentExpireDays") + private int segmentExpireDays; + @SerializedName("state") + private int state; + @SerializedName("activedAt") + private long activedAt; + @SerializedName("createdAt") + private long createdAt; + @SerializedName("updatedAt") + private long updatedAt; + + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getRemoteIp() { + return remoteIp; + } + + public void setRemoteIp(String remoteIp) { + this.remoteIp = remoteIp; + } + + public long getLoginAt() { + return loginAt; + } + + public void setLoginAt(long loginAt) { + this.loginAt = loginAt; + } + + public int getSegmentExpireDays() { + return segmentExpireDays; + } + + public void setSegmentExpireDays(int segmentExpireDays) { + this.segmentExpireDays = segmentExpireDays; + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + public long getActivedAt() { + return activedAt; + } + + public void setActivedAt(long activedAt) { + this.activedAt = activedAt; + } + + public long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(long createdAt) { + this.createdAt = createdAt; + } + + public long getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + } + +} + diff --git a/src/main/java/com/qiniu/linking/model/DeviceHistoryItem.java b/src/main/java/com/qiniu/linking/model/DeviceHistoryItem.java new file mode 100644 index 000000000..2fa96acd3 --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/DeviceHistoryItem.java @@ -0,0 +1,47 @@ +package com.qiniu.linking.model; + +import com.google.gson.annotations.SerializedName; + +public class DeviceHistoryItem { + + @SerializedName("loginAt") + private long loginAt; + @SerializedName("logoutAt") + private long logoutAt; + @SerializedName("remoteIp") + private String remoteIp; + @SerializedName("logoutReason") + private String logoutReason; + + public long getLoginAt() { + return loginAt; + } + + public void setLoginAt(long loginAt) { + this.loginAt = loginAt; + } + + public long getLogoutAt() { + return logoutAt; + } + + public void setLogoutAt(long logoutAt) { + this.logoutAt = logoutAt; + } + + public String getRemoteIp() { + return remoteIp; + } + + public void setRemoteIp(String remoteIp) { + this.remoteIp = remoteIp; + } + + public String getLogoutReason() { + return logoutReason; + } + + public void setLogoutReason(String logoutReason) { + this.logoutReason = logoutReason; + } +} diff --git a/src/main/java/com/qiniu/linking/model/DeviceHistoryListing.java b/src/main/java/com/qiniu/linking/model/DeviceHistoryListing.java new file mode 100644 index 000000000..6da8c150f --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/DeviceHistoryListing.java @@ -0,0 +1,7 @@ +package com.qiniu.linking.model; + +public class DeviceHistoryListing { + + DeviceHistoryItem[] items; + String marker; +} diff --git a/src/main/java/com/qiniu/linking/model/DeviceKey.java b/src/main/java/com/qiniu/linking/model/DeviceKey.java new file mode 100644 index 000000000..a52e0e920 --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/DeviceKey.java @@ -0,0 +1,47 @@ +package com.qiniu.linking.model; + +import com.google.gson.annotations.SerializedName; + +public class DeviceKey { + + @SerializedName("accessKey") + private String accessKey; + @SerializedName("secretKey") + private String secretKey; + @SerializedName("state") + private int state; + @SerializedName("createdAt") + private long createdAt; + + public String getAccessKey() { + return accessKey; + } + + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + public long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(long createdAt) { + this.createdAt = createdAt; + } +} diff --git a/src/main/java/com/qiniu/linking/model/DeviceListing.java b/src/main/java/com/qiniu/linking/model/DeviceListing.java new file mode 100644 index 000000000..d146faa53 --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/DeviceListing.java @@ -0,0 +1,7 @@ +package com.qiniu.linking.model; + +public class DeviceListing { + + public Device[] items; + public String marker; +} diff --git a/src/main/java/com/qiniu/linking/model/PatchOperation.java b/src/main/java/com/qiniu/linking/model/PatchOperation.java new file mode 100644 index 000000000..6609dbb6b --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/PatchOperation.java @@ -0,0 +1,44 @@ +package com.qiniu.linking.model; + +public class PatchOperation { + + // 更该或删除某个属性,replace:更改,delete:删除 + private String op; + + // 要修改或删除的属性 + private String key; + + // 要修改或删除属性的值 + private Object value; + + + public PatchOperation(String op, String key, Object value) { + this.op = op; + this.key = key; + this.value = value; + } + + public String getOp() { + return op; + } + + public void setOp(String op) { + this.op = op; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } +} diff --git a/src/main/java/com/qiniu/linking/model/SaveasReply.java b/src/main/java/com/qiniu/linking/model/SaveasReply.java new file mode 100644 index 000000000..423fe7069 --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/SaveasReply.java @@ -0,0 +1,37 @@ +package com.qiniu.linking.model; + +import com.google.gson.annotations.SerializedName; + +public class SaveasReply { + @SerializedName("frame") + private String frame; + @SerializedName("persistentId") + private String persistentId; + @SerializedName("duration") + private int duration; + + public String getFrame() { + return frame; + } + + public void setFrame(String frame) { + this.frame = frame; + } + + public String getPersistentId() { + return persistentId; + } + + public void setPersistentId(String persistentId) { + this.persistentId = persistentId; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + +} diff --git a/src/main/java/com/qiniu/linking/model/Segment.java b/src/main/java/com/qiniu/linking/model/Segment.java new file mode 100644 index 000000000..ad4f24517 --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/Segment.java @@ -0,0 +1,36 @@ +package com.qiniu.linking.model; + +import com.google.gson.annotations.SerializedName; + +public class Segment { + @SerializedName("from") + private int from; + @SerializedName("to") + private int to; + @SerializedName("frame") + private String frame; + + public int getFrom() { + return from; + } + + public void setFrom(int from) { + this.from = from; + } + + public int getTo() { + return to; + } + + public void setTo(int to) { + this.to = to; + } + + public String getFrame() { + return frame; + } + + public void setFrame(String frame) { + this.frame = frame; + } +} diff --git a/src/main/java/com/qiniu/linking/model/SegmentListing.java b/src/main/java/com/qiniu/linking/model/SegmentListing.java new file mode 100644 index 000000000..906d9823c --- /dev/null +++ b/src/main/java/com/qiniu/linking/model/SegmentListing.java @@ -0,0 +1,7 @@ +package com.qiniu.linking.model; + +public class SegmentListing { + + Segment[] items; + String marker; +} diff --git a/src/main/java/com/qiniu/util/Auth.java b/src/main/java/com/qiniu/util/Auth.java index 9dce43e18..01b9ecd16 100755 --- a/src/main/java/com/qiniu/util/Auth.java +++ b/src/main/java/com/qiniu/util/Auth.java @@ -1,11 +1,15 @@ package com.qiniu.util; +import com.google.gson.annotations.SerializedName; import com.qiniu.http.Client; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.net.URI; import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.security.Timestamp; +import java.util.Date; public final class Auth { @@ -334,4 +338,55 @@ public String signRoomToken(String roomAccess) throws Exception { String encodedSign = UrlSafeBase64.encodeToString(sign); return this.accessKey + ":" + encodedSign + ":" + encodedRoomAcc; } + + + public static final String DTOKEN_ACTION_VOD = "linking:vod"; + public static final String DTOKEN_ACTION_STATUS = "linking:status"; + public static final String DTOKEN_ACTION_TUTK = "linking:tutk"; + + class LinkingDtokenStatement { + @SerializedName("action") + private String action; + + LinkingDtokenStatement(String action) { + this.action = action; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + } + + + public String generateLinkingDeviceToken(String appid, String deviceName, long deadline, String[] actions) { + LinkingDtokenStatement[] staments = new LinkingDtokenStatement[actions.length]; + + for (int i = 0; i < actions.length; ++i) { + staments[i] = new LinkingDtokenStatement(actions[i]); + } + + SecureRandom random = new SecureRandom(); + StringMap map = new StringMap(); + map.put("appid", appid).put("device", deviceName).put("deadline", deadline) + .put("random", random.nextInt()).put("statement", staments); + String s = Json.encode(map); + return signWithData(StringUtils.utf8Bytes(s)); + } + + public String generateLinkingDeviceTokenWithExpires(String appid, String deviceName, long expires, String[] actions) { + long deadline = (new Date().getTime() / 1000) + expires; + return generateLinkingDeviceToken(appid, deviceName, deadline, actions); + } + + public String generateLinkingDeviceVodTokenWithExpires(String appid, String deviceName, long expires) { + return generateLinkingDeviceTokenWithExpires(appid, deviceName, expires, new String[]{DTOKEN_ACTION_VOD}); + } + + public String generateLinkingDeviceStatusTokenWithExpires(String appid, String deviceName, long expires) { + return generateLinkingDeviceTokenWithExpires(appid, deviceName, expires, new String[]{DTOKEN_ACTION_STATUS}); + } } diff --git a/src/test/java/test/com/qiniu/TestConfig.java b/src/test/java/test/com/qiniu/TestConfig.java index fd59b7692..da1b34a5d 100644 --- a/src/test/java/test/com/qiniu/TestConfig.java +++ b/src/test/java/test/com/qiniu/TestConfig.java @@ -37,6 +37,8 @@ public final class TestConfig { //code public static final int ERROR_CODE_BUCKET_NOT_EXIST = 631; public static final int ERROR_CODE_KEY_NOT_EXIST = 612; + + public static final String testLinkingAppid = System.getenv("QINIU_LINKING_APPID"); private TestConfig() { } diff --git a/src/test/java/test/com/qiniu/linking/DeviceTest.java b/src/test/java/test/com/qiniu/linking/DeviceTest.java new file mode 100644 index 000000000..f69199c35 --- /dev/null +++ b/src/test/java/test/com/qiniu/linking/DeviceTest.java @@ -0,0 +1,139 @@ +package test.com.qiniu.linking; + +import com.qiniu.common.QiniuException; +import com.qiniu.http.Client; +import com.qiniu.http.Response; +import com.qiniu.linking.*; +import com.qiniu.linking.model.*; +import com.qiniu.util.Auth; + +import java.util.Date; + +import com.qiniu.util.StringMap; +import com.qiniu.util.UrlSafeBase64; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import test.com.qiniu.TestConfig; + +public class DeviceTest { + + private final static String testDeviceName1 = "test1"; + private final static String testDeviceName2 = "test2"; + private final static Client client = new Client(); + @Test + @Ignore + public void testDevice() throws QiniuException { + Auth auth = TestConfig.testAuth; + String testAppid = TestConfig.testLinkingAppid; + LinkingDeviceManager deviceManager = new LinkingDeviceManager(auth); + try { + + { + //创建设备 + deviceManager.createDevice(testAppid, testDeviceName1); + } + + { + //添加dak + DeviceKey[] keys = deviceManager.addDeviceKey(testAppid, testDeviceName1); + Assert.assertNotEquals(keys.length,0); + } + + { + //查询设备 + DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid, testDeviceName1); + Assert.assertEquals(keys.length,1); + + //删除设备 + deviceManager.deleteDeviceKey(testAppid, testDeviceName1, keys[0].getAccessKey()); + keys = deviceManager.queryDeviceKey(testAppid, testDeviceName1); + Assert.assertEquals(keys.length,0); + } + + { + //列出设备 + DeviceListing deviceslist = deviceManager.listDevice(testAppid, "", "", 1, false); + Assert.assertNotEquals(deviceslist.items.length,0); + } + + + { + //修改设备字段 + PatchOperation[] operations = {new PatchOperation("replace", "segmentExpireDays", 9)}; + Device device = deviceManager.updateDevice(testAppid, testDeviceName1, operations); + Assert.assertEquals(device.getSegmentExpireDays(),9); + } + + { + //查询设备在线历史记录 + DeviceHistoryListing history = deviceManager.listDeviceHistory(testAppid, testDeviceName1, + 0, (new Date().getTime()) / 1000, "", 0); + } + } finally { + //删除设备信息 + deviceManager.deleteDevice(testAppid, testDeviceName1); + } + + } + + @Test + @Ignore + public void testDeviceKey() throws QiniuException { + Auth auth = TestConfig.testAuth; + String testAppid = TestConfig.testLinkingAppid; + LinkingDeviceManager deviceManager = new LinkingDeviceManager(auth); + try { + deviceManager.createDevice(testAppid, testDeviceName1); + deviceManager.createDevice(testAppid, testDeviceName2); + + //添加dak + deviceManager.addDeviceKey(testAppid, testDeviceName1); + DeviceKey[] keys = deviceManager.queryDeviceKey(testAppid, testDeviceName1); + String dak = keys[0].getAccessKey(); + + //移动dak + deviceManager.cloneDeviceKey(testAppid, testDeviceName1, testDeviceName2, true, false, dak); + Device device = deviceManager.getDeviceByAccessKey(dak); + + deviceManager.deleteDeviceKey(testAppid, testDeviceName2, dak); + + } finally { + try { + deviceManager.deleteDevice(testAppid, testDeviceName1); + } catch (Exception ignored) { + } + try { + deviceManager.deleteDevice(testAppid, testDeviceName2); + } catch (Exception ignored) { + } + } + } + + + @Test + @Ignore + public void testLinkingDeviceToken() throws QiniuException { + String vodToken = TestConfig.testAuth.generateLinkingDeviceVodTokenWithExpires( + TestConfig.testLinkingAppid, testDeviceName1, 1000); + String statusToken = TestConfig.testAuth.generateLinkingDeviceStatusTokenWithExpires( + TestConfig.testLinkingAppid, testDeviceName1, 1000); + String testAppid = TestConfig.testLinkingAppid; + LinkingDeviceManager deviceManager = new LinkingDeviceManager(TestConfig.testAuth); + try { + deviceManager.createDevice(testAppid, testDeviceName1); + StringMap map = new StringMap().put("dtoken",statusToken); + String queryString = map.formString(); + String url = String.format("%s/v1/device/resource/status?%s", + "http://linking.qiniuapi.com", queryString); + Response res = client.get(url); + int code = res.statusCode; + res.close(); + Assert.assertNotEquals(code,401); + } finally { + deviceManager.deleteDevice(testAppid, testDeviceName1); + } + + } + +}