cuixubin 4 years ago
parent
commit
297e072f43

+ 3 - 1
file-move-tool.iml

@@ -6,11 +6,13 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-log4j12:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
     <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.47" level="project" />
     <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.5" level="project" />
     <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />

+ 6 - 0
pom.xml

@@ -13,6 +13,12 @@
     </properties>
 
     <dependencies>
+        <!-- log -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.25</version>
+        </dependency>
         <!-- json -->
         <dependency>
             <groupId>com.alibaba</groupId>

+ 0 - 49
src/main/java/com/persagy/filemove/app/Ex6_ChoiceBox.java

@@ -1,49 +0,0 @@
-package com.persagy.filemove.app;
-
-import javafx.application.Application;
-import javafx.collections.FXCollections;
-import javafx.geometry.Insets;
-import javafx.geometry.Orientation;
-import javafx.scene.Scene;
-import javafx.scene.control.ChoiceBox;
-import javafx.scene.control.Separator;
-import javafx.scene.layout.FlowPane;
-import javafx.scene.text.Text;
-import javafx.stage.Stage;
-
-public class Ex6_ChoiceBox extends Application {
-    public static void main(String[] args) {
-        launch(args);
-    }
-
-    private void build(FlowPane basePane) {
-        Text tips = new Text();
-
-        ChoiceBox cb = new ChoiceBox();
-        // 设置列表项,分隔符也算列表项的一个元素占用一个位置,但不能被选中
-        cb.setItems(FXCollections.observableArrayList("A", "B", new Separator(), "C"));
-        cb.setPrefSize(100, 30);
-        // 设置默认选择第一项
-        cb.getSelectionModel().selectFirst();
-
-        cb.getSelectionModel().selectedIndexProperty().addListener((obv, ov, nv)->{
-            // 显示选中项的下标,从0开始
-            tips.setText("selectIndex=" + nv.intValue() + cb.getItems().get(nv.intValue()));
-        });
-
-        basePane.getChildren().addAll(cb, tips);
-    }
-
-    @Override
-    public void start(Stage primaryStage) throws Exception {
-        FlowPane root = new FlowPane();
-        build(root);
-        Scene scene = new Scene(root, 350, 150);
-        primaryStage.setScene(scene);
-        primaryStage.setTitle("ChoiceBox");
-        root.setPadding(new Insets(10)); root.setVgap(20);
-        root.setOrientation(Orientation.VERTICAL);
-
-        primaryStage.show();
-    }
-}

+ 50 - 23
src/main/java/com/persagy/filemove/app/SagaFileMoveApp.java

@@ -10,31 +10,29 @@ import javafx.geometry.Pos;
 import javafx.scene.Node;
 import javafx.scene.Scene;
 import javafx.scene.control.*;
-import javafx.scene.control.Label;
-import javafx.scene.control.Menu;
-import javafx.scene.control.MenuBar;
-import javafx.scene.control.MenuItem;
-import javafx.scene.control.TextField;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Pane;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
 import javafx.stage.Stage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import javax.sound.midi.Soundbank;
 import java.lang.reflect.Field;
 import java.util.LinkedHashMap;
 
 public class SagaFileMoveApp extends Application {
-    private static int appWidth = 600;
-    private static int appHeight = 500;
+    private static final Logger log = LoggerFactory.getLogger(SagaFileMoveApp.class);
+
+    private static int appWidth = 640;
+    private static int appHeight = 520;
 
     private SagaFileMoveDTO dto = new SagaFileMoveDTO();
     private SagaFileMoveService service = new SagaFileMoveService(dto);
 
     /** 文件服务上传下载接口类型 */
-    private static final String[] apiTypes = {"file", "image"};
+    private static final String[] apiTypes = {"default", "file", "image"};
 
     /** 对象类型 */
     private static String[] objTypes;
@@ -120,17 +118,22 @@ public class SagaFileMoveApp extends Application {
         tfImgToSysId.setPrefWidth(appWidth * .25);
         tfImgToSecret.setPrefWidth(appWidth * .25);
         cbImgToApiType.setPrefWidth(appWidth * .15);
-        cbImgToApiType.getSelectionModel().selectFirst();
+        cbImgToApiType.getSelectionModel().select(1);
 
         btnValid.setOnAction(e -> {
-
             validParam();
         });
 
         btnExecute.setOnAction(e -> {
-            disableSet(true, this);
             if(validParam()) {
-                // 操作按钮置为不可操作
+                // 所有控件设置为不可操作
+                disableSet(true, this);
+
+                // 执行资源迁移逻辑
+                service.resourceMove(this);
+
+                // 所有控件设置为可操作
+                disableSet(false, this);
             }
         });
 
@@ -140,15 +143,27 @@ public class SagaFileMoveApp extends Application {
         });
     }
 
