This is an automated email from the ASF dual-hosted git repository.

zhangzicheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 10d466cfc [ISSUE #3740] add websocket upload file example and 
integrated test (#3798)
10d466cfc is described below

commit 10d466cfc5f1bd0e37d3d11e3e5b070528a775e1
Author: Haitao Ma(jimmy) <[email protected]>
AuthorDate: Fri Aug 5 00:23:12 2022 +0800

    [ISSUE #3740] add websocket upload file example and integrated test (#3798)
    
    * feat:add websocket upload file example and integrated test
    
    * feat:fix
    
    * feat:fix file with checkstyle problem
    
    * feat:fix checkstyle problem
    
    * feat:fix websocket-integrated-test
    
    * formate
    
    * feat:format
    
    Co-authored-by: mahaitao617 <[email protected]>
---
 .../examples/websocket/service/SaveFile.java       | 25 +++++++
 .../examples/websocket/service/SaveFileImpl.java   | 50 +++++++++++++
 .../examples/websocket/ws/UpLoadController.java    | 82 ++++++++++++++++++++++
 .../websocket/config/WsSessionManager.java         |  4 ++
 .../websocket/controller/TestHttpController.java   | 22 ++++++
 .../websocket/config/WebSocketConfiguration.java   | 11 +++
 .../websocket/handler/UploadFileHandler.java       | 40 +++++++++++
 .../test/websocket/UploadControllerTest.java       | 65 +++++++++++++++++
 8 files changed, 299 insertions(+)

diff --git 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/service/SaveFile.java
 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/service/SaveFile.java
new file mode 100644
index 000000000..207863c33
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/service/SaveFile.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.examples.websocket.service;
+
+import java.util.Map;
+
+public interface SaveFile {
+
+    boolean saveFileFromBytes(byte[] b, Map<String, Object> map);
+}
diff --git 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/service/SaveFileImpl.java
 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/service/SaveFileImpl.java
new file mode 100644
index 000000000..559b7db72
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/service/SaveFileImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.examples.websocket.service;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Map;
+
+@Service
+public class SaveFileImpl implements SaveFile {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(SaveFileImpl.class);
+
+    @Override
+    public boolean saveFileFromBytes(final byte[] b, final Map<String, Object> 
map) {
+        //从map中获取file对象
+        File file = (File) map.get("file");
+        //判断路径是否存在,不存在就创建
+        if (!file.getParentFile().exists()) {
+            file.getParentFile().mkdirs();
+        }
+
+        try (FileOutputStream fstream = new FileOutputStream(file, true)) {
+            fstream.write(b);
+        } catch (Exception e) {
+            LOG.error("saveFileFromBytes error", e);
+            return false;
+        }
+        return true;
+    }
+}
diff --git 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/ws/UpLoadController.java
 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/ws/UpLoadController.java
new file mode 100644
index 000000000..8258808b4
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-annotation-websocket/src/main/java/org/apache/shenyu/examples/websocket/ws/UpLoadController.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.examples.websocket.ws;
+
+import 
org.apache.shenyu.client.spring.websocket.annotation.ShenyuSpringWebSocketClient;
+import org.apache.shenyu.examples.websocket.service.SaveFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+
+@ShenyuSpringWebSocketClient("/upload")
+@ServerEndpoint("/upload")
+@Controller
+public class UpLoadController {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(UpLoadController.class);
+
+    @Autowired
+    private SaveFile saveFile;
+
+    @OnOpen
+    public void onOpen(final Session session) {
+        LOG.info("connect successful");
+    }
+
+    /**
+     * connect close.
+     *
+     * @param session used for verify
+     */
+    @OnClose
+    public void onClose(final Session session) {
+        LOG.info("connect1 closed");
+    }
+
+    @OnMessage
+    public void onMessage(final String message, final Session session) {
+        try {
+            session.getBasicRemote().sendText("ok");
+        } catch (IOException e) {
+            LOG.error("UpLoadController onMessage error", e);
+        }
+    }
+
+    @OnMessage
+    public void onMessage(final byte[] message, final Session session) {
+        File file = (File) session.getUserProperties().get("file");
+        try {
+            ConcurrentHashMap map = new ConcurrentHashMap<>();
+            map.put("file", file);
+            saveFile.saveFileFromBytes(message, map);
+            session.getBasicRemote().sendText("ok");
+        } catch (Exception e) {
+            LOG.error("UpLoadController onMessage", e);
+        }
+    }
+}
diff --git 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WsSessionManager.java
 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WsSessionManager.java
index eda516312..6392fe80a 100644
--- 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WsSessionManager.java
+++ 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WsSessionManager.java
@@ -18,6 +18,8 @@
 package org.apache.shenyu.examples.websocket.config;
 
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.web.socket.WebSocketSession;
 
 import java.io.IOException;
@@ -28,6 +30,8 @@ import java.util.concurrent.ConcurrentHashMap;
  */
 @Slf4j
 public class WsSessionManager {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(WsSessionManager.class);
     /**
      * save the connection session.
      */
diff --git 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/controller/TestHttpController.java
 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/controller/TestHttpController.java
index 510cb1668..870cd6bc5 100644
--- 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/controller/TestHttpController.java
+++ 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-native-websocket/src/main/java/org/apache/shenyu/examples/websocket/controller/TestHttpController.java
@@ -21,8 +21,12 @@ import 
org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
 import org.apache.shenyu.examples.common.aop.Log;
 import org.apache.shenyu.examples.websocket.config.WsSessionManager;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.socket.BinaryMessage;
 import org.springframework.web.socket.TextMessage;
 import org.springframework.web.socket.WebSocketSession;
 
@@ -47,4 +51,22 @@ public class TestHttpController {
         webSocketSession.sendMessage(new TextMessage(msg));
         return "Message sent successfully";
     }
+
+    @PostMapping(value = "/upload")
+    @Log
+    public @ResponseBody
+    Object file(String token, @RequestParam("file") final MultipartFile file) {
+        try {
+            WebSocketSession webSocketSession = WsSessionManager.get(token);
+            if (webSocketSession == null) {
+                return "User login has expired";
+            }
+            if (file.getOriginalFilename().endsWith(".bin")) {
+                webSocketSession.sendMessage(new 
BinaryMessage(file.getBytes()));
+            }
+        } catch (Exception e) {
+
+        }
+        return "ok";
+    }
 }
\ No newline at end of file
diff --git 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-reactive-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WebSocketConfiguration.java
 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-reactive-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WebSocketConfiguration.java
index 7084d095a..d19387385 100644
--- 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-reactive-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WebSocketConfiguration.java
+++ 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-reactive-websocket/src/main/java/org/apache/shenyu/examples/websocket/config/WebSocketConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.examples.websocket.config;
 
 import 
org.apache.shenyu.client.spring.websocket.annotation.ShenyuSpringWebSocketClient;
 import org.apache.shenyu.examples.websocket.handler.EchoHandler;
+import org.apache.shenyu.examples.websocket.handler.UploadFileHandler;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.Ordered;
@@ -53,6 +54,16 @@ public class WebSocketConfiguration {
         return mapping;
     }
 
+    @Bean
+    public HandlerMapping websocketFileMapping(final UploadFileHandler 
uploadFileHandler){
+        final Map<String, WebSocketHandler> map = new HashMap<>(1);
+        map.put("/websocket/upload", uploadFileHandler);
+        final SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
+        mapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
+        mapping.setUrlMap(map);
+        return mapping;
+    }
+
     /**
      * Handler adapter web socket handler adapter.
      *
diff --git 
a/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-reactive-websocket/src/main/java/org/apache/shenyu/examples/websocket/handler/UploadFileHandler.java
 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-reactive-websocket/src/main/java/org/apache/shenyu/examples/websocket/handler/UploadFileHandler.java
new file mode 100644
index 000000000..55c240e22
--- /dev/null
+++ 
b/shenyu-examples/shenyu-examples-websocket/shenyu-example-spring-reactive-websocket/src/main/java/org/apache/shenyu/examples/websocket/handler/UploadFileHandler.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.examples.websocket.handler;
+
+import org.apache.shenyu.examples.common.aop.Log;
+import org.springframework.lang.NonNull;
+import org.springframework.stereotype.Component;
+import org.springframework.web.reactive.socket.WebSocketHandler;
+import org.springframework.web.reactive.socket.WebSocketSession;
+import reactor.core.publisher.Mono;
+
+
+@Component
+public class UploadFileHandler implements WebSocketHandler {
+
+
+    @Override
+    @NonNull
+    @Log
+    public Mono<Void> handle(final WebSocketSession session) {
+        return session.send(
+                session.receive()
+                        .map(msg -> 
session.binaryMessage(msg.getNativeMessage())));
+    }
+}
diff --git 
a/shenyu-integrated-test/shenyu-integrated-test-websocket/src/test/java/org/apache/shenyu/integrated/test/websocket/UploadControllerTest.java
 
b/shenyu-integrated-test/shenyu-integrated-test-websocket/src/test/java/org/apache/shenyu/integrated/test/websocket/UploadControllerTest.java
new file mode 100644
index 000000000..9250230d5
--- /dev/null
+++ 
b/shenyu-integrated-test/shenyu-integrated-test-websocket/src/test/java/org/apache/shenyu/integrated/test/websocket/UploadControllerTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.integrated.test.websocket;
+
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.RequestBody;
+import org.apache.shenyu.integratedtest.common.AbstractPluginDataInit;
+import org.apache.shenyu.integratedtest.common.helper.HttpHelper;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.assertEquals;
+
+public class UploadControllerTest extends AbstractPluginDataInit {
+
+    private static final String FILE_PATH = "1.bin";
+
+    @BeforeAll
+    public static void setup() throws IOException {
+        Path pathOne = Paths.get(FILE_PATH);
+        if (!Files.exists(pathOne)) {
+            Files.createFile(pathOne);
+        }
+        BufferedWriter bufferedWriterOne = Files.newBufferedWriter(pathOne);
+        bufferedWriterOne.write("111");
+        bufferedWriterOne.flush();
+        bufferedWriterOne.close();
+    }
+
+    @Test
+    public void testWebsocketUpLoad() throws IOException {
+        File fileOne = new File(FILE_PATH);
+        RequestBody fileBodyOne = 
RequestBody.create(MediaType.parse("multipart/form-data"), fileOne);
+        MultipartBody requestBody = new MultipartBody.Builder()
+                .setType(MultipartBody.FORM)
+                .addFormDataPart("file", FILE_PATH, fileBodyOne)
+                .build();
+        final String response = 
HttpHelper.INSTANCE.postGateway("/ws-native/ws/upload", requestBody, 
String.class);
+        assertEquals(response, "ok");
+    }
+
+}

Reply via email to