package license.sdk; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public final class LicenseClient { public static final class ApiResponse { private final int statusCode; private final String body; private ApiResponse(int statusCode, String body) { this.statusCode = statusCode; this.body = body; } public int statusCode() { return statusCode; } public String body() { return body; } } private final HttpClient http = HttpClient.newHttpClient(); private final String baseUrl; private final String machineCode; private final String appKey; public LicenseClient(String baseUrl, String machineCode) { this(baseUrl, machineCode, ""); } /** @param appKey 软件接入密钥(管理后台「软件管理」生成),为空表示不携带 */ public LicenseClient(String baseUrl, String machineCode, String appKey) { this.baseUrl = baseUrl.replaceAll("/$", ""); this.machineCode = machineCode.trim().toUpperCase(); this.appKey = appKey == null ? "" : appKey.trim(); } public String login(String cardKey, String deviceName) throws IOException, InterruptedException { return loginResponse(cardKey, deviceName).body(); } public String heartbeat(String cardKey) throws IOException, InterruptedException { return heartbeatResponse(cardKey).body(); } public String listDevices(String cardKey) throws IOException, InterruptedException { return listDevicesResponse(cardKey).body(); } public String unbind(String cardKey) throws IOException, InterruptedException { return unbindResponse(cardKey).body(); } public ApiResponse loginResponse(String cardKey, String deviceName) throws IOException, InterruptedException { StringBuilder sb = new StringBuilder(160); sb.append("{\"cardKey\":\"").append(escape(cardKey)).append("\",\"machineCode\":\"").append(machineCode) .append("\",\"deviceName\":\"").append(escape(deviceName == null ? "" : deviceName)).append('"'); if (!appKey.isEmpty()) sb.append(",\"appKey\":\"").append(escape(appKey)).append('"'); sb.append('}'); return post("/api/card/verify", sb.toString()); } public ApiResponse heartbeatResponse(String cardKey) throws IOException, InterruptedException { return post("/api/card/heartbeat", request(cardKey)); } public ApiResponse listDevicesResponse(String cardKey) throws IOException, InterruptedException { return post("/api/card/devices", request(cardKey)); } public ApiResponse unbindResponse(String cardKey) throws IOException, InterruptedException { return post("/api/card/unbind", request(cardKey)); } private String request(String cardKey) { StringBuilder sb = new StringBuilder(128); sb.append("{\"cardKey\":\"").append(escape(cardKey)).append("\",\"machineCode\":\"").append(machineCode).append('"'); if (!appKey.isEmpty()) sb.append(",\"appKey\":\"").append(escape(appKey)).append('"'); sb.append('}'); return sb.toString(); } private ApiResponse post(String path, String body) throws IOException, InterruptedException { HttpRequest request = HttpRequest.newBuilder(URI.create(baseUrl + path)).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(body)).build(); HttpResponse response = http.send(request, HttpResponse.BodyHandlers.ofString()); return new ApiResponse(response.statusCode(), response.body()); } private String escape(String value) { return value == null ? "" : value.replace("\\", "\\\\").replace("\"", "\\\""); } }