diff --git a/pom.xml b/pom.xml
index 5a95fbcc..68328396 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.sonic
sonic-agent
- v1.2.0-beta1
+ v1.2.0-beta2
jar
@@ -35,15 +35,22 @@
Java-WebSocket
1.5.2
-
+
- org.springframework.boot
- spring-boot-starter-actuator
+ io.netty
+ netty-all
+ 4.1.52.Final
-
+
- org.springframework.boot
- spring-boot-starter-amqp
+ org.jboss.marshalling
+ jboss-marshalling
+ 2.0.10.Final
+
+
+ org.jboss.marshalling
+ jboss-marshalling-serial
+ 2.0.10.Final
diff --git a/src/main/java/com/sonic/agent/AgentApplication.java b/src/main/java/com/sonic/agent/AgentApplication.java
index d4c964ee..055ef3ce 100644
--- a/src/main/java/com/sonic/agent/AgentApplication.java
+++ b/src/main/java/com/sonic/agent/AgentApplication.java
@@ -1,16 +1,30 @@
package com.sonic.agent;
+import com.sonic.agent.tools.SpringTool;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
/**
* @author ZhouYiXun
* @des Agent端启动类
* @date 2021/08/16 19:26
*/
+@Import(SpringTool.class)
@SpringBootApplication
public class AgentApplication {
+ @Value("${sonic.agent.port}")
+ private int port;
+
public static void main(String[] args) {
SpringApplication.run(AgentApplication.class, args);
}
+
+ @Bean
+ public TomcatServletWebServerFactory servletContainer(){
+ return new TomcatServletWebServerFactory(port) ;
+ }
}
diff --git a/src/main/java/com/sonic/agent/automation/RemoteDebugDriver.java b/src/main/java/com/sonic/agent/automation/RemoteDebugDriver.java
index 9024f7b7..628e0a84 100644
--- a/src/main/java/com/sonic/agent/automation/RemoteDebugDriver.java
+++ b/src/main/java/com/sonic/agent/automation/RemoteDebugDriver.java
@@ -11,6 +11,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -25,13 +26,14 @@
* @des
* @date 2021/10/29 0:28
*/
+@ConditionalOnProperty(value = "modules.webview.enable", havingValue = "true")
@Configuration
public class RemoteDebugDriver {
private static final Logger logger = LoggerFactory.getLogger(RemoteDebugDriver.class);
private static String chromePath;
public static int port = 0;
public static WebDriver webDriver;
- @Value("${sonic.chrome.path}")
+ @Value("${modules.webview.chrome-driver-path}")
private String path;
@Bean
@@ -58,6 +60,7 @@ public ServletRegistrationBean proxyServletRegistration() {
@Bean
@DependsOn(value = "setChromePath")
public static void startChromeDriver() {
+ logger.info("开启webview相关功能");
try {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
ChromeOptions chromeOptions = new ChromeOptions();
diff --git a/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java b/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java
index 3bcc0fb9..a899b0cd 100644
--- a/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java
+++ b/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java
@@ -5,6 +5,7 @@
import com.sonic.agent.tools.DownImageTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
@@ -18,7 +19,8 @@
* @des ADB工具类
* @date 2021/08/16 19:26
*/
-@DependsOn({"androidThreadPoolInit", "rabbitMsgInit"})
+@ConditionalOnProperty(value = "modules.android.enable", havingValue = "true")
+@DependsOn({"androidThreadPoolInit", "nettyMsgInit"})
@Component
public class AndroidDeviceBridgeTool {
private static final Logger logger = LoggerFactory.getLogger(AndroidDeviceBridgeTool.class);
@@ -26,6 +28,7 @@ public class AndroidDeviceBridgeTool {
private static AndroidDeviceStatusListener androidDeviceStatusListener = new AndroidDeviceStatusListener();
public AndroidDeviceBridgeTool() {
+ logger.info("开启安卓相关功能");
init();
}
@@ -369,7 +372,7 @@ public static void pushToCamera(IDevice iDevice, String url) {
* @des 开启miniCap服务
* @date 2021/8/16 20:04
*/
- public static void startMiniCapServer(IDevice iDevice, int quality, int screen, Session session) throws AdbCommandRejectedException, IOException, SyncException, TimeoutException {
+ public static void startMiniCapServer(IDevice iDevice, String quality, int screen, Session session) throws AdbCommandRejectedException, IOException, SyncException, TimeoutException {
//先删除原有路径下的文件,防止上次出错后停止,再次打开会报错的情况
executeCommand(iDevice, "rm -rf /data/local/tmp/minicap*");
//获取cpu信息
@@ -386,11 +389,18 @@ public static void startMiniCapServer(IDevice iDevice, int quality, int screen,
//给文件权限
executeCommand(iDevice, "chmod 777 /data/local/tmp/" + miniCapFileName);
String size = getScreenSize(iDevice);
- String vSize = Integer.parseInt(size.substring(0, size.indexOf("x"))) / 2 + "x" + Integer.parseInt(size.substring(size.indexOf("x") + 1)) / 2;
+ String vSize;
+ int q = 80;
+ if (quality.equals("fixed")) {
+ vSize = size;
+ q = 40;
+ } else {
+ vSize = "800x800";
+ }
try {
//开始启动
- iDevice.executeShellCommand(String.format("LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/%s -Q " + quality + " -P %s@%s/%d",
- miniCapFileName, size, vSize, screen), new IShellOutputReceiver() {
+ iDevice.executeShellCommand(String.format("LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/%s -Q %d -S -P %s@%s/%d",
+ miniCapFileName, q, size, vSize, screen), new IShellOutputReceiver() {
@Override
public void addOutput(byte[] bytes, int i, int i1) {
String res = new String(bytes, i, i1);
diff --git a/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceLocalStatus.java b/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceLocalStatus.java
index 79260752..053c4300 100644
--- a/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceLocalStatus.java
+++ b/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceLocalStatus.java
@@ -3,8 +3,7 @@
import com.alibaba.fastjson.JSONObject;
import com.sonic.agent.interfaces.DeviceStatus;
import com.sonic.agent.maps.AndroidDeviceManagerMap;
-import com.sonic.agent.rabbitmq.RabbitMQThread;
-import com.sonic.agent.tools.AgentTool;
+import com.sonic.agent.netty.NettyThreadPool;
/**
* @author ZhouYiXun
@@ -26,7 +25,7 @@ public static void send(String udId, String status) {
deviceDetail.put("msg", "deviceDetail");
deviceDetail.put("udId", udId);
deviceDetail.put("status", status);
- RabbitMQThread.send(deviceDetail);
+ NettyThreadPool.send(deviceDetail);
}
/**
diff --git a/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceStatusListener.java b/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceStatusListener.java
index cc07fc2e..25c26c88 100644
--- a/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceStatusListener.java
+++ b/src/main/java/com/sonic/agent/bridge/android/AndroidDeviceStatusListener.java
@@ -5,8 +5,7 @@
import com.android.ddmlib.IDevice;
import com.sonic.agent.interfaces.PlatformType;
import com.sonic.agent.maps.AndroidDeviceManagerMap;
-import com.sonic.agent.rabbitmq.RabbitMQThread;
-import com.sonic.agent.tools.AgentTool;
+import com.sonic.agent.netty.NettyThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,7 +36,7 @@ private void send(IDevice device) {
deviceDetail.put("size", AndroidDeviceBridgeTool.getScreenSize(device));
deviceDetail.put("cpu", device.getProperty(IDevice.PROP_DEVICE_CPU_ABI));
deviceDetail.put("manufacturer", device.getProperty(IDevice.PROP_DEVICE_MANUFACTURER));
- RabbitMQThread.send(deviceDetail);
+ NettyThreadPool.send(deviceDetail);
}
@Override
diff --git a/src/main/java/com/sonic/agent/bridge/ios/LibIMobileDeviceTool.java b/src/main/java/com/sonic/agent/bridge/ios/LibIMobileDeviceTool.java
index 815acaea..83cc329e 100644
--- a/src/main/java/com/sonic/agent/bridge/ios/LibIMobileDeviceTool.java
+++ b/src/main/java/com/sonic/agent/bridge/ios/LibIMobileDeviceTool.java
@@ -2,13 +2,14 @@
import com.alibaba.fastjson.JSONObject;
import com.sonic.agent.maps.IOSDeviceManagerMap;
-import com.sonic.agent.rabbitmq.RabbitMQThread;
+import com.sonic.agent.netty.NettyThreadPool;
import com.sonic.agent.tools.ProcessCommandTool;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
@@ -17,7 +18,8 @@
import java.io.LineNumberReader;
import java.util.List;
-@DependsOn({"iOSThreadPoolInit", "rabbitMsgInit"})
+@ConditionalOnProperty(value = "modules.ios.enable", havingValue = "true")
+@DependsOn({"iOSThreadPoolInit", "nettyMsgInit"})
@Component
public class LibIMobileDeviceTool {
private static final Logger logger = LoggerFactory.getLogger(LibIMobileDeviceTool.class);
@@ -27,6 +29,7 @@ public LibIMobileDeviceTool() {
}
public static void init() {
+ logger.info("开启iOS相关功能");
if (!System.getProperty("os.name").contains("Mac")) {
logger.info("iOS设备监听已关闭");
return;
@@ -67,7 +70,7 @@ public static void sendDisConnectStatus(String udId) {
deviceStatus.put("serialNum", udId);
deviceStatus.put("status", "DISCONNECTED");
logger.info("iOS设备:" + udId + " 下线!");
- RabbitMQThread.send(deviceStatus);
+ NettyThreadPool.send(deviceStatus);
IOSDeviceManagerMap.getMap().remove(udId);
// wdaKill(udid);
// relayKill(udid);
@@ -87,7 +90,7 @@ public static void sendOnlineStatus(String udId) {
deviceStatus.put("cpu", getCpuByUdId(udId));
deviceStatus.put("manufacturer", "APPLE");
logger.info("iOS设备:" + udId + " 上线!");
- RabbitMQThread.send(deviceStatus);
+ NettyThreadPool.send(deviceStatus);
IOSDeviceManagerMap.getMap().remove(udId);
}
diff --git a/src/main/java/com/sonic/agent/netty/MarshallingCodeCFactory.java b/src/main/java/com/sonic/agent/netty/MarshallingCodeCFactory.java
new file mode 100644
index 00000000..9a33038a
--- /dev/null
+++ b/src/main/java/com/sonic/agent/netty/MarshallingCodeCFactory.java
@@ -0,0 +1,26 @@
+package com.sonic.agent.netty;
+
+import io.netty.handler.codec.marshalling.*;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.Marshalling;
+import org.jboss.marshalling.MarshallingConfiguration;
+
+public final class MarshallingCodeCFactory {
+ public static MarshallingDecoder buildMarshallingDecoder() {
+ final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
+ final MarshallingConfiguration configuration = new MarshallingConfiguration();
+ configuration.setVersion(5);
+ UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
+ MarshallingDecoder decoder = new MarshallingDecoder(provider, 10*1024*1024);
+ return decoder;
+ }
+
+ public static MarshallingEncoder buildMarshallingEncoder() {
+ final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
+ final MarshallingConfiguration configuration = new MarshallingConfiguration();
+ configuration.setVersion(5);
+ MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
+ MarshallingEncoder encoder = new MarshallingEncoder(provider);
+ return encoder;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/sonic/agent/netty/NettyClient.java b/src/main/java/com/sonic/agent/netty/NettyClient.java
new file mode 100644
index 00000000..f168e79b
--- /dev/null
+++ b/src/main/java/com/sonic/agent/netty/NettyClient.java
@@ -0,0 +1,68 @@
+package com.sonic.agent.netty;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class NettyClient implements ApplicationRunner {
+ private final Logger logger = LoggerFactory.getLogger(NettyClient.class);
+ private NioEventLoopGroup group = new NioEventLoopGroup(4);
+ private Channel channel;
+ private Bootstrap bootstrap;
+ @Value("${sonic.server.transport-port}")
+ private int serverPort;
+ @Value("${sonic.server.host}")
+ private String serverHost;
+ @Value("${sonic.agent.port}")
+ private int agentPort;
+ @Value("${sonic.agent.host}")
+ private String agentHost;
+ @Value("${sonic.agent.key}")
+ private String key;
+ @Value("${spring.version}")
+ private String version;
+
+ @Override
+ public void run(ApplicationArguments args) {
+ group = new NioEventLoopGroup();
+ bootstrap = new Bootstrap()
+ .group(group)
+ .option(ChannelOption.TCP_NODELAY, true)
+ .channel(NioSocketChannel.class)
+ .handler(new ChannelInitializer() {
+ @Override
+ protected void initChannel(SocketChannel socketChannel) throws Exception {
+ socketChannel.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
+ socketChannel.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
+ socketChannel.pipeline().addLast(new SecurityHandler(NettyClient.this, key, agentHost, agentPort, version));
+ }
+ });
+ doConnect();
+ }
+
+ protected void doConnect() {
+ if (channel != null && channel.isActive()) {
+ return;
+ }
+ ChannelFuture future = bootstrap.connect(serverHost, serverPort);
+ future.addListener((ChannelFutureListener) futureListener -> {
+ if (futureListener.isSuccess()) {
+ channel = futureListener.channel();
+ } else {
+ logger.info("连接到服务器{}:{}失败!10s后重连...", serverHost, serverPort);
+ futureListener.channel().eventLoop().schedule(() -> doConnect(), 10, TimeUnit.SECONDS);
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/sonic/agent/netty/NettyClientHandler.java b/src/main/java/com/sonic/agent/netty/NettyClientHandler.java
new file mode 100644
index 00000000..7eee6ae6
--- /dev/null
+++ b/src/main/java/com/sonic/agent/netty/NettyClientHandler.java
@@ -0,0 +1,126 @@
+package com.sonic.agent.netty;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.android.ddmlib.IDevice;
+import com.sonic.agent.automation.AndroidStepHandler;
+import com.sonic.agent.bridge.android.AndroidDeviceBridgeTool;
+import com.sonic.agent.bridge.ios.LibIMobileDeviceTool;
+import com.sonic.agent.interfaces.PlatformType;
+import com.sonic.agent.maps.AndroidPasswordMap;
+import com.sonic.agent.maps.HandlerMap;
+import com.sonic.agent.tests.AndroidTests;
+import com.sonic.agent.tools.SpringTool;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.websocket.Session;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class NettyClientHandler extends ChannelInboundHandlerAdapter {
+ private final Logger logger = LoggerFactory.getLogger(NettyClientHandler.class);
+ private static Map sessionMap = new ConcurrentHashMap();
+ private NettyClient nettyClient;
+ public static Channel channel = null;
+ private AndroidTests androidTests = SpringTool.getBean(AndroidTests.class);
+
+ public NettyClientHandler(NettyClient nettyClient, Channel channel) {
+ this.nettyClient = nettyClient;
+ this.channel = channel;
+ }
+
+ @Override
+ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
+ logger.info("Agent:{} 连接到服务器 {} 成功!", ctx.channel().localAddress(), ctx.channel().remoteAddress());
+ }
+
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+ JSONObject jsonObject = JSON.parseObject((String) msg);
+ logger.info("Agent:{} 收到服务器 {} 消息: {}", ctx.channel().localAddress(), ctx.channel().remoteAddress(), jsonObject);
+ NettyThreadPool.cachedThreadPool.execute(() -> {
+ switch (jsonObject.getString("msg")) {
+ case "reboot":
+ if (jsonObject.getInteger("platform") == PlatformType.ANDROID) {
+ IDevice rebootDevice = AndroidDeviceBridgeTool.getIDeviceByUdId(jsonObject.getString("udId"));
+ if (rebootDevice != null) {
+ AndroidDeviceBridgeTool.reboot(rebootDevice);
+ }
+ }
+ if (jsonObject.getInteger("platform") == PlatformType.IOS) {
+ if (LibIMobileDeviceTool.getDeviceList().contains(jsonObject.getString("udId"))) {
+ LibIMobileDeviceTool.reboot(jsonObject.getString("udId"));
+ }
+ }
+ break;
+ case "heartBeat":
+ JSONObject heartBeat = new JSONObject();
+ heartBeat.put("msg", "heartBeat");
+ heartBeat.put("status", "alive");
+ NettyThreadPool.send(heartBeat);
+ break;
+ case "runStep":
+ if (jsonObject.getInteger("pf") == PlatformType.ANDROID) {
+ AndroidPasswordMap.getMap().put(jsonObject.getString("udId")
+ , jsonObject.getString("pwd"));
+ AndroidStepHandler androidStepHandler = HandlerMap.getAndroidMap().get(jsonObject.getString("sessionId"));
+ androidStepHandler.resetResultDetailStatus();
+ androidStepHandler.setGlobalParams(jsonObject.getJSONObject("gp"));
+ List steps = jsonObject.getJSONArray("steps").toJavaList(JSONObject.class);
+ for (JSONObject step : steps) {
+ try {
+ androidStepHandler.runStep(step);
+ } catch (Throwable e) {
+ break;
+ }
+ }
+ androidStepHandler.sendStatus();
+ }
+ break;
+ case "suite":
+ JSONObject device = jsonObject.getJSONObject("device");
+ if (AndroidDeviceBridgeTool.getIDeviceByUdId(device.getString("udId")) != null) {
+ AndroidPasswordMap.getMap().put(device.getString("udId")
+ , device.getString("password"));
+ try {
+ androidTests.run(jsonObject);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ //取消本次测试
+ JSONObject subResultCount = new JSONObject();
+ subResultCount.put("rid", jsonObject.getInteger("rid"));
+ NettyThreadPool.send(subResultCount);
+ }
+ break;
+ }
+ });
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ logger.info("服务器: {} 发生异常 {}", ctx.channel().remoteAddress(), cause.fillInStackTrace());
+ ctx.close();
+ }
+
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ logger.info("服务器: {} 连接断开", ctx.channel().remoteAddress());
+ NettyThreadPool.isPassSecurity = false;
+ if (channel != null) {
+ channel.close();
+ }
+ channel = null;
+ nettyClient.doConnect();
+ }
+
+ public static Map getMap() {
+ return sessionMap;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/sonic/agent/netty/NettyThreadPool.java b/src/main/java/com/sonic/agent/netty/NettyThreadPool.java
new file mode 100644
index 00000000..1b4a311d
--- /dev/null
+++ b/src/main/java/com/sonic/agent/netty/NettyThreadPool.java
@@ -0,0 +1,63 @@
+package com.sonic.agent.netty;
+
+import com.alibaba.fastjson.JSONObject;
+import com.sonic.agent.tools.AgentTool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+
+@Configuration
+public class NettyThreadPool {
+ private final Logger logger = LoggerFactory.getLogger(NettyThreadPool.class);
+ private static LinkedBlockingQueue dataQueue;
+ public static ExecutorService cachedThreadPool;
+ public static boolean isPassSecurity = false;
+ private static Future> read = null;
+
+ @Bean
+ public void nettyMsgInit() {
+ cachedThreadPool = Executors.newCachedThreadPool();
+ dataQueue = new LinkedBlockingQueue<>();
+ }
+
+ public static void send(JSONObject jsonObject) {
+ dataQueue.offer(jsonObject);
+ }
+
+ public static void readQueue() {
+ if (read != null) {
+ isPassSecurity = false;
+ while (!read.isDone()) {
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ isPassSecurity = true;
+ read = cachedThreadPool.submit(() -> {
+ while (isPassSecurity) {
+ try {
+ if (NettyClientHandler.channel != null) {
+ if (!dataQueue.isEmpty()) {
+ JSONObject m = dataQueue.poll();
+ m.put("agentId", AgentTool.agentId);
+ NettyClientHandler.channel.writeAndFlush(m.toJSONString());
+ }
+ } else {
+ Thread.sleep(10000);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+}
diff --git a/src/main/java/com/sonic/agent/netty/SecurityHandler.java b/src/main/java/com/sonic/agent/netty/SecurityHandler.java
new file mode 100644
index 00000000..ce9f1fb8
--- /dev/null
+++ b/src/main/java/com/sonic/agent/netty/SecurityHandler.java
@@ -0,0 +1,76 @@
+package com.sonic.agent.netty;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sonic.agent.tools.AgentTool;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SecurityHandler extends ChannelInboundHandlerAdapter {
+ private final Logger logger = LoggerFactory.getLogger(SecurityHandler.class);
+ private NettyClient nettyClient;
+ public static Channel channel = null;
+ private String key;
+ private String version;
+ private String host;
+ private int port;
+
+ public SecurityHandler(NettyClient nettyClient, String key, String host, int port, String version) {
+ this.nettyClient = nettyClient;
+ this.key = key;
+ this.host = host;
+ this.port = port;
+ this.version = version;
+ }
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ logger.info("Agent:{} 请求连接到服务器 {} !", ctx.channel().localAddress(), ctx.channel().remoteAddress());
+ JSONObject auth = new JSONObject();
+ auth.put("msg", "auth");
+ auth.put("key", key);
+ ctx.channel().writeAndFlush(auth.toJSONString());
+ }
+
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+ JSONObject jsonMsg = JSON.parseObject((String) msg);
+ logger.info("Agent:{} 收到服务器 {} 返回验证消息: {}", ctx.channel().localAddress(), ctx.channel().remoteAddress(), jsonMsg);
+ if (jsonMsg.getString("msg") != null && jsonMsg.getString("msg").equals("auth") && jsonMsg.getString("result").equals("pass")) {
+ logger.info("服务器认证通过!");
+ logger.info("当前sonic-agent版本为:" + version);
+ AgentTool.agentId = jsonMsg.getInteger("id");
+ ctx.pipeline().remove(SecurityHandler.class);
+ channel = ctx.channel();
+ JSONObject agentInfo = new JSONObject();
+ agentInfo.put("msg", "agentInfo");
+ agentInfo.put("agentId", jsonMsg.getInteger("id"));
+ agentInfo.put("port", port);
+ agentInfo.put("version", version);
+ agentInfo.put("systemType", System.getProperty("os.name"));
+ agentInfo.put("host", host);
+ channel.writeAndFlush(agentInfo.toJSONString());
+ NettyThreadPool.readQueue();
+ ctx.pipeline().addLast(new NettyClientHandler(nettyClient, channel));
+ } else {
+ logger.info("服务器认证不通过!");
+ NettyThreadPool.isPassSecurity = false;
+ ctx.close();
+ }
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ logger.info("Agent: {} 发生异常 {}", ctx.channel().remoteAddress(), cause.getMessage());
+ }
+
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ logger.info("Agent: {} 连接断开", ctx.channel().remoteAddress());
+ NettyThreadPool.isPassSecurity = false;
+ ctx.close();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/sonic/agent/rabbitmq/RabbitListenerConfig.java b/src/main/java/com/sonic/agent/rabbitmq/RabbitListenerConfig.java
deleted file mode 100644
index b9143466..00000000
--- a/src/main/java/com/sonic/agent/rabbitmq/RabbitListenerConfig.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.sonic.agent.rabbitmq;
-
-import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
-import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.messaging.converter.MappingJackson2MessageConverter;
-import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
-import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;
-
-/**
- * @author ZhouYiXun
- * @des rabbitmq监听配置
- * @date 2021/8/23 19:26
- */
-@Configuration
-public class RabbitListenerConfig implements RabbitListenerConfigurer {
- @Override
- public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) {
- rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
- }
-
- @Bean
- MessageHandlerMethodFactory messageHandlerMethodFactory() {
- DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();
- messageHandlerMethodFactory.setMessageConverter(mappingJackson2MessageConverter());
- return messageHandlerMethodFactory;
- }
-
- @Bean
- public MappingJackson2MessageConverter mappingJackson2MessageConverter() {
- return new MappingJackson2MessageConverter();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/sonic/agent/rabbitmq/RabbitMQThread.java b/src/main/java/com/sonic/agent/rabbitmq/RabbitMQThread.java
deleted file mode 100644
index 9b3ab65c..00000000
--- a/src/main/java/com/sonic/agent/rabbitmq/RabbitMQThread.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.sonic.agent.rabbitmq;
-
-import com.alibaba.fastjson.JSONObject;
-import com.sonic.agent.tools.AgentTool;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.amqp.rabbit.core.RabbitTemplate;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.stereotype.Component;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-
-@Component
-public class RabbitMQThread {
- private static LinkedBlockingQueue msgQueue;
- public static ExecutorService cachedThreadPool;
- public static boolean isPass = false;
- @Autowired
- private RabbitTemplate rabbitTemplate;
-
- @Bean
- public void rabbitMsgInit() {
- cachedThreadPool = Executors.newCachedThreadPool();
- msgQueue = new LinkedBlockingQueue<>();
- }
-
- public static void send(JSONObject jsonObject) {
- msgQueue.offer(jsonObject);
- }
-
- @Bean
- public void sendToRabbitMQ() {
- cachedThreadPool.submit(() -> {
- while (true) {
- if (!isPass) {
- Thread.sleep(5000);
- continue;
- }
- try {
- if (!msgQueue.isEmpty()) {
- JSONObject m = msgQueue.poll();
- m.put("agentId", AgentTool.agentId);
- rabbitTemplate.convertAndSend("DataExchange", "data"
- , m);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- });
- }
-}
diff --git a/src/main/java/com/sonic/agent/rabbitmq/RabbitQueueConfig.java b/src/main/java/com/sonic/agent/rabbitmq/RabbitQueueConfig.java
deleted file mode 100644
index d4785165..00000000
--- a/src/main/java/com/sonic/agent/rabbitmq/RabbitQueueConfig.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.sonic.agent.rabbitmq;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.amqp.core.*;
-import org.springframework.amqp.rabbit.connection.ConnectionFactory;
-import org.springframework.amqp.rabbit.core.RabbitTemplate;
-import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-@Configuration
-public class RabbitQueueConfig {
- private final Logger logger = LoggerFactory.getLogger(RabbitQueueConfig.class);
- private String queueId;
- @Value("${sonic.agent.key}")
- private String key;
-
- @Bean
- public String queueId() {
- queueId = UUID.randomUUID().toString();
- return queueId;
- }
-
- @Bean("MsgDirectExchange")
- public DirectExchange MsgDirectExchange() {
- return new DirectExchange("MsgDirectExchange", true, false);
- }
-
- @Bean("MsgQueue")
- public Queue MsgQueue() {
- return new Queue("MsgQueue-" + key, true);
- }
-
- @Bean("TaskDirectExchange")
- public DirectExchange TaskDirectExchange() {
- return new DirectExchange("TaskDirectExchange", true, false);
- }
-
- @Bean("TaskQueue")
- public Queue TaskQueue() {
- Map params = new HashMap<>();
- params.put("x-message-ttl", 1000 * 60 * 5);
- params.put("x-dead-letter-exchange", "MsgDirectExchange");
- params.put("x-dead-letter-routing-key", key);
- return QueueBuilder.durable("TaskQueue-" + key).withArguments(params).build();
- }
-
- @Bean
- public Binding bindingMsgDirect(@Qualifier("MsgQueue") Queue queue,
- @Qualifier("MsgDirectExchange") DirectExchange exchange) {
- return BindingBuilder.bind(queue).to(exchange).with(key);
- }
-
- @Bean
- public Binding bindingTaskDirect(@Qualifier("TaskQueue") Queue queue,
- @Qualifier("TaskDirectExchange") DirectExchange exchange) {
- return BindingBuilder.bind(queue).to(exchange).with(key);
- }
-
- @Bean
- public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
- RabbitTemplate rabbitTemplate = new RabbitTemplate();
- rabbitTemplate.setConnectionFactory(connectionFactory);
- rabbitTemplate.setMandatory(true);
- rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
- rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
- if (!ack) {
- logger.error("ConfirmCallback: 相关数据:" + correlationData + "\n" +
- "确认情况:" + false + "\n" +
- "原因:" + cause);
- }
- });
-
- rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) ->
- logger.info("ConfirmCallback: 消息:" + message + "\n" +
- "回应码:" + replyCode + "\n" +
- "回应信息:" + replyText + "\n" +
- "交换机:" + exchange + "\n" +
- "路由键:" + routingKey));
-
- return rabbitTemplate;
- }
-
-}
diff --git a/src/main/java/com/sonic/agent/receiver/MsgReceiver.java b/src/main/java/com/sonic/agent/receiver/MsgReceiver.java
deleted file mode 100644
index aa0e8182..00000000
--- a/src/main/java/com/sonic/agent/receiver/MsgReceiver.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package com.sonic.agent.receiver;
-
-import com.alibaba.fastjson.JSONObject;
-import com.android.ddmlib.IDevice;
-import com.rabbitmq.client.Channel;
-import com.sonic.agent.automation.AndroidStepHandler;
-import com.sonic.agent.bridge.android.AndroidDeviceBridgeTool;
-import com.sonic.agent.bridge.android.AndroidDeviceThreadPool;
-import com.sonic.agent.bridge.ios.LibIMobileDeviceTool;
-import com.sonic.agent.interfaces.PlatformType;
-import com.sonic.agent.maps.AndroidPasswordMap;
-import com.sonic.agent.maps.HandlerMap;
-import com.sonic.agent.rabbitmq.RabbitMQThread;
-import com.sonic.agent.tests.AndroidTests;
-import com.sonic.agent.tools.AgentTool;
-import com.sonic.agent.tools.GetWebStartPort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.amqp.core.Message;
-import org.springframework.amqp.rabbit.annotation.RabbitListener;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.io.IOException;
-import java.util.*;
-
-/**
- * @author ZhouYiXun
- * @des
- * @date 2021/9/16 18:40
- */
-@Component
-public class MsgReceiver {
- @Value("${spring.version}")
- private String version;
- @Value("${sonic.agent.host}")
- private String host;
- @Autowired
- private AndroidTests androidTests;
- private final Logger logger = LoggerFactory.getLogger(MsgReceiver.class);
-
- @RabbitListener(queues = "MsgQueue-${sonic.agent.key}")
- public void process(JSONObject jsonObject, Channel channel, Message message) {
- logger.info("MsgReceiver消费者收到消息 : " + jsonObject.toString());
- long deliveryTag = message.getMessageProperties().getDeliveryTag();
- AndroidDeviceThreadPool.cachedThreadPool.execute(() -> {
- switch (jsonObject.getString("msg")) {
- case "auth":
- logger.info("当前sonic-agent版本为:" + version);
- AgentTool.agentId = jsonObject.getInteger("id");
- RabbitMQThread.isPass = true;
- JSONObject agentInfo = new JSONObject();
- agentInfo.put("msg", "agentInfo");
- agentInfo.put("port", GetWebStartPort.getTomcatPort());
- agentInfo.put("version", version);
- agentInfo.put("systemType", System.getProperty("os.name"));
- agentInfo.put("host", host);
- RabbitMQThread.send(agentInfo);
- try {
- channel.basicAck(deliveryTag, true);
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- case "reboot":
- if (jsonObject.getInteger("platform") == PlatformType.ANDROID) {
- IDevice rebootDevice = AndroidDeviceBridgeTool.getIDeviceByUdId(jsonObject.getString("udId"));
- if (rebootDevice != null) {
- AndroidDeviceBridgeTool.reboot(rebootDevice);
- }
- }
- if (jsonObject.getInteger("platform") == PlatformType.IOS) {
- if (LibIMobileDeviceTool.getDeviceList().contains(jsonObject.getString("udId"))) {
- LibIMobileDeviceTool.reboot(jsonObject.getString("udId"));
- }
- }
- try {
- channel.basicAck(deliveryTag, true);
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- case "runStep":
- if (jsonObject.getInteger("pf") == PlatformType.ANDROID) {
- AndroidPasswordMap.getMap().put(jsonObject.getString("udId")
- , jsonObject.getString("pwd"));
- AndroidStepHandler androidStepHandler = HandlerMap.getAndroidMap().get(jsonObject.getString("sessionId"));
- androidStepHandler.resetResultDetailStatus();
- androidStepHandler.setGlobalParams(jsonObject.getJSONObject("gp"));
- List steps = jsonObject.getJSONArray("steps").toJavaList(JSONObject.class);
- for (JSONObject step : steps) {
- try {
- androidStepHandler.runStep(step);
- } catch (Throwable e) {
- break;
- }
- }
- androidStepHandler.sendStatus();
- }
- try {
- channel.basicAck(deliveryTag, true);
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- case "suite":
- JSONObject device = jsonObject.getJSONObject("device");
- if (AndroidDeviceBridgeTool.getIDeviceByUdId(device.getString("udId")) != null) {
- AndroidPasswordMap.getMap().put(device.getString("udId")
- , device.getString("password"));
- try {
- androidTests.run(channel, deliveryTag, jsonObject);
- } catch (Exception e) {
- e.printStackTrace();
- try {
- channel.basicReject(deliveryTag, true);
- } catch (IOException ioException) {
- ioException.printStackTrace();
- }
- }
- } else {
- //取消本次测试
- JSONObject subResultCount = new JSONObject();
- subResultCount.put("rid", jsonObject.getInteger("rid"));
- RabbitMQThread.send(subResultCount);
- try {
- channel.basicAck(deliveryTag, true);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- break;
- }
- });
- }
-}
diff --git a/src/main/java/com/sonic/agent/tests/AndroidTests.java b/src/main/java/com/sonic/agent/tests/AndroidTests.java
index 1193c9ec..4b6d3c23 100644
--- a/src/main/java/com/sonic/agent/tests/AndroidTests.java
+++ b/src/main/java/com/sonic/agent/tests/AndroidTests.java
@@ -2,7 +2,6 @@
import com.alibaba.fastjson.JSONObject;
import com.android.ddmlib.IDevice;
-import com.rabbitmq.client.Channel;
import com.sonic.agent.automation.AndroidStepHandler;
import com.sonic.agent.bridge.android.AndroidDeviceBridgeTool;
import com.sonic.agent.bridge.android.AndroidDeviceLocalStatus;
@@ -13,8 +12,6 @@
import org.bytedeco.javacv.FrameRecorder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.amqp.rabbit.core.RabbitTemplate;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -31,12 +28,10 @@
@Component
public class AndroidTests {
private final Logger logger = LoggerFactory.getLogger(AndroidTests.class);
- @Autowired
- private RabbitTemplate rabbitTemplate;
@Value("${sonic.agent.key}")
private String key;
- public void run(Channel channel, long tag, JSONObject jsonObject) throws IOException {
+ public void run(JSONObject jsonObject) throws IOException {
AndroidStepHandler androidStepHandler = new AndroidStepHandler();
List steps = jsonObject.getJSONArray("steps").toJavaList(JSONObject.class);
int rid = jsonObject.getInteger("rid");
@@ -45,7 +40,6 @@ public void run(Channel channel, long tag, JSONObject jsonObject) throws IOExcep
JSONObject gp = jsonObject.getJSONObject("gp");
androidStepHandler.setGlobalParams(gp);
androidStepHandler.setTestMode(cid, rid, udId, DeviceStatus.TESTING, "");
- channel.basicAck(tag, true);
int wait = jsonObject.getInteger("wait");
if (!AndroidDeviceLocalStatus.startTest(udId)) {
androidStepHandler.waitDevice(wait + 1);
@@ -56,7 +50,7 @@ public void run(Channel channel, long tag, JSONObject jsonObject) throws IOExcep
} else {
//延时队列
jsonObject.put("wait", wait);
- rabbitTemplate.convertAndSend("TaskDirectExchange", key, jsonObject);
+// rabbitTemplate.convertAndSend("TaskDirectExchange", key, jsonObject);
logger.info("进入延时队列:" + jsonObject);
}
return;
@@ -131,29 +125,6 @@ public void run(Channel channel, long tag, JSONObject jsonObject) throws IOExcep
}
continue;
}
-// File logDec = new File("test-output/log");
-// if (!logDec.exists()) {
-// logDec.mkdirs();
-// }
- //写入logcat
-// File logcatFile = new File(logDec + File.separator + Calendar.getInstance().getTimeInMillis() + "_" + udId + ".log");
-// FileOutputStream logFileOut = null;
-// try {
-// logFileOut = new FileOutputStream(logcatFile);
-// } catch (FileNotFoundException e) {
-// logger.error(e.getMessage());
-// }
-// FileOutputStream finalLogFileOut = logFileOut;
- //添加监听
-// androidStepHandler.getAndroidDriver().addLogcatMessagesListener((msg) -> {
-// try {
-// finalLogFileOut.write((msg + "\n").getBytes(StandardCharsets.UTF_8));
-// } catch (IOException e) {
-// logger.error(e.getMessage());
-// }
-// });
- //开始广播
-// androidStepHandler.getAndroidDriver().startLogcatBroadcast("localhost", AppiumServer.service.getUrl().getPort());
Future> miniCapPro = null;
AtomicReference> imgList = new AtomicReference<>(new ArrayList<>());
AtomicReference banner = new AtomicReference<>(new String[24]);
@@ -168,30 +139,15 @@ public void run(Channel channel, long tag, JSONObject jsonObject) throws IOExcep
MiniCapTool miniCapTool = new MiniCapTool();
miniCapPro = miniCapTool.start(udId, banner, imgList, "high", -1, null);
}
- //两分钟录一次
- try {
- Thread.sleep(120000);
- } catch (InterruptedException e) {
- logger.error(e.getMessage());
+ int w = 0;
+ while (w < 10 && (!runStep.isDone())) {
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage());
+ }
+ w++;
}
- //移除监听
-// androidStepHandler.getAndroidDriver().removeAllLogcatListeners();
- //移除logcat广播
-// androidStepHandler.getAndroidDriver().stopLogcatBroadcast();
- //关闭流
-// if (logFileOut != null) {
-// try {
-// logFileOut.close();
-// } catch (IOException e) {
-// logger.error(e.getMessage());
-// }
-// }
- //处理logcat日志
-// if (isFail.get()) {
-// androidStepHandler.log.sendSelfLog(logcatFile.getName(), UploadTools.upload(logcatFile, "logFiles"));
-// } else {
-// logcatFile.delete();
-// }
//处理录像
if (isSupportRecord) {
if (androidStepHandler.getStatus() == 3) {
diff --git a/src/main/java/com/sonic/agent/tools/GetWebStartPort.java b/src/main/java/com/sonic/agent/tools/GetWebStartPort.java
deleted file mode 100644
index 460ab5bf..00000000
--- a/src/main/java/com/sonic/agent/tools/GetWebStartPort.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.sonic.agent.tools;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.web.context.WebServerInitializedEvent;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-@Component
-public class GetWebStartPort implements ApplicationListener {
- private final Logger logger = LoggerFactory.getLogger(GetWebStartPort.class);
-
- private static int serverPort = 0;
-
- public static int getTomcatPort(){
- return serverPort;
- }
-
- @Override
- public void onApplicationEvent(WebServerInitializedEvent event) {
- serverPort = event.getWebServer().getPort();
- logger.info("tomcat开启端口: {}", serverPort);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/sonic/agent/tools/LaunchTool.java b/src/main/java/com/sonic/agent/tools/LaunchTool.java
index 518bd0b4..06d2c3e0 100644
--- a/src/main/java/com/sonic/agent/tools/LaunchTool.java
+++ b/src/main/java/com/sonic/agent/tools/LaunchTool.java
@@ -1,14 +1,9 @@
package com.sonic.agent.tools;
-import com.alibaba.fastjson.JSONObject;
import com.sonic.agent.automation.AppiumServer;
import com.sonic.agent.automation.RemoteDebugDriver;
-import com.sonic.agent.rabbitmq.RabbitMQThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.amqp.rabbit.core.RabbitTemplate;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.DependsOn;
@@ -17,28 +12,17 @@
import javax.annotation.PreDestroy;
@Component
-@DependsOn("rabbitMsgInit")
+@DependsOn("nettyMsgInit")
public class LaunchTool implements ApplicationRunner {
private final Logger logger = LoggerFactory.getLogger(LaunchTool.class);
- @Autowired
- private RabbitTemplate rabbitTemplate;
- @Value("${sonic.agent.key}")
- private String key;
@Override
public void run(ApplicationArguments args) {
AppiumServer.start();
- JSONObject auth = new JSONObject();
- auth.put("msg", "auth");
- auth.put("key", key);
- rabbitTemplate.convertAndSend("DataExchange", "data", auth);
}
@PreDestroy
public void destroy() throws InterruptedException {
- JSONObject agentOffLine = new JSONObject();
- agentOffLine.put("msg", "offLine");
- RabbitMQThread.send(agentOffLine);
RemoteDebugDriver.close();
AppiumServer.close();
Thread.sleep(3000);
diff --git a/src/main/java/com/sonic/agent/tools/LogTool.java b/src/main/java/com/sonic/agent/tools/LogTool.java
index be154f67..db9fddbb 100644
--- a/src/main/java/com/sonic/agent/tools/LogTool.java
+++ b/src/main/java/com/sonic/agent/tools/LogTool.java
@@ -4,7 +4,7 @@
import com.sonic.agent.interfaces.DeviceStatus;
import com.sonic.agent.interfaces.StepType;
import com.sonic.agent.maps.WebSocketSessionMap;
-import com.sonic.agent.rabbitmq.RabbitMQThread;
+import com.sonic.agent.netty.NettyThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,7 +56,7 @@ public void send(JSONObject message) {
*/
private void sendToServer(JSONObject message) {
message.put("time", new Date());
- RabbitMQThread.send(message);
+ NettyThreadPool.send(message);
}
/**
diff --git a/src/main/java/com/sonic/agent/tools/MiniCapTool.java b/src/main/java/com/sonic/agent/tools/MiniCapTool.java
index 350b391a..d124e776 100644
--- a/src/main/java/com/sonic/agent/tools/MiniCapTool.java
+++ b/src/main/java/com/sonic/agent/tools/MiniCapTool.java
@@ -33,18 +33,6 @@ public class MiniCapTool {
public Future> start(String udId, AtomicReference banner, AtomicReference> imgList, String pic, int tor, Session session) {
Queue dataQueue = new LinkedBlockingQueue<>();
IDevice iDevice = AndroidDeviceBridgeTool.getIDeviceByUdId(udId);
- int qua = 0;
- switch (pic) {
- case "low":
- qua = 10;
- break;
- case "middle":
- qua = 30;
- break;
- case "high":
- qua = 60;
- break;
- }
int s;
if (tor == -1) {
s = AndroidDeviceBridgeTool.getScreen(AndroidDeviceBridgeTool.getIDeviceByUdId(udId));
@@ -66,12 +54,12 @@ public Future> start(String udId, AtomicReference banner, AtomicRefe
c = 270;
break;
}
- int finalQua = qua;
+// int finalQua = qua;
int finalC = c;
Future> miniCapPro = AndroidDeviceThreadPool.cachedThreadPool.submit(() ->
{
try {
- AndroidDeviceBridgeTool.startMiniCapServer(iDevice, finalQua, finalC, session);
+ AndroidDeviceBridgeTool.startMiniCapServer(iDevice, pic, finalC, session);
} catch (AdbCommandRejectedException e) {
e.printStackTrace();
} catch (IOException e) {
@@ -231,6 +219,7 @@ public Future> start(String udId, AtomicReference banner, AtomicRefe
count++;
break;
case "middle":
+ case "fixed":
count += 2;
break;
case "high":
diff --git a/src/main/java/com/sonic/agent/tools/ScrcpyTool.java b/src/main/java/com/sonic/agent/tools/ScrcpyTool.java
index ac4f02fc..7836a335 100644
--- a/src/main/java/com/sonic/agent/tools/ScrcpyTool.java
+++ b/src/main/java/com/sonic/agent/tools/ScrcpyTool.java
@@ -4,18 +4,51 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
public class ScrcpyTool {
- public static void main(String[] args) throws IOException {
- Socket capSocket;
+ private static final int BUFFER_SIZE = 1024 * 1024;
+ private static final int READ_BUFFER_SIZE = 1024 * 5;
+
+ public static void main(String[] args) throws IOException, InterruptedException {
+ Socket capSocket = new Socket("localhost", 8666);
OutputStream outputStream;
InputStream inputStream;
- capSocket = new Socket("localhost", 8666);
outputStream = capSocket.getOutputStream();
inputStream = capSocket.getInputStream();
- outputStream.write(0);
+// outputStream.write(0);
+
+ int readLength;
+ int naluIndex = 0;
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int bufferLength = 0;
while (capSocket.isConnected()) {
- System.out.println(inputStream.read());
+ readLength = inputStream.read(buffer, bufferLength, READ_BUFFER_SIZE);
+// System.out.println(inputStream.read());
+ System.out.println(readLength);
+ if(readLength>0) {
+ System.out.println(readLength);
+ bufferLength += readLength;
+ System.out.println(readLength);
+ for (int i = 5; i < bufferLength - 4; i++) {
+ if (buffer[i] == 0x00 &&
+ buffer[i + 1] == 0x00 &&
+ buffer[i + 2] == 0x00 &&
+ buffer[i + 3] == 0x01
+ ){
+ naluIndex = i;
+
+ byte[] naluBuffer = new byte[naluIndex];
+ System.arraycopy(buffer, 0, naluBuffer, 0, naluIndex);
+// dataQueue.add(naluBuffer);
+ bufferLength -= naluIndex;
+ System.arraycopy(buffer, naluIndex, buffer, 0, bufferLength);
+ i = 5;
+ }
+ }
+
+ }
}
}
diff --git a/src/main/java/com/sonic/agent/tools/SpringTool.java b/src/main/java/com/sonic/agent/tools/SpringTool.java
new file mode 100644
index 00000000..9b0a44fe
--- /dev/null
+++ b/src/main/java/com/sonic/agent/tools/SpringTool.java
@@ -0,0 +1,28 @@
+package com.sonic.agent.tools;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public final class SpringTool implements ApplicationContextAware {
+ private static ApplicationContext applicationContext = null;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ if (SpringTool.applicationContext == null) {
+ SpringTool.applicationContext = applicationContext;
+ }
+ }
+
+ public static ApplicationContext getApplicationContext() {
+ return applicationContext;
+ }
+
+ public static Object getBean(String name) {
+ return getApplicationContext().getBean(name);
+ }
+
+ public static T getBean(Class clazz){
+ return getApplicationContext().getBean(clazz);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/sonic/agent/tools/UploadTools.java b/src/main/java/com/sonic/agent/tools/UploadTools.java
index 75dacba9..9b6ddf44 100644
--- a/src/main/java/com/sonic/agent/tools/UploadTools.java
+++ b/src/main/java/com/sonic/agent/tools/UploadTools.java
@@ -28,8 +28,10 @@
@Component
public class UploadTools {
private final static Logger logger = LoggerFactory.getLogger(UploadTools.class);
- @Value("${sonic.folder.url}")
- private String url;
+ @Value("${sonic.server.host}")
+ private String host;
+ @Value("${sonic.server.folder-port}")
+ private String port;
private static String baseUrl;
private static RestTemplate restTemplate;
@@ -37,7 +39,7 @@ public class UploadTools {
@Autowired
public void setRestTemplate(RestTemplate restTemplate) {
UploadTools.restTemplate = restTemplate;
- baseUrl = url;
+ baseUrl = "http://" + host + ":" + port + "/api/folder";
}
public static String upload(File uploadFile, String type) {
diff --git a/src/main/java/com/sonic/agent/websockets/AndroidWSServer.java b/src/main/java/com/sonic/agent/websockets/AndroidWSServer.java
index ef40a048..74787a45 100644
--- a/src/main/java/com/sonic/agent/websockets/AndroidWSServer.java
+++ b/src/main/java/com/sonic/agent/websockets/AndroidWSServer.java
@@ -16,17 +16,12 @@
import com.sonic.agent.interfaces.DeviceStatus;
import com.sonic.agent.maps.HandlerMap;
import com.sonic.agent.maps.WebSocketSessionMap;
-import com.sonic.agent.rabbitmq.RabbitMQThread;
+import com.sonic.agent.netty.NettyThreadPool;
import com.sonic.agent.tools.MiniCapTool;
import com.sonic.agent.tools.PortTool;
import com.sonic.agent.tools.ProcessCommandTool;
import com.sonic.agent.tools.UploadTools;
import org.openqa.selenium.OutputType;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.chrome.ChromeOptions;
-import org.openqa.selenium.remote.CapabilityType;
-import org.openqa.selenium.remote.DesiredCapabilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,15 +34,11 @@
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
@Component
@@ -435,7 +426,7 @@ public void onMessage(String message, Session session) throws InterruptedExcepti
jsonDebug.put("pwd", msg.getString("pwd"));
jsonDebug.put("sessionId", session.getId());
jsonDebug.put("caseId", msg.getInteger("caseId"));
- RabbitMQThread.send(jsonDebug);
+ NettyThreadPool.send(jsonDebug);
}
break;
}
@@ -452,12 +443,12 @@ private void sendText(Session session, String message) {
}
private void exit(Session session) {
+ AndroidDeviceLocalStatus.finish(udIdMap.get(session).getSerialNumber());
try {
HandlerMap.getAndroidMap().get(session.getId()).closeAndroidDriver();
} catch (Exception e) {
e.printStackTrace();
} finally {
- AndroidDeviceLocalStatus.finish(udIdMap.get(session).getSerialNumber());
HandlerMap.getAndroidMap().remove(session.getId());
}
List has = webViewForwardMap.get(udIdMap.get(session));
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index 952985e7..fe483f04 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -1,37 +1,26 @@
-server:
- port: 7777
-
-spring:
- application:
- name: sonic-agent
- rabbitmq:
+sonic:
+ agent:
+ host: localhost
+ port: 7777
+ key: 29002272-4659-4808-a804-08ce3388b136
+ server:
host: localhost
- port: 5672
- username: sonic
- password: sonic
- virtual-host: sonic
- listener:
- simple:
- acknowledge-mode: manual
- publisher-confirm-type: correlated
- publisher-returns: true
+ folder-port: 8094
+ transport-port: 8095
+
+modules:
+ android:
+ enable: true
+ ios:
+ enable: true
+ webview:
+ enable: true
+ chrome-driver-path: C:\Program Files\Google\Chrome\Application\chromedriver.exe
logging:
file:
- name: logs/${spring.application.name}.log
+ name: logs/sonic-agent.log
logback:
rollingpolicy:
clean-history-on-start: true
max-history: 3
-
-sonic:
- modules:
- android: true
- ios: true
- chrome:
- path: C:\Program Files\Google\Chrome\Application\chromedriver.exe
- folder:
- url: http://localhost:8094/api/folder
- agent:
- host: 127.0.0.1
- key: 29002272-4659-4808-a804-08ce3388b136
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index 411c3d11..31879ee6 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -1,47 +1,39 @@
-server:
- #Agent服务的端口,可以自行更改
- port: 7777
-
-spring:
- application:
- name: apex-agent
- rabbitmq:
- #rabbitMQ的host地址(如果用体验版的mq,这个host改为部署体验版机器的ip)
+sonic:
+ agent:
+ # 替换为部署Agent机器的ipv4
host: localhost
- #如果用体验版的mq,这里是5673
- port: 5673
- #MQ的用户名
- username: guest
- #MQ的密码
- password: guest
- #MQ的vHost
- virtual-host: /
- listener:
- simple:
- acknowledge-mode: manual
- publisher-confirm-type: correlated
- publisher-returns: true
+ # 替换为Agent服务的端口,可以自行更改
+ port: 7777
+ # 替换为前端新增Agent生成的key
+ key: 29002272-4659-4808-a804-08ce3388b136
+ server:
+ # 如果跨网段,这个host改成后端的port
+ host: localhost
+ # 如果跨网段,这个port改成后端文件中心的port(一般不变)
+ folder-port: 8094
+ # 如果跨网段,这个port改成后端传输中心的port(一般不变)
+ transport-port: 8095
+
+modules:
+ # 安卓模块配置
+ android:
+ enable: true
+ # iOS模块配置
+ ios:
+ enable: true
+ # 在线webView调试模块配置
+ webview:
+ enable: true
+ # Agent机器上的chrome浏览器的driver路径,可以去http://npm.taobao.org/mirrors/chromedriver/下载
+ chrome-driver-path: C:\Program Files\Google\Chrome\Application\chromedriver.exe
+# Agent日志管理,一般不需要更改,可根据自己需要配置
logging:
file:
- name: logs/${spring.application.name}.log
+ #日志路径
+ name: logs/sonic-agent.log
logback:
rollingpolicy:
clean-history-on-start: true
+ #保留天数
max-history: 3
-
-sonic:
- modules:
- android: true
- ios: true
- chrome:
- # Agent机器上的chrome浏览器的driver路径,可以去http://npm.taobao.org/mirrors/chromedriver/下载
- path: C:\Program Files\Google\Chrome\Application\chromedriver.exe
- folder:
- # 如果跨网段,这个host和port改成后端的host和port
- url: http://localhost:8094/api/folder
- agent:
- # 替换为部署Agent机器的ipv4
- host: 127.0.0.1
- # 替换为前端新增Agent生成的key
- key: 29002272-4659-4808-a804-08ce3388b136