diff --git a/sermant-backend/pom.xml b/sermant-backend/pom.xml index 1fcd440d70..66d6ebdbce 100644 --- a/sermant-backend/pom.xml +++ b/sermant-backend/pom.xml @@ -15,72 +15,31 @@ 1.8 2.5.3 UTF-8 - 9.0.43 4.1.75.Final 2.5.8 1.12.1 ${project.basedir}/src/main/webapp/frontend - - - - - org.springframework.boot - spring-boot-dependencies - ${spring.boot.version} - pom - import - - - + org.springframework.boot - spring-boot-starter - ${spring-boot.version} - - - org.slf4j - jul-to-slf4j - - - - - org.apache.logging.log4j - log4j-to-slf4j - 2.17.1 + spring-boot-dependencies + ${spring.boot.version} + pom + import - org.apache.logging.log4j - log4j-api - 2.17.1 + org.springframework.boot + spring-boot-starter + ${spring-boot.version} org.springframework.boot spring-boot-starter-web ${spring-boot.version} - - org.apache.tomcat.embed - tomcat-embed-core - ${org.apache.tomcat.embed.version} - - - org.apache.tomcat.embed - tomcat-embed-el - ${org.apache.tomcat.embed.version} - - - org.apache.tomcat.embed - tomcat-embed-websocket - ${org.apache.tomcat.embed.version} - - - org.apache.tomcat - tomcat-annotations-api - ${org.apache.tomcat.embed.version} - org.springframework.boot spring-boot-configuration-processor @@ -128,11 +87,6 @@ protobuf-java 3.9.1 - - org.apache.kafka - kafka-clients - 2.8.1 - org.projectlombok lombok @@ -166,37 +120,11 @@ 2.28.2 test - - org.apache.zookeeper - zookeeper-jute - 3.6.0 - compile - - - org.apache.zookeeper - zookeeper - 3.6.3 - - - io.netty - netty-transport-native-epoll - - - log4j - log4j - - - org.slf4j slf4j-api 1.7.32 - - org.apache.httpcomponents - httpclient - 4.5.13 - org.apache.commons commons-lang3 @@ -217,7 +145,7 @@ spring-boot-maven-plugin ${spring.boot.version} - com.huaweicloud.sermant.backend.NettyServerApplication + com.huaweicloud.sermant.backend.Backend ${package.output.dir} @@ -240,7 +168,7 @@ spring-boot-maven-plugin ${spring.boot.version} - com.huaweicloud.sermant.backend.NettyServerApplication + com.huaweicloud.sermant.backend.Backend ${package.output.dir} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/NettyServerApplication.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/Backend.java similarity index 90% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/NettyServerApplication.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/Backend.java index 4a0ac60c9a..30ae0d74ad 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/NettyServerApplication.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/Backend.java @@ -29,10 +29,8 @@ */ @SpringBootApplication @ConfigurationPropertiesScan -public class NettyServerApplication { - +public class Backend { public static void main(String[] args) { - SpringApplication.run(NettyServerApplication.class, args); + SpringApplication.run(Backend.class, args); } - } diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/CollectorCache.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/CollectorCache.java index d4d9709c60..00f6fc0df7 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/CollectorCache.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/CollectorCache.java @@ -17,10 +17,10 @@ package com.huaweicloud.sermant.backend.cache; -import com.huaweicloud.sermant.backend.entity.Consanguinity; -import com.huaweicloud.sermant.backend.entity.Contract; -import com.huaweicloud.sermant.backend.entity.ServerInfo; -import com.huaweicloud.sermant.backend.entity.ServiceType; +import com.huaweicloud.sermant.backend.entity.visibility.Consanguinity; +import com.huaweicloud.sermant.backend.entity.visibility.Contract; +import com.huaweicloud.sermant.backend.entity.visibility.ServerInfo; +import com.huaweicloud.sermant.backend.entity.visibility.ServiceType; import com.alibaba.fastjson.JSONObject; @@ -46,6 +46,11 @@ public class CollectorCache { */ public static final Map SERVER_MAP = new ConcurrentHashMap<>(); + /** + * 服务有消息 + */ + public static final Map SERVER_VALIDITY_PERIOD_MAP = new ConcurrentHashMap<>(); + private static final Logger LOGGER = LoggerFactory.getLogger(CollectorCache.class); private CollectorCache() { diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/HeartbeatCache.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/HeartbeatCache.java index 8388faf032..9c87c6fb21 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/HeartbeatCache.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/HeartbeatCache.java @@ -16,8 +16,7 @@ package com.huaweicloud.sermant.backend.cache; -import com.huaweicloud.sermant.backend.entity.HeartbeatEntity; -import com.huaweicloud.sermant.backend.entity.ServerInfo; +import com.huaweicloud.sermant.backend.entity.heartbeat.HeartbeatMessage; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -25,22 +24,16 @@ /** * 心跳数据缓存 * - * @author xuezechao - * @since 2022-02-15 + * @author luanwenfei + * @since 2022-10-27 */ public class HeartbeatCache { - private static Map heartbeatMessages = new ConcurrentHashMap<>(); - - private static Map lastHeartBeatDate = new ConcurrentHashMap<>(); + private static final Map HEARTBEAT_MESSAGE_MAP = new ConcurrentHashMap<>(); private HeartbeatCache() { } - public static Map getHeartbeatMessages() { - return heartbeatMessages; - } - - public static Map getHeartbeatDate() { - return lastHeartBeatDate; + public static Map getHeartbeatMessageMap() { + return HEARTBEAT_MESSAGE_MAP; } } diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/conf/KafkaConf.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/conf/KafkaConf.java deleted file mode 100644 index a0c6ce5cdf..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/conf/KafkaConf.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.common.conf; - -import lombok.Getter; -import lombok.Setter; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; - -/** - * kafka的配置类 - * - * @author lilai - * @version 0.0.1 - * @since 2021-08-07 - */ -@Getter -@Setter -@Component -@Configuration -public class KafkaConf { - // kafka地址 - @Value("${spring.kafka.bootstrap-servers}") - private String bootStrapServers; - - // common主题名 - @Value("${kafka.heartbeat.topic}") - private String topicHeartBeat; - - @Value("${kafka.pool.timeoutMs}") - private Integer kafkaPoolTimeoutMs; - - @Value("${kafka.key.deserializer}") - private String kafkaKeyDeserializer; - - @Value("${kafka.value.deserializer}") - private String kafkaValueDeserializer; - - @Value("${kafka.group.id}") - private String kafkaGroupId; - - @Value("${kafka.enable.auto.commit}") - private String kafkaEnableAutoCommit; - - @Value("${kafka.auto.commit.interval.ms}") - private String kafkaAutoCommitIntervalMs; - - @Value("${kafka.auto.offset.reset}") - private String kafkaAutoOffsetReset; - - @Value("${kafka.session.timeout.ms}") - private String kafkaSessionTimeoutMs; - - @Value("${fetch.min.bytes}") - private String kafkaFetchMinBytes; - - @Value("${fetch.max.wait.ms}") - private String kafkaFetchMaxWaitMs; - - @Value("${kafka.key.serializer}") - private String kafkaKeySerializer; - - @Value("${kafka.value.serializer}") - private String kafkaValueSerializer; - - @Value("${kafka.acks}") - private String kafkaAcks; - - @Value("${kafka.max.request.size}") - private String kafkaMaxRequestSize; - - @Value("${kafka.buffer.memory}") - private String kafkaBufferMemory; - - @Value("${kafka.retries}") - private String kafkaRetries; - - @Value("${kafka.request.timeout.ms}") - private String kafkaRequestTimeoutMs; - - @Value("${kafka.max.block.ms}") - private String kafkaMaxBlockMs; - - @Value("${heartbeat.cache}") - private String isHeartbeatCache; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/conf/WebConfig.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/conf/WebConfig.java index 01696a422c..67ff9c579b 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/conf/WebConfig.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/conf/WebConfig.java @@ -43,10 +43,7 @@ public void addViewControllers(ViewControllerRegistry registry) { @Override public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**") - .allowCredentials(false) - .allowedMethods("POST","GET","DELETE","PUT","OPTIONS") - .allowedOrigins("*") - ; + registry.addMapping("/**").allowCredentials(false).allowedMethods("POST", "GET", "DELETE", "PUT", "OPTIONS") + .allowedOrigins("*"); } } diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/exception/KafkaTopicException.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/exception/KafkaTopicException.java deleted file mode 100644 index c30ed1511c..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/exception/KafkaTopicException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.common.exception; - -import java.util.Locale; - -/** - * kafka主题异常类 - * - * @author lilai - * @version 0.0.1 - * @since 2021-08-07 - */ -public class KafkaTopicException extends RuntimeException { - - private static final long serialVersionUID = 6574606778367040187L; - - public static final ErrorMsgParser TOPIC_NOT_EXISTS = args -> String.format(Locale.ROOT, - "These topics %s don't exist.", args); - - public KafkaTopicException(ErrorMsgParser parser, String args) { - parser.parseErrorMsg(args); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/exception/ZookeeperDynamicConfigurationException.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/exception/ZookeeperDynamicConfigurationException.java deleted file mode 100644 index 5d2939c1f7..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/exception/ZookeeperDynamicConfigurationException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.common.exception; - -/** - * zookeeper动态配置异常类 - * - * @author 薛泽超 - * @since 2022-03-16 - */ -public class ZookeeperDynamicConfigurationException extends Exception { - private static final long serialVersionUID = -940403875065143157L; - - /** - * zookeeper 动态配置异常 - * - * @param msg 异常信息 - */ - public ZookeeperDynamicConfigurationException(String msg) { - super(msg); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/handler/BaseHandler.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/handler/BaseHandler.java index 535de6271e..1153488daf 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/handler/BaseHandler.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/handler/BaseHandler.java @@ -16,9 +16,8 @@ package com.huaweicloud.sermant.backend.common.handler; -import com.huawei.sermant.backend.pojo.Message; +import com.huaweicloud.sermant.backend.pojo.Message; -import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.timeout.IdleStateEvent; @@ -42,15 +41,6 @@ public void channelRead0(ChannelHandlerContext ctx, Message.NettyMessage msg) { // 获取收到的消息类型 int type = msg.getMessageTypeValue(); switch (type) { - // 如果收到消息类型为心跳PING,直接发送心跳PONG - case Message.NettyMessage.MessageType.HEARTBEAT_PING_VALUE: - sendPongMsg(ctx, msg); - break; - - // 如果收到消息为PONG,证明对方状态正常,连接正常 - case Message.NettyMessage.MessageType.HEARTBEAT_PONG_VALUE: - break; - // 如果为业务数据进行各自的处理 case Message.NettyMessage.MessageType.SERVICE_DATA_VALUE: handlerData(ctx, msg); @@ -68,18 +58,9 @@ public void channelRead0(ChannelHandlerContext ctx, Message.NettyMessage msg) { */ protected abstract void handlerData(ChannelHandlerContext ctx, Message.NettyMessage msg); - private void sendPongMsg(ChannelHandlerContext ctx, Message.NettyMessage msg) { - Message.NettyMessage message = msg.newBuilderForType() - .setMessageType(Message.NettyMessage.MessageType.HEARTBEAT_PONG) - .setHeartBeat(Message.HeartBeat.newBuilder().build()) - .build(); - Channel channel = ctx.channel(); - channel.writeAndFlush(message); - } - @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { - IdleStateEvent stateEvent = (IdleStateEvent) evt; + IdleStateEvent stateEvent = (IdleStateEvent)evt; switch (stateEvent.state()) { case READER_IDLE: handlerReaderIdle(ctx); diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/controller/HeartBeatInfoController.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/controller/HeartBeatInfoController.java new file mode 100644 index 0000000000..38f791e58a --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/controller/HeartBeatInfoController.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.controller; + +import com.huaweicloud.sermant.backend.cache.HeartbeatCache; +import com.huaweicloud.sermant.backend.entity.heartbeat.HeartbeatMessage; + +import com.alibaba.fastjson.JSONObject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 心跳信息Controller + * + * @author luanwenfei + * @since 2022-10-27 + */ +@RestController +@RequestMapping("/sermant") +public class HeartBeatInfoController { + private static final Logger LOGGER = LoggerFactory.getLogger(HeartBeatInfoController.class); + + @GetMapping("/getPluginsInfo") + public String getPluginsInfo() { + return JSONObject.toJSONString(getHeartbeatMessageCache()); + } + + private List getHeartbeatMessageCache() { + Map heartbeatMessages = HeartbeatCache.getHeartbeatMessageMap(); + return new ArrayList<>(heartbeatMessages.values()); + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/controller/VisibilityController.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/controller/VisibilityController.java index 952a36f836..9289d06db9 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/controller/VisibilityController.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/controller/VisibilityController.java @@ -17,7 +17,7 @@ package com.huaweicloud.sermant.backend.controller; import com.huaweicloud.sermant.backend.cache.CollectorCache; -import com.huaweicloud.sermant.backend.entity.ServerInfo; +import com.huaweicloud.sermant.backend.entity.visibility.ServerInfo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Address.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Address.java deleted file mode 100644 index a9a05c0560..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Address.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class Address { - /** - * 主机名,可以是ip也可以是域名 - */ - private String host; - - /** - * 端口 - */ - private int port; - - /** - * 安全端口 - */ - private int sport; - - /** - * inner或者outer,代表是内网还是外网,地址优先链接内网的 - */ - private AddressType type; - - /** - * 内外 - */ - private AddressScope scope; - - /* - * 协议,当前只支持ws - */ - private Protocol protocol; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AddressScope.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AddressScope.java deleted file mode 100644 index 30461882b5..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AddressScope.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -public enum AddressScope { - /** - * 内部地址 - */ - INNER, - - /** - * 对外的地址 - */ - OUTER; - - public static AddressScope getValue(String s) { - try { - return AddressScope.valueOf(s); - } catch (Exception e) { - return null; - } - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AddressType.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AddressType.java deleted file mode 100644 index f29ce60f29..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AddressType.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -public enum AddressType { - /** - * acess服务器的地址 - */ - ACCESS; - - public static AddressType getValue(String s) { - - try { - return AddressType.valueOf(s); - } catch (IllegalArgumentException e) { - return null; - } - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AgentInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AgentInfo.java deleted file mode 100644 index 0ebf04a634..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/AgentInfo.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2021-2022 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import lombok.Getter; -import lombok.Setter; - -import java.util.Map; - -/** - * 插件信息 - * - * @author xuezechao - * @since 2022-02-28 - */ - -@Getter -@Setter -public class AgentInfo { - - private Object ip; - - private Object version; - - private Object lastHeartbeatTime; - - private Object heartbeatTime; - - private Map pluginsMap; - - private Object instanceId; - - private Object appName; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/HeartBeatResult.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/HeartBeatResult.java deleted file mode 100644 index 2dadcc959c..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/HeartBeatResult.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import java.util.List; -import java.util.Map; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class HeartBeatResult extends Result { - /** - * 下一次心跳的周期 - */ - private Integer heartBeatInterval; - - /** - * 附属信息,收到这个信息后,原封不动得通过数据上报 - */ - private Map attachment; - - private List monitorItemList; - - /** - * 系统属性 - */ - private Map systemProperties; - - /** - * access的地址描述 - */ - private List
accessAddressList; - - /** - * 实例状态0 代表ok, 1代表disabled - */ - private Integer instanceStatus; - - /** - * 对结果进行md5计算,如果内容变化了就下发新的配置 - */ - private String md5; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/MonitorItem.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/MonitorItem.java deleted file mode 100644 index 35a5082617..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/MonitorItem.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import java.util.Map; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class MonitorItem { - private String collectorName; - - private Integer interval; - - private Integer collectorId; - - private Long monitorItemId; - - private Integer status; - - private Map parameters; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/PluginInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/PluginInfo.java deleted file mode 100644 index 08d4cd453c..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/PluginInfo.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class PluginInfo { - String name; - - String version; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Protocol.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Protocol.java deleted file mode 100644 index ee7f55dd0a..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Protocol.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -public enum Protocol { - /** - * websocket - */ - WS("ws", "wss"), - /** - * http - */ - HTTP("http", "https"), - ; - - private String value; - - private String secure; - - Protocol(String value, String secure) { - this.value = value; - this.secure = secure; - } - - public String getValue() { - return value; - } - - public String getSecure() { - return secure; - } - -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/PublishConfigEntity.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/PublishConfigEntity.java deleted file mode 100644 index edfc06dc85..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/PublishConfigEntity.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import lombok.Getter; -import lombok.Setter; -import java.util.Map; - -@Getter -@Setter -public class PublishConfigEntity { - - private String key; - - private String content; - - private Map group; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/RegisterResult.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/RegisterResult.java deleted file mode 100644 index 011c04060b..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/RegisterResult.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class RegisterResult extends Result { - - private Long appId; - - private Long envId; - - private int domainId; - - private String agentVersion; - - private Long instanceId; -} - diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Result.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Result.java deleted file mode 100644 index 699c1efe9c..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Result.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.entity; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class Result { - - private String errorCode; - - private String errorMsg; - - private String hint; - - /** - * 业务ID,实际情况可能会变动 - */ - private Long businessId; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/Event.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/Event.java new file mode 100644 index 0000000000..693fbfbb16 --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/Event.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.entity.event; + +/** + * 事件 + * + * @author luanwenfei + * @since 2023-03-02 + */ +public class Event { + private String metaHash; + + private long time; + + private String scope; + + private EventLevel eventLevel; + + private EventType eventType; + + private EventInfo eventInfo; + + private LogInfo logInfo; + + public String getMetaHash() { + return metaHash; + } + + public void setMetaHash(String metaHash) { + this.metaHash = metaHash; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public EventLevel getEventLevel() { + return eventLevel; + } + + public void setEventLevel(EventLevel eventLevel) { + this.eventLevel = eventLevel; + } + + public EventType getEventType() { + return eventType; + } + + public void setEventType(EventType eventType) { + this.eventType = eventType; + } + + public EventInfo getEventInfo() { + return eventInfo; + } + + public void setEventInfo(EventInfo eventInfo) { + this.eventInfo = eventInfo; + } + + public LogInfo getLogInfo() { + return logInfo; + } + + public void setLogInfo(LogInfo logInfo) { + this.logInfo = logInfo; + } + + @Override + public String toString() { + return "Event{" + "metaHash='" + metaHash + '\'' + ", time=" + time + ", scope='" + scope + '\'' + + ", eventLevel=" + eventLevel + ", eventType=" + eventType + ", eventInfo=" + eventInfo + ", logInfo=" + + logInfo + '}'; + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventInfo.java new file mode 100644 index 0000000000..b13d75fc91 --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventInfo.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.entity.event; + +/** + * 事件信息实体 + * + * @author luanwenfei + * @since 2023-03-02 + */ +public class EventInfo { + private String name; + + private String description; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String toString() { + return "EventInfo{" + "name='" + name + '\'' + ", description='" + description + '\'' + '}'; + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigType.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventLevel.java similarity index 56% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigType.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventLevel.java index 7761dcb3f9..2ea120d3fc 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigType.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventLevel.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,31 +14,37 @@ * limitations under the License. */ -package com.huaweicloud.sermant.backend.service.dynamicconfig.service; +package com.huaweicloud.sermant.backend.entity.event; /** - * Enum for DynamicConfigType, - * Currently support ZooKeeper, Kie, Nop. - * Probably will support Nacos, etcd in the future. + * 事件等级 * - * @author yangyi - * @since 2021-12-10 + * @author luanwenfei + * @since 2023-03-04 */ -public enum DynamicConfigType { - +public enum EventLevel { /** - * zookeeper 配置中心 + * 紧急 */ - ZOO_KEEPER, + EMERGENCY(300), /** - * servicecomb-kie 配置中心 + * 重要 */ - KIE, + IMPORTANT(200), /** - * 配置中心无实现 + * 一般 */ - NOP; + NORMAL(100); + + private final int levelThreshold; + + EventLevel(int levelThreshold) { + this.levelThreshold = levelThreshold; + } + public int getLevelThreshold() { + return levelThreshold; + } } diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventMessage.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventMessage.java new file mode 100644 index 0000000000..00822334a6 --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventMessage.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.entity.event; + +import java.util.List; + +/** + * 事件消息 + * + * @author luanwenfei + * @since 2023-03-07 + */ +public class EventMessage { + String metaHash; + + List events; + + /** + * 构造函数 + * + * @param metaHash metaHash + * @param events events + */ + public EventMessage(String metaHash, List events) { + this.metaHash = metaHash; + this.events = events; + } + + public String getMetaHash() { + return metaHash; + } + + public void setMetaHash(String metaHash) { + this.metaHash = metaHash; + } + + public List getEvents() { + return events; + } + + public void setEvents(List events) { + this.events = events; + } + + @Override + public String toString() { + return "EventMessage{" + "metaHash='" + metaHash + '\'' + ", events=" + events + '}'; + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventType.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventType.java new file mode 100644 index 0000000000..90147e4c3d --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/EventType.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.entity.event; + +/** + * 事件种类 + * + * @author luanwenfei + * @since 2023-03-04 + */ +public enum EventType { + /** + * 运行事件 + */ + OPERATION(0, "operation"), + + /** + * 治理事件 + */ + GOVERNANCE(1, "governance"), + + /** + * 日志事件 + */ + LOG(2, "log"); + + /** + * 事件种类的整型标识 + */ + private final int type; + + /** + * 事件种类描述 + */ + private final String description; + + EventType(int type, String description) { + this.type = type; + this.description = description; + } + + public int getType() { + return type; + } + + public String getDescription() { + return description; + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/LogInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/LogInfo.java new file mode 100644 index 0000000000..6cc18a9d48 --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/event/LogInfo.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.entity.event; + +/** + * 日志信息 + * + * @author luanwenfei + * @since 2023-03-08 + */ +public class LogInfo { + private String logLevel; + + private String logMessage; + + private String logClass; + + private String logMethod; + + private int logThreadId; + + private Throwable throwable; + + public String getLogLevel() { + return logLevel; + } + + public void setLogLevel(String logLevel) { + this.logLevel = logLevel; + } + + public String getLogMessage() { + return logMessage; + } + + public void setLogMessage(String logMessage) { + this.logMessage = logMessage; + } + + public String getLogClass() { + return logClass; + } + + public void setLogClass(String logClass) { + this.logClass = logClass; + } + + public String getLogMethod() { + return logMethod; + } + + public void setLogMethod(String logMethod) { + this.logMethod = logMethod; + } + + public int getLogThreadId() { + return logThreadId; + } + + public void setLogThreadId(int logThreadId) { + this.logThreadId = logThreadId; + } + + public Throwable getThrowable() { + return throwable; + } + + public void setThrowable(Throwable throwable) { + this.throwable = throwable; + } + + @Override + public String toString() { + return "LogInfo{" + "logLevel='" + logLevel + '\'' + ", logMessage='" + logMessage + '\'' + ", logClass='" + + logClass + '\'' + ", logMethod='" + logMethod + '\'' + ", logThreadId='" + logThreadId + '\'' + + ", throwable=" + throwable + '}'; + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/heartbeat/HeartbeatMessage.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/heartbeat/HeartbeatMessage.java new file mode 100644 index 0000000000..c2d386bdfe --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/heartbeat/HeartbeatMessage.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.entity.heartbeat; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * 心跳消息 + * + * @author luanwenfei + * @since 2022-03-19 + */ +public class HeartbeatMessage { + private String appName; + + private String appType; + + private String hostName; + + @JSONField(serialize = false) + private long receiveTime; + + private AtomicBoolean health = new AtomicBoolean(false); + + private List ip; + + private long heartbeatTime; + + private long lastHeartbeatTime; + + private String version; + + private String instanceId; + + private Map pluginInfoMap = new HashMap<>(); + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public List getIp() { + return ip; + } + + public void setIp(List ip) { + this.ip = ip; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getAppType() { + return appType; + } + + public void setAppType(String appType) { + this.appType = appType; + } + + public long getHeartbeatTime() { + return heartbeatTime; + } + + public void setHeartbeatTime(long heartbeatTime) { + this.heartbeatTime = heartbeatTime; + } + + public long getLastHeartbeatTime() { + return lastHeartbeatTime; + } + + public void setLastHeartbeatTime(long lastHeartbeatTime) { + this.lastHeartbeatTime = lastHeartbeatTime; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public List getPluginInfoMap() { + return new ArrayList<>(pluginInfoMap.values()); + } + + public void setPluginInfoMap(Map pluginInfoMap) { + this.pluginInfoMap = pluginInfoMap; + } + + public void setReceiveTime(long receiveTime) { + this.receiveTime = receiveTime; + } + + public long getReceiveTime() { + return receiveTime; + } + + public boolean isHealth() { + return this.health.get(); + } + + /** + * 设置健康状态 + * + * @param health health + */ + public void setHealth(boolean health) { + this.health.compareAndSet(!health, health); + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/heartbeat/PluginInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/heartbeat/PluginInfo.java new file mode 100644 index 0000000000..c1101f2ce4 --- /dev/null +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/heartbeat/PluginInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.backend.entity.heartbeat; + +import java.util.Map; + +/** + * 插件信息 + * + * @author luanwenfei + * @since 2022-10-28 + */ +public class PluginInfo { + private String name; + + private String version; + + private Map extInfo; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public void setExtInfo(Map extInfo) { + this.extInfo = extInfo; + } + + public Map getExtInfo() { + return extInfo; + } +} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/BaseInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/BaseInfo.java similarity index 95% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/BaseInfo.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/BaseInfo.java index 13e5f2cfcb..6bff57368f 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/BaseInfo.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/BaseInfo.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; /** * 服务可见性基础信息 diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Consanguinity.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/Consanguinity.java similarity index 96% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Consanguinity.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/Consanguinity.java index c794518039..36a8bfde9a 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Consanguinity.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/Consanguinity.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; import java.util.List; diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Contract.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/Contract.java similarity index 97% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Contract.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/Contract.java index f740c95a08..2f8025f89a 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/Contract.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/Contract.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; import java.util.List; diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/MethodInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/MethodInfo.java similarity index 96% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/MethodInfo.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/MethodInfo.java index 8ab5b83aa9..8965be8dd7 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/MethodInfo.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/MethodInfo.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; import java.util.List; diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/OperateType.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/OperateType.java similarity index 95% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/OperateType.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/OperateType.java index 468f91ab9b..10f02b1809 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/OperateType.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/OperateType.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; /** * 操作类型 diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ParamInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ParamInfo.java similarity index 95% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ParamInfo.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ParamInfo.java index da11f235ff..2565de8d02 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ParamInfo.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ParamInfo.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; /** * 参数信息 diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ServerInfo.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ServerInfo.java similarity index 98% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ServerInfo.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ServerInfo.java index 5301dbfb00..6856d69b2c 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ServerInfo.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ServerInfo.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; import java.util.Date; import java.util.List; diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ServiceType.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ServiceType.java similarity index 94% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ServiceType.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ServiceType.java index 6eec57f6e8..f3a8905405 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/ServiceType.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/entity/visibility/ServiceType.java @@ -15,7 +15,7 @@ * */ -package com.huaweicloud.sermant.backend.entity; +package com.huaweicloud.sermant.backend.entity.visibility; /** * 服务类型 diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/kafka/KafkaConsumerManager.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/kafka/KafkaConsumerManager.java deleted file mode 100644 index 45ebce3d20..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/kafka/KafkaConsumerManager.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.kafka; - -import com.huaweicloud.sermant.backend.common.conf.KafkaConf; -import com.huaweicloud.sermant.backend.common.exception.KafkaTopicException; - -import org.apache.kafka.clients.consumer.ConsumerConfig; -import org.apache.kafka.clients.consumer.KafkaConsumer; - -import java.util.Properties; - -public class KafkaConsumerManager { - - private KafkaConsumer consumer; - - private static KafkaConsumerManager instance; - - private KafkaConsumerManager(KafkaConf conf) { - setConsumerConf(conf); - } - - /** - * 获取kafka消费者管理类实例 - * - * @param conf kafka配置 - * @return kafka消费者管理实例 - */ - public static synchronized KafkaConsumerManager getInstance(KafkaConf conf) { - if (instance == null) { - instance = new KafkaConsumerManager(conf); - } - return instance; - } - - /** - * 配置kafkaConf - * - * @param conf kafka配置信息 - * @throws KafkaTopicException kafka主题异常 - */ - private void setConsumerConf(KafkaConf conf) throws KafkaTopicException { - Properties properties = new Properties(); - properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, conf.getBootStrapServers()); - properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, conf.getKafkaKeyDeserializer()); - properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, conf.getKafkaValueDeserializer()); - properties.put(ConsumerConfig.GROUP_ID_CONFIG, conf.getKafkaGroupId()); - properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, conf.getKafkaEnableAutoCommit()); - properties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, conf.getKafkaAutoCommitIntervalMs()); - properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, conf.getKafkaAutoOffsetReset()); - properties.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, conf.getKafkaSessionTimeoutMs()); - properties.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, conf.getKafkaFetchMinBytes()); - properties.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, conf.getKafkaFetchMaxWaitMs()); - consumer = new KafkaConsumer(properties); - } - - /** - * 获取消费者 - * - * @return 消费者 - */ - public KafkaConsumer getConsumer() { - return consumer; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/kafka/KafkaProducerManager.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/kafka/KafkaProducerManager.java deleted file mode 100644 index 56de3241a1..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/kafka/KafkaProducerManager.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.kafka; - -import com.huaweicloud.sermant.backend.common.conf.KafkaConf; -import com.huaweicloud.sermant.backend.common.exception.KafkaTopicException; - -import org.apache.kafka.clients.producer.KafkaProducer; -import org.apache.kafka.clients.producer.ProducerConfig; - -import java.util.Properties; - -/** - * kafka生产者管理类 - * - * @author lilai - * @version 0.0.1 - * @since 2021-08-07 - */ -public class KafkaProducerManager { - - private KafkaProducer producer; - - private static KafkaProducerManager instance; - - private KafkaProducerManager(KafkaConf conf) { - setProducerConf(conf); - } - - /** - * 获取kafka生产者管理类实例 - * - * @param conf kafka配置 - * @return kafka生产者管理实例 - */ - public static synchronized KafkaProducerManager getInstance(KafkaConf conf) { - if (instance == null) { - instance = new KafkaProducerManager(conf); - } - return instance; - } - - /** - * 配置kafkaConf - * - * @param conf kafka配置信息 - * @throws KafkaTopicException kafka主题异常 - */ - private void setProducerConf(KafkaConf conf) throws KafkaTopicException { - Properties properties = new Properties(); - properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, conf.getBootStrapServers()); - properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, conf.getKafkaKeySerializer()); - properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, conf.getKafkaValueSerializer()); - properties.put(ProducerConfig.ACKS_CONFIG, conf.getKafkaAcks()); - properties.put(ProducerConfig.MAX_REQUEST_SIZE_CONFIG, conf.getKafkaMaxRequestSize()); - properties.put(ProducerConfig.BUFFER_MEMORY_CONFIG, conf.getKafkaBufferMemory()); - properties.put(ProducerConfig.RETRIES_CONFIG, conf.getKafkaRetries()); - properties.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG, conf.getKafkaRequestTimeoutMs()); - properties.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, conf.getKafkaMaxBlockMs()); - producer = new KafkaProducer<>(properties); - } - - /** - * 获取生产者 - * - * @return 生产者 - */ - public KafkaProducer getProducer() { - return producer; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/HttpServer.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/HttpServer.java deleted file mode 100644 index 31f1e01c3f..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/HttpServer.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.server; - -import com.huaweicloud.sermant.backend.cache.HeartbeatCache; -import com.huaweicloud.sermant.backend.common.conf.KafkaConf; -import com.huaweicloud.sermant.backend.entity.Address; -import com.huaweicloud.sermant.backend.entity.AddressScope; -import com.huaweicloud.sermant.backend.entity.AddressType; -import com.huaweicloud.sermant.backend.entity.AgentInfo; -import com.huaweicloud.sermant.backend.entity.HeartBeatResult; -import com.huaweicloud.sermant.backend.entity.HeartbeatEntity; -import com.huaweicloud.sermant.backend.entity.MonitorItem; -import com.huaweicloud.sermant.backend.entity.Protocol; -import com.huaweicloud.sermant.backend.entity.PublishConfigEntity; -import com.huaweicloud.sermant.backend.entity.RegisterResult; -import com.huaweicloud.sermant.backend.kafka.KafkaConsumerManager; -import com.huaweicloud.sermant.backend.service.dynamicconfig.DynamicConfigurationFactoryServiceImpl; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigurationService; -import com.huaweicloud.sermant.backend.service.dynamicconfig.utils.LabelGroupUtils; -import com.huaweicloud.sermant.backend.util.DateUtil; -import com.huaweicloud.sermant.backend.util.RandomUtil; -import com.huaweicloud.sermant.backend.util.UuidUtil; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; - -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -@Component -@RestController -@RequestMapping("/sermant") -public class HttpServer { - - private static final Logger LOGGER = LoggerFactory.getLogger(HttpServer.class); - - private static final String SUCCESS = "success"; - private static final String FAILED = "failed"; - private static final int DEFAULT_IP_INDEX = 0; - private static final int NULL_IP_LENGTH = 0; - private static final int MAX = 10; - - @Autowired - private KafkaConf conf; - - @Autowired - private DynamicConfigurationFactoryServiceImpl dynamicConfigurationFactoryService; - - - private final RandomUtil randomUtil = new RandomUtil(); - - private long randomLong = UuidUtil.getId(); - private final int randomInt = randomUtil.getRandomInt(MAX); - private final String randomStr = randomUtil.getRandomStr(MAX); - - - @PostMapping("/master/v1/register") - public String invokePost(@RequestBody JSONObject jsonParam) { - long instanceId = UuidUtil.getId(); - RegisterResult registerResult = new RegisterResult(); - registerResult.setAppId(randomLong); - registerResult.setEnvId(randomLong); - registerResult.setDomainId(randomInt); - registerResult.setAgentVersion(randomStr); - registerResult.setInstanceId(instanceId); - registerResult.setBusinessId(randomLong); - return JSONObject.toJSONString(registerResult); - } - - @PostMapping("/master/v1/heartbeat") - public String invokePost() { - - Hashtable map = new Hashtable<>(); - - HeartBeatResult heartBeatResult = new HeartBeatResult(); - heartBeatResult.setHeartBeatInterval(randomInt); - heartBeatResult.setAttachment(map); - heartBeatResult.setMonitorItemList(Collections.singletonList(getMonitorItem(map))); - heartBeatResult.setSystemProperties(map); - heartBeatResult.setAccessAddressList(Collections.singletonList(getAddress())); - heartBeatResult.setInstanceStatus(randomInt); - heartBeatResult.setBusinessId(randomLong); - heartBeatResult.setMd5(randomStr); - return JSONObject.toJSONString(heartBeatResult); - } - - @GetMapping("/getPluginsInfo") - public String invokeGet() { - if (Boolean.parseBoolean(conf.getIsHeartbeatCache())) { - return JSONObject.toJSONString(getHeartbeatMessageCache()); - } else { - ConsumerRecords consumerRecords = getHeartbeatInfo(); - return JSONObject.toJSONString(getHeartbeatMessage(consumerRecords)); - } - } - - @PostMapping("/publishConfig") - public String invokePost(@RequestBody PublishConfigEntity publishConfig) { - try { - DynamicConfigurationService dcs = dynamicConfigurationFactoryService.getDynamicConfigurationService(); - dcs.publishConfig(publishConfig.getKey(), - LabelGroupUtils.createLabelGroup(publishConfig.getGroup()), - publishConfig.getContent()); - return SUCCESS; - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return FAILED; - } - - public MonitorItem getMonitorItem(Hashtable map) { - MonitorItem monitorItem = new MonitorItem(); - monitorItem.setCollectorName(randomStr); - monitorItem.setInterval(randomInt); - monitorItem.setCollectorId(randomInt); - monitorItem.setMonitorItemId(randomLong); - monitorItem.setStatus(randomInt); - monitorItem.setParameters(map); - return monitorItem; - } - - public Address getAddress() { - Address address = new Address(); - address.setHost(randomStr); - address.setPort(randomInt); - address.setSport(randomInt); - address.setType(AddressType.ACCESS); - address.setScope(AddressScope.OUTER); - address.setProtocol(Protocol.WS); - return address; - } - - private ConsumerRecords getHeartbeatInfo() { - ConsumerRecords consumerRecords = null; - try { - KafkaConsumer consumer = KafkaConsumerManager.getInstance(conf).getConsumer(); - consumer.subscribe(Arrays.asList(conf.getTopicHeartBeat())); - ConsumerRecords records = consumer.poll(conf.getKafkaPoolTimeoutMs()); - consumerRecords = records; - } catch (Exception e) { - LOGGER.error("getHeartbeatInfo failed"); - } - return consumerRecords; - } - - private String pluginMapToStr(Map map) { - StringBuilder result = new StringBuilder(); - for (Map.Entry entry : map.entrySet()) { - result.append("\n").append(entry.getKey()).append("-").append(entry.getValue()); - } - return result.toString(); - } - - private List getHeartbeatMessage(ConsumerRecords consumerRecords) { - Map agentMap = new HashMap<>(); - for (ConsumerRecord record : consumerRecords) { - HeartbeatEntity heartbeatEntity = JSON.parseObject(record.value(), HeartbeatEntity.class); - setAgentInfo(agentMap, heartbeatEntity); - } - return new ArrayList<>(agentMap.values()); - } - - private List getHeartbeatMessageCache() { - Map heartbeatMessages = HeartbeatCache.getHeartbeatMessages(); - if (heartbeatMessages != null) { - Map agentMap = new HashMap<>(); - for (HeartbeatEntity heartbeatEntity : heartbeatMessages.values()) { - setAgentInfo(agentMap, heartbeatEntity); - } - return new ArrayList<>(agentMap.values()); - } else { - return new ArrayList<>(); - } - } - - private void setAgentInfo(Map agentMap, HeartbeatEntity heartbeatEntity) { - List ips = heartbeatEntity.getIp(); - String instanceId = heartbeatEntity.getInstanceId(); - if (ips == null || ips.size() == NULL_IP_LENGTH) { - return; - } - if (agentMap.get(instanceId) == null) { - String ip = ips.get(DEFAULT_IP_INDEX); - AgentInfo agentInfo = new AgentInfo(); - agentInfo.setIp(ip); - agentInfo.setVersion(heartbeatEntity.getVersion()); - agentInfo.setPluginsMap(new HashMap()); - agentInfo.setInstanceId(instanceId); - agentInfo.setAppName(heartbeatEntity.getApp()); - agentMap.put(instanceId, agentInfo); - } - if (agentMap.get(instanceId) != null && heartbeatEntity.getPluginName() != null) { - AgentInfo agentInfo = agentMap.get(instanceId); - Map pluginMap = agentInfo.getPluginsMap(); - pluginMap.put(heartbeatEntity.getPluginName(), heartbeatEntity.getPluginVersion()); - agentInfo.setPluginsMap(pluginMap); - agentInfo.setLastHeartbeatTime(DateUtil.getFormatDate(heartbeatEntity.getLastHeartbeat())); - agentInfo.setHeartbeatTime(DateUtil.getFormatDate(heartbeatEntity.getHeartbeatVersion())); - } - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/NettyServer.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/NettyServer.java index 1662b1040a..a9ac263214 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/NettyServer.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/NettyServer.java @@ -16,14 +16,9 @@ package com.huaweicloud.sermant.backend.server; -import com.huaweicloud.sermant.backend.cache.DeleteTimeoutData; -import com.huaweicloud.sermant.backend.common.conf.DataTypeTopicMapping; -import com.huaweicloud.sermant.backend.common.conf.KafkaConf; import com.huaweicloud.sermant.backend.common.conf.VisibilityConfig; -import com.huaweicloud.sermant.backend.common.exception.KafkaTopicException; -import com.huaweicloud.sermant.backend.kafka.KafkaConsumerManager; -import com.huaweicloud.sermant.backend.kafka.KafkaProducerManager; -import com.huawei.sermant.backend.pojo.Message; +import com.huaweicloud.sermant.backend.pojo.Message; +import com.huaweicloud.sermant.backend.timer.DeleteTimeoutDataTask; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; @@ -39,8 +34,6 @@ import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; import io.netty.handler.timeout.IdleStateHandler; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.clients.producer.KafkaProducer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -75,21 +68,22 @@ public class NettyServer { // 读等待时间 @Value("${netty.wait.time}") - private int readWaitTime = 60; + private int readWaitTime; // 网关端口 @Value("${netty.port}") private int port; - // kafka配置文件加载 - @Autowired - private KafkaConf conf; + // 心跳有效时间 + @Value("${max.effective.time:60000}") + private long maxEffectiveTime; - @Autowired - private VisibilityConfig visibilityConfig; + // 心跳缓存时间 + @Value("${max.cache.time:600000}") + private long maxCacheTime; @Autowired - private DataTypeTopicMapping topicMapping; + private VisibilityConfig visibilityConfig; /** * 服务端核心方法 @@ -97,11 +91,11 @@ public class NettyServer { */ @PostConstruct public void start() { - LOGGER.info("Starting the netty server..."); + LOGGER.info("Start netty server..."); // 清理过期数据 - TIMER.schedule(new DeleteTimeoutData(visibilityConfig), DELETE_TIMEOUT_DATA_DELAY_TIME, - DELETE_TIMEOUT_DATA_PERIOD_TIME); + TIMER.schedule(new DeleteTimeoutDataTask(maxEffectiveTime, maxCacheTime, visibilityConfig), + DELETE_TIMEOUT_DATA_DELAY_TIME, DELETE_TIMEOUT_DATA_PERIOD_TIME); // 处理连接的线程组 EventLoopGroup bossGroup = new NioEventLoopGroup(1); @@ -110,32 +104,27 @@ public void start() { EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); - KafkaProducer producer = KafkaProducerManager.getInstance(conf).getProducer(); - KafkaConsumer consumer = KafkaConsumerManager.getInstance(conf).getConsumer(); - serverBootstrap.group(bossGroup, workerGroup) - .channel(NioServerSocketChannel.class) - .option(ChannelOption.SO_BACKLOG, CONNECTION_SIZE) - .childHandler(new ChannelInitializer() { - @Override - protected void initChannel(Channel channel) { - ChannelPipeline pipeline = channel.pipeline(); - - // 如果超过读等待时间还是没有收到对应客户端,触发读等待事件 - pipeline.addLast(new IdleStateHandler(readWaitTime, 0, 0)); - pipeline.addLast(new ProtobufVarint32FrameDecoder()); - pipeline.addLast(new ProtobufDecoder(Message.NettyMessage.getDefaultInstance())); - pipeline.addLast(new ProtobufVarint32LengthFieldPrepender()); - pipeline.addLast(new ProtobufEncoder()); - pipeline.addLast(new ServerHandler(producer, consumer, topicMapping, - conf.getIsHeartbeatCache())); - } - }); + serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG, CONNECTION_SIZE).childHandler(new ChannelInitializer() { + @Override + protected void initChannel(Channel channel) { + ChannelPipeline pipeline = channel.pipeline(); + + // 如果超过读等待时间还是没有收到对应客户端,触发读等待事件 + pipeline.addLast(new IdleStateHandler(readWaitTime, 0, 0)); + pipeline.addLast(new ProtobufVarint32FrameDecoder()); + pipeline.addLast(new ProtobufDecoder(Message.NettyMessage.getDefaultInstance())); + pipeline.addLast(new ProtobufVarint32LengthFieldPrepender()); + pipeline.addLast(new ProtobufEncoder()); + pipeline.addLast(new ServerHandler()); + } + }); // 同步阻塞等待服务启动 serverBootstrap.bind(port).sync(); - LOGGER.info("Netty server start, port is {}", port); - } catch (InterruptedException | KafkaTopicException e) { - LOGGER.error("Exception occurs when start netty server, exception message : {}", e); + LOGGER.info("Netty server started, port is {}", port); + } catch (InterruptedException e) { + LOGGER.error("Exception occurs when start netty server, exception message : {}", e.getMessage()); bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/ServerHandler.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/ServerHandler.java index 45a01387e0..b0b7c28b67 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/ServerHandler.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/server/ServerHandler.java @@ -18,32 +18,26 @@ import com.huaweicloud.sermant.backend.cache.CollectorCache; import com.huaweicloud.sermant.backend.cache.HeartbeatCache; -import com.huaweicloud.sermant.backend.common.conf.DataTypeTopicMapping; import com.huaweicloud.sermant.backend.common.handler.BaseHandler; -import com.huaweicloud.sermant.backend.common.util.GzipUtils; -import com.huaweicloud.sermant.backend.entity.HeartbeatEntity; -import com.huaweicloud.sermant.backend.entity.OperateType; -import com.huaweicloud.sermant.backend.entity.ServerInfo; -import com.huawei.sermant.backend.pojo.Message; +import com.huaweicloud.sermant.backend.entity.event.EventMessage; +import com.huaweicloud.sermant.backend.entity.heartbeat.HeartbeatMessage; +import com.huaweicloud.sermant.backend.entity.visibility.OperateType; +import com.huaweicloud.sermant.backend.entity.visibility.ServerInfo; +import com.huaweicloud.sermant.backend.pojo.Message; +import com.huaweicloud.sermant.backend.util.GzipUtils; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; import com.google.protobuf.ByteString; import io.netty.channel.ChannelHandlerContext; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.clients.producer.KafkaProducer; -import org.apache.kafka.clients.producer.ProducerRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Objects; /** * 网关服务端handler @@ -55,59 +49,33 @@ public class ServerHandler extends BaseHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ServerHandler.class); - private static final int HEARTBEAT_TOPIC_INDEX = 0; - - private static final int VISIBILITY_TOPIC_INDEX = 12; - private final KafkaProducer producer; - private KafkaConsumer consumer; - private boolean isHeartBeatCache; - - private final DataTypeTopicMapping topicMapping; - - private final Map hbMessages = HeartbeatCache.getHeartbeatMessages(); - - private final Map lastHeartBeatDate = HeartbeatCache.getHeartbeatDate(); + private final Map hbMessages = HeartbeatCache.getHeartbeatMessageMap(); /** * ServerHandler - * - * @param producer kafka producer - * @param consumer kafka consumer - * @param topicMapping kafka topic map - * @param isHeartBeatCache is or not open heartbeat cache */ - public ServerHandler(KafkaProducer producer, KafkaConsumer consumer, - DataTypeTopicMapping topicMapping, String isHeartBeatCache) { - this.producer = producer; - this.consumer = consumer; - this.topicMapping = topicMapping; - this.isHeartBeatCache = Boolean.parseBoolean(isHeartBeatCache); + public ServerHandler() { } @Override protected void handlerData(ChannelHandlerContext ctx, Message.NettyMessage msg) { List serviceDataList = msg.getServiceDataList(); for (Message.ServiceData serviceData : serviceDataList) { - // 获取NettyMessage中的业务数据 ByteString data = serviceData.getData(); - - // 解压业务数据 byte[] message = GzipUtils.decompress(data.toByteArray()); int dataType = serviceData.getDataTypeValue(); - String topic = topicMapping.getTopicOfType(dataType); - if (StringUtils.hasText(topic)) { - if (Objects.equals(topic, topicMapping.getTopicOfType(HEARTBEAT_TOPIC_INDEX))) { - writeHeartBeatCacheCache(topic, message); - continue; - } - if (Objects.equals(topic, topicMapping.getTopicOfType(VISIBILITY_TOPIC_INDEX))) { - handlerServiceVisibility(message); - } - if (!this.isHeartBeatCache) { - producer.send(new ProducerRecord<>(topic, message)); - } - } else { - LOGGER.warn("Can not find the corresponding topic of type {}.", dataType); + switch (dataType) { + case Message.ServiceData.DataType.HEARTBEAT_DATA_VALUE: + handleHeartBeat(message); + break; + case Message.ServiceData.DataType.EVENT_DATA_VALUE: + handleEvent(message); + break; + case Message.ServiceData.DataType.VISIBILITY_DATA_VALUE: + handleServiceVisibility(message); + break; + default: + LOGGER.warn("Can not find the corresponding data type {}.", dataType); } } } @@ -115,7 +83,7 @@ protected void handlerData(ChannelHandlerContext ctx, Message.NettyMessage msg) @Override protected void handlerReaderIdle(ChannelHandlerContext ctx) { super.handlerReaderIdle(ctx); - LOGGER.info("Client timeOut, close it"); + LOGGER.info("Client timeout, close it"); ctx.close(); } @@ -127,28 +95,29 @@ public void channelInactive(ChannelHandlerContext ctx) { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - LOGGER.error("Exception occurs. Exception info: {}", cause); + LOGGER.error("Exception occurs. Exception info: {}", cause.getMessage()); } - private void writeHeartBeatCacheCache(String topic, byte[] message) { + private void handleHeartBeat(byte[] message) { // 缓存心跳数据 - if (Objects.equals(topic, topicMapping.getTopicOfType(HEARTBEAT_TOPIC_INDEX))) { - String messageStr = new String(message, StandardCharsets.UTF_8); - if (!this.isHeartBeatCache) { - producer.send(new ProducerRecord<>(topic, message)); - } - HeartbeatEntity heartbeatEntity = JSONObject.parseObject(messageStr, HeartbeatEntity.class); - List ips = heartbeatEntity.getIp(); - if (ips != null && ips.size() != 0 && heartbeatEntity.getPluginName() != null) { - String instanceId = heartbeatEntity.getInstanceId(); - String pluginName = heartbeatEntity.getPluginName(); - hbMessages.put(pluginName + instanceId, heartbeatEntity); - } - ServerInfo serverInfo = new ServerInfo(); - serverInfo.setInstanceId(heartbeatEntity.getInstanceId()); - serverInfo.setValidateDate(new Date()); - lastHeartBeatDate.put(heartbeatEntity.getInstanceId(), serverInfo); + HeartbeatMessage heartbeatMessage = + JSON.parseObject(new String(message, StandardCharsets.UTF_8), HeartbeatMessage.class); + List ips = heartbeatMessage.getIp(); + if (ips != null && ips.size() != 0) { + heartbeatMessage.setReceiveTime(System.currentTimeMillis()); + heartbeatMessage.setHealth(true); + hbMessages.put(heartbeatMessage.getAppName() + heartbeatMessage.getInstanceId(), heartbeatMessage); } + setServiceValidityPeriod(heartbeatMessage.getInstanceId()); + } + + /** + * 配置服务可见性数据有效时间 + */ + private void setServiceValidityPeriod(String instanceId) { + ServerInfo serverInfo = new ServerInfo(); + serverInfo.setValidateDate(new Date()); + CollectorCache.SERVER_VALIDITY_PERIOD_MAP.put(instanceId, serverInfo); } /** @@ -156,7 +125,7 @@ private void writeHeartBeatCacheCache(String topic, byte[] message) { * * @param message 消息内容 */ - private void handlerServiceVisibility(byte[] message) { + private void handleServiceVisibility(byte[] message) { String messageStr = new String(message, StandardCharsets.UTF_8); ServerInfo visibilityInfo = JSON.parseObject(messageStr, ServerInfo.class); if (OperateType.ADD.getType().equals(visibilityInfo.getOperateType())) { @@ -165,4 +134,14 @@ private void handlerServiceVisibility(byte[] message) { CollectorCache.removeServer(visibilityInfo); } } + + /** + * 处理事件数据 + * + * @param message 消息内容 + */ + private void handleEvent(byte[] message) { + String messageStr = new String(message, StandardCharsets.UTF_8); + EventMessage eventMessage = JSON.parseObject(messageStr, EventMessage.class); + } } diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/Config.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/Config.java deleted file mode 100644 index 2d981a65da..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/Config.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Config for this DynamicConfig Module - * - * @author yangyi - * @since 2021-12-10 - */ -public class Config { - - private static final Logger logger = LoggerFactory.getLogger(Config.class); - - static Config singleInst; - - private static final int DEFAULT_TIMEOUT_TIME = 30000; - - /** - * 超时时间 - */ - protected int timeoutValue = DEFAULT_TIMEOUT_TIME; - - protected String defaultGroup = "sermant"; - - protected String zookeeperUri = "zookeeper://127.0.0.1:2181"; - - protected DynamicConfigType dynamicConfigType = DynamicConfigType.ZOO_KEEPER; - - /** - * kie配置地址 - */ - protected String kieUrl = "http://127.0.0.1:30110"; - - /** - * 默认kie的命名空间 - */ - protected String project = "default"; - - /** - * 获取配置 - * - * @return 配置 - */ - public static synchronized Config getInstance() { - if (singleInst == null) { - logger.warn("Config failed to init from configfile. Load config from hardcode."); - singleInst = new Config(); - } - return singleInst; - } - - public static int getTimeout_value() { - return getInstance().timeoutValue; - } - - public static String getDefaultGroup() { - return getInstance().defaultGroup; - } - - public static String getZookeeperUri() { - return getInstance().zookeeperUri; - } - - public static DynamicConfigType getDynamic_config_type() { - return getInstance().dynamicConfigType; - } - - /** - * 设置超时时间 - * - * @param time 超时时间 - */ - protected void setTimeoutValue(int time) { - this.timeoutValue = time; - } - - /** - * 设置配置组 - * - * @param defaultGroup group - */ - protected void setDefaultGroup(String defaultGroup) { - this.defaultGroup = defaultGroup; - } - - /** - * 设置zk uri - * - * @param uri 地址 - */ - protected void setZookeeperUri(String uri) { - this.zookeeperUri = uri; - } - - /** - * 设置动态配置类型 - * - * @param dynamicConfigType 动态配置类型 - */ - protected void setDynamicConfigType(DynamicConfigType dynamicConfigType) { - this.dynamicConfigType = dynamicConfigType; - } - - public String getKieUrl() { - return kieUrl; - } - - public void setKieUrl(String url) { - this.kieUrl = url; - } - - public String getProject() { - return project; - } - - public void setProject(String project) { - this.project = project; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/DynamicConfigurationFactoryServiceImpl.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/DynamicConfigurationFactoryServiceImpl.java deleted file mode 100644 index 0f71de88a3..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/DynamicConfigurationFactoryServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.KieDynamicConfigurationServiceImpl; -import com.huaweicloud.sermant.backend.service.dynamicconfig.nop.NopDynamicConfigurationService; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigType; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigurationFactoryService; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigurationService; -import com.huaweicloud.sermant.backend.service.dynamicconfig.zookeeper.ZookeeperDynamicConfigurationService; - -import org.springframework.stereotype.Component; - -/** - * - * The implementation for the DynamicConfigurationFactoryService - * - */ -@Component -public class DynamicConfigurationFactoryServiceImpl implements DynamicConfigurationFactoryService { - - /** - * 获取动态配置 - * - * @param dct 动态配置类型 - * @return 配置实例 - * @throws Exception 异常 - */ - protected DynamicConfigurationService getDynamicConfigurationService(DynamicConfigType dct) throws Exception { - - if (dct == DynamicConfigType.ZOO_KEEPER) { - return ZookeeperDynamicConfigurationService.getInstance(); - } - - if (dct == DynamicConfigType.KIE) { - return KieDynamicConfigurationServiceImpl.getInstance(); - } - - if (dct == DynamicConfigType.NOP) { - return NopDynamicConfigurationService.getInstance(); - } - - return null; - } - - @Override - public DynamicConfigurationService getDynamicConfigurationService() throws Exception { - return this.getDynamicConfigurationService(Config.getDynamic_config_type()); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/KieDynamicConfigurationServiceImpl.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/KieDynamicConfigurationServiceImpl.java deleted file mode 100644 index f897e9312b..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/KieDynamicConfigurationServiceImpl.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.Config; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.listener.SubscriberManager; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigurationListener; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigurationService; -import com.huaweicloud.sermant.backend.service.dynamicconfig.utils.LabelGroupUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * kie配置中心实现 - *

- * - * @author zhouss - * @since 2021-11-22 - */ -public class KieDynamicConfigurationServiceImpl implements DynamicConfigurationService { - private static final Logger LOGGER = LoggerFactory.getLogger(KieDynamicConfigurationServiceImpl.class); - - private static SubscriberManager subscriberManager; - - private static KieDynamicConfigurationServiceImpl instance; - - private final Map> groupKeyCache = new ConcurrentHashMap>(); - - private KieDynamicConfigurationServiceImpl() { - - } - - /** - * 获取实现单例 - * - * @return KieDynamicConfigurationService - */ - public static synchronized KieDynamicConfigurationServiceImpl getInstance() { - if (instance == null) { - instance = new KieDynamicConfigurationServiceImpl(); - subscriberManager = new SubscriberManager(Config.getInstance().getKieUrl()); - } - return instance; - } - - @Override - public boolean removeGroupListener(String key, String group, ConfigurationListener listener) { - return updateListener("GroupKey", group, listener, false); - } - - @Override - public boolean addGroupListener(String group, ConfigurationListener listener) { - return updateListener("GroupKey", group, listener, true); - } - - @Override - public boolean addConfigListener(String key, String group, ConfigurationListener listener) { - return updateListener(key, LabelGroupUtils.createLabelGroup( - Collections.singletonMap(fixSeparator(group, true), fixSeparator(key, false))), - listener, true); - } - - @Override - public boolean removeConfigListener(String key, String group, ConfigurationListener listener) { - throw new UnsupportedOperationException(); - } - - @Override - public String getConfig(String key, String group) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean publishConfig(String key, String group, String content) { - return subscriberManager.publishConfig(key, group, content); - } - - @Override - public String getDefaultGroup() { - return "sermant"; - } - - @Override - public long getDefaultTimeout() { - return 0; - } - - @Override - public List listConfigsFromGroup(String group) { - return groupKeyCache.get(group); - } - - /** - * 更新监听器(删除||添加) - * 若第一次添加监听器,则会将数据通知给监听器 - * - * @param key 监听键 - * @param group 分组, 针对KIE特别处理生成group方法{@link LabelGroupUtils#createLabelGroup(Map)} - * @param listener 对应改组的监听器 - * @param forSubscribe 是否为订阅 - * @return 更新是否成功 - */ - private synchronized boolean updateListener(String key, String group, ConfigurationListener listener, boolean forSubscribe) { - updateGroupKey(key, group, forSubscribe); - try { - if (forSubscribe) { - return subscriberManager.addGroupListener(group, listener); - } else { - return subscriberManager.removeGroupListener(group, listener); - } - } catch (Exception exception) { - LOGGER.warn("Subscribed kie request failed! raw key : " + key); - return false; - } - } - - private void updateGroupKey(String key, String group, boolean forSubscribe) { - List keys = groupKeyCache.get(group); - if (keys == null) { - keys = new ArrayList<>(); - } - if (forSubscribe) { - keys.remove(key); - } else { - keys.add(key); - } - groupKeyCache.put(group, keys); - } - - /** - * 去除路径分隔符 - * - * @param str key or group - * @param isGroup 是否为组 - * @return 修正值 - */ - private String fixSeparator(String str, boolean isGroup) { - if (str == null) { - if (isGroup) { - // 默认分组 - str = getDefaultGroup(); - } else { - throw new IllegalArgumentException("Key must not be empty!"); - } - } - return str.startsWith("/") ? str.substring(1) : str; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/AbstractClient.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/AbstractClient.java deleted file mode 100644 index da6ec04b42..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/AbstractClient.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http.DefaultHttpClient; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http.HttpClient; - -/** - * 抽象客户端 - * - * @author zhouss - * @since 2021-11-17 - */ -public abstract class AbstractClient implements Client { - protected final ClientUrlManager clientUrlManager; - - protected HttpClient httpClient; - - protected AbstractClient(ClientUrlManager clientUrlManager) { - this.clientUrlManager = clientUrlManager; - initDefaultClient(); - } - - protected AbstractClient(ClientUrlManager clientUrlManager, HttpClient httpClient) { - this.clientUrlManager = clientUrlManager; - if (httpClient != null) { - this.httpClient = httpClient; - } else { - initDefaultClient(); - } - } - - private void initDefaultClient() { - this.httpClient = new DefaultHttpClient(); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/Client.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/Client.java deleted file mode 100644 index dd927031ea..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/Client.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client; - -/** - * 客户端 - * - * @author zhouss - * @since 2021-11-17 - */ -public interface Client { -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/ClientUrlManager.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/ClientUrlManager.java deleted file mode 100644 index 2213f8ff89..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/ClientUrlManager.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.selector.url.UrlSelector; - -import java.util.Arrays; -import java.util.List; - -/** - * 客户端请求地址管理器 - * - * @author zhouss - * @since 2021-11-17 - */ -public class ClientUrlManager { - private final UrlSelector urlSelector = new UrlSelector(); - private List urls; - - public ClientUrlManager(String urls) { - resolveUrls(urls); - } - - /** - * 客户端请求地址 - * - * @return url - */ - public String getUrl() { - return urlSelector.select(urls); - } - - /** - * 解析url - * 默认多个url使用逗号隔开 - * - * @param rawUrls url字符串 - */ - private void resolveUrls(String rawUrls) { - if (rawUrls == null || rawUrls.trim().length() == 0) { - return; - } - urls = Arrays.asList(rawUrls.split(",")); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/DefaultHttpClient.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/DefaultHttpClient.java deleted file mode 100644 index 81c06cc21b..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/DefaultHttpClient.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.listener.SubscriberManager; - -import com.alibaba.fastjson.JSONObject; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * HTTP客户端 - * - * @author zhouss - * @since 2021-11-17 - */ -public class DefaultHttpClient implements - com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http.HttpClient { - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHttpClient.class); - - /** - * 默认超时时间 - */ - private static final int DEFAULT_TIMEOUT_MS = 5000; - - /** - * 最大的连接数 - * 该值建议 > {@link SubscriberManager}最大线程数MAX_THREAD_SIZE - */ - private static final int MAX_TOTAL = SubscriberManager.MAX_THREAD_SIZE * 2; - - /** - * 没分支最大连接数 - */ - private static final int DEFAULT_MAX_PER_ROUTE = 10; - - private final HttpClient httpClient; - - public DefaultHttpClient() { - httpClient = HttpClientBuilder.create().setDefaultRequestConfig( - RequestConfig.custom().setConnectTimeout(DEFAULT_TIMEOUT_MS) - .setSocketTimeout(DEFAULT_TIMEOUT_MS) - .setConnectionRequestTimeout(DEFAULT_TIMEOUT_MS) - .build() - ).setConnectionManager(buildConnectionManager()).build(); - } - - public DefaultHttpClient(RequestConfig requestConfig) { - this.httpClient = HttpClientBuilder.create() - .setDefaultRequestConfig(requestConfig) - .setConnectionManager(buildConnectionManager()) - .build(); - } - - - /** - * 配置连接池的主要目的是防止在发送请求时连接不够导致无法请求 - * 特别是针对订阅者 - * - * @return PoolingHttpClientConnectionManager - */ - private PoolingHttpClientConnectionManager buildConnectionManager() { - RegistryBuilder builder = RegistryBuilder.create(); - builder.register("http", PlainConnectionSocketFactory.INSTANCE); - // 如果需配置SSL 在此处注册https - Registry connectionSocketFactoryRegistry = builder.build(); - - // connection pool management - PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager( - connectionSocketFactoryRegistry); - connectionManager.setMaxTotal(MAX_TOTAL); - connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE); - return connectionManager; - } - - /** - * get请求 - * - * @param url 请求地址 - * @return HttpResult - */ - @Override - public HttpResult doGet(String url) { - return doGet(url, null, null); - } - - @Override - public HttpResult doGet(String url, RequestConfig requestConfig) { - return doGet(url, null, requestConfig); - } - - /** - * get请求 - * - * @param url 请求地址 - * @param headers 请求头 - * @return HttpResult - */ - @Override - public HttpResult doGet(String url, Map headers, RequestConfig requestConfig) { - final HttpGet httpGet = new HttpGet(url); - beforeRequest(httpGet, requestConfig, headers); - return execute(httpGet); - } - - @Override - public HttpResult doPost(String url, Map params) { - return doPost(url, params, null); - } - - @Override - public HttpResult doPost(String url, Map params, RequestConfig requestConfig) { - return doPost(url, params, requestConfig, new HashMap<>()); - } - - @Override - public HttpResult doPost(String url, Map params, RequestConfig requestConfig, - Map headers) { - HttpPost httpPost = new HttpPost(url); - beforeRequest(httpPost, requestConfig, headers); - addParams(httpPost, params); - return execute(httpPost); - } - - /** - * 执行请求 - * - * @param request 请求参数 - * @return HttpResult - */ - private HttpResult execute(HttpUriRequest request) { - HttpEntity entity = null; - HttpResponse response = null; - String result = null; - try { - response = this.httpClient.execute(request); - if (response == null) { - return HttpResult.error(); - } - entity = response.getEntity(); - if (entity == null) { - return new HttpResult(response.getStatusLine().getStatusCode(), "", response.getAllHeaders()); - } - result = EntityUtils.toString(entity, "UTF-8"); - } catch (IOException ex) { - LOGGER.warn(String.format("Execute request failed, %s", ex.getMessage())); - } finally { - consumeEntity(entity); - } - if (response == null) { - return HttpResult.error(); - } - return new HttpResult(response.getStatusLine().getStatusCode(), result, response.getAllHeaders()); - } - - private void consumeEntity(HttpEntity entity) { - try { - EntityUtils.consume(entity); - } catch (IOException ex) { - LOGGER.warn(String.format("Consumed http entity failed, %s", ex.getMessage())); - } - } - - private void addParams(HttpPost httpPost, Map params) { - if (params == null || params.isEmpty()) { - return; - } - httpPost.setEntity(new StringEntity(JSONObject.toJSONString(params), ContentType.APPLICATION_JSON)); - } - - private void beforeRequest(HttpRequestBase httpRequest, RequestConfig requestConfig, Map headers) { - addDefaultHeaders(httpRequest); - addHeaders(httpRequest, headers); - if (requestConfig != null) { - httpRequest.setConfig(requestConfig); - } - } - - private void addHeaders(HttpRequestBase base, Map headers) { - if (headers != null && !headers.isEmpty()) { - for (Map.Entry entry : headers.entrySet()) { - base.addHeader(entry.getKey(), entry.getValue()); - } - } - } - - /** - * 添加默认的请求头 - */ - private void addDefaultHeaders(HttpRequestBase base) { - base.addHeader(HttpHeaders.CONTENT_TYPE, "application/json; charset=utf-8"); - base.addHeader(HttpHeaders.USER_AGENT, "sermant/client"); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/HttpClient.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/HttpClient.java deleted file mode 100644 index 0b3c4179f3..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/HttpClient.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.Client; -import org.apache.http.client.config.RequestConfig; - -import java.util.Map; - -/** - * http请求 - * - * @author zhouss - * @since 2021-11-17 - */ -public interface HttpClient extends Client { - - /** - * get请求 - * - * @param url 请求地址 - * @param headers 请求头 - * @param requestConfig 请求配置 - * @return HttpResult - */ - HttpResult doGet(String url, Map headers, RequestConfig requestConfig); - - /** - * get请求 - * - * @param url 请求地址 - * @return HttpResult - */ - HttpResult doGet(String url); - - /** - * get请求 - * - * @param url 请求地址 - * @param requestConfig 请求配置 - * @return HttpResult - */ - HttpResult doGet(String url, RequestConfig requestConfig); - - /** - * post请求 - * - * @param url 请求地址 - * @param params 请求参数 - * @return HttpResult - */ - HttpResult doPost(String url, Map params); - - /** - * post请求 - * - * @param url 请求地址 - * @param params 请求参数 - * @param requestConfig 请求配置 - * @return HttpResult - */ - HttpResult doPost(String url, Map params, RequestConfig requestConfig); - - /** - * post请求 - * - * @param url 请求地址 - * @param params 请求参数 - * @param headers 请求头 - * @param requestConfig 请求配置 - * @return HttpResult - */ - HttpResult doPost(String url, Map params, RequestConfig requestConfig, Map headers); - -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/HttpResult.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/HttpResult.java deleted file mode 100644 index 1c23617a57..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/http/HttpResult.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http; - -import org.apache.http.Header; -import org.apache.http.HttpStatus; - -import java.util.HashMap; -import java.util.Map; - -/** - * httpclient响应结果 - * - * @author zhouss - * @since 2021-11-17 - */ -public class HttpResult { - /** - * 错误请求响应码 - */ - public static final int ERROR_CODE = -1; - - /** - * 可接受编号 - * SC_OK : 正常返回 - * SC_NOT_MODIFIED : 未做任何修改 - */ - private final int[] okCodes = {HttpStatus.SC_OK, HttpStatus.SC_NOT_MODIFIED}; - - /** - * 响应码 - */ - private int code; - - /** - * 响应结果 - */ - private String result; - - private Map responseHeaders; - - public HttpResult(int code, String result, Header[] headers) { - this.code = code; - this.result = result; - if (headers != null) { - responseHeaders = new HashMap(headers.length); - for (Header header : headers) { - responseHeaders.put(header.getName(), header.getValue()); - } - } - } - - /** - * 错误响应结果 - * - * @return HttpResult - */ - public static HttpResult error() { - return new HttpResult(ERROR_CODE, null, null); - } - - /** - * 响应是否出错 - * - * @return 是否错误响应 - */ - public boolean isError() { - for (int okCode : okCodes) { - if (okCode == this.code) { - return false; - } - } - return true; - } - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public String getResult() { - return result; - } - - public Map getResponseHeaders() { - return responseHeaders; - } - - public void setResponseHeaders(Map responseHeaders) { - this.responseHeaders = responseHeaders; - } - - public void setResult(String result) { - this.result = result; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieClient.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieClient.java deleted file mode 100644 index 0dd54521bc..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieClient.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.Config; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.AbstractClient; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.ClientUrlManager; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http.HttpClient; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http.HttpResult; - -import org.apache.http.HttpStatus; - -import java.util.HashMap; -import java.util.Map; - -/** - * kie客户端 - * - * @author zhouss - * @since 2021-11-17 - */ -public class KieClient extends AbstractClient { - - private static final String KIE_API_TEMPLATE = "/v1/%s/kie/kv?"; - - private final ResultHandler defaultHandler = new ResultHandler.DefaultResultHandler(); - - private String kieApi; - - /** - * Constructor. - * - * @param clientUrlManager clientUrlManager - */ - public KieClient(ClientUrlManager clientUrlManager) { - this(clientUrlManager, Config.getInstance().getProject()); - } - - /** - * Constructor. - * - * @param clientUrlManager clientUrlManager - * @param project project - */ - public KieClient(ClientUrlManager clientUrlManager, String project) { - this(clientUrlManager, null, project); - } - - /** - * Constructor. - * - * @param clientUrlManager clientUrlManager - * @param httpClient httpClient - * @param project project - */ - public KieClient(ClientUrlManager clientUrlManager, HttpClient httpClient, String project) { - super(clientUrlManager, httpClient); - kieApi = String.format(KIE_API_TEMPLATE, project); - } - - public void setProject(String project) { - this.kieApi = String.format(KIE_API_TEMPLATE, project); - } - - /** - * 插叙Kie配置 - * - * @param request 请求体 - * @return KieResponse - */ - public KieResponse queryConfigurations(KieRequest request) { - return queryConfigurations(request, defaultHandler); - } - - /** - * 查询Kie配置 - * - * @param request 请求体 - * @param responseHandler http结果处理器 - * @param 转换后的目标类型 - * @return 响应结果 - */ - public T queryConfigurations(KieRequest request, ResultHandler responseHandler) { - if (request == null || responseHandler == null) { - return null; - } - final StringBuilder requestUrl = new StringBuilder().append(clientUrlManager.getUrl()).append(kieApi); - requestUrl.append(formatNullString(request.getLabelCondition())) - .append("&revision=") - .append(formatNullString(request.getRevision())); - if (request.isAccurateMatchLabel()) { - requestUrl.append("&match=exact"); - } - if (request.getWait() != null) { - requestUrl.append("&wait=").append(formatNullString(request.getWait())).append("s"); - } - final HttpResult httpResult = httpClient.doGet(requestUrl.toString(), request.getRequestConfig()); - return responseHandler.handle(httpResult); - } - - /** - * 发布配置 - * - * @param key 请求键 - * @param labels 标签 - * @param content 配置 - * @param enabled 状态 - * @return 是否发布成功 - */ - public boolean publishConfig(String key, Map labels, String content, boolean enabled) { - final Map params = new HashMap<>(); - params.put("key", key); - params.put("value", content); - params.put("labels", labels); - params.put("status", enabled ? "enabled" : "disabled"); - final HttpResult httpResult = this.httpClient.doPost(clientUrlManager.getUrl() + kieApi, params); - return httpResult.getCode() == HttpStatus.SC_OK; - } - - private String formatNullString(String val) { - if (val == null || val.trim().length() == 0) { - return ""; - } - return val; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieConfigEntity.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieConfigEntity.java deleted file mode 100644 index 1facec22fc..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieConfigEntity.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie; - -import java.util.HashMap; -import java.util.Map; - -/** - * Kie响应单个配置实体 - * - * @author zhouss - * @since 2021-11-17 - */ -public class KieConfigEntity { - private String id; - private String key; - private Map labels = new HashMap(); - private String value; - private String valueType; - private String status; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public Map getLabels() { - return labels; - } - - public void setLabels(Map labels) { - this.labels = labels; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getValueType() { - return valueType; - } - - public void setValueType(String valueType) { - this.valueType = valueType; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieListenerWrapper.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieListenerWrapper.java deleted file mode 100644 index 4c020fb1b0..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieListenerWrapper.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.listener.KvDataHolder; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.listener.SubscriberManager; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigChangeType; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigChangedEvent; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigurationListener; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Locale; -import java.util.Map; - -/** - * listener封装,关联任务执行器 - * - * @author zhouss - * @since 2021-11-18 - */ -public class KieListenerWrapper { - private static final Logger LOGGER = LoggerFactory.getLogger(KieListenerWrapper.class); - - private ConfigurationListener configurationListener; - - private SubscriberManager.Task task; - - private String group; - - private final KvDataHolder kvDataHolder; - - /** - * listener封装,关联任务执行器 - * - * @param group group - * @param configurationListener listen - * @param kvDataHolder holder - */ - public KieListenerWrapper(String group, ConfigurationListener configurationListener, KvDataHolder kvDataHolder) { - this.group = group; - this.configurationListener = configurationListener; - this.kvDataHolder = kvDataHolder; - } - - public void notifyListener(KvDataHolder.EventDataHolder eventDataHolder) { - if (!eventDataHolder.getAdded().isEmpty()) { - // 新增事件 - notify(eventDataHolder.getAdded(), ConfigChangeType.ADDED); - } - if (!eventDataHolder.getDeleted().isEmpty()) { - // 删除事件 - notify(eventDataHolder.getDeleted(), ConfigChangeType.DELETED); - } - if (!eventDataHolder.getModified().isEmpty()) { - // 修改事件 - notify(eventDataHolder.getModified(), ConfigChangeType.MODIFIED); - } - } - - private void notify(Map configData, ConfigChangeType configChangeType) { - for (Map.Entry entry : configData.entrySet()) { - try { - configurationListener.process(new ConfigChangedEvent(entry.getKey(), this.group, entry.getValue(), - configChangeType)); - } catch (Throwable ex) { - LOGGER.warn(String.format(Locale.ENGLISH, "Process config data failed, key: [%s], group: [%s]", - entry.getKey(), this.group)); - } - } - } - - public ConfigurationListener getConfigurationListener() { - return configurationListener; - } - - public void setConfigurationListener(ConfigurationListener configurationListener) { - this.configurationListener = configurationListener; - } - - public SubscriberManager.Task getTask() { - return task; - } - - public void setTask(SubscriberManager.Task task) { - this.task = task; - } - - public KvDataHolder getKvDataHolder() { - return kvDataHolder; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieRequest.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieRequest.java deleted file mode 100644 index ff58cb4fb0..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieRequest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie; - -import org.apache.http.client.config.RequestConfig; - -/** - * kie请求体 - * - * @author zhouss - * @since 2021-11-17 - */ -public class KieRequest { - /** - * 标签条件 - * 例如label=version:1.0 查询含标签版本为1.0的kv - */ - private String labelCondition; - - /** - * 与kie建立连接等待时间,单位S - * 在这段时间会一直等待,如果相关kie有变更则会返回 - * 官方说明: - * "wait until any kv changed. for example wait=5s, server will not response until 5 seconds, - * during that time window, if any kv changed, server will return 200 and kv list, - * otherwise return 304 and empty body", - * - * 建议时间不超过50s,超过50s的将以50s计算 - */ - private String wait; - - /** - * 请求版本 - * 若配置中心版本高于当前版本,则会返回新数据 - */ - private String revision; - - /** - * http请求配置 - */ - private RequestConfig requestConfig; - - /** - * 匹配标签 - * true : 精确匹配标签的kv - * false : 匹配包含labelCondition的所有kv - */ - private boolean accurateMatchLabel = true; - - public RequestConfig getRequestConfig() { - return requestConfig; - } - - public void setRequestConfig(RequestConfig requestConfig) { - this.requestConfig = requestConfig; - } - - public String getLabelCondition() { - return labelCondition; - } - - public KieRequest setLabelCondition(String labelCondition) { - this.labelCondition = labelCondition; - return this; - } - - public boolean isAccurateMatchLabel() { - return accurateMatchLabel; - } - - public void setAccurateMatchLabel(boolean accurateMatchLabel) { - this.accurateMatchLabel = accurateMatchLabel; - } - - public String getWait() { - return wait; - } - - public KieRequest setWait(String wait) { - this.wait = wait; - return this; - } - - public String getRevision() { - return revision; - } - - public KieRequest setRevision(String revision) { - this.revision = revision; - return this; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - - KieRequest that = (KieRequest) obj; - - return labelCondition != null ? labelCondition.equals(that.labelCondition) : that.labelCondition == null; - } - - @Override - public int hashCode() { - return labelCondition != null ? labelCondition.hashCode() : 0; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieResponse.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieResponse.java deleted file mode 100644 index e39512a5c5..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieResponse.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie; - -import java.util.List; - -/** - * 响应结果 - * - * @author zhouss - * @since 2021-11-17 - */ -public class KieResponse { - /** - * 配置总数 - */ - private Integer total; - - /** - * kv数据 - */ - private List data; - - /** - * 响应版本 - */ - private String revision; - - /** - * 是否改变 - */ - private boolean changed = true; - - public String getRevision() { - return revision; - } - - public void setRevision(String revision) { - this.revision = revision; - } - - public Integer getTotal() { - return total; - } - - public void setTotal(Integer total) { - this.total = total; - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - - public boolean isChanged() { - return changed; - } - - public void setChanged(boolean changed) { - this.changed = changed; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieSubscriber.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieSubscriber.java deleted file mode 100644 index c2565b2b54..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/KieSubscriber.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie; - -/** - * 增加是否为长请求判断 - * - * @author zhouss - * @since 2021-11-18 - */ -public class KieSubscriber { - /** - * 最大等待时间 - * 50S - */ - private static final int MAX_WAIT = 50; - - private Boolean isLongConnectionRequest; - - private final KieRequest kieRequest; - - public KieSubscriber(KieRequest kieRequest) { - this.kieRequest = kieRequest; - } - - /** - * 是否为长请求 - * - * @return boolean - */ - public boolean isLongConnectionRequest() { - String wait = kieRequest.getWait(); - if (this.isLongConnectionRequest != null) { - return this.isLongConnectionRequest; - } - if (wait == null || wait.trim().length() == 0) { - this.isLongConnectionRequest = false; - return false; - } - try { - final int parseWait = Integer.parseInt(wait); - this.isLongConnectionRequest = parseWait >= 1; - if (parseWait > MAX_WAIT) { - kieRequest.setWait(String.valueOf(MAX_WAIT)); - } - } catch (Exception ex) { - this.isLongConnectionRequest = false; - } - return this.isLongConnectionRequest; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - - KieSubscriber that = (KieSubscriber) obj; - - if (!isLongConnectionRequest.equals(that.isLongConnectionRequest)) { - return false; - } - return kieRequest != null ? kieRequest.equals(that.kieRequest) : that.kieRequest == null; - } - - @Override - public int hashCode() { - int isLongConnect = (isLongConnectionRequest == null || !isLongConnectionRequest) ? 1 : 0; - return 31 * isLongConnect + (kieRequest != null ? kieRequest.hashCode() : 0); - } - - public KieRequest getKieRequest() { - return kieRequest; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/ResultHandler.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/ResultHandler.java deleted file mode 100644 index 6882195628..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/client/kie/ResultHandler.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.http.HttpResult; - -import com.alibaba.fastjson.JSONObject; - -import org.apache.http.HttpStatus; - -import java.util.Iterator; -import java.util.List; - -/** - * Kie结果处理器 - * - * @author zhouss - * @since 2021-11-17 - */ -public interface ResultHandler { - /** - * 处理响应结果 - * - * @param result 响应 - * @return R - */ - R handle(HttpResult result); - - /** - * 默认结果处理器 - */ - class DefaultResultHandler implements ResultHandler { - private final boolean onlyEnabled; - public DefaultResultHandler() { - onlyEnabled = true; - } - - public DefaultResultHandler(boolean onlyEnabled) { - this.onlyEnabled = onlyEnabled; - } - - @Override - public KieResponse handle(HttpResult result) { - if (result.isError()) { - return null; - } - final String content = result.getResult(); - final KieResponse kieResponse = JSONObject.parseObject(content, KieResponse.class); - if (kieResponse == null) { - return null; - } - if (result.getCode() == HttpStatus.SC_NOT_MODIFIED) { - // KIE如果响应状态码为304,则表示没有相关键变更 - kieResponse.setChanged(false); - } - // 过滤掉disabled的kv配置 - final List data = kieResponse.getData(); - if (data == null) { - return kieResponse; - } - kieResponse.setRevision(String.valueOf(result.getResponseHeaders().get("X-Kie-Revision"))); - filter(data); - kieResponse.setTotal(data.size()); - return kieResponse; - } - - /** - * 过滤未开启的kv - * - * @param data kv列表 - */ - private void filter(List data) { - if (!onlyEnabled) { - return; - } - final Iterator iterator = data.iterator(); - while (iterator.hasNext()) { - final KieConfigEntity next = iterator.next(); - if ("disabled".equals(next.getStatus())) { - iterator.remove(); - } - } - } - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/constants/KieConstants.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/constants/KieConstants.java deleted file mode 100644 index a492f39c05..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/constants/KieConstants.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.constants; - -/** - * Kie配置常量 - * - * @author zhouss - * @since 2021-11-23 - */ -public class KieConstants { - /** - * 核心线程数 - */ - public static final int CORE_THREAD_SIZE = 1; - - /** - * 最大线程数 - */ - public static final int MAX_THREAD_SIZE = 3; - - /** - * 队列长度 - */ - public static final int QUEUE_SIZE = 100; -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/listener/KvDataHolder.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/listener/KvDataHolder.java deleted file mode 100644 index e3d360a024..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/listener/KvDataHolder.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.listener; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie.KieConfigEntity; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie.KieResponse; - -import java.util.HashMap; -import java.util.Map; - -/** - * 监听键响应数据 - * 用于对比新旧数据并保留旧数据 - * - * @author zhouss - * @since 2021-11-18 - */ -public class KvDataHolder { - /** - * 当前数据 - */ - private Map currentData; - - /** - * 分析最新的数据 - * - * @param response 最新数据 - * @return EventDataHolder - */ - public EventDataHolder analyzeLatestData(KieResponse response) { - final Map latestData = formatKieResponse(response); - final EventDataHolder eventDataHolder = new EventDataHolder(); - if (currentData != null) { - if (latestData.isEmpty()) { - eventDataHolder.deleted.putAll(currentData); - } else { - Map temp = new HashMap(currentData); - for (Map.Entry entry : latestData.entrySet()) { - final String value = currentData.get(entry.getKey()); - if (value == null) { - // 增加的键 - eventDataHolder.added.put(entry.getKey(), entry.getValue()); - } else { - // 如果存在该键,则比对值是否相等 - if (!value.equals(entry.getValue())) { - // 修改 - eventDataHolder.modified.put(entry.getKey(), entry.getValue()); - } - } - temp.remove(entry.getKey()); - } - // temp留下的键即为删除的 - eventDataHolder.deleted.putAll(temp); - } - } else { - eventDataHolder.added.putAll(latestData); - } - currentData = latestData; - return eventDataHolder; - } - - private Map formatKieResponse(KieResponse response) { - final HashMap latestData = new HashMap(); - if (response == null || response.getData() == null || response.getData().isEmpty()) { - return latestData; - } - for (KieConfigEntity entity : response.getData()) { - latestData.put(entity.getKey(), entity.getValue()); - } - return latestData; - } - - /** - * 数据变更 - */ - public static class EventDataHolder { - /** - * 修改的key - */ - private Map modified; - - /** - * 删除的key - */ - private Map deleted; - - /** - * 新增key - */ - private Map added; - - public EventDataHolder() { - modified = new HashMap(); - deleted = new HashMap(); - added = new HashMap(); - } - - public Map getModified() { - return modified; - } - - public void setModified(Map modified) { - this.modified = modified; - } - - public Map getDeleted() { - return deleted; - } - - public void setDeleted(Map deleted) { - this.deleted = deleted; - } - - public Map getAdded() { - return added; - } - - public void setAdded(Map added) { - this.added = added; - } - - public boolean isChanged() { - return !added.isEmpty() || !deleted.isEmpty() || !modified.isEmpty(); - } - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/listener/SubscriberManager.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/listener/SubscriberManager.java deleted file mode 100644 index f337be8cdc..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/listener/SubscriberManager.java +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.listener; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.ClientUrlManager; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie.KieClient; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie.KieListenerWrapper; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie.KieRequest; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie.KieResponse; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.client.kie.KieSubscriber; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigurationListener; -import com.huaweicloud.sermant.backend.service.dynamicconfig.utils.LabelGroupUtils; -import com.huaweicloud.sermant.backend.util.BackendThreadFactory; - -import org.apache.commons.lang3.StringUtils; -import org.apache.http.client.config.RequestConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * 监听器管理 - * - * @author zhouss - * @since 2021-11-17 - */ -public class SubscriberManager { - /** - * 基础时间 - */ - public static final long BASE_MS = 3000L; - - /** - * 最大线程数 - */ - public static final int MAX_THREAD_SIZE = 100; - - private static final Logger LOGGER = LoggerFactory.getLogger(SubscriberManager.class); - - /** - * 线程数 - */ - private static final int THREAD_SIZE = 5; - - /** - * 秒转换为毫秒 - */ - private static final int SECONDS_UNIT = 1000; - - /** - * 定时请求间隔 - */ - private static final int SCHEDULE_REQUEST_INTERVAL_MS = 5000; - - /** - * 等待时间 - */ - private static final String WAIT = "20"; - - /** - * 长连接拉取间隔 - */ - private static final long LONG_CONNECTION_REQUEST_INTERVAL_MS = 2000L; - - /** - * 当前长连接请求数 要求最大连接数必须小于 MAX_THREAD_SIZE - */ - private final AtomicInteger curLongConnectionRequestCount = new AtomicInteger(0); - - /** - * map 监听键, 监听该键的监听器列表 - */ - private final Map> listenerMap = new ConcurrentHashMap<>(); - - /** - * kie客户端 - */ - private final KieClient kieClient; - - /** - * 订阅执行器 最大支持MAX_THREAD_SIZE个任务 由于是长连接请求,必然会占用线程,因此这里不考虑将任务存在队列中 - */ - private final ThreadPoolExecutor longRequestExecutor = new ThreadPoolExecutor(THREAD_SIZE, MAX_THREAD_SIZE, - 0, TimeUnit.MILLISECONDS, new SynchronousQueue<>(), - new BackendThreadFactory("kie-subscribe-long-task")); - - /** - * 快速返回的请求 - */ - private ScheduledExecutorService scheduledExecutorService; - - /** - * 指定KIE地址 - * - * @param urls KIE地址列表 - */ - public SubscriberManager(String urls) { - kieClient = new KieClient(new ClientUrlManager(urls)); - } - - /** - * 添加组监听 - * - * @param group 标签组 - * @param listener 监听器 - * @return 是否添加成功 - */ - public boolean addGroupListener(String group, ConfigurationListener listener) { - try { - return subscribe(new KieRequest().setLabelCondition(LabelGroupUtils.getLabelCondition(group)).setWait(WAIT), - listener); - } catch (Exception ex) { - LOGGER.warn(String.format(Locale.ENGLISH, "Add group listener failed, %s", ex.getMessage())); - return false; - } - } - - /** - * 移除组监听 - * - * @param group 标签组 - * @param listener 监听器 - * @return 是否添加成功 - */ - public boolean removeGroupListener(String group, ConfigurationListener listener) { - try { - return unSubscribe( - new KieRequest().setLabelCondition(LabelGroupUtils.getLabelCondition(group)).setWait(WAIT), listener); - } catch (Exception ex) { - LOGGER.warn(String.format(Locale.ENGLISH, "Removed group listener failed, %s", ex.getMessage())); - return false; - } - } - - /** - * 发布配置 - * - * @param key 配置键 - * @param group 分组 - * @param content 配置内容 - * @return 是否发布成功 - */ - public boolean publishConfig(String key, String group, String content) { - if (StringUtils.isEmpty(key)) { - return false; - } - final Map labels = LabelGroupUtils.resolveGroupLabels(group); - return kieClient.publishConfig(key, labels, content, true); - } - - /** - * 注册监听器 - * - * @param kieRequest 请求 - * @param configurationListener 监听器 - * @return 订阅成功返回true - */ - public boolean subscribe(KieRequest kieRequest, ConfigurationListener configurationListener) { - final KieSubscriber kieSubscriber = new KieSubscriber(kieRequest); - Task task; - KieListenerWrapper kieListenerWrapper = new KieListenerWrapper(kieRequest.getLabelCondition(), - configurationListener, new KvDataHolder()); - if (!kieSubscriber.isLongConnectionRequest()) { - task = new ShortTimerTask(kieSubscriber, kieListenerWrapper); - } else { - if (exceedMaxLongRequestCount()) { - LOGGER.warn(String.format(Locale.ENGLISH, - "Exceeded max long connection request subscribers, the max number is %s, it will be discarded!", - curLongConnectionRequestCount.get())); - return false; - } - buildRequestConfig(kieRequest); - task = new LoopPullTask(kieSubscriber, kieListenerWrapper); - firstRequest(kieRequest, kieListenerWrapper); - } - List configurationListeners = listenerMap.get(kieSubscriber); - if (configurationListeners == null) { - configurationListeners = new ArrayList<>(); - } - kieListenerWrapper.setTask(task); - configurationListeners.add(kieListenerWrapper); - listenerMap.put(kieSubscriber, configurationListeners); - executeTask(task); - return true; - } - - /** - * 是否超过最大限制长连接任务数 - * - * @return boolean - */ - private boolean exceedMaxLongRequestCount() { - return curLongConnectionRequestCount.incrementAndGet() > MAX_THREAD_SIZE; - } - - /** - * 针对长请求的场景需要做第一次拉取,获取已有的数据 - * - * @param kieRequest 请求体 - * @param kieListenerWrapper 监听器 - */ - public void firstRequest(KieRequest kieRequest, KieListenerWrapper kieListenerWrapper) { - try { - final KieRequest cloneRequest = new KieRequest().setRevision(kieRequest.getRevision()) - .setLabelCondition(kieRequest.getLabelCondition()); - final KieResponse kieResponse = kieClient.queryConfigurations(cloneRequest); - if (kieResponse != null && kieResponse.isChanged()) { - tryPublishEvent(kieResponse, kieListenerWrapper); - kieRequest.setRevision(kieResponse.getRevision()); - } - } catch (Exception ex) { - LOGGER.warn(String.format(Locale.ENGLISH, "Pull the first request failed! %s", ex.getMessage())); - } - } - - /** - * 取消订阅 - * - * @param kieRequest 请求体 - * @param configurationListener 监听器 - * @return 取消订阅成功 - */ - public boolean unSubscribe(KieRequest kieRequest, ConfigurationListener configurationListener) { - for (Map.Entry> next : listenerMap.entrySet()) { - if (!next.getKey().getKieRequest().equals(kieRequest)) { - continue; - } - final Iterator iterator = next.getValue().iterator(); - while (iterator.hasNext()) { - final KieListenerWrapper listenerWrapper = iterator.next(); - if (listenerWrapper.getConfigurationListener() == configurationListener) { - iterator.remove(); - listenerWrapper.getTask().stop(); - LOGGER.info(String.format(Locale.ENGLISH, "%s has been stopped!", - configurationListener.getClass().getName())); - return true; - } - } - } - LOGGER.warn(String.format(Locale.ENGLISH, "The subscriber of group %s not found!", - kieRequest.getLabelCondition())); - return false; - } - - private void buildRequestConfig(KieRequest kieRequest) { - int wait = (Integer.parseInt(kieRequest.getWait()) + 1) * SECONDS_UNIT; - if (kieRequest.getRequestConfig() == null) { - kieRequest.setRequestConfig(RequestConfig.custom() - .setConnectionRequestTimeout(wait) - .setConnectTimeout(wait) - .setSocketTimeout(wait) - .build()); - } - } - - private void executeTask(final Task task) { - try { - if (task.isLongConnectionRequest()) { - longRequestExecutor.execute(new TaskRunnable(task)); - } else { - if (scheduledExecutorService == null) { - synchronized (SubscriberManager.class) { - scheduledExecutorService = new ScheduledThreadPoolExecutor(THREAD_SIZE, - new BackendThreadFactory("kie-subscribe-task")); - } - } - scheduledExecutorService.scheduleAtFixedRate( - new TaskRunnable(task), 0, SCHEDULE_REQUEST_INTERVAL_MS, TimeUnit.MILLISECONDS); - } - } catch (RejectedExecutionException ex) { - LOGGER.warn(String.format(Locale.ENGLISH, "Rejected the task %s, %s", - task.getClass(), ex.getMessage())); - } - } - - private void tryPublishEvent(KieResponse kieResponse, KieListenerWrapper kieListenerWrapper) { - final KvDataHolder kvDataHolder = kieListenerWrapper.getKvDataHolder(); - final KvDataHolder.EventDataHolder eventDataHolder = kvDataHolder.analyzeLatestData(kieResponse); - if (eventDataHolder.isChanged()) { - kieListenerWrapper.notifyListener(eventDataHolder); - } - } - - /** - * 请求任务 - * - * @since 2021-11-17 - */ - static class TaskRunnable implements Runnable { - private final Task task; - - TaskRunnable(Task task) { - this.task = task; - } - - @Override - public void run() { - try { - task.execute(); - } catch (Exception ex) { - LOGGER.warn(String.format(Locale.ENGLISH, "The error occurred when execute task , %s", - ex.getMessage())); - } - } - } - - /** - * 任务定义 - * - * @since 2021-11-17 - */ - public interface Task { - /** - * 任务执行 - */ - void execute(); - - /** - * 是否为长时间保持连接的请求 - * - * @return boolean - */ - boolean isLongConnectionRequest(); - - /** - * 任务终止 - */ - void stop(); - } - - /** - * 抽象任务 - * - * @since 2021-11-17 - */ - abstract static class AbstractTask implements Task { - protected volatile boolean isContinue = true; - - @Override - public void execute() { - if (!isContinue) { - return; - } - executeInner(); - } - - @Override - public void stop() { - isContinue = false; - } - - /** - * 子类执行方法 - */ - public abstract void executeInner(); - } - - /** - * 定时短期任务 - * - * @since 2021-11-17 - */ - class ShortTimerTask extends AbstractTask { - private final KieSubscriber kieSubscriber; - - private final KieListenerWrapper kieListenerWrapper; - - ShortTimerTask(KieSubscriber kieSubscriber, KieListenerWrapper kieListenerWrapper) { - this.kieSubscriber = kieSubscriber; - this.kieListenerWrapper = kieListenerWrapper; - } - - @Override - public void executeInner() { - final KieResponse kieResponse = kieClient.queryConfigurations(kieSubscriber.getKieRequest()); - if (kieResponse != null && kieResponse.isChanged()) { - tryPublishEvent(kieResponse, kieListenerWrapper); - kieSubscriber.getKieRequest().setRevision(kieResponse.getRevision()); - } - } - - @Override - public boolean isLongConnectionRequest() { - return false; - } - } - - /** - * 长连接任务 - * - * @since 2021-11-17 - */ - class LoopPullTask extends AbstractTask { - private final KieSubscriber kieSubscriber; - - private final KieListenerWrapper kieListenerWrapper; - - private int failCount; - - LoopPullTask(KieSubscriber kieSubscriber, KieListenerWrapper kieListenerWrapper) { - this.kieSubscriber = kieSubscriber; - this.kieListenerWrapper = kieListenerWrapper; - } - - @Override - public void executeInner() { - try { - final KieResponse kieResponse = kieClient.queryConfigurations(kieSubscriber.getKieRequest()); - if (kieResponse != null && kieResponse.isChanged()) { - tryPublishEvent(kieResponse, kieListenerWrapper); - kieSubscriber.getKieRequest().setRevision(kieResponse.getRevision()); - } - - // 间隔一段时间拉取,减轻服务压力;如果在间隔时间段内有键变更,服务可以通过传入的revision判断是否需要将最新的数据立刻返回,不会存在键监听不到的问题 - this.failCount = 0; - SubscriberManager.this.executeTask(new SleepCallBackTask(this, LONG_CONNECTION_REQUEST_INTERVAL_MS)); - } catch (Exception ex) { - LOGGER.warn(String.format(Locale.ENGLISH, "pull kie config failed, %s, it will rePull", - ex.getMessage())); - ++failCount; - SubscriberManager.this.executeTask(new SleepCallBackTask(this, failCount)); - } - } - - @Override - public boolean isLongConnectionRequest() { - return kieSubscriber.isLongConnectionRequest(); - } - } - - /** - * 等待执行任务, 等待一定的时间执行 - * - * @since 2021-11-17 - */ - class SleepCallBackTask extends AbstractTask { - private final Task nextTask; - - private int failedCount; - - private long waitTimeMs; - - SleepCallBackTask(Task nextTask, int failedCount) { - this.nextTask = nextTask; - this.failedCount = failedCount; - } - - SleepCallBackTask(Task nextTask, long waitTimeMs) { - this.nextTask = nextTask; - this.waitTimeMs = waitTimeMs; - } - - @Override - public void executeInner() { - long maxWaitMs = Duration.ofHours(1L).toMillis(); - long wait; - if (waitTimeMs != 0) { - wait = Math.min(waitTimeMs, maxWaitMs); - } else { - wait = Math.min(maxWaitMs, BASE_MS * failedCount * failedCount); - } - try { - Thread.sleep(wait); - SubscriberManager.this.executeTask(nextTask); - } catch (InterruptedException ignored) { - // ignored - } - } - - @Override - public boolean isLongConnectionRequest() { - return nextTask.isLongConnectionRequest(); - } - - @Override - public void stop() { - nextTask.stop(); - } - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/SelectStrategy.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/SelectStrategy.java deleted file mode 100644 index 2b6c29a5ce..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/SelectStrategy.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.selector; - -import java.util.List; -import java.util.Random; - -/** - * 选择策略 - * - * @author zhouss - * @since 2021-11-17 - */ -public interface SelectStrategy { - - /** - * 选择 - * - * @param list 目标集合 - * @return 确定的目标 - */ - R select(List list); - - /** - * 轮询策略 - * - * @param 集合类型 - */ - class RoundStrategy implements SelectStrategy { - private int index = 0; - - @Override - public R select(List list) { - if (list == null || list.isEmpty()) { - return null; - } - index++; - int selectIndex = Math.abs(index) % list.size(); - if (index == Integer.MAX_VALUE) { - index = 0; - } - return list.get(selectIndex); - } - } - - /** - * 随机选择策略 - * - * @param 集合类型 - */ - class RandomStrategy implements SelectStrategy { - private final Random random = new Random(); - @Override - public R select(List list) { - if (list == null || list.isEmpty()) { - return null; - } - return list.get(random.nextInt(list.size())); - } - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/Selector.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/Selector.java deleted file mode 100644 index 7b0b0d6d3f..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/Selector.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.selector; - -import java.util.List; - -/** - * 选择器 - * - * @author zhouss - * @since 2021-11-17 - */ -public interface Selector { - /** - * 选择 - * - * @param list 目标集合 - * @return 确定的目标 - */ - R select(List list); - - /** - * 选择 - * - * @param strategy 选择策略 - * @param list 目标集合 - * @return 确定的目标 - */ - R select(List list, SelectStrategy strategy); -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/url/UrlSelector.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/url/UrlSelector.java deleted file mode 100644 index 2e3eb78881..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/kie/selector/url/UrlSelector.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.kie.selector.url; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.selector.SelectStrategy; -import com.huaweicloud.sermant.backend.service.dynamicconfig.kie.selector.Selector; - -import java.util.List; - -/** - * url - * - * @author zhouss - * @since 2021-11-17 - */ -public class UrlSelector implements Selector { - - private final SelectStrategy defaultStrategy = new SelectStrategy.RoundStrategy(); - - @Override - public String select(List list) { - return defaultStrategy.select(list); - } - - @Override - public String select(List list, SelectStrategy strategy) { - return strategy.select(list); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/nop/NopDynamicConfigurationService.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/nop/NopDynamicConfigurationService.java deleted file mode 100644 index 4b62aecb9c..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/nop/NopDynamicConfigurationService.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.nop; - -import com.huaweicloud.sermant.backend.service.dynamicconfig.Config; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigurationListener; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigurationService; - -/** - * This class is for testing purpose only. - * - * @deprecated 测试类 - */ -@Deprecated -public class NopDynamicConfigurationService implements DynamicConfigurationService { - static private NopDynamicConfigurationService serviceInst; - - private NopDynamicConfigurationService() { - // no-op - } - - /** - * 获取nop动态配置服务 - * - * @return nop动态配置服务 - */ - public static synchronized NopDynamicConfigurationService getInstance() { - if (serviceInst == null) { - serviceInst = new NopDynamicConfigurationService(); - } - return serviceInst; - } - - - @Override - public boolean addConfigListener(String key, String group, ConfigurationListener listener) { - return true; - } - - @Override - public boolean removeConfigListener(String key, String group, ConfigurationListener listener) { - return true; - } - - @Override - public String getConfig(String key, String group) throws IllegalStateException { - // no-op - return ""; - } - - /** - * @since 2.7.5 - */ - @Override - public boolean publishConfig(String key, String group, String content) { - return true; - } - - @Override - public String getDefaultGroup() { - return Config.getDefaultGroup(); - } - - @Override - public long getDefaultTimeout() { - return Config.getTimeout_value(); - } - - @Override - public void close() throws Exception { - // no-op - } - -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigChangeType.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigChangeType.java deleted file mode 100644 index a4fc400d25..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigChangeType.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.service; - -/** - * Config change event type - */ -public enum ConfigChangeType { - /** - * A config is created. - */ - ADDED, - - /** - * A config is updated. - */ - MODIFIED, - - /** - * A config is deleted. - */ - DELETED -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigChangedEvent.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigChangedEvent.java deleted file mode 100644 index b2808803f9..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigChangedEvent.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.service; - -import java.util.EventObject; -import java.util.Objects; - -/** - * An event raised when the config changed, immutable. - * - * @see ConfigChangeType - */ -public class ConfigChangedEvent extends EventObject { - - private static final long serialVersionUID = -2774678643852195546L; - private final String key; - private final String group; - private final String content; - private final ConfigChangeType changeType; - - public ConfigChangedEvent(String key, String group, String content) { - this(key, group, content, ConfigChangeType.MODIFIED); - } - - public ConfigChangedEvent(String key, String group, String content, ConfigChangeType changeType) { - super(key + "," + group); - this.key = key; - this.group = group; - this.content = content; - this.changeType = changeType; - } - - public String getKey() { - return key; - } - - public String getGroup() { - return group; - } - - public String getContent() { - return content; - } - - public ConfigChangeType getChangeType() { - return changeType; - } - - @Override - public String toString() { - return "ConfigChangedEvent{" + - "key='" + key + '\'' + - ", group='" + group + '\'' + - ", content='" + content + '\'' + - ", changeType=" + changeType + - "} " + super.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ConfigChangedEvent)) { - return false; - } - ConfigChangedEvent that = (ConfigChangedEvent) o; - return Objects.equals(getKey(), that.getKey()) && - Objects.equals(getGroup(), that.getGroup()) && - Objects.equals(getContent(), that.getContent()) && - getChangeType() == that.getChangeType(); - } - - @Override - public int hashCode() { - return Objects.hash(getKey(), getGroup(), getContent(), getChangeType()); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigurationListener.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigurationListener.java deleted file mode 100644 index 541fbc2b61..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/ConfigurationListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.service; - -import java.util.EventListener; - -/** - * Config listener, will get notified when the config it listens on changes. - */ -public interface ConfigurationListener extends EventListener { - - /** - * Listener call back method. Listener gets notified by this method once there's any change happens on the config - * the listener listens on. - * - * @param event config change event - */ - void process(ConfigChangedEvent event); -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigurationFactoryService.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigurationFactoryService.java deleted file mode 100644 index 2d27d90b78..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigurationFactoryService.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.service; - -/** - * - * Core service for the dynamic config service. - * This factory is used to retrieve the default configuration service. - * - */ -public interface DynamicConfigurationFactoryService { - - /** - * 获取动态配置接口 - * - * @return 动态配置 - * @throws Exception 异常 - */ - DynamicConfigurationService getDynamicConfigurationService() throws Exception; - -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigurationService.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigurationService.java deleted file mode 100644 index dfea05644f..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/service/DynamicConfigurationService.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.service; - -import java.util.List; - -public interface DynamicConfigurationService extends AutoCloseable { - - default boolean addConfigListener(String key, ConfigurationListener listener) { - return addConfigListener(key, getDefaultGroup(), listener); - } - - /** - * 添加监听器 - * - * @param group 配置组 - * @param listener 监听器 - * @return 是否成功 - */ - default boolean addGroupListener(String group, ConfigurationListener listener) { - throw new UnsupportedOperationException(); - } - - default boolean removeConfigListener(String key, ConfigurationListener listener) { - return removeConfigListener(key, getDefaultGroup(), listener); - } - - default boolean removeGroupListener(String key, String group, ConfigurationListener listener) { - throw new UnsupportedOperationException(); - } - - boolean addConfigListener(String key, String group, ConfigurationListener listener); - - boolean removeConfigListener(String key, String group, ConfigurationListener listener); - - String getConfig(String key, String group); - - /** - * 获取配置 - * - * @param key key - * @return 配置 - */ - default String getConfig(String key) { - return getConfig(key, getDefaultGroup()); - } - - default boolean publishConfig(String key, String content) { - return publishConfig(key, getDefaultGroup(), content); - } - - /** - * 推送配置 - * - * @param key key - * @param group group - * @param content content - * @return 是否成功 - */ - boolean publishConfig(String key, String group, String content); - - String getDefaultGroup(); - - long getDefaultTimeout(); - - @Override - default void close() throws Exception { - throw new UnsupportedOperationException(); - } - - default boolean removeConfig(String key, String group) throws Exception { - throw new UnsupportedOperationException(); - } - - default List listConfigsFromGroup(String group) throws Exception { - throw new UnsupportedOperationException(); - } - - default List listConfigsFromConfig(String key) throws Exception { - return listConfigsFromConfig(key, getDefaultGroup()); - } - - default List listConfigsFromConfig(String key, String group) throws Exception { - throw new UnsupportedOperationException(); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/utils/LabelGroupUtils.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/utils/LabelGroupUtils.java deleted file mode 100644 index d4d94cac9a..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/utils/LabelGroupUtils.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.utils; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * group生成工具 - * - * @author zhouss - * @since 2021-11-23 - */ -public class LabelGroupUtils { - private static final Logger LOGGER = LoggerFactory.getLogger(LabelGroupUtils.class); - - private static final String GROUP_SEPARATOR = "&"; - - private static final String KV_SEPARATOR = "="; - - /** - * 查询时使用的kv分隔符 - */ - private static final String LABEL_QUERY_SEPARATOR = ":"; - - /** - * 查询标签前缀 - */ - private static final String LABEL_PREFIX = "label="; - - /** - * 键值对长度 - */ - private static final int KV_LEN = 2; - - private LabelGroupUtils() { - } - - /** - * 创建标签组 - * - * @param labels 标签组 - * @return labelGroup 例如: app=sc&service=helloService - */ - public static String createLabelGroup(Map labels) { - if (labels == null || labels.isEmpty()) { - return StringUtils.EMPTY; - } - final StringBuilder group = new StringBuilder(); - final List keys = new ArrayList<>(labels.keySet()); - - // 防止相同map因排序不同而导致最后的label不一致 - Collections.sort(keys); - for (String key : keys) { - String value = labels.get(key); - if (key == null || value == null) { - LOGGER.warn(String.format(Locale.ENGLISH, "Invalid group label, key = %s, value = %s", - key, value)); - continue; - } - group.append(key).append(KV_SEPARATOR).append(value).append(GROUP_SEPARATOR); - } - if (group.length() == 0) { - return StringUtils.EMPTY; - } - return group.deleteCharAt(group.length() - 1).toString(); - } - - /** - * 重组group, 防止因多个标签因顺序问题而导致group不同 - * - * @param group 标签组 - * @return group - */ - public static String rebuildGroup(String group) { - if (isLabelGroup(group)) { - return createLabelGroup(resolveGroupLabels(group)); - } - return LabelGroupUtils.createLabelGroup(Collections.singletonMap("GROUP", group)); - } - - /** - * 是否为标签组key - * - * @param group 监听键 - * @return 是否为标签组 - */ - public static boolean isLabelGroup(String group) { - return group != null && group.contains(KV_SEPARATOR); - } - - /** - * 解析标签为map - * - * @param group 标签组 app=sc&service=helloService - * @return 标签键值对 - */ - public static Map resolveGroupLabels(String group) { - final Map result = new HashMap<>(); - if (group == null) { - return result; - } - String curGroup = group; - if (!isLabelGroup(curGroup)) { - // 如果非group标签(ZK配置中心场景适配),则为该group创建标签 - curGroup = LabelGroupUtils.createLabelGroup(Collections.singletonMap("GROUP", curGroup)); - } - try { - final String decode = URLDecoder.decode(curGroup, "UTF-8"); - final String[] labels = decode.split("&"); - for (String label : labels) { - final String[] labelKv = label.split("="); - if (labelKv.length != KV_LEN) { - continue; - } - result.put(labelKv[0], labelKv[1]); - } - } catch (UnsupportedEncodingException ignored) { - // ignored - } - return result; - } - - /** - * 获取标签信息 - * - * @param group 分组 app=sc&service=helloService转换label=app:sc&label=service:helloService - * @return 标签组条件 - */ - public static String getLabelCondition(String group) { - if (StringUtils.isEmpty(group)) { - return group; - } - String curGroup = rebuildGroup(group); - final Map labels = resolveGroupLabels(curGroup); - final StringBuilder finalGroup = new StringBuilder(); - for (Map.Entry entry : labels.entrySet()) { - finalGroup.append(LABEL_PREFIX) - .append(buildSingleLabel(entry.getKey(), entry.getValue())) - .append(GROUP_SEPARATOR); - } - return finalGroup.deleteCharAt(finalGroup.length() - 1).toString(); - } - - private static String buildSingleLabel(String key, String value) { - try { - return URLEncoder.encode(key + LABEL_QUERY_SEPARATOR + value, "UTF-8"); - } catch (UnsupportedEncodingException ignored) { - // ignored - } - return StringUtils.EMPTY; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/zookeeper/ZookeeperDynamicConfigurationService.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/zookeeper/ZookeeperDynamicConfigurationService.java deleted file mode 100644 index 753e9c5ccc..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/service/dynamicconfig/zookeeper/ZookeeperDynamicConfigurationService.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.service.dynamicconfig.zookeeper; - -import com.huaweicloud.sermant.backend.common.exception.ZookeeperDynamicConfigurationException; -import com.huaweicloud.sermant.backend.service.dynamicconfig.Config; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigChangeType; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigChangedEvent; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.ConfigurationListener; -import com.huaweicloud.sermant.backend.service.dynamicconfig.service.DynamicConfigurationService; - -import org.apache.zookeeper.AddWatchMode; -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.KeeperException; -import org.apache.zookeeper.WatchedEvent; -import org.apache.zookeeper.Watcher; -import org.apache.zookeeper.ZooDefs; -import org.apache.zookeeper.ZooKeeper; -import org.apache.zookeeper.data.Stat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Locale; -import java.util.Vector; - -/** - * Zookeeper implementation for DynamicConfigurationService - */ -public class ZookeeperDynamicConfigurationService implements DynamicConfigurationService { - - private static final Logger logger = LoggerFactory.getLogger(ZookeeperDynamicConfigurationService.class); - - ZooKeeper zkClient; - - static private ZookeeperDynamicConfigurationService serviceInst; - - private ZookeeperDynamicConfigurationService() { - - } - - @Override - public String getDefaultGroup() { - return Config.getDefaultGroup(); - } - - @Override - public long getDefaultTimeout() { - return Config.getTimeout_value(); - } - - /** - * zookeeper 动态配置实现 - * - * @return 配置实现 - * @throws ZookeeperDynamicConfigurationException 异常 - */ - public static synchronized ZookeeperDynamicConfigurationService getInstance() - throws ZookeeperDynamicConfigurationException { - if (serviceInst == null) { - serviceInst = new ZookeeperDynamicConfigurationService(); - URI zkUri; - - try { - zkUri = new URI(Config.getZookeeperUri()); - } catch (URISyntaxException e) { - logger.error(e.getMessage(), e); - throw new ZookeeperDynamicConfigurationException(e.getMessage()); - } - - String zkConStr = zkUri.getHost(); - if (zkUri.getPort() > 0) { - zkConStr = zkConStr + ":" + zkUri.getPort(); - } - - ZooKeeper zkInst; - try { - zkInst = new ZooKeeper(zkConStr, Config.getTimeout_value(), new Watcher() { - @Override - public void process(WatchedEvent event) { - } - }); - } catch (IOException e) { - logger.error(e.getMessage(), e); - throw new ZookeeperDynamicConfigurationException(e.getMessage()); - } - - serviceInst.zkClient = zkInst; - } - - return serviceInst; - } - - private String getPath(String key, String group) { - group = fixGroup(group); - return group.startsWith("/") ? group + key : '/' + group + key; - } - - private String fixGroup(String group) { - return group == null ? getDefaultGroup() : group; - } - - private ConfigChangeType transEventType(Watcher.Event.EventType type) { - switch (type) { - case NodeCreated: - return ConfigChangeType.ADDED; - case NodeDeleted: - return ConfigChangeType.DELETED; - case None: - case NodeDataChanged: - case DataWatchRemoved: - case ChildWatchRemoved: - case NodeChildrenChanged: - case PersistentWatchRemoved: - default: - return ConfigChangeType.MODIFIED; - } - } - - /** - * 添加组监听 - * 若由Kie配置中心转换而来,则配置路径为

/group/key

- *
-     * 其中:
-     * group: 由{@link LabelGroupUtils#createLabelGroup(Map)}生成
-     * key: 则是对应kie的键名
-     * 
- *

第一次添加会将group下的所有子路径的数据通知给监听器

- * - * @param group 分组 - * @param listener 监听器 - * @return boolean - */ - @Override - public boolean addGroupListener(String group, ConfigurationListener listener) { - try { - if (listener == null) { - return false; - } - // 监听group底下所有的子节点数据变更 - final String path = getPath("", fixGroup(group)); - zkClient.addWatch(path, new Watcher() { - @Override - public void process(WatchedEvent event) { - if (event.getPath() == null || event.getPath().equals(path) - || !event.getPath().startsWith(path)) { - return; - } - // 带有分隔符"/"的键 - String keyWithSeparator = event.getPath().substring(group.length() + 1); - if (keyWithSeparator.length() < 1) { - return; - } - final String content = getConfig(keyWithSeparator, group); - listener.process(new ConfigChangedEvent(keyWithSeparator.substring(1), group, content, - transEventType(event.getType()))); - } - }, AddWatchMode.PERSISTENT_RECURSIVE); - notifyGroup(group, listener); - } catch (KeeperException.NoNodeException ignored) { - // ignored - } catch (Exception e) { - logger.warn( - String.format(Locale.ENGLISH, "Added zookeeper group listener failed, %s", e.getMessage()), e); - return false; - } - return true; - } - - @Override - public boolean removeGroupListener(String key, String group, ConfigurationListener listener) { - return true; - } - - /** - * 添加zookeeper路径监听 - * 将会监听路径/group/key的数据变更 - *

一次添加将会将节点数据通知给监听器

- * - * @param key 子路径 - * @param group 父路径 - * @param listener 监听器 - * @return 当连接zk失败返回false - */ - @Override - public boolean addConfigListener(String key, String group, ConfigurationListener listener) { - - if (listener == null) { - return false; - } - - final String finalGroup = fixGroup(group); - final String fullPath = getPath(key, finalGroup); - Watcher wc = new Watcher() { - @Override - public void process(WatchedEvent event) { - if (!fullPath.equals(event.getPath())) { - logger.warn("unexpected event " + event + " for " + key + ":" + finalGroup); - } - String content = getConfig(key, finalGroup); - ConfigChangeType changeType = transEventType(event.getType()); - ConfigChangedEvent cce = new ConfigChangedEvent(key, finalGroup, content, changeType); - listener.process(cce); - } - }; - - try { - zkClient.addWatch(fullPath, wc, AddWatchMode.PERSISTENT); - notifyKey(key, group, listener); - } catch (KeeperException.NoNodeException ignored) { - // ignored - } catch (Exception e) { - logger.warn(e.getMessage(), e); - return false; - } - return true; - } - - /** - * @param key postfix of key path - * @param group prefix of key path - * @param listener configuration listener - */ - @Override - public boolean removeConfigListener(String key, String group, ConfigurationListener listener) { - throw new UnsupportedOperationException(); - } - - /** - * @param key key path - */ - @Override - public String getConfig(String key, String group) { - - final String fullPath = getPath(key, group); - - String rs = null; - try { - Stat st = new Stat(); - rs = new String(zkClient.getData(fullPath, false, st)); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - return null; - } - return rs; - } - - - @Override - public boolean publishConfig(String key, String group, String content) { - - final String fullPath = getPath(key, group); - - boolean rs = false; - try { - rs = this.updateNode(fullPath, content.getBytes(StandardCharsets.UTF_8), -1); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - return false; - } - return rs; - } - - - protected boolean createRecursivly(String path) { - try { - if (zkClient.exists(path, null) == null && path.length() > 0) { - String temp = path.substring(0, path.lastIndexOf("/")); - if (temp != null && temp.length() > 1) { - createRecursivly(temp); - } - zkClient.create(path, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); - } - } catch (KeeperException e) { - logger.warn(e.getMessage(), e); - return false; - } catch (InterruptedException e) { - logger.warn(e.getMessage(), e); - return false; - } - return true; - - } - - protected boolean updateNode(String path, byte[] data, int version) { - try { - if (zkClient.exists(path, null) == null) { - createRecursivly(path); - } - zkClient.setData(path, data, version); - } catch (KeeperException e) { - logger.warn(e.getMessage(), e); - return false; - } catch (InterruptedException e) { - logger.warn(e.getMessage(), e); - return false; - } - return true; - - } - - @Override - public void close() { - try { - this.zkClient.close(); - } catch (InterruptedException e) { - logger.error(e.getMessage(), e); - } - } - - @Override - public List listConfigsFromGroup(String group) { - group = group.trim(); - if (!group.startsWith("/")) { - group = "/" + group; - } - List strArray = null; - try { - strArray = listNodesFromNode(group); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - return strArray; - } - - @Override - public List listConfigsFromConfig(String key, String group) { - group = group.trim(); - if (!group.startsWith("/")) { - group = "/" + group; - } - key = key.trim(); - if (!key.startsWith("/")) { - key = "/" + key; - } - - List strArray = null; - try { - strArray = listNodesFromNode(group + key); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - return strArray; - } - - private List listNodesFromNode(String node) { - List strArray = new Vector(); - try { - if (zkClient.exists(node, false) != null) { - strArray = zkClient.getChildren(node, null); - } - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - for (int len = 0; len < strArray.size(); len++) { - String str = strArray.get(len); - for (String grandChild : listNodesFromNode(node + "/" + str)) { - strArray.add(str + '/' + grandChild); - } - } - - return strArray; - } - - /** - * 第一次增加监听器时,将关联查询的数据传给listener - * - * @param group 分组 - * @param listener 监听器 - */ - private void notifyGroup(String group, ConfigurationListener listener) { - final List keys = listConfigsFromGroup(group); - if (keys != null) { - for (String key : keys) { - notifyKey(key, group, listener); - } - } - } - - private void notifyKey(String key, String group, ConfigurationListener listener) { - final String content = getConfig(fixKey(key), group); - listener.process(new ConfigChangedEvent(key, group, content, ConfigChangeType.ADDED)); - } - - private String fixKey(String key) { - if (key == null) { - return null; - } - return key.startsWith("/") ? key : "/" + key; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/DeleteTimeoutData.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/timer/DeleteTimeoutDataTask.java similarity index 51% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/DeleteTimeoutData.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/timer/DeleteTimeoutDataTask.java index 65a1f6c5ed..95c69d92a0 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/cache/DeleteTimeoutData.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/timer/DeleteTimeoutDataTask.java @@ -14,11 +14,13 @@ * limitations under the License. */ -package com.huaweicloud.sermant.backend.cache; +package com.huaweicloud.sermant.backend.timer; +import com.huaweicloud.sermant.backend.cache.CollectorCache; +import com.huaweicloud.sermant.backend.cache.HeartbeatCache; import com.huaweicloud.sermant.backend.common.conf.VisibilityConfig; -import com.huaweicloud.sermant.backend.entity.HeartbeatEntity; -import com.huaweicloud.sermant.backend.entity.ServerInfo; +import com.huaweicloud.sermant.backend.entity.heartbeat.HeartbeatMessage; +import com.huaweicloud.sermant.backend.entity.visibility.ServerInfo; import java.util.Iterator; import java.util.Map; @@ -30,20 +32,25 @@ * @author xuezechao * @since 2022-03-14 */ -public class DeleteTimeoutData extends TimerTask { +public class DeleteTimeoutDataTask extends TimerTask { + private final long maxEffectiveTime; - private static final int MAX_EFFECTIVE_TIME = 6000; + private final long maxCacheTime; - private VisibilityConfig visibilityConfig; + private final VisibilityConfig visibilityConfig; /** - * 初始化任务 + * 构造方法 * + * @param maxEffectiveTime 最大有效时间 + * @param maxCacheTime 最大缓存时间 * @param visibilityConfig 服务可见性配置 */ - public DeleteTimeoutData(VisibilityConfig visibilityConfig) { - deleteHeartbeatCache(); + public DeleteTimeoutDataTask(long maxEffectiveTime, long maxCacheTime, VisibilityConfig visibilityConfig) { + this.maxEffectiveTime = maxEffectiveTime; + this.maxCacheTime = maxCacheTime; this.visibilityConfig = visibilityConfig; + deleteHeartbeatCache(); } @Override @@ -53,15 +60,18 @@ public void run() { } private void deleteHeartbeatCache() { - Map heartbeatMessages = HeartbeatCache.getHeartbeatMessages(); - for (Iterator> it = heartbeatMessages.entrySet().iterator(); - it.hasNext(); ) { - Map.Entry heartbeatEntityEntry = it.next(); + Map heartbeatMessages = HeartbeatCache.getHeartbeatMessageMap(); + for (Iterator> it = heartbeatMessages.entrySet().iterator(); + it.hasNext();) { + Map.Entry heartbeatMessageEntry = it.next(); long nowTime = System.currentTimeMillis(); - long lastHeartbeatTime = heartbeatEntityEntry.getValue().getLastHeartbeat(); - if ((nowTime - lastHeartbeatTime) > MAX_EFFECTIVE_TIME) { + long receiveTime = heartbeatMessageEntry.getValue().getReceiveTime(); + if ((nowTime - receiveTime) > maxCacheTime) { it.remove(); } + if ((nowTime - receiveTime) > maxEffectiveTime) { + heartbeatMessageEntry.getValue().setHealth(false); + } } } @@ -69,12 +79,12 @@ private void deleteHeartbeatCache() { * 清理服务可见性采集的信息 */ private void deleteCollectorCache() { - Map heartbeatMessages = HeartbeatCache.getHeartbeatDate(); - for (Iterator> it = heartbeatMessages.entrySet().iterator(); it.hasNext(); ) { + for (Iterator> it = + CollectorCache.SERVER_VALIDITY_PERIOD_MAP.entrySet().iterator(); it.hasNext();) { Map.Entry heartbeatEntityEntry = it.next(); long nowTime = System.currentTimeMillis(); - if ((nowTime - heartbeatEntityEntry.getValue().getValidateDate().getTime()) - > visibilityConfig.getEffectiveTimes()) { + if ((nowTime - heartbeatEntityEntry.getValue().getValidateDate().getTime()) > visibilityConfig + .getEffectiveTimes()) { CollectorCache.removeServer(heartbeatEntityEntry.getValue()); it.remove(); } diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/BackendThreadFactory.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/BackendThreadFactory.java deleted file mode 100644 index 6516b3bddb..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/BackendThreadFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.util; - -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -public class BackendThreadFactory implements ThreadFactory { - private final static AtomicInteger FACTORY_NUMBER = new AtomicInteger(0); - - private final AtomicInteger threadNumber = new AtomicInteger(0); - - private final String threadPrefix; - - private final boolean daemon; - - public BackendThreadFactory() { - this("backend", true); - } - - public BackendThreadFactory(String threadName) { - this(threadName, true); - } - - public BackendThreadFactory(String threadName, boolean daemon) { - this.threadPrefix = prefix(threadName, FACTORY_NUMBER.getAndIncrement()); - this.daemon = daemon; - } - - public static ThreadFactory createThreadFactory(String threadName) { - return createThreadFactory(threadName, false); - } - - public static ThreadFactory createThreadFactory(String threadName, boolean daemon) { - return new BackendThreadFactory(threadName, daemon); - } - - private String prefix(String threadName, int factoryId) { - return threadName + '(' + factoryId + ')'; - } - - @Override - public Thread newThread(Runnable job) { - String newThreadName = createThreadName(); - Thread thread = new Thread(job, newThreadName); - if (daemon) { - thread.setDaemon(true); - } - return thread; - } - - private String createThreadName() { - return threadPrefix + threadNumber.getAndIncrement() + ')'; - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/DateUtil.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/DateUtil.java deleted file mode 100644 index 9a1bcd3099..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/DateUtil.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.util; - -import java.text.SimpleDateFormat; - -/** - * 日期格式化 - * - * @author xuezechao - * @since 2022-03-11 - */ -public class DateUtil { - - private DateUtil() { - } - - /** - * 格式化日期 - * - * @param times - * @return 格式化后日期 - */ - public static String getFormatDate(Long times) { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - return formatter.format(times); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/util/GzipUtils.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/GzipUtils.java similarity index 98% rename from sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/util/GzipUtils.java rename to sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/GzipUtils.java index 4c7ddfea0e..5d7a0a459d 100644 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/common/util/GzipUtils.java +++ b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/GzipUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.huaweicloud.sermant.backend.common.util; +package com.huaweicloud.sermant.backend.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +40,9 @@ public class GzipUtils { // 缓冲区大小 private static final int BUFFER = 1024; + private GzipUtils() { + } + /** * 数据压缩 * diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/RandomUtil.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/RandomUtil.java deleted file mode 100644 index 8b23b58018..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/RandomUtil.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021-2021 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.util; - -import org.apache.commons.lang.RandomStringUtils; - -import java.util.Random; - -public class RandomUtil { - - private final Random random = new Random(); - - public Integer getRandomInt(Integer range) { - return random.nextInt(range) + 1; - } - - public String getRandomStr(Integer len) { - return RandomStringUtils.randomAlphanumeric(len); - } - - public Long getRandomLong(Integer min, Integer max) { - return min + (((long) (random.nextDouble() * (max - min)))); - } -} diff --git a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/UuidUtil.java b/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/UuidUtil.java deleted file mode 100644 index e46f397fdb..0000000000 --- a/sermant-backend/src/main/java/com/huaweicloud/sermant/backend/util/UuidUtil.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.backend.util; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.concurrent.atomic.AtomicLong; - -/** - * uuid - * - * @author xuezechao - * @since 2022-02-28 - */ -public class UuidUtil { - - private UuidUtil() { - - } - - /** - * 生成Long 类型唯一ID - * - * @return uuid - */ - public static long getId() { - long nowTime = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())); - AtomicLong instanceId = new AtomicLong(nowTime); - if (instanceId.get() < 0) { - return -instanceId.get(); - } - return instanceId.get(); - } -} diff --git a/sermant-backend/src/main/proto/Message.proto b/sermant-backend/src/main/proto/Message.proto index dfc047788c..22292a51d0 100644 --- a/sermant-backend/src/main/proto/Message.proto +++ b/sermant-backend/src/main/proto/Message.proto @@ -1,38 +1,21 @@ syntax = "proto3"; -option java_package = "com.huawei.sermant.backend.pojo"; +option java_package = "com.huaweicloud.sermant.backend.pojo"; message NettyMessage{ - enum MessageType { - HEARTBEAT_PING = 0; - HEARTBEAT_PONG = 1; - SERVICE_DATA = 2; + SERVICE_DATA = 0; } - MessageType messageType = 1; - HeartBeat heartBeat = 2; - repeated ServiceData serviceData = 3; - - + repeated ServiceData serviceData = 2; } -message HeartBeat{ -} message ServiceData{ enum DataType{ - SERVICE_HEARTBEAT = 0; - LOG = 1; - PLUGIN_FLOW_CONTROL_DATA = 2; - PLUGIN_FLOW_RECORD_DATA = 3; - SERVER_MONITOR = 4; - ORACLE_JVM_MONITOR = 5; - IBM_JVM_MONITOR = 6; - AGENT_REGISTRATION = 7; - AGENT_MONITOR = 8; - AGENT_SPAN_EVENT = 9; - DRUID_MONITOR = 10; - VISIBILITY = 12; + HEARTBEAT_DATA = 0; + EVENT_DATA = 1; + TRACING_DATA = 2; + VISIBILITY_DATA = 3; } DataType dataType = 1; bytes data = 2; -} \ No newline at end of file +} diff --git a/sermant-backend/src/main/resources/application.properties b/sermant-backend/src/main/resources/application.properties index d4220d35ba..8f48aec594 100644 --- a/sermant-backend/src/main/resources/application.properties +++ b/sermant-backend/src/main/resources/application.properties @@ -1,48 +1,13 @@ server.port=8900 -# kafka address -spring.kafka.bootstrap-servers=127.0.0.1:9092 -kafka.pool.timeoutMs=1000 -kafka.key.deserializer=org.apache.kafka.common.serialization.StringDeserializer -kafka.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer -kafka.group.id=test -kafka.enable.auto.commit=true -kafka.auto.commit.interval.ms=1000 -kafka.auto.offset.reset=latest -kafka.session.timeout.ms=30000 -fetch.min.bytes=1048576 -fetch.max.wait.ms=2000 - -kafka.key.serializer=org.apache.kafka.common.serialization.StringSerializer -kafka.value.serializer=org.apache.kafka.common.serialization.ByteArraySerializer -kafka.acks=1 -kafka.max.request.size=1048576 -kafka.buffer.memory=33554432 -kafka.retries=0 -kafka.request.timeout.ms=10000 -kafka.max.block.ms=60000 - -# heartbeat topic name -kafka.heartbeat.topic=topic-heartbeat - -# netty config +# netty netty.port=6888 netty.wait.time=60 +netty.connection.size=1024 -heartbeat.cache=true - -datatype.topic.mapping.0=topic-heartbeat -datatype.topic.mapping.1=topic-log -datatype.topic.mapping.2=topic-flowcontrol -datatype.topic.mapping.3=topic-flowecord -datatype.topic.mapping.4=topic-server-monitor -datatype.topic.mapping.5=topic-open-jdk-jvm-monitor -datatype.topic.mapping.6=topic-ibm-jvm-monitor -datatype.topic.mapping.7=topic-agent-registration -datatype.topic.mapping.8=topic-agent-monitor -datatype.topic.mapping.9=topic-agent-span-event -datatype.topic.mapping.10=topic-druid-monitor -datatype.topic.mapping.11=topic-flowcontrol-metric -datatype.topic.mapping.12=topic-visibility +# heartbeat +max.effective.time=60000 +max.cache.time=600000 +# visibility visibility.effectiveTimes=60000 diff --git a/sermant-backend/src/test/java/com/huaweicloud/sermant/backend/NettyServerTest.java b/sermant-backend/src/test/java/com/huaweicloud/sermant/backend/NettyServerTest.java deleted file mode 100644 index d469cee650..0000000000 --- a/sermant-backend/src/test/java/com/huaweicloud/sermant/backend/NettyServerTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.huaweicloud.sermant.backend; - -import static org.mockito.Mockito.mock; - -import com.huaweicloud.sermant.backend.common.conf.DataTypeTopicMapping; -import com.huawei.sermant.backend.pojo.Message; -import com.huaweicloud.sermant.backend.server.ServerHandler; - -import io.netty.channel.embedded.EmbeddedChannel; - -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.clients.producer.KafkaProducer; -import org.junit.Assert; -import org.junit.Before; -import org.junit.jupiter.api.Test; - -public class NettyServerTest { - private KafkaProducer producer; - private KafkaConsumer consumer; - private String isHeartBeatCache = "false"; - - private DataTypeTopicMapping topicMapping; - - @Before - public void setUp() { - producer = mock(KafkaProducer.class); - topicMapping = mock(DataTypeTopicMapping.class); - } - - /** - * 测试入站消息 - */ - @Test - public void testWriteInBound() { - EmbeddedChannel embeddedChannel = new EmbeddedChannel( - new ServerHandler(producer, consumer, topicMapping, isHeartBeatCache)); - boolean writeInbound = embeddedChannel.writeInbound(Message.ServiceData.newBuilder().build()); - Assert.assertTrue(writeInbound); - Assert.assertTrue(embeddedChannel.finish()); - - Object object = embeddedChannel.readInbound(); - Assert.assertNotNull(object); - } - - /** - * 测试出站消息 - */ - @Test - public void testWriteOutBound() { - EmbeddedChannel embeddedChannel = new EmbeddedChannel( - new ServerHandler(producer, consumer, topicMapping, isHeartBeatCache)); - boolean writeOutBound = embeddedChannel.writeOutbound(Message.ServiceData.newBuilder().build()); - Assert.assertTrue(writeOutBound); - Assert.assertTrue(embeddedChannel.finish()); - - Object object = embeddedChannel.readOutbound(); - Assert.assertNotNull(object); - } - -} diff --git a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/DynamicServerListInterceptorTest.java b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/DynamicServerListInterceptorTest.java index 8caa34860a..6cd937d14b 100644 --- a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/DynamicServerListInterceptorTest.java +++ b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/test/java/com/huawei/registry/interceptors/DynamicServerListInterceptorTest.java @@ -16,6 +16,7 @@ package com.huawei.registry.interceptors; +import com.huawei.registry.config.RegisterDynamicConfig; import com.huawei.registry.context.RegisterContext; import com.huawei.registry.entity.MicroServiceInstance; import com.huawei.registry.interceptors.cloud3.x.ZookeeperInstanceSupplierInterceptorTest; @@ -78,11 +79,13 @@ public void setUp() throws Exception { @Test public void doBefore() throws NoSuchMethodException { + RegisterDynamicConfig.INSTANCE.setClose(false); RegisterContext.INSTANCE.setAvailable(true); final ExecuteContext context = interceptor.doBefore(buildContext(serverListLoadBalancer, null)); Assert.assertTrue(context.isSkip()); Mockito.verify(serverList, Mockito.times(1)).getUpdatedListOfServers(); RegisterContext.INSTANCE.setAvailable(false); + RegisterDynamicConfig.INSTANCE.setClose(true); } @Override