使用SQLFLow的RESTFul接口

SQLFlow的restful接口

我们不光可以在SQLFlow图形化界面上使用,还可以通过SQLFlow提供的一系列restful接口进行使用,目前SQLFlow提供很多接口供第三方调用。

接口文档

使用案例

通过SQLFlow的api实现从对指定SQL脚本文件进行分析并得到分析结果。

java实现版本
  • sqlflow调用
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SqlFlowUtil {

    private static String token = "";

    private SqlFlowUtil() {
    }

    public static String getToken(String url, String userId,
                                  String secretKey, Integer flag) {
        try {
            System.out.println("start get token from sqlflow.");
            Map<String, String> param = new HashMap<>();
            param.put("secretKey", secretKey);
            param.put("userId", userId);
            if ("gudu|0123456789".equals(userId)) {
                return "token";
            }
            String result = doPost(url, param);
            JSONObject object = JSONObject.parseObject(result);
            if ("200".equals(object.getString("code"))) {
                token = object.getString("token");
                System.out.println("get token from sqlflow successful.");
                return token;
            }
            return "";
        } catch (Exception e) {
            if (flag == 0) {
                if (url.startsWith("http:")) {
                    url = url.replace("http", "https");
                }
                return getToken(url, userId,
                        secretKey, 1);
            }
            if (flag == 1) {
                System.err.println("get token from sqlflow failed.");
            }
            return token;
        }
    }

    public static String submitJob(String filePath,
                                   String url,
                                   String dbVendor,
                                   String userId,
                                   String token,
                                   String jobName) throws IOException {
        System.out.println("start submit job to sqlflow.");
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost uploadFile = new HttpPost(url);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addTextBody("dbvendor", dbVendor, ContentType.TEXT_PLAIN);
        builder.addTextBody("jobName", jobName, ContentType.TEXT_PLAIN);
        builder.addTextBody("token", token, ContentType.TEXT_PLAIN);
        builder.addTextBody("userId", userId, ContentType.TEXT_PLAIN);
        File f = new File(filePath);
        builder.addBinaryBody("sqlfiles", new FileInputStream(f), ContentType.APPLICATION_OCTET_STREAM, f.getName());

        HttpEntity multipart = builder.build();
        uploadFile.setEntity(multipart);
        CloseableHttpResponse response = httpClient.execute(uploadFile);
        HttpEntity responseEntity = response.getEntity();
        return EntityUtils.toString(responseEntity, "UTF-8");
    }


    public static String getStatus(String url,
                                   String userId,
                                   String token,
                                   String jobId) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost uploadFile = new HttpPost(url);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addTextBody("jobId", jobId, ContentType.TEXT_PLAIN);
        builder.addTextBody("token", token, ContentType.TEXT_PLAIN);
        builder.addTextBody("userId", userId, ContentType.TEXT_PLAIN);

        HttpEntity multipart = builder.build();
        uploadFile.setEntity(multipart);
        CloseableHttpResponse response = httpClient.execute(uploadFile);
        HttpEntity responseEntity = response.getEntity();
        return EntityUtils.toString(responseEntity, "UTF-8");
    }


    public static String exportLineage(ExportLineageReq req) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost uploadFile = new HttpPost(req.getUrl());
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addTextBody("jobId", req.getJobId(), ContentType.TEXT_PLAIN);
        builder.addTextBody("userId", req.getUserId(), ContentType.TEXT_PLAIN);
        builder.addTextBody("token", req.getToken(), ContentType.TEXT_PLAIN);
        builder.addTextBody("tableToTable", String.valueOf(req.getTableToTable()), ContentType.TEXT_PLAIN);

        HttpEntity multipart = builder.build();
        uploadFile.setEntity(multipart);
        CloseableHttpResponse response = httpClient.execute(uploadFile);

        HttpEntity responseEntity = response.getEntity();

        InputStream in = responseEntity.getContent();
        FileUtil.mkFile(req.getDownloadFilePath());
        File file = new File(req.getDownloadFilePath());
        FileOutputStream fout = new FileOutputStream(file);
        int a;
        byte[] tmp = new byte[1024];
        while ((a = in.read(tmp)) != -1) {
            fout.write(tmp, 0, a);
        }
        fout.flush();
        fout.close();
        in.close();
        return "download success, path:" + req.getDownloadFilePath();
    }


    private static String doPost(String url, Map<String, String> param) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "utf-8");
                httpPost.setEntity(entity);
            }
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }

    public static class ExportLineageReq {

        private String jobId;
        private String userId;
        private String token;

        private String url;
        private String downloadFilePath;
        private Boolean tableToTable = false;

        public String getJobId() {
            return jobId;
        }

        public void setJobId(String jobId) {
            this.jobId = jobId;
        }

        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }

        public Boolean getTableToTable() {
            return tableToTable;
        }

        public void setTableToTable(Boolean tableToTable) {
            this.tableToTable = tableToTable;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getDownloadFilePath() {
            return downloadFilePath;
        }

        public void setDownloadFilePath(String downloadFilePath) {
            this.downloadFilePath = downloadFilePath;
        }
    }

}

  • 文件工具类
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileUtil {

    private static final int BUFFER_SIZE = 10 * 1024 * 1024;

    private FileUtil() {
    }

    public static void mkFile(String filePath) throws IOException {
        File testFile = new File(filePath);
        File fileParent = testFile.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }
        if (!testFile.exists()) {
            testFile.createNewFile();
        }
    }

    public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
            throws RuntimeException {
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(out);
            File sourceFile = new File(srcDir);
            compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private static void compress(File sourceFile, ZipOutputStream zos, String name,
                                 boolean KeepDirStructure) throws Exception {
        byte[] buf = new byte[BUFFER_SIZE];
        if (sourceFile.isFile()) {
            zos.putNextEntry(new ZipEntry(name));
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                if (KeepDirStructure) {
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    zos.closeEntry();
                }

            } else {
                for (File file : listFiles) {
                    if (KeepDirStructure) {
                        compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
                    } else {
                        compress(file, zos, file.getName(), KeepDirStructure);
                    }
                }
            }
        }
    }

    public static OutputStream outStream(String path) throws IOException {
        FileOutputStream fileOutputStream;
        try {
            fileOutputStream = new FileOutputStream(path);
        } catch (Exception ex) {
            mkFile(path);
            fileOutputStream = new FileOutputStream(path);
        }
        return fileOutputStream;
    }

}

  • 时间工具类
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtil {
    public DateUtil() {
    }

    public static String format(Date date) {
        return format(date, "yyyyMMdd");
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        } else {
            return null;
        }
    }

    public static String timeStamp2Date(Long seconds) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(new Date(seconds));
    }

}

