[agent] start rabbitmq accomplish the register procedure

This commit is contained in:
zeaslity
2022-12-01 17:25:03 +08:00
parent fbcb193a57
commit d89bc2947a
36 changed files with 841 additions and 213 deletions

View File

@@ -0,0 +1,48 @@
package io.wdd.agent.config.rabbitmq;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import org.springframework.context.annotation.Configuration;
/**
* response chain design pattern
*/
@Configuration
public abstract class AbstractOctopusMessageHandler {
private AbstractOctopusMessageHandler next;
public void addHandler(AbstractOctopusMessageHandler handler) {
this.next = handler;
}
public AbstractOctopusMessageHandler getNextHandler() {
return next;
}
public static class Builder {
private AbstractOctopusMessageHandler head;
private AbstractOctopusMessageHandler tail;
public Builder addHandler(AbstractOctopusMessageHandler nextHandler) {
if (this.head == null) {
this.head = this.tail = nextHandler;
return this;
}
this.tail.addHandler(nextHandler);
this.tail = nextHandler;
return this;
}
public AbstractOctopusMessageHandler build(){
return this.head;
}
}
public abstract boolean handle(OctopusMessage octopusMessage);
}

View File

@@ -0,0 +1,14 @@
package io.wdd.agent.config.rabbitmq;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import io.wdd.common.beans.rabbitmq.OctopusMessageType;
public class OMHandlerAgent extends AbstractOctopusMessageHandler {
@Override
public boolean handle(OctopusMessage octopusMessage) {
if (!octopusMessage.getType().equals(OctopusMessageType.AGENT)) {
this.getNextHandler().handle(octopusMessage);
}
return false;
}
}

View File

@@ -0,0 +1,17 @@
package io.wdd.agent.config.rabbitmq;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class OMHandlerBlackHole extends AbstractOctopusMessageHandler {
@Override
public boolean handle(OctopusMessage octopusMessage) {
log.error("Octopus Message Handle error ! No Handler Find !");
return false;
}
}

View File

@@ -0,0 +1,15 @@
package io.wdd.agent.config.rabbitmq;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import io.wdd.common.beans.rabbitmq.OctopusMessageType;
public class OMHandlerExecutor extends AbstractOctopusMessageHandler {
@Override
public boolean handle(OctopusMessage octopusMessage) {
if (!octopusMessage.getType().equals(OctopusMessageType.EXECUTOR)) {
this.getNextHandler().handle(octopusMessage);
}
return false;
}
}

View File

@@ -0,0 +1,22 @@
package io.wdd.agent.config.rabbitmq;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import io.wdd.common.beans.rabbitmq.OctopusMessageType;
public class OMHandlerInit extends AbstractOctopusMessageHandler {
@Override
public boolean handle(OctopusMessage octopusMessage) {
if (!octopusMessage.getType().equals(OctopusMessageType.INIT)) {
this.getNextHandler().handle(octopusMessage);
}
// handle the init message
return false;
}
}

View File

@@ -0,0 +1,16 @@
package io.wdd.agent.config.rabbitmq;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import io.wdd.common.beans.rabbitmq.OctopusMessageType;
public class OMHandlerStatus extends AbstractOctopusMessageHandler {
@Override
public boolean handle(OctopusMessage octopusMessage) {
if (!octopusMessage.getType().equals(OctopusMessageType.STATUS)) {
this.getNextHandler().handle(octopusMessage);
}
return false;
}
}

View File

@@ -1,8 +0,0 @@
package io.wdd.agent.config.rabbitmq;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RuntimeMessageConfig {
}

View File