-    private void disableSet(boolean isAble, SagaFileMoveApp father) {
+    /**
+     * 资源转移逻辑
+     */
+    private void resourceMove() {
+    }
+
+    /**
+     * 设置视图中的所有控件是否为不可编辑状态
+     * @param disable true-控件不可编辑;false-控件可编辑
+     * @param father
+     */
+    private void disableSet(boolean disable, SagaFileMoveApp father) {
         Field[] allFields = SagaFileMoveApp.class.getDeclaredFields();
+
         for(Field field : allFields) {
-            if(Node.class.isAssignableFrom(field.getDeclaringClass())) {
-                try {
+            try {
+                if(Node.class.isAssignableFrom(field.get(father).getClass())) {
                     Node node = (Node) field.get(father);
-                    node.setDisable(isAble);
-                }catch (Exception e) {}
-            }
+                    node.setDisable(disable);
+                }
+            }catch (Exception e) {}
         }
     }
 
@@ -190,24 +205,36 @@ public class SagaFileMoveApp extends Application {
         return true;
     }
 
-    private void showTipsSuccess(String info) {
+    public void showTipsSuccess(String info) {
         lblExecute.setTextFill(Color.DARKGREEN);
         lblExecute.setText(info);
+        log.info(info);
     }
 
-    private void showTipsInfo(String info) {
+    public void showTipsInfo(String info) {
         lblExecute.setTextFill(Color.BLACK);
         lblExecute.setText(info);
+        log.info(info);
     }
 
-    private void showTipsError(String errMsg) {
+    public void showTipsError(String errMsg) {
         lblExecute.setTextFill(Color.RED);
         lblExecute.setText(errMsg);
+        log.error(errMsg);
     }
 
-    private void showTipsWarn(String warnMsg) {
+    public void showTipsWarn(String warnMsg) {
         lblExecute.setTextFill(Color.DARKORANGE);
         lblExecute.setText(warnMsg);
+        log.warn(warnMsg);
+    }
+
+    public void writeToLogFile(String msg) {
+        log.error(msg);
+    }
+
+    public String getTips() {
+        return lblExecute.getText();
     }
 
     /**

+ 57 - 0
src/main/java/com/persagy/filemove/dto/TransErrDTO.java

@@ -0,0 +1,57 @@
+package com.persagy.filemove.dto;
+
+public class TransErrDTO {
+    private String objId;
+    private String key;
+    private String msg;
+    private String getUrl;
+    private String sendUrl;
+
+    public TransErrDTO(String objId, String key, String msg, String getUrl, String sendUrl) {
+        this.objId = objId;
+        this.key = key;
+        this.msg = msg;
+        this.getUrl = getUrl;
+        this.sendUrl = sendUrl;
+    }
+
+    public String getObjId() {
+        return objId;
+    }
+
+    public void setObjId(String objId) {
+        this.objId = objId;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getGetUrl() {
+        return getUrl;
+    }
+
+    public void setGetUrl(String getUrl) {
+        this.getUrl = getUrl;
+    }
+
+    public String getSendUrl() {
+        return sendUrl;
+    }
+
+    public void setSendUrl(String sendUrl) {
+        this.sendUrl = sendUrl;
+    }
+}

+ 209 - 1
src/main/java/com/persagy/filemove/service/SagaFileMoveService.java

@@ -1,17 +1,26 @@
 package com.persagy.filemove.service;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.persagy.filemove.app.SagaFileMoveApp;
 import com.persagy.filemove.dto.SagaFileMoveDTO;
+import com.persagy.filemove.dto.TransErrDTO;
 import com.persagy.filemove.util.HttpTools;
+import com.persagy.filemove.util.JsonTools;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 public class SagaFileMoveService {
     private SagaFileMoveDTO dto;
     private static final String resp_success = "success";
     private static final String testKey = "persagyAndSagaTest2020121130";
     private static final String url_pj_get = "/mng/project/query";
-    private static final String url_source_get = "BASE/common/TYPE_get?systemId=SYSID&key=KEY";
+    private static final String url_obj_query = "/object/subset_query?projectId=PJID&secret=SEC";
+    private static final String url_source_get = "/common/TYPE_get?systemId=SYSID&key=";
+    private static final String url_source_send = "/common/TYPE_upload?systemId=SYSID&secret=SEC&overwrite=true&key=";
 
     public SagaFileMoveService(SagaFileMoveDTO dto) {
         this.dto = dto;
@@ -35,6 +44,205 @@ public class SagaFileMoveService {
     }
 
     /**
+     * 资源转移逻辑
+     */
+    public void resourceMove(SagaFileMoveApp app) {
+        final String tipPrefix = "文件迁移:";
+        Map<String, String> obj_key = requestSourceKey(app);
+        if(!obj_key.isEmpty()) {
+            int totalNum = obj_key.size();
+
+            // 文件不存在对象id集合
+            Set<TransErrDTO> noFileSet = new HashSet<>();
+            // 资源key为null的对象id集合
+            Set<TransErrDTO> nullKeySet = new HashSet<>();
+            // 文件转移失败的对象id集合
+            Set<TransErrDTO> moveErrorSet = new HashSet<>();
+
+            int handleIndex = 1;
+
+            // 默认使用image_get下载文件
+            String getApiType = "image";
+            if("file".equals(dto.imgFromApiType.getValue())) {
+                getApiType = "file";
+            }
+
+            // 默认使用file_upload上传文件
+            String toImgApi = "file";
+            if("image".equals(dto.imgToApiType.getValue())) {
+                toImgApi = "image";
+            }
+
+            String getUrl = dto.imgFromUrl.getValue() + url_source_get;
+            getUrl = getUrl.replace("TYPE", getApiType)
+                    .replace("SYSID", dto.imgFromSysId.getValue());
+
+            for(String objId : obj_key.keySet()) {
+                app.showTipsInfo(tipPrefix + handleIndex + " / " + totalNum);
+
+                fileMove(objId, obj_key.get(objId), getUrl, toImgApi, noFileSet, nullKeySet, moveErrorSet);
+
+                handleIndex ++;
+            }
+
+            String tips = app.getTips();
+            int noFileNum = noFileSet.size(), nullKeyNum = nullKeySet.size(), moveErrNum = moveErrorSet.size();
+            int errorNum = noFileNum + nullKeyNum + moveErrNum;
+            if(errorNum > 0) {
+                tips = tips + " 执行结束,转移失败数:" + (totalNum - errorNum) + "。详情见日志文件。";
+                app.showTipsError(tips);
+
+                StringBuilder sb = null;
+
+                if(noFileNum > 0) {
+                    sb = new StringBuilder("对象关联的文件不存在的数量:" + noFileNum + "。详情:\n");
+                    for(TransErrDTO item : noFileSet) {
+                        sb.append(JsonTools.beanToJson(item) + "\n");
+                    }
+                    app.writeToLogFile(sb.toString());
+                }
+
+                if(nullKeyNum > 0) {
+                    sb = new StringBuilder("对象关联文件key为空的数量:" + nullKeyNum + "。详情:\n");
+                    for(TransErrDTO item : nullKeySet) {
+                        sb.append(JsonTools.beanToJson(item) + "\n");
+                    }
+                    app.writeToLogFile(sb.toString());
+                }
+
+                if(moveErrNum > 0) {
+                    sb = new StringBuilder("文件迁移出错的数量:" + moveErrNum + "。详情:\n");
+                    for(TransErrDTO item : moveErrorSet) {
+                        sb.append(JsonTools.beanToJson(item) + "\n");
+                    }
+                    app.writeToLogFile(sb.toString());
+                }
+            }else {
+                app.showTipsInfo(tips + " 执行结束,转移成功数:" + totalNum);
+            }
+        }
+    }
+
+    /**
+     * 在两个文件服务器之间转移文件
+     * @param objId 对象id
+     * @param key 文件资源的key
+     * @param getUrl 获取资源的url
+     * @param toImgApi 上传文件使用的接口类型
+     * @param noFileSet 文件不存在对象id集合
+     * @param nullKeySet 资源key为null的对象id集合
+     * @param moveErrorSet 文件转移失败的对象id集合
+     */
+    private void fileMove(String objId, String key, String getUrl, String toImgApi, Set<TransErrDTO> noFileSet, Set<TransErrDTO> nullKeySet, Set<TransErrDTO> moveErrorSet) {
+        if(key == null || key.trim().length() == 0) {
+            // 文件资源key值为空
+            nullKeySet.add(new TransErrDTO(objId, key, "", "", ""));
+            return;
+        }
+
+        getUrl = getUrl + key;
+
+        if(key.endsWith(".jsonz")) {
+            // 对于.jsonz文件,从file_get接口获取
+            getUrl = getUrl.replace("image_get","file_get");
+        }
+
+        String sendUrl = dto.imgToUrl.getValue() + url_source_send;
+        sendUrl = sendUrl.replace("TYPE", toImgApi)
+                .replace("SYSID", dto.imgToSysId.getValue())
+                .replace("SEC", dto.imgToSecret.getValue())
+                + key;
+
+
+        try {
+            byte[] byteData = HttpTools.httpGetFile(getUrl);
+            if(byteData != null) {
+                if(byteData.length == 17) {
+                    // 文件不存在
+                    noFileSet.add(new TransErrDTO(objId, key, "not exist", getUrl, ""));
+                }else {
+                    String uploadResult = HttpTools.httpPostRequest(sendUrl, byteData);
+                    if(null == uploadResult || !uploadResult.contains(resp_success)) {
+                        // 文件转移失败
+                        moveErrorSet.add(new TransErrDTO(objId, key, "downloadSuccess uploadError", getUrl, sendUrl));
+                    }
+                }
+            }
+        }catch (Exception e){
+            // 文件转移报错
+            moveErrorSet.add(new TransErrDTO(objId, key, "serviceError:" + e.getMessage(), getUrl, sendUrl));
+        }
+    }
+
+    /**
+     * 从数据平台获取对象关联的资源key
+     * @param app
+     * @return
+     */
+    private Map<String, String> requestSourceKey(SagaFileMoveApp app) {
+        Map<String, String> obj_key = new HashMap<>();
+
+        app.showTipsInfo("查询数据平台对象,获取文件资源key...");
+
+        String reqUrl = dto.dpf.getValue() + url_obj_query;
+        reqUrl = reqUrl.replace("PJID", dto.pjId.getValue()).replace("SEC", dto.pjSecret.getValue());
+
+        JSONObject paramObj = new JSONObject();
+
+        JSONObject criteria = new JSONObject();
+        criteria.put("type", JSONArray.parse("["+dto.objType.getValue()+"]"));
+
+        JSONObject returnInfos = new JSONObject();
+        returnInfos.put("returnInfos", JSONArray.parse("["+dto.objInfoCode.getValue()+"]"));
+
+        paramObj.put("customInfo", true);
+        paramObj.put("criteria", criteria);
+        paramObj.put("returnInfos", returnInfos);
+
+        String resp = null;
+        try{
+            resp = HttpTools.httpPostJson(reqUrl, paramObj);
+            app.showTipsInfo("查询数据平台对象完成。");
+        }catch (Exception e){
+            app.showTipsError("请求数据平台出错:" + e.getMessage());
+        }
+
+        if(null != resp) {
+            app.showTipsInfo("查询结果转为Json对象...");
+
+            JSONObject respJson = null;
+            try {
+                respJson = JsonTools.strToJsonObj(resp);
+            }catch (Exception e) {
+                app.showTipsError("String转Json对象失败:" + e.getMessage());
+            }
+
+            if(respJson != null && resp_success.equals(respJson.getString("Result"))) {
+                JSONArray content = respJson.getJSONArray("Content");
+                if(null != content && !content.isEmpty()) {
+                    String objId = null, sourceKey = null;
+
+                    for(int i=0; i<content.size(); i++) {
+                        objId = content.getJSONObject(i).getString("id");
+                        JSONObject infoJson = content.getJSONObject(i).getJSONObject("infos");
+
+                        if(null != infoJson) {
+                            sourceKey = infoJson.getString(dto.objInfoCode.getValue());
+                        }
+                        obj_key.put(objId, sourceKey);
+                    }
+                }else {
+                    app.showTipsWarn("结束。查询到数据平台对象数量为0。");
+                }
+            }else {
+                app.showTipsError("请求数据平台数据出错:" + respJson.getString("ResultMsg"));
+            }
+        }
+
+        return obj_key;
+    }
+
+    /**
      * 校验文件服务From是否可访问
      * @return
      */

+ 7 - 0
src/main/java/com/persagy/filemove/util/HttpTools.java

@@ -9,6 +9,7 @@ import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.entity.FileEntity;
 import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.entity.StringEntity;
@@ -106,6 +107,12 @@ public class HttpTools {
 		return sendRequest(httpPost);
 	}
 
+	public static String httpPostRequest(String url, byte[] bytes) throws Exception {
+		HttpPost httpPost = new HttpPost(url);
+		httpPost.setEntity(new ByteArrayEntity(bytes));
+		return sendRequest(httpPost);
+	}
+
 	public static String httpPostRequest(String url, File file) throws Exception {
 		HttpPost httpPost = new HttpPost(url);
 		httpPost.setEntity(new FileEntity(file));

+ 13 - 0
src/main/resources/log4j.properties

@@ -0,0 +1,13 @@
+log4j.rootLogger=INFO, console, file
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n
+
+log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.file.File=logs/log.log
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+
+log4j.appender.A3.MaxFileSize=5120KB
+log4j.appender.A3.MaxBackupIndex=10
+log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n