java-demo

php版本
  • 入口
<?php


class Grabit
{

    function run($argv)
    {
        if (sizeof($argv) < 2) {
            echo 'please enter the correct parameters.';
            exit(1);
        }

        $userSecret = '';
        $userId = '';
        $dbvendor = '';
        $sqlfiles = '';
        $server = '';
        $port = '';
        $download = 1;
        for ($i = 0; $i < sizeof($argv) - 1; $i++) {
            if ($argv[$i] == '/s') {
                $server = $argv[$i + 1];
            }
            if ($argv[$i] == '/p') {
                $port = $argv[$i + 1];
            }
            if ($argv[$i] == '/f') {
                $sqlfiles = $argv[$i + 1];
                if (!file_exists($sqlfiles)) {
                    echo "The file is no exists";
                    exit(1);
                }
            }
            if ($argv[$i] == '/u') {
                $userId = $argv[$i + 1];
                $userId = str_replace("'", '', $userId);
            }
            if ($argv[$i] == '/t') {
                $dbvendor = 'dbv' . $argv[$i + 1];
                if ($dbvendor == 'dbvsqlserver') {
                    $dbvendor = 'dbvmssql';
                }
            }
            if ($argv[$i] == '/k') {
                $userSecret = $argv[$i + 1];
            }
            if ($argv[$i] == '/r') {
                $download = $argv[$i + 1];
            }
        }

        if (!substr($server, 0, 4) === "http" && !substr($server, 0, 5) === "https") {
            $server = "http://" . $server;
        }
        if (substr($server, -strlen(DIRECTORY_SEPARATOR)) === DIRECTORY_SEPARATOR) {
            $server = substr($server, 0, strlen($server) - 1);
        }
        if ($port != '') {
            $server = $server . ':' . $port;
        }

        echo '===================================== start =====================================';
        echo PHP_EOL;

        echo('start get token.');
        echo PHP_EOL;

        include('SqlFlowUtil.php');
        $obj = new SqlFlowUtil();
        $token = $obj->getToken($server, $userId, $userSecret);
        echo 'get token successful.';
        echo PHP_EOL;
        if (is_dir($sqlfiles)) {
            if (substr($sqlfiles, -strlen(DIRECTORY_SEPARATOR)) === DIRECTORY_SEPARATOR) {
                $sqlfiles = rtrim($sqlfiles, DIRECTORY_SEPARATOR);
            }

            $zip = new \ZipArchive();
            $sqlfileDir = $sqlfiles . '.zip';
            if (file_exists($sqlfileDir)) {
                if (PATH_SEPARATOR == ':') {
                    unlink($sqlfileDir);
                } else {
                    $url = iconv('utf-8', 'gbk', $sqlfileDir);
                    unlink($url);
                }
            }

            $open = $zip->open($sqlfileDir, \ZipArchive::CREATE);
            if ($open === true) {
                $this->toZip($sqlfiles, $zip);
                $zip->close();
            }
            $sqlfiles = $sqlfileDir;
        }

        echo 'start submit job.';
        echo PHP_EOL;

        $result = $obj->submitJob($server, $userId, $token, $sqlfiles, time(), $dbvendor);
        if ($result['code'] == 200) {
            echo 'submit job successful.';
            echo PHP_EOL;

            $jobId = $result['data']['jobId'];
            while (true) {
                $result = $obj->getStatus($server, $userId, $token, $jobId);
                if ($result['code'] == 200) {
                    $status = $result['data']['status'];
                    if ($status == 'partial_success' || $status == 'success') {
                        break;
                    }
                    if ($status == 'fail') {
                        echo 'job execution failed.';
                        exit(1);
                    }
                }
            }
            echo $status;
            echo 'start get result from sqlflow.';
            echo PHP_EOL;
            $filePath = $obj->getResult($server, $userId, $token, $jobId, $download);
            echo 'get result from sqlflow successful. file path is : ' . $filePath;
        } else {
            echo 'submit job failed.';
        }
        echo PHP_EOL;
        echo '===================================== end =====================================';
    }