@@ -0,0 +1,35 @@
package io.wdd.agent.config.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.wdd.common.handler.MyRuntimeException;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
//@Configuration
@Deprecated
public class BeanFactoryUtils implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Bean
public ObjectMapper getMapper() {
ObjectMapper objectMapper = (ObjectMapper) applicationContext.getBean("jacksonObjectMapper");
if (ObjectUtils.isEmpty(objectMapper)) {
throw new MyRuntimeException(" Collect server info error !");
}
return objectMapper;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

View File

@@ -0,0 +1,19 @@
package io.wdd.agent.config.utils;
import io.wdd.common.utils.OctopusObjectMapperConfig;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class OctopusObjectMapper {
//注意该段代码并未覆盖SpringBoot自动装配的ObjectMapper对象而是加强其配置。
// use the common config of object mapper
@Bean
public Jackson2ObjectMapperBuilderCustomizer customJackson() {
return OctopusObjectMapperConfig.common();
}
}

View File

@@ -4,16 +4,14 @@ package io.wdd.agent.initialization.beans;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder(toBuilder = true)
@Configuration
public class ServerInfo {
@Component
public class AgentServerInfo {
@Value("${serverName}")
private String serverName;

View File

@@ -155,7 +155,7 @@ check_sys() {
# 判断系统的包管理工具 apt, yum, or zypper
getPackageManageTool() {
if [[ -n $(command -v apt-get) ]]; then
if [[ -n $(command -v apt-getMapper) ]]; then
CMD_INSTALL="apt-get -y -qq install"
CMD_UPDATE="apt-get -qq update"
CMD_REMOVE="apt-get -y remove"
@@ -364,7 +364,7 @@ InstallDocker() {
fi
colorEcho ${BLUE} "正在执行更新操作!!"
apt-get update
apt-getMapper update
colorEcho ${GREEN} "----------更新完成----------"
FunctionSuccess
colorEcho ${BLUE} "可以安装的docker-ce的版本为"
@@ -923,7 +923,7 @@ generateSystemInfo() {
deployOctopusAgent() {
FunctionStart
# get the latest version of Octopus agent
# getMapper the latest version of Octopus agent
# poll the start up shell
echo "docker run -d \

View File

@@ -1,7 +1,7 @@
package io.wdd.agent.initialization.bootup;
import io.wdd.agent.initialization.beans.ServerInfo;
import io.wdd.agent.initialization.beans.AgentServerInfo;
import io.wdd.common.handler.MyRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@@ -29,7 +29,9 @@ public class CollectSystemInfo implements ApplicationContextAware {
private ApplicationContext context;
@Resource
InitConfiguration initConfiguration;
OctopusAgentInitService octopusAgentInitService;
public AgentServerInfo agentServerInfo;
@Bean
@Lazy
@@ -88,16 +90,16 @@ public class CollectSystemInfo implements ApplicationContextAware {
log.info("Starting getInjectServerInfo");
ServerInfo serverInfo = (ServerInfo) context.getBean("serverInfo");
agentServerInfo = (AgentServerInfo) context.getBean("agentServerInfo");
if (ObjectUtils.isEmpty(serverInfo)) {
if (ObjectUtils.isEmpty(agentServerInfo)) {
throw new MyRuntimeException(" Collect server info error !");
}
log.info("host server info has been collected == {}", serverInfo);
log.info("host server info has been collected == {}", agentServerInfo);
// start to send message to Octopus Server
initConfiguration.SendInfoToServer(serverInfo);
octopusAgentInitService.SendInfoToServer(agentServerInfo);
log.info("init server info has been send to octopus server !");
}

View File

@@ -1,94 +0,0 @@
package io.wdd.agent.initialization.bootup;
import io.wdd.agent.initialization.beans.ServerInfo;
import io.wdd.agent.initialization.rabbitmq.InitialRabbitMqConnector;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
@Service
@Lazy
public class InitConfiguration {
@Resource
RabbitTemplate rabbitTemplate;
@Resource
InitialRabbitMqConnector initialRabbitMqConnector;
@Value("${octopus.message.init_ttl}")
String defaultInitRegisterTimeOut;
private class InitMessagePostProcessor implements MessagePostProcessor {
private String initMessageTTL;
public InitMessagePostProcessor(Long initMessageTTL) {
this.initMessageTTL = String.valueOf(initMessageTTL);
}
public InitMessagePostProcessor(String initMessageTTL) {
this.initMessageTTL = initMessageTTL;
}
@Override
public Message postProcessMessage(Message message) throws AmqpException {
// set init register expiration time
MessageProperties messageProperties = message.getMessageProperties();
messageProperties.setExpiration(initMessageTTL);
return message;
}
}
public void SendInfoToServer(ServerInfo serverInfo){
// set init agent register ttl
InitMessagePostProcessor initMessagePostProcessor = new InitMessagePostProcessor(defaultInitRegisterTimeOut);
rabbitTemplate.convertAndSend("hello wmm !");
// send the register server info to EXCHANGE:INIT_EXCHANGE QUEUE: init_to_server
rabbitTemplate.convertAndSend(initialRabbitMqConnector.INIT_EXCHANGE, initialRabbitMqConnector.INIT_TO_SERVER_KEY, String.valueOf(serverInfo).getBytes(StandardCharsets.UTF_8), initMessagePostProcessor);
}
/**
* listen to the init queue from octopus server
*
* @RabbitListener : 用于标记当前方法是一个RabbitMQ的消息监听方法可以持续性的自动接收消息
* @param message
* 该方法不需要手动调用Spring会自动运行这个监听方法
*
* 注意如果该监听方法正常结束那么Spring会自动确认消息
* 如果出现异常则Spring不会确认消息该消息一直存在于消息队列中
*/
@RabbitHandler
@RabbitListener(
bindings =
@QueueBinding(
value = @Queue(name = "${octopus.message.init_from_server}" ),
exchange = @Exchange(name = "${octopus.message.init_exchange}", type = "direct"),
key = {"${octopus.message.init_from_server_key}"}
)
,
ackMode = "MANUAL"
)
public void ReceiveInitInfoFromServer(String message){
System.out.println("message = " + message);
}
}

View File

@@ -0,0 +1,133 @@
package io.wdd.agent.initialization.bootup;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import io.wdd.agent.initialization.beans.AgentServerInfo;
import io.wdd.agent.initialization.rabbitmq.InitialRabbitMqConnector;
import io.wdd.agent.message.handler.OctopusMessageHandler;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import io.wdd.common.handler.MyRuntimeException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Lazy
@Slf4j
public class OctopusAgentInitService {
@Resource
RabbitTemplate rabbitTemplate;
@Resource
InitialRabbitMqConnector initialRabbitMqConnector;
@Autowired
ObjectMapper objectMapper;
@Autowired
OctopusMessageHandler octopusMessageHandler;
@Value("${octopus.message.init_ttl}")
String defaultInitRegisterTimeOut;
@SneakyThrows
public void SendInfoToServer(AgentServerInfo agentServerInfo) {
// set init agent register ttl
InitMessagePostProcessor initMessagePostProcessor = new InitMessagePostProcessor(defaultInitRegisterTimeOut);
log.info("send INIT AgentServerInfo to Server = {}", agentServerInfo);
// send the register server info to EXCHANGE:INIT_EXCHANGE QUEUE: init_to_server
rabbitTemplate.convertAndSend(initialRabbitMqConnector.INIT_EXCHANGE, initialRabbitMqConnector.INIT_TO_SERVER_KEY, objectMapper.writeValueAsString(agentServerInfo), initMessagePostProcessor);
}
/**
* listen to the init queue from octopus server
*
* @param message 该方法不需要手动调用Spring会自动运行这个监听方法
* <p>
* 注意如果该监听方法正常结束那么Spring会自动确认消息
* 如果出现异常则Spring不会确认消息该消息一直存在于消息队列中
* @RabbitListener : 用于标记当前方法是一个RabbitMQ的消息监听方法可以持续性的自动接收消息
*/
@SneakyThrows
@RabbitHandler
@RabbitListener(
bindings =
@QueueBinding(
value = @Queue(name = "${octopus.message.init_from_server}"),
exchange = @Exchange(name = "${octopus.message.init_exchange}", type = "direct"),
key = {"${octopus.message.init_from_server_key}"}
)
,
ackMode = "MANUAL"
)
public void ReceiveInitInfoFromServer(Message message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
try {
OctopusMessage octopusMessage = objectMapper.readValue(message.getBody(), OctopusMessage.class);
// response chain to handle all kind of type of octopus message
if (!octopusMessageHandler.handle(octopusMessage)) {
throw new MyRuntimeException(" Handle Octopus Message Error !");
}
} catch (Exception e) {
// reject the message
channel.basicNack(deliveryTag, false, true);
// long deliveryTag, boolean requeue
// channel.basicReject(deliveryTag,true);
Thread.sleep(1000); // 这里只是便于出现死循环时查看
throw new MyRuntimeException("Octopus Agent Initialization Error, please check !");
}
// ack the info
channel.basicAck(deliveryTag, false);
}
private class InitMessagePostProcessor implements MessagePostProcessor {
private final String initMessageTTL;
public InitMessagePostProcessor(Long initMessageTTL) {
this.initMessageTTL = String.valueOf(initMessageTTL);
}
public InitMessagePostProcessor(String initMessageTTL) {
this.initMessageTTL = initMessageTTL;
}
@Override
public Message postProcessMessage(Message message) throws AmqpException {
// set init register expiration time
MessageProperties messageProperties = message.getMessageProperties();
messageProperties.setExpiration(initMessageTTL);
return message;
}
}
}

View File

@@ -115,7 +115,7 @@ check_sys() {
# 判断系统的包管理工具 apt, yum, or zypper
getPackageManageTool() {
if [[ -n $(command -v apt-get) ]]; then
if [[ -n $(command -v apt-getMapper) ]]; then
CMD_INSTALL="apt-get -y -qq install"
CMD_UPDATE="apt-get -qq update"
CMD_REMOVE="apt-get -y remove"
@@ -350,7 +350,7 @@ InstallDocker() {
fi
colorEcho ${BLUE} "正在执行更新操作!!"
apt-get update
apt-getMapper update
colorEcho ${GREEN} "----------更新完成----------"
FunctionSuccess
colorEcho ${BLUE} "可以安装的docker-ce的19.03版本为:"
@@ -432,7 +432,7 @@ EOF
colorEcho ${GREEN} "----------添加完成----------"
colorEcho ${BLUE} "开始添加国内的阿里云源的kubernetes的apt源……"
colorEcho ${BLUE} "开始执行apt update 操作……"
apt-get update
apt-getMapper update
colorEcho ${GREEN} "--------------------------------------------------------------"
fi
echo ""

View File

@@ -0,0 +1,38 @@
package io.wdd.agent.initialization.webtest;
import io.wdd.agent.initialization.beans.AgentServerInfo;
import io.wdd.agent.initialization.bootup.CollectSystemInfo;
import io.wdd.agent.initialization.bootup.OctopusAgentInitService;
import io.wdd.common.beans.response.R;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("sendInfoToOctopusServer")
public class SendServerInfoController {
@Resource
CollectSystemInfo collectSystemInfo;
@Resource
OctopusAgentInitService octopusAgentInitService;
@PostMapping("sendAgentInfo")
public R<AgentServerInfo> send(){
AgentServerInfo agentServerInfo = collectSystemInfo.agentServerInfo;
octopusAgentInitService.SendInfoToServer(agentServerInfo);
return R.ok(agentServerInfo);
}
}

View File

@@ -0,0 +1,37 @@
package io.wdd.agent.message.handler;
import io.wdd.agent.config.rabbitmq.*;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class OctopusMessageHandler {
private AbstractOctopusMessageHandler octopusMessageHandler;
@PostConstruct
private void registerAllHandler() {
AbstractOctopusMessageHandler.Builder builder = new AbstractOctopusMessageHandler.Builder();
octopusMessageHandler = builder
.addHandler(new OMHandlerExecutor())
.addHandler(new OMHandlerAgent())
.addHandler(new OMHandlerStatus())
.addHandler(new OMHandlerInit())
.build();
}
public boolean handle(OctopusMessage octopusMessage) {
return this.octopusMessageHandler.handle(octopusMessage);
}
}

View File

@@ -22,4 +22,4 @@ octopus:
# agent boot up default common exchange routing key
init_from_server_key: InitFromServerKey
# initialization register time out (unit ms) default is 5 min
init_ttl: "300000"
init_ttl: "3000000"

View File

@@ -1,6 +1,6 @@
package io.wdd.agent;
import io.wdd.agent.initialization.bootup.InitConfiguration;
import io.wdd.agent.initialization.bootup.OctopusAgentInitService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@@ -10,11 +10,10 @@ import javax.annotation.Resource;
public class InitRabbitMQTest {
@Resource
InitConfiguration initConfiguration;
OctopusAgentInitService octopusAgentInitService;
@Test
void testInitSendInfo(){
initConfiguration.SendInfoToServer();
}
}