//package com.backendsys.SDK.Meitu;
//
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.InputStream;
//import java.net.URI;
//import java.net.URISyntaxException;
//import java.net.URL;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.Iterator;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.Executors;
//import java.util.concurrent.ScheduledExecutorService;
//import java.util.concurrent.ThreadFactory;
//import java.util.concurrent.TimeUnit;
//import java.util.Map.Entry;
//
//import com.backendsys.SDK.Meitu.model.BizConfigResponseDTO;
//import com.backendsys.SDK.Meitu.model.InferenceParamsDTO;
//import com.backendsys.SDK.Meitu.model.MtlabParamsDTO;
//import com.backendsys.SDK.Meitu.model.SdkRequestDTO;
//import com.backendsys.SDK.Meitu.model.SdkResponseDTO;
//import com.backendsys.SDK.Meitu.model.BizConfigResponseDTO.BizData;
//import com.backendsys.SDK.Meitu.model.SdkRequestDTO.InitImage;
//import com.obs.services.ObsClient;
//import com.obs.services.ObsConfiguration;
//import com.obs.services.exception.ObsException;
//import com.obs.services.model.PutObjectResult;
//
//import lombok.Data;
//import lombok.Getter;
//import lombok.Setter;
//import lombok.extern.slf4j.Slf4j;
//import shade.fasterxml.jackson.annotation.JsonProperty;
//import shade.fasterxml.jackson.databind.DeserializationFeature;
//import shade.fasterxml.jackson.databind.JsonNode;
//import shade.fasterxml.jackson.databind.ObjectMapper;
//import shade.fasterxml.jackson.databind.node.ArrayNode;
//import shade.okhttp3.HttpUrl;
//import shade.okhttp3.MediaType;
//import shade.okhttp3.OkHttpClient;
//import shade.okhttp3.Request;
//import shade.okhttp3.RequestBody;
//import shade.okhttp3.Response;
//
///**
// * ai 访问客户端
// */
//@Slf4j
//public class AiClient {
//    public static final String default_strategy_type = "mtai";
//    public static final String default_strategy_host = "https://strategy.app.meitudata.com";
//
//    public static final int default_obs_socket_timeout = 30; // 单位秒
//    public static final int default_obs_connect_timeout = 10; // 单位秒
//
//    public static final int default_api_socket_timeout = 45; // 单位秒 sync_timeout默认30秒，请求超时需要高于这个数
//    public static final int default_api_connect_timeout = 5; // 单位秒
//
//    public static final int default_status_socket_timeout = 2; // 单位秒
//    public static final int default_status_connect_timeout = 2; // 单位秒
//
//    public static final int status_code_suc = 10; // 成功
//    public static final int status_code_timeout = 9; // 同步请求超时
//    public static final int status_code_fail = 2; // 失败
//
//    public static final int get_strategy_retry_times = 3; // 获取策略重试次数
//    public static final int get_strategy_retry_duration = 1000; // 重试间隔时间
//    public static final int get_strategy_connect_timeout = 10; // 重试间隔时间
//    public static final int get_strategy_socket_timeout = 30; // 重试间隔时间
//
//    public static final int get_biz_config_connect_timeout = 10; // 重试间隔时间
//    public static final int get_biz_config_socket_timeout = 30; // 重试间隔时间
//    public static final String process_type_mtlab = "mtlab";
//    public static final String process_type_inference = "inference";
//
//    private String openapiHost = null;
//
//    @Setter(lombok.AccessLevel.PROTECTED)
//    private String ak;
//    @Setter(lombok.AccessLevel.PROTECTED)
//    private String sk;
//    @Setter(lombok.AccessLevel.PROTECTED)
//    private String types;
//    @Setter(lombok.AccessLevel.PROTECTED)
//    private String strategyHost;
//
//    @Getter(lombok.AccessLevel.PROTECTED)
//    private Map<String, List<ObsClientAware>> obsAwareMap;
//    @Getter(lombok.AccessLevel.PROTECTED)
//    private Map<String, List<ApiAware>> apiAwareMap;
//    private OkHttpClient strategyOkHttpClient = new OkHttpClient.Builder()
//            .connectTimeout(get_strategy_connect_timeout, java.util.concurrent.TimeUnit.SECONDS)
//            .readTimeout(get_strategy_socket_timeout, java.util.concurrent.TimeUnit.SECONDS)
//            .writeTimeout(get_strategy_socket_timeout, java.util.concurrent.TimeUnit.SECONDS)
//            .build();
//
//    private OkHttpClient bziConfigOkHttpClient = new OkHttpClient.Builder()
//            .connectTimeout(get_biz_config_connect_timeout, java.util.concurrent.TimeUnit.SECONDS)
//            .readTimeout(get_strategy_socket_timeout, java.util.concurrent.TimeUnit.SECONDS)
//            .writeTimeout(get_biz_config_socket_timeout, java.util.concurrent.TimeUnit.SECONDS)
//            .build();
//
//    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, new ThreadFactory() {
//        private int count = 0;
//
//        @Override
//        public Thread newThread(Runnable r) {
//            count++;
//            return new Thread(r, "refresh_strategy-" + count);
//        }
//    });
//
//    protected AiClient() {
//
//    }
//
//    /**
//     *
//     * @param accessKey
//     * @param secret
//     * @param "types"     需要获取处理token类型(效果类型，创意玩法/文生图/图生图等),支持多个名称，例：type=p1,p2
//     */
//    public AiClient(String accessKey, String secret) {
//        this(accessKey, secret, default_strategy_type, default_strategy_host);
//    }
//
//    /**
//     *
//     * @param ak
//     * @param sk
//     * @param types        需要获取处理token类型(效果类型，创意玩法/文生图/图生图等),支持多个名称，例：type=p1,p2
//     * @param strategyHost 策略服务地址
//     */
//    public AiClient(String ak, String sk, String types, String strategyHost) {
//        this.ak = ak;
//        this.sk = sk;
//        this.types = types;
//        this.strategyHost = strategyHost;
//        init();
//    }
//
//    protected SdkResponseDTO.Result push(SdkRequestDTO sdkRequestDTO, String type, String processType) {
//        log.info("push start, sdkRequestDTO:{}", sdkRequestDTO);
//        if (sdkRequestDTO.getTask() == null || sdkRequestDTO.getTask().length() == 0) {
//            throw new AIException(AIException.code_params_err, "task is null");
//        }
//        if (sdkRequestDTO.getTaskType() == null || sdkRequestDTO.getTaskType().length() == 0) {
//            throw new AIException(AIException.code_params_err, "taskType is null");
//        }
//
//        List<ApiAware> apiAwares = apiAwareMap.get(type);
//        if (apiAwares == null) {
//            throw new AIException(AIException.code_params_err,
//                    String.format("type:%s is not configured", type));
//        }
//        SdkResponseDTO.Result result = retryPush(sdkRequestDTO, apiAwares, processType);
//
//        return result;
//    }
//
//    /**
//     * 美图设计室任务提交接口
//     *
//     * @param mtlabParamsDTO
//     * @return
//     */
//    public SdkResponseDTO.Result pushMtlabTask(MtlabParamsDTO mtlabParamsDTO) {
//        mtlabParamsDTO.setTaskType("mtlab");
//        for (InitImage initImage : mtlabParamsDTO.getInitImages()) {
//            String url = initImage.getUrl();
//            url = upload(default_strategy_type, url);
//            initImage.setUrl(url);
//        }
//        return push(mtlabParamsDTO, default_strategy_type, process_type_mtlab);
//    }
//
//    /**
//     * 获取业务配置，业务配置是AI服务在调用推理时，用来约定用户能使用的模型、风格与图像尺寸的配置。
//     */
//    public BizData getBusinessConfig() {
//        String url = String.format("%s/whee/business/config.json", openapiHost);
//        Map<String, String> header = new HashMap<>();
//        Map<String, String> params = new HashMap<>();
//
//        Request reuqest = buildGetRequest(url, params, header);
//
//        Response response = null;
//        try {
//            response = bziConfigOkHttpClient.newCall(reuqest).execute();
//        } catch (Exception ex) {
//            throw new AIException(AIException.code_cloud_biz_config_net_err, "Request exception", ex);
//        }
//        try {
//            String body = "";
//            try {
//                body = response.body().string();
//            } catch (Exception ex) {
//                // 忽略异常
//            }
//
//            // body反序列到BizConfigResponseDTO
//            ObjectMapper objectMapper = new ObjectMapper();
//            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//            BizConfigResponseDTO bizConfigResponseDTO = null;
//            try {
//                bizConfigResponseDTO = objectMapper.readValue(body, BizConfigResponseDTO.class);
//            } catch (Exception ex) {
//                throw new AIException(AIException.code_cloud_biz_config_err, "Deserialization Exception", ex);
//            }
//
//            if (bizConfigResponseDTO.getCode() != 0) {
//                throw new AIException(AIException.code_cloud_biz_config_err,
//                        String.format("Request exception:httpCode=%s,messge=%s", response.code(), response.message()));
//            }
//            return bizConfigResponseDTO.getData();
//        } finally {
//            if (response != null) {
//                response.close();
//            }
//        }
//
//    }
//
//    /**
//     * 执行推理，推理接口包含文生图与图生图
//     *
//     * @param inferenceParamsDTO
//     * @return
//     */
//    public SdkResponseDTO.Result inference(InferenceParamsDTO inferenceParamsDTO) {
//        ObjectMapper objectMapper = new ObjectMapper();
//        if (inferenceParamsDTO.getModel() == null || inferenceParamsDTO.getModel().length() == 0) {
//            throw new AIException(AIException.code_params_err, "model is null");
//        }
//        if (inferenceParamsDTO.getPrompt() == null || inferenceParamsDTO.getPrompt().length() == 0) {
//            throw new AIException(AIException.code_params_err, "prompt is null");
//        }
//        if (inferenceParamsDTO.getModelHash() == null || inferenceParamsDTO.getModelHash().length() == 0) {
//            inferenceParamsDTO.setModelHash("XZKFKEVaKRPSDC5PHl2Fi0xBbYts25xnfA6hsfEp");
//        }
//        if (inferenceParamsDTO.getModelPlatform() == null || inferenceParamsDTO.getModelPlatform().length() == 0) {
//            throw new AIException(AIException.code_params_err, "model platform is null");
//        }
//
//        log.info("inference start, inferenceParamsDTO:{}", jsonToString(inferenceParamsDTO, objectMapper));
//        long start = System.currentTimeMillis();
//        SdkResponseDTO.Result result = doInference(inferenceParamsDTO, default_strategy_type);
//
//        log.info("inference end, result:{} latency:{}", jsonToString(result, objectMapper),
//                System.currentTimeMillis() - start);
//        return result;
//
//    }
//
//    /**
//     * 推理接口，如果initImages有传入为图生图，没有传入为文生图
//     *
//     * @param inferenceParamsDTO
//     * @param type
//     */
//    private SdkResponseDTO.Result doInference(InferenceParamsDTO inferenceParamsDTO, String type) {
//        List<InitImage> initImageObjectList = new ArrayList<>();
//        String[] initImage = inferenceParamsDTO.getInitImages();
//        String task;
//        if (initImage != null && initImage.length > 0) {
//            String[] newInitImage = new String[initImage.length];
//            for (int i = 0; i < initImage.length; i++) {
//                String url = upload(type, initImage[i]);
//                newInitImage[i] = url;
//                InitImage image = new InitImage();
//                image.setUrl(url);
//                initImageObjectList.add(image);
//            }
//            task = "img2img";
//            inferenceParamsDTO.setInitImages(newInitImage);
//        } else {
//            task = "txt2img";
//        }
//
//        SdkRequestDTO request = new SdkRequestDTO();
//        request.setInitImages(initImageObjectList);
//        request.setTaskType("inference");
//        request.setTask(task);
//        request.setParams(jsonToString(inferenceParamsDTO, null));
//        SdkResponseDTO.Result result = push(request, type, process_type_inference);
//        return result;
//
//    }
//
//    /**
//     * 重试的机制放在AiClientRefreshStrategyTask
//     */
//    private void init() {
//        String configStr = getStrategy();
//        log.info("Get Strategy Success, config:{}", configStr);
//        ConfigAware configAware = parseTockenConfig(configStr);
//        initObsClient(configAware.getObsConfigMap());
//        initApiConfig(configAware.getApiConfigMap());
//        int minTTL = configAware.getMinTTL();
//        if (minTTL <= 0) {
//            minTTL = 3600;
//        }
//        long delay = minTTL / 2;
//        log.info("Add refresh strategy task, delay={} ttl={}", delay, minTTL);
//        scheduledExecutorService.schedule(new AiClientRefreshStrategyTask(this), delay, TimeUnit.SECONDS);
//    }
//
//    protected Request buildGetRequest(String url, Map<String, String> params, Map<String, String> headers) {
//        HttpUrl.Builder httpUrlBuild = HttpUrl
//                .parse(url)
//                .newBuilder();
//
//        for (Entry<String, String> entry : params.entrySet()) {
//            httpUrlBuild.addQueryParameter(entry.getKey(), entry.getValue());
//        }
//
//        HttpUrl httpUrl = httpUrlBuild.build();
//
//        Signer signer = new Signer(ak, sk);
//        Map<String, String> sigHeader = null;
//
//        try {
//            sigHeader = signer.sign(httpUrl.toString(), "GET", headers, "");
//        } catch (URISyntaxException ex) {
//            throw new AIException(AIException.code_sig_err, "Sign exception", ex);
//        }
//
//        log.info("get request, url={} header={}", httpUrl.toString(), jsonToString(sigHeader, null));
//
//        Request.Builder request = new Request.Builder()
//                .url(httpUrlBuild.build()).get();
//
//        sigHeader.forEach((key, value) -> {
//            request.addHeader(key, value);
//        });
//        return request.build();
//    }
//
//    /**
//     * 关闭客户端
//     */
//    public void close() {
//        log.info("close ai client");
//
//        scheduledExecutorService.shutdownNow();
//
//        obsAwareMap.forEach((s, clientList) -> {
//            for (ObsClientAware obsClientAware : clientList) {
//                try {
//                    obsClientAware.getObsClient().close();
//                } catch (Exception ex) {
//                    throw new AIException(AIException.code_obs_close_err, "Close obs client exception", ex);
//                }
//
//            }
//        });
//
//        bziConfigOkHttpClient.dispatcher().executorService().shutdownNow();
//
//        strategyOkHttpClient.dispatcher().executorService().shutdownNow();
//
//        apiAwareMap.forEach((k, clientList) -> {
//            for (ApiAware apiAware : clientList) {
//                if (!apiAware.getPushClient().dispatcher().executorService().isShutdown()) {
//                    apiAware.getPushClient().dispatcher().executorService().shutdownNow();
//                }
//                if (!apiAware.getStatusClient().dispatcher().executorService().isShutdown()) {
//                    apiAware.getStatusClient().dispatcher().executorService().shutdownNow();
//                }
//            }
//        });
//    }
//
//    /**
//     * 请求策略服务获取策略配置
//     *
//     * @return 策略配置
//     */
//    protected String getStrategy() {
//        long start = System.currentTimeMillis();
//        String url = String.format("%s/ai/token_policy", strategyHost);
//        Map<String, String> params = new HashMap<>();
//        params.put("type", types);
//        URI uri = URI.create(url);
//        Map<String, String> headMap = new HashMap<>();
//
//        Request request = buildGetRequest(url, params, headMap);
//
//        log.info("get strategy request, url={}", request.url().toString());
//
//        Response response = null;
//        try {
//            response = strategyOkHttpClient.newCall(request).execute();
//        } catch (Exception ex) {
//            throw new AIException(AIException.code_strategy_net_error, "Request exception", ex);
//        }
//        try {
//
//            String body = "";
//            try {
//                body = response.body().string();
//            } catch (Exception ex) {
//                // 忽略异常
//            }
//
//            log.info("get strategy response, latency={} url={} httpcode={} body={}", System.currentTimeMillis() - start,
//                    url, response.code(), body);
//
//            if (!response.isSuccessful()) {
//                throw new AIException(AIException.code_strategy_err,
//                        String.format("Request exception:httpCode=%s,messge=%s", response.code(), response.message()));
//            }
//            return body;
//
//        } finally {
//            response.close();
//        }
//    }
//
//    /**
//     * 解析返回后端返回的参数
//     *
//     * @param json
//     * @return
//     */
//    protected ConfigAware parseTockenConfig(String jsonString) {
//        ConfigAware configAware = new ConfigAware();
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//        JsonNode jsonNode = null;
//        try {
//            jsonNode = objectMapper.readTree(jsonString);
//        } catch (Exception ex) {
//            throw new AIException(AIException.code_strategy_err, "反序列化异常", ex);
//        }
//
//        int code = jsonNode.get("code").asInt();
//
//        if (code != 0) {
//            int errorCode = jsonNode.get("error_code").asInt();
//            String message = jsonNode.get("message").asText();
//            throw new AIException(AIException.code_strategy_err, String.format("%s:%s", errorCode, message));
//        }
//        JsonNode dataNode = jsonNode.get("data");
//        if (dataNode == null || dataNode.isNull()) {
//            throw new AIException(AIException.code_strategy_err, "data is null");
//        }
//        Map<String, List<ObsConfig>> obsConfigMap = new HashMap<>();
//        Map<String, List<APIConfig>> apiConfigMap = new HashMap<>();
//        configAware.setApiConfigMap(apiConfigMap);
//        configAware.setObsConfigMap(obsConfigMap);
//        Iterator<Entry<String, JsonNode>> fields = dataNode.fields();
//        int minTTL = Integer.MAX_VALUE;
//        while (fields.hasNext()) {
//            Entry<String, JsonNode> field = fields.next();
//            String bizName = field.getKey();
//            JsonNode bizConfig = field.getValue();
//            List<ObsConfig> obsConfigs = obsConfigMap.get(bizName);
//            if (obsConfigs == null) {
//                obsConfigs = new ArrayList<>();
//                obsConfigMap.put(bizName, obsConfigs);
//            }
//
//            List<APIConfig> apiConfigs = apiConfigMap.get(bizName);
//            if (apiConfigs == null) {
//                apiConfigs = new ArrayList<>();
//                apiConfigMap.put(bizName, apiConfigs);
//            }
//
//            int ttl = parseObsConfig(objectMapper, bizConfig.get("upload"), obsConfigs);
//            if (minTTL > ttl) {
//                minTTL = ttl;
//            }
//            parseApiConfig(objectMapper, bizConfig.get("api"), apiConfigs);
//        }
//
//        configAware.setMinTTL(minTTL);
//
//        return configAware;
//    }
//
//    private void parseApiConfig(ObjectMapper objectMapper, JsonNode apiConfigJSON, List<APIConfig> apiConfigs) {
//        List<JsonNode> configJSONArr = parseConfigJsonNodeArr(apiConfigJSON);
//        for (JsonNode curConfigJSON : configJSONArr) {
//            APIConfig apiConfig = null;
//            try {
//                apiConfig = objectMapper.treeToValue(curConfigJSON, APIConfig.class);
//            } catch (Exception ex) {
//                throw new AIException(AIException.code_strategy_err, "Deserialization Exception", ex);
//            }
//            if (openapiHost == null && apiConfig.getUrl() != null) {
//                openapiHost = apiConfig.getUrl();
//            }
//
//            apiConfigs.add(apiConfig);
//        }
//    }
//
//    /**
//     *
//     * @param objectMapper
//     * @param obsConfigJSON
//     * @param obsConfigs
//     * @return 最小的ttl
//     * @throws Exception
//     */
//    private int parseObsConfig(ObjectMapper objectMapper, JsonNode obsConfigJSON, List<ObsConfig> obsConfigs) {
//        int minTTL = Integer.MAX_VALUE;
//        List<JsonNode> configJSONArr = parseConfigJsonNodeArr(obsConfigJSON);
//        for (JsonNode curConfigJSON : configJSONArr) {
//            ObsConfig apiConfig = null;
//            try {
//                apiConfig = objectMapper.treeToValue(curConfigJSON, ObsConfig.class);
//            } catch (Exception ex) {
//                throw new AIException(AIException.code_strategy_err, "Deserialization Exception", ex);
//            }
//            if (minTTL > apiConfig.getTtl()) {
//                minTTL = apiConfig.getTtl();
//            }
//            obsConfigs.add(apiConfig);
//        }
//        return minTTL;
//    }
//
//    private List<JsonNode> parseConfigJsonNodeArr(JsonNode configJSON) {
//        List<JsonNode> resultList = new ArrayList<>();
//        ArrayNode orderJSONArr = configJSON.withArray("order");
//        for (JsonNode jsonNode : orderJSONArr) {
//            String order = jsonNode.asText();
//            JsonNode curConfigJSON = configJSON.get(order);
//            if (curConfigJSON == null || curConfigJSON.isNull()) {
//                continue;
//            }
//            resultList.add(curConfigJSON);
//        }
//
//        return resultList;
//
//    }
//
//    /**
//     * 初始化api访问配置
//     */
//    protected void initApiConfig(Map<String, List<APIConfig>> apiConfigMap) {
//        // 为了允许多个type有多个配置
//        Map<String, List<ApiAware>> apiAwareMap = new HashMap<>();
//        // 当前status是一个不可变更的值
//        OkHttpClient statusClient = new OkHttpClient.Builder()
//                .connectTimeout(default_status_connect_timeout, java.util.concurrent.TimeUnit.SECONDS)
//                .writeTimeout(default_status_socket_timeout, java.util.concurrent.TimeUnit.SECONDS)
//                .readTimeout(default_status_socket_timeout, java.util.concurrent.TimeUnit.SECONDS)
//                .build();
//
//        for (Entry<String, List<APIConfig>> entry : apiConfigMap.entrySet()) {
//            List<APIConfig> apiConfigs = entry.getValue();
//            String type = entry.getKey();
//            List<ApiAware> apiAwaress = apiAwareMap.get(type);
//            if (apiAwaress == null) {
//                apiAwaress = new ArrayList<>();
//                apiAwareMap.put(type, apiAwaress);
//            }
//            for (APIConfig apiConfig : apiConfigs) {
//                OkHttpClient httpClient = new OkHttpClient.Builder()
//                        .connectTimeout(apiConfig.getConnectTimeout() <= 0 ? default_api_connect_timeout
//                                : apiConfig.getConnectTimeout(), java.util.concurrent.TimeUnit.SECONDS)
//                        .readTimeout(apiConfig.getSocketTimeout() <= 0 ? default_api_socket_timeout
//                                : apiConfig.getSocketTimeout(), java.util.concurrent.TimeUnit.SECONDS)
//                        .build();
//
//                apiAwaress.add(new ApiAware(httpClient, statusClient, apiConfig, apiConfig.getUrl()));
//                if (apiConfig.getBackupUrl() != null && apiConfig.getBackupUrl().length() > 0) {
//                    apiAwaress.add(new ApiAware(httpClient, statusClient, apiConfig, apiConfig.getBackupUrl()));
//                }
//            }
//        }
//        this.apiAwareMap = apiAwareMap;
//
//    }
//
//    /**
//     * 根据下发的obsConfig初始化obs客户端
//     */
//    protected void initObsClient(Map<String, List<ObsConfig>> obsConfigMap) {
//        Map<String, List<ObsClientAware>> obsClientAwareMap = new HashMap<>();
//        for (Entry<String, List<ObsConfig>> entry : obsConfigMap.entrySet()) {
//            List<ObsConfig> obsConfigs = entry.getValue();
//            String type = entry.getKey();
//            List<ObsClientAware> obsClientAwares = obsClientAwareMap.get(type);
//            if (obsClientAwares == null) {
//                obsClientAwares = new ArrayList<>();
//                obsClientAwareMap.put(type, obsClientAwares);
//            }
//            for (ObsConfig obsConfig : obsConfigs) {
//
//                ObsConfiguration config = buildObjConfiguration(obsConfig, obsConfig.getUrl());
//                ObsClient obsClient = new ObsClient(obsConfig.getCredentials().getAccessKey(),
//                        obsConfig.getCredentials().getSecretKey(),
//                        obsConfig.getCredentials().getSessionToken(),
//                        config);
//                obsClientAwares.add(new ObsClientAware(obsClient, obsConfig));
//
//                if (obsConfig.getBackupUrl() != null && obsConfig.getBackupUrl().length() > 0) {
//                    ObsConfiguration backupConfig = buildObjConfiguration(obsConfig, obsConfig.getBackupUrl());
//                    ObsClient bakcupClient = new ObsClient(obsConfig.getCredentials().getAccessKey(),
//                            obsConfig.getCredentials().getSecretKey(),
//                            obsConfig.getCredentials().getSessionToken(),
//                            backupConfig);
//                    obsClientAwares.add(new ObsClientAware(bakcupClient, obsConfig));
//                }
//
//            }
//        }
//        this.obsAwareMap = obsClientAwareMap;
//    }
//
//    private ObsConfiguration buildObjConfiguration(ObsConfig obsConfig, String url) {
//        ObsConfiguration config = new ObsConfiguration();
//        if (obsConfig.getSocketTimeout() <= 0) {
//            config.setSocketTimeout(default_obs_socket_timeout * 1000);
//        } else {
//            config.setSocketTimeout(obsConfig.getSocketTimeout() * 1000);
//        }
//
//        if (obsConfig.getConnectTimeout() <= 0) {
//            config.setConnectionTimeout(default_obs_connect_timeout * 1000);
//        } else {
//            config.setConnectionTimeout(obsConfig.getConnectTimeout() * 1000);
//        }
//
//        config.setEndPoint(url);
//        return config;
//    }
//
//    /**
//     *
//     * @throws Exception
//     */
//    protected String upload(String type, String uri) {
//        InputStream inputStream = null;
//        // 允许上传http的资源链接，因为需要从网络现在后上传到obs，需要控制资源大小在10M以内
//        if (uri.startsWith("https://") || uri.startsWith("http://")) {
//            try {
//                URL url = new URL(uri);
//                inputStream = url.openStream();
//            } catch (Exception ex) {
//                throw new AIException(AIException.code_params_resource,
//                        String.format("Resource access errorm, file:%s", uri), ex);
//            }
//        } else {
//            File file = new File(uri);
//            if (!file.exists()) {
//                throw new AIException(AIException.code_params_resource_notfound,
//                        (String.format("file:%s is not exists", uri)));
//            }
//            try {
//                inputStream = new FileInputStream(file);
//            } catch (Exception ex) {
//                throw new AIException(AIException.code_params_resource,
//                        String.format("Resource access errorm, file:%s", uri), ex);
//            }
//        }
//
//        List<ObsClientAware> obsClientAwares = obsAwareMap.get(type);
//        if (obsClientAwares == null) {
//            throw new AIException(AIException.code_params_err, String.format("type:%s is not configured", type));
//        }
//
//        Exception ex = null;
//
//        for (ObsClientAware obsClientAware : obsClientAwares) {
//            try {
//                log.info("upload start, type={} uri={} key={} bucket={} client={}", type, uri,
//                        obsClientAware.getObsConfig().getKey(),
//                        obsClientAware.getObsConfig().getBucket(),
//                        obsClientAware.getObsClient().toString());
//
//                PutObjectResult result = obsClientAware.getObsClient()
//                        .putObject(obsClientAware.getObsConfig().getBucket(),
//                                obsClientAware.getObsConfig().getKey(),
//                                inputStream);
//                String objUrl = result.getObjectUrl();
//                return objUrl;
//            } catch (ObsException obsException) {
//                log.warn(String.format("Upload OBS exception,code:%s,message:%s", obsException.getResponseCode(),
//                        obsException.getLocalizedMessage()), obsException);
//                ex = obsException;
//            }
//        }
//        throw new AIException(AIException.code_upload_err, "Upload OBS exception", ex);
//    }
//
//    /**
//     * 重试创建AI处理任务
//     *
//     * @param sdkRequestDTO
//     * @return
//     * @throws Exception
//     */
//    private SdkResponseDTO.Result retryPush(SdkRequestDTO sdkRequestDTO, List<ApiAware> apiAwares, String processType) {
//        AIException finalEx = null;
//        for (ApiAware apiAware : apiAwares) {
//            APIConfig apConfig = apiAware.getApiConfig();
//            for (int i = 0; i < apConfig.getRetry().times; i++) {
//                sleepRetry(i, apConfig.getRetry());
//                SdkResponseDTO response = null;
//                try {
//                    response = doPush(sdkRequestDTO, apiAware, processType);
//                } catch (AIException ex) {
//                    log.info("push retry, times=" + i, ex);
//                    // 权限问题直接返回
//                    if (ex.getErrorCode() == AIException.code_cloud_process_unauthorized
//                            || ex.getErrorCode() == AIException.code_params_err) {
//                        throw ex;
//                    }
//                    finalEx = ex;
//                    continue;
//                } catch (Exception ex) {
//                    log.info("push retry, times=" + i, ex);
//                    finalEx = new AIException(AIException.code_cloud_process_err, "Request exception", ex);
//                    continue;
//                }
//                if (response == null) {
//                    continue;
//                }
//
//                // 使用status异步获取结果
//                if (response.getCode() == 0 && response.getData().getStatus() == status_code_suc) {
//                    return response.getData().getResult();
//                }
//                if (response.getCode() == 0 && response.getData().getStatus() == status_code_timeout) {
//                    if (response.getData() == null || response.getData().getResult() == null
//                            || response.getData().getResult().getId() == null) {
//                        throw new AIException(AIException.code_cloud_process_err,
//                                "Task ID not found in backend request");
//                    }
//                    return getResultStatus(sdkRequestDTO, response.getData().getResult().getId(), apiAware);
//                } else {
//                    // 后端出现异常，不在进行循环
//                    throw new AIException(response.getCode(),
//                            response.getMessage());
//                }
//            }
//        }
//        throw finalEx;
//    }
//
//    /**
//     * 重新获取状态
//     *
//     * @param taskId
//     * @return
//     * @throws Exception
//     */
//    private SdkResponseDTO.Result getResultStatus(SdkRequestDTO requestDTO, String taskId, ApiAware apiAware) {
//        AIException finalEx = null;
//        StatusQuery statusQuery = apiAware.getApiConfig().getStatusQuery();
//        String durations = statusQuery.durations;
//        if (durations == null || durations.length() == 0) {
//            durations = String.valueOf(statusQuery.defaultDuration);
//        }
//
//        String[] durationArr = durations.split(",");
//        for (String duration : durationArr) {
//            try {
//                Thread.sleep(Integer.parseInt(duration));
//            } catch (InterruptedException e) {
//                log.warn("sleep异常", e);
//            }
//            SdkResponseDTO responseDTO = null;
//            try {
//                responseDTO = doResultStatus(requestDTO.getContext(), taskId, apiAware);
//            } catch (AIException ex) {
//                finalEx = ex;
//                continue;
//            } catch (Exception ex) {
//                finalEx = new AIException(AIException.code_cloud_get_status_err, "Get status exception", ex);
//                continue;
//
//            }
//
//            if (responseDTO == null) {
//                continue;
//            }
//
//            if (responseDTO.getCode() == 0 && responseDTO.getData().getStatus() == status_code_suc) {
//                // 使用status异步获取结果
//                return responseDTO.getData().getResult();
//            } else if (responseDTO.getCode() == 0 && responseDTO.getData().getStatus() == status_code_fail) {
//                // 后端出现异常，不在进行循环
//                throw new AIException(responseDTO.getCode(),
//                        responseDTO.getMessage());
//            } else if (responseDTO.getCode() != 0) {
//                throw new AIException(responseDTO.getCode(),
//                        responseDTO.getMessage());
//            }
//
//        }
//
//        if (finalEx != null) {
//            throw finalEx;
//        } else {
//            throw new AIException(AIException.code_cloud_process_timeout, "Process timeout");
//        }
//    }
//
//    /**
//     * 获取
//     *
//     * @param requestDTO
//     * @param taskId
//     * @param apiAware
//     * @return
//     */
//    private SdkResponseDTO doResultStatus(String contextParam, String taskId, ApiAware apiAware) {
//        long start = System.currentTimeMillis();
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//        Map<String, String> headers = new HashMap<>();
//        Map<String, String> params = new HashMap<>();
//        params.put("task_id", taskId);
//        if (contextParam != null && contextParam.length() > 0) {
//            params.put("context", contextParam);
//        }
//
//        Request request = buildGetRequest(apiAware.getStatusUrl(), params, headers);
//
//        Response response = null;
//        try {
//            response = apiAware.getPushClient().newCall(request).execute();
//        } catch (Exception ex) {
//            throw new AIException(AIException.code_cloud_process_net_err, "Request exception", ex);
//        }
//
//        try {
//            String body = "";
//            try {
//                body = response.body().string();
//            } catch (Exception ex) {
//                // 忽略异常
//            }
//
//            log.info("get status response, latency={} url={} httpcode={} body={}", System.currentTimeMillis() - start,
//                    apiAware.getPushUrl(), response.code(), body);
//
//            if (!response.isSuccessful()) {
//                throw new AIException(AIException.code_cloud_process_err,
//                        String.format("Request exception:httpCode:", response.code()));
//            }
//
//            try {
//                SdkResponseDTO responseDTO = objectMapper.readValue(body, SdkResponseDTO.class);
//                return responseDTO;
//            } catch (Exception ex) {
//                throw new AIException(AIException.code_cloud_process_err, "Result deserialization exception", ex);
//            }
//        } finally {
//            response.close();
//        }
//    }
//
//    private void sleepRetry(int index, RetryConfig retryConfig) {
//        if (index == 0) {
//            return;
//        }
//        try {
//            Thread.sleep(retryConfig.duration);
//        } catch (InterruptedException e) {
//            log.warn("sleep异常", e);
//        }
//    }
//
//    /**
//     * 提交ai 任务
//     *
//     * @param sdkRequestDTO
//     * @return
//     */
//    protected SdkResponseDTO doPush(SdkRequestDTO sdkRequestDTO, ApiAware apiAware, String processType) {
//        String url = apiAware.getPushUrl();
//        if (process_type_inference.equals(processType)) {
//            url = apiAware.getInferenceUrl();
//        }
//        long start = System.currentTimeMillis();
//        String json = null;
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//        try {
//            json = objectMapper.writeValueAsString(sdkRequestDTO);
//        } catch (Exception ex) {
//            throw new AIException(AIException.code_serialization_err, "Json exception", ex);
//        }
//        URI uri = URI.create(url);
//        String host = uri.getHost();
//        Map<String, String> headers = new HashMap<>();
//        headers.put(Signer.HeaderHost, host);
//
//        Signer signer = new Signer(ak, sk);
//        Map<String, String> sigHeader = null;
//        try {
//            sigHeader = signer.sign(url, "POST", headers, json);
//        } catch (URISyntaxException ex) {
//            throw new AIException(AIException.code_cloud_process_err, "Sign exception", ex);
//        }
//
//        Request.Builder request = new Request.Builder()
//                .post(RequestBody.create(json, MediaType.parse("application/json")))
//                .url(url);
//
//        sigHeader.forEach((key, value) -> {
//            if (Signer.HeaderHost.equals(key)) {
//                return;
//            }
//            request.addHeader(key, value);
//        });
//
//        log.info("push request, url={} body={} header={}", url, json,
//                jsonToString(sigHeader, objectMapper));
//
//        OkHttpClient okHttpClient = apiAware.getPushClient();
//
//        /**
//         * 设置同步超时时间
//         */
//        if (sdkRequestDTO.getSyncTimeout() > 0) {
//            OkHttpClient.Builder builder = apiAware.getPushClient().newBuilder();
//            int socketTimeout = sdkRequestDTO.getSyncTimeout() * 2;
//            if (sdkRequestDTO.getSyncTimeout() > 0) {
//                builder.readTimeout(socketTimeout, TimeUnit.SECONDS);
//                builder.writeTimeout(socketTimeout, TimeUnit.SECONDS);
//            }
//            okHttpClient = builder.build();
//        }
//
//        Response response = null;
//        try {
//            response = okHttpClient.newCall(request.build()).execute();
//        } catch (Exception ex) {
//            throw new AIException(AIException.code_cloud_process_net_err, "Request exception", ex);
//        }
//
//        try {
//            String body = null;
//            try {
//                body = response.body().string();
//            } catch (Exception ex) {
//                // 忽略异常
//            }
//
//            log.info("push response, latency={} url={} httpcode={} body={}", System.currentTimeMillis() - start,
//                    url, response.code(), body);
//
//            if (!response.isSuccessful()) {
//                if (response.code() == 400) {
//                    int code = response.code();
//                    String msg = response.message();
//                    try {
//                        SdkResponseDTO responseDTO = objectMapper.readValue(body, SdkResponseDTO.class);
//                        code = responseDTO.getCode();
//                        msg = responseDTO.getMessage();
//                    } catch (Exception ex) {
//                        // 忽略错误，出现错误也是正常情况。
//                    }
//                    throw new AIException(AIException.code_params_err,
//                            String.format("Request exception:code=%s, message=%s", code, msg));
//                } else if (response.code() == 401 || response.code() == 403) {
//                    throw new AIException(AIException.code_cloud_process_unauthorized,
//                            String.format("Request exception:httpCode=%s, message=%s", response.code(),
//                                    response.message()));
//                } else {
//                    throw new AIException(AIException.code_cloud_process_err,
//                            String.format("Request exception:httpCode=%s, message=%s", response.code(),
//                                    response.message()));
//                }
//
//            }
//
//            try {
//                SdkResponseDTO responseDTO = objectMapper.readValue(body, SdkResponseDTO.class);
//                return responseDTO;
//            } catch (Exception ex) {
//                throw new AIException(AIException.code_cloud_process_err, "Result deserialization exception", ex);
//            }
//        } finally {
//            response.close();
//        }
//    }
//
//    protected String jsonToString(Object obj, ObjectMapper objectMapper) {
//        if (objectMapper == null) {
//            objectMapper = new ObjectMapper();
//        }
//
//        try {
//            return objectMapper.writeValueAsString(obj);
//        } catch (Exception ex) {
//            throw new AIException(AIException.code_serialization_err, "Json exception", ex);
//        }
//    }
//
//    @Data
//    protected static class ConfigAware {
//        private Map<String, List<ObsConfig>> obsConfigMap;
//        private Map<String, List<APIConfig>> apiConfigMap;
//        private int minTTL; // token最小存活时间，单位秒。所有obsconfig中ttl最小的
//    }
//
//    @Data
//    protected static class ObsConfig {
//        @JsonProperty("socket_timeout")
//        private int socketTimeout = default_obs_socket_timeout; // 单位秒
//        @JsonProperty("connect_timeout")
//        private int connectTimeout = default_obs_connect_timeout; // 单位秒
//
//        private String url;
//
//        @JsonProperty("backup_url")
//        private String backupUrl;
//
//        private Credentials credentials;
//
//        private String key;
//
//        private String bucket;
//
//        /**
//         * token存活时间，单位秒
//         */
//        private int ttl;
//    }
//
//    @Data
//    protected static class Credentials {
//        @JsonProperty("access_key")
//        private String accessKey;
//        @JsonProperty("secret_key")
//        private String secretKey;
//        @JsonProperty("session_token")
//        private String sessionToken;
//    }
//
//    @Data
//    protected static class ObsClientAware {
//        private ObsClient obsClient;
//        private ObsConfig obsConfig;
//
//        public ObsClientAware(ObsClient obsClient, ObsConfig obsConfig) {
//            this.obsClient = obsClient;
//            this.obsConfig = obsConfig;
//        }
//    }
//
//    @Data
//    protected static class APIConfig {
//        private String url;
//        @JsonProperty("backup_url")
//        private String backupUrl;
//        @JsonProperty("push_path")
//        private String pushPath;
//        @JsonProperty("status_path")
//        private String statusPath;
//        private RetryConfig retry;
//        @JsonProperty("connect_timeout")
//        private int connectTimeout = 5; // 单位秒
//        @JsonProperty("socket_timeout")
//        private int socketTimeout = 10; // 单位秒
//        @JsonProperty("status_query")
//        private StatusQuery statusQuery;
//        private String type;
//    }
//
//    @Data
//    protected static class RetryConfig {
//        private String strategy;
//        private int duration; // 单位毫秒
//        private int times; // 重试次数
//    }
//
//    @Data
//    protected static class StatusQuery {
//        private String path;
//        private String durations; // "2000,2000,2000,1000,1000,500,500" 点位毫秒
//        @JsonProperty("default")
//        private String defaultDuration;
//
//    }
//
//    @Data
//    protected static class ApiAware {
//        private OkHttpClient pushClient;
//        private OkHttpClient statusClient;
//        private APIConfig apiConfig;
//        private String pushUrl;
//        private String statusUrl;
//        private String inferenceUrl;
//
//        public ApiAware(OkHttpClient pushClient, OkHttpClient statusClient, APIConfig apiConfig, String host) {
//            this.pushClient = pushClient;
//            this.statusClient = statusClient;
//            this.apiConfig = apiConfig;
//            this.pushUrl = host + "/" + apiConfig.pushPath;
//            this.statusUrl = host + "/" + apiConfig.statusPath;
//            this.inferenceUrl = host + "/whee/business/push.json";
//
//        }
//    }
//
//    /**
//     * 自动刷新策略任务,如果无法获取策略将进行轮询获取，知道获取到策略为止
//     */
//    private static class AiClientRefreshStrategyTask implements Runnable {
//        private AiClient aiClient;
//
//        public AiClientRefreshStrategyTask(AiClient aiClient) {
//            this.aiClient = aiClient;
//        }
//
//        public void run() {
//            log.info("refresh strategy task start");
//            Exception finalEx = null;
//            for (int i = 0; i < get_strategy_retry_times; i++) {
//                try {
//                    aiClient.init();
//                    return;
//                } catch (Exception ex) {
//                    log.info("Retry getting strategy exception", ex);
//                    finalEx = ex;
//                    continue;
//                }
//            }
//
//            if (finalEx != null) {
//                log.error("Getting strategy exception", finalEx);
//            }
//
//        }
//    }
//}