    function toZip($path, $zip)
    {
        $handler = opendir($path);
        while (($filename = readdir($handler)) !== false) {
            if ($filename != "." && $filename != "..") {
                if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) {
                    $obj = new Grabit();
                    $obj->toZip($path . DIRECTORY_SEPARATOR . $filename, $zip);
                } else {
                    $zip->addFile($path . DIRECTORY_SEPARATOR . $filename);
                    $zip->renameName($path . DIRECTORY_SEPARATOR . $filename, $filename);
                }
            }
        }
        @closedir($path);
    }
}

$obj = new Grabit();
$obj->run($argv);

  • sqlflow接口调用
<?php
include('HttpClient.php');

class SqlFlowUtil
{
    function getToken($server, $userId, $userSecret)
    {
        if ($userId == 'gudu|0123456789') {
            return 'token';
        }

        $httpVendor = new HttpClient();
        $json['userId'] = $userId;
        $json['secretKey'] = $userSecret;
        $url = $server . '/gspLive_backend/user/generateToken';
        $result = $httpVendor->postFrom($url, $json);
        return $result['token'];
    }

    function submitJob($server, $userId, $token, $sqlfiles, $jobName, $dbvendor)
    {
        $httpVendor = new HttpClient();
        $params = array(
            'userId' => $userId,
            'token' => $token,
            'jobName' => $jobName,
            'dbvendor' => $dbvendor,
            'filename' => $jobName,
            'sqlfiles' => file_get_contents($sqlfiles)
        );
        $url = $server . '/gspLive_backend/sqlflow/job/submitUserJob';
        $result = $httpVendor->postFile($url, $params);
        return $result;
    }

    function getStatus($server, $userId, $token, $jobId)
    {
        $httpVendor = new HttpClient();
        $json['userId'] = $userId;
        $json['token'] = $token;
        $json['jobId'] = $jobId;
        $url = $server . '/gspLive_backend/sqlflow/job/displayUserJobSummary';
        $result = $httpVendor->postFrom($url, $json);
        return $result;
    }

    function getResult($server, $userId, $token, $jobId, $download)
    {
        $dir = 'data' . DIRECTORY_SEPARATOR . 'result';
        $str = $dir . DIRECTORY_SEPARATOR . date("Ymd") . '_' . $jobId;
        $filePath = '';
        $url = '';
        if ($download == 1) {
            $url = $server . '/gspLive_backend/sqlflow/job/exportLineageAsJson';
            $filePath = $str . '_json.json';
        } else if ($download == 2) {
            $url = $server . '/gspLive_backend/sqlflow/job/exportLineageAsGraphml';
            $filePath = $str . '_graphml.graphml';
        } else if ($download == 3) {
            $url = $server . '/gspLive_backend/sqlflow/job/exportLineageAsCsv';
            $filePath = $str . '_csv.csv';
        }

        $httpVendor = new HttpClient();
        $json['userId'] = $userId;
        $json['token'] = $token;
        $json['jobId'] = $jobId;
        $httpVendor->mkdirs($dir);
        $httpVendor->postJson($url, $json, $filePath);
        return $filePath;
    }
}
  • http工具
<?php


class HttpClient
{

    protected static $url;
    protected static $delimiter;

    function mkdirs($a1, $mode = 0777)
    {
        if (is_dir($a1) || @mkdir($a1, $mode)) return TRUE;
        if (!static::mkdirs(dirname($a1), $mode)) return FALSE;
        return @mkdir($a1, $mode);
    }


    public function __construct()
    {
        static::$delimiter = uniqid();
    }

    private static function buildData($param)
    {
        $data = '';
        $eol = "\r\n";
        $upload = $param['sqlfiles'];
        unset($param['sqlfiles']);

        foreach ($param as $name => $content) {
            $data .= "--" . static::$delimiter . "\r\n"
                . 'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n"
                . $content . "\r\n";
        }
        $data .= "--" . static::$delimiter . $eol
            . 'Content-Disposition: form-data; name="sqlfiles"; filename="' . $param['filename'] . '"' . "\r\n"
            . 'Content-Type:application/octet-stream' . "\r\n\r\n";

        $data .= $upload . "\r\n";
        $data .= "--" . static::$delimiter . "--\r\n";
        return $data;
    }

    function postFile($url, $param)
    {
        $post_data = static::buildData($param);
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($curl, CURLOPT_HTTPHEADER, [
            "Content-Type: multipart/form-data; boundary=" . static::$delimiter,
            "Content-Length: " . strlen($post_data)
        ]);
        $response = curl_exec($curl);
        curl_close($curl);
        $info = json_decode($response, true);
        return $info;
    }


    function postFrom($url, $data)
    {
        $headers = array('Content-Type: application/x-www-form-urlencoded');
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        $result = curl_exec($curl);
        if (curl_errno($curl)) {
            return 'Errno' . curl_error($curl);
        }
        curl_close($curl);
        return json_decode($result, true);
    }


    function postJson($url, $data, $filePath)
    {
        $headers = array('Content-Type: application/x-www-form-urlencoded');
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        $result = curl_exec($curl);
        if (curl_errno($curl)) {
            return 'Errno' . curl_error($curl);
        }
        $fp = @fopen($filePath, "a");
        fwrite($fp, $result);
        fclose($fp);
    }

}

php-demo

python版本

python-demo

总结

通过SQLFlow提供的一系列restful接口可以在我们的程序中操作获取到我们想要分析的SQL脚本的分析结果。

SQLFlow的地址:SQLFlow

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用wxWidgets调用RESTful接口可以通过以下步骤实现: 1. 在代码引入curl库,可以使用以下代码: ``` #include <curl/curl.h> ``` 2. 创建一个CurlHandle类,用于处理curl库的初始化和请求。以下是一个简单的CurlHandle类的示例代码: ``` class CurlHandle { public: CurlHandle() { curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); } ~CurlHandle() { curl_easy_cleanup(curl); curl_global_cleanup(); } CURL* get() { return curl; } private: CURL* curl; }; ``` 3. 创建一个HTTPRequest类,用于封装http请求。以下是一个简单的HTTPRequest类的示例代码: ``` class HTTPRequest { public: HTTPRequest(const std::string& url) { curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); } void setHeader(const std::string& header) { headers = curl_slist_append(headers, header.c_str()); curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, headers); } void setMethod(const std::string& method) { curl_easy_setopt(curl.get(), CURLOPT_CUSTOMREQUEST, method.c_str()); } void setBody(const std::string& body) { curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, body.c_str()); } CURLcode perform() { return curl_easy_perform(curl.get()); } private: CurlHandle curl; struct curl_slist* headers = nullptr; }; ``` 4. 在wxWidgets的GUI代码创建一个按钮,并为其添加一个事件处理程序。在事件处理程序,创建一个HTTPRequest对象,并设置请求的URL、header、method和body,并执行请求。以下是一个简单的事件处理程序的示例代码: ``` void MyFrame::OnButtonClicked(wxCommandEvent& event) { HTTPRequest request("http://localhost:8080/test"); request.setHeader("Content-Type: application/json"); request.setMethod("POST"); request.setBody("{\"name\": \"test\"}"); CURLcode res = request.perform(); if (res != CURLE_OK) { wxMessageBox("Error: " + std::string(curl_easy_strerror(res))); } } ``` 通过以上步骤,您就可以使用wxWidgets调用RESTful接口了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值