Compare commits
8 Commits
2de1a23d69
...
51e7c2c0c0
Author | SHA1 | Date |
---|---|---|
|
51e7c2c0c0 | |
|
5a91f224cd | |
|
9ff1093c03 | |
|
581c3622a9 | |
|
2f0fd35808 | |
|
3ea65346d8 | |
|
5143ef67de | |
|
3180012c6c |
|
@ -16,11 +16,31 @@
|
|||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.muyu</groupId>-->
|
||||
<!-- <artifactId>cloud-common-saas</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos Config -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Sentinel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- SpringBoot Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -45,6 +65,7 @@
|
|||
<artifactId>cloud-common-api-doc</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
|
@ -87,6 +108,7 @@
|
|||
<artifactId>cloud-common-log</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -10,7 +10,11 @@ import com.muyu.common.security.auth.AuthUtil;
|
|||
import com.muyu.common.security.service.TokenService;
|
||||
import com.muyu.common.security.utils.SecurityUtils;
|
||||
import com.muyu.common.system.domain.LoginUser;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
@ -25,16 +29,20 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||
*/
|
||||
@RestController
|
||||
public class TokenController {
|
||||
|
||||
@Resource
|
||||
private TokenService tokenService;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
|
||||
private SysLoginService sysLoginService;
|
||||
|
||||
@PostMapping("login")
|
||||
public Result<?> login (@RequestBody LoginBody form) {
|
||||
// 用户登录
|
||||
|
||||
LoginUser userInfo = sysLoginService.login(form);
|
||||
|
||||
// 获取登录token
|
||||
return Result.success(tokenService.createToken(userInfo));
|
||||
}
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
package com.muyu.auth.form;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用户登录对象
|
||||
*
|
||||
* @author muyu
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class LoginBody {
|
||||
|
||||
private String firmCode;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
|
@ -20,4 +25,16 @@ public class LoginBody {
|
|||
* 用户密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
|
||||
|
||||
public String getUsername () {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername (String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,14 +13,13 @@ import com.muyu.common.core.utils.StringUtils;
|
|||
import com.muyu.common.core.utils.ip.IpUtils;
|
||||
import com.muyu.common.redis.service.RedisService;
|
||||
import com.muyu.common.security.utils.SecurityUtils;
|
||||
import com.muyu.common.system.domain.LoginUser;
|
||||
import com.muyu.common.system.domain.SysUser;
|
||||
import com.muyu.common.system.remote.RemoteSaasService;
|
||||
import com.muyu.common.system.remote.RemoteUserService;
|
||||
import com.muyu.common.system.domain.SysUser;
|
||||
import com.muyu.common.system.domain.LoginUser;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,11 @@ import com.muyu.common.core.exception.ServiceException;
|
|||
import com.muyu.common.redis.service.RedisService;
|
||||
import com.muyu.common.security.utils.SecurityUtils;
|
||||
import com.muyu.common.system.domain.SysUser;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -18,14 +22,22 @@ import java.util.concurrent.TimeUnit;
|
|||
*/
|
||||
@Component
|
||||
public class SysPasswordService {
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private RedisService redisService;
|
||||
|
||||
private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT;
|
||||
|
||||
private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME;
|
||||
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private SysRecordLogService recordLogService;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,11 @@ import com.muyu.common.core.utils.StringUtils;
|
|||
import com.muyu.common.core.utils.ip.IpUtils;
|
||||
import com.muyu.common.system.remote.RemoteLogService;
|
||||
import com.muyu.common.system.domain.SysLogininfor;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
|
@ -16,7 +20,11 @@ import org.springframework.stereotype.Component;
|
|||
*/
|
||||
@Component
|
||||
public class SysRecordLogService {
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private RemoteLogService remoteLogService;
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,10 +4,14 @@ server:
|
|||
|
||||
# nacos线上地址
|
||||
nacos:
|
||||
addr: 47.116.173.119:8848
|
||||
addr: 106.54.193.225:8848
|
||||
user-name: nacos
|
||||
password: nacos
|
||||
|
||||
namespace: one-saas
|
||||
|
||||
namespace: one
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
|
@ -40,8 +44,15 @@ spring:
|
|||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
|
||||
# 系统环境Config共享配置
|
||||
- application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
# 系统共享配置
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
|
||||
# 系统共享配置
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
# 系统环境Config共享配置
|
||||
- application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join-boot-starter</artifactId>
|
||||
|
@ -168,11 +169,13 @@
|
|||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -46,8 +46,10 @@ public class SecurityConstants {
|
|||
*/
|
||||
public static final String ROLE_PERMISSION = "role_permission";
|
||||
|
||||
|
||||
/**
|
||||
* SAAS请求头的key
|
||||
*/
|
||||
public static final String SAAS_KEY = "ent-code";
|
||||
|
||||
}
|
||||
|
|
|
@ -29,4 +29,5 @@ public class ServiceNameConstants {
|
|||
public static final String ENT_SERVICE = "cloud-ent";
|
||||
|
||||
public static final String SAAS_SERVICE = "cloud-system-saas";
|
||||
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ public class SecurityContextHolder {
|
|||
THREAD_LOCAL.remove();
|
||||
}
|
||||
|
||||
|
||||
public static String getSaasKey() {
|
||||
return get(SecurityConstants.SAAS_KEY);
|
||||
}
|
||||
|
@ -88,4 +89,5 @@ public class SecurityContextHolder {
|
|||
set(SecurityConstants.SAAS_KEY,saasKey);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ public class JwtUtils {
|
|||
return Convert.toStr(claims.get(key), "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据身份信息获取SAASKey
|
||||
*
|
||||
|
@ -173,4 +174,5 @@ public class JwtUtils {
|
|||
public static String getSaasKey(Claims claims) {
|
||||
return getValue(claims, SecurityConstants.SAAS_KEY);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ public class IpUtils {
|
|||
ip = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
|
||||
return "0:0:0:0:0:0:0:1".equals(ip) ? "106.54.193.225" : getMultistageReverseProxyIp(ip);
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,10 @@ public class IpUtils {
|
|||
*/
|
||||
public static boolean internalIp (String ip) {
|
||||
byte[] addr = textToNumericFormatV4(ip);
|
||||
|
||||
return internalIp(addr) || "106.54.193.225".equals(ip);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,6 +201,7 @@ public class IpUtils {
|
|||
return InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
|
||||
return "106.54.193.225";
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,11 @@ import org.aspectj.lang.annotation.Aspect;
|
|||
import org.aspectj.lang.annotation.Before;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -48,7 +52,11 @@ public class LogAspect {
|
|||
*/
|
||||
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
|
||||
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private AsyncLogService asyncLogService;
|
||||
|
||||
/**
|
||||
|
@ -82,7 +90,7 @@ public class LogAspect {
|
|||
|
||||
protected void handleLog (final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
|
||||
try {
|
||||
// *========数据库日志=========*//
|
||||
// *=数据库日志==*//
|
||||
SysOperLog operLog = new SysOperLog();
|
||||
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
|
||||
// 请求的地址
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.muyu.common.core.constant.SecurityConstants;
|
|||
import com.muyu.common.system.remote.RemoteLogService;
|
||||
import com.muyu.common.system.domain.SysOperLog;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
@ -14,7 +15,7 @@ import org.springframework.stereotype.Service;
|
|||
*/
|
||||
@Service
|
||||
public class AsyncLogService {
|
||||
@Resource
|
||||
@Autowired
|
||||
private RemoteLogService remoteLogService;
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,4 +32,7 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.muyu.common.rabbit;
|
||||
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
|
||||
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
|
||||
|
||||
@Configuration
|
||||
public class RabbitListenerConfigurer implements org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer {
|
||||
|
||||
static {
|
||||
System.setProperty("spring.amqp.deserialization.trust.all", "true");
|
||||
}
|
||||
|
||||
//以下配置RabbitMQ消息服务
|
||||
@Autowired
|
||||
public ConnectionFactory connectionFactory;
|
||||
|
||||
|
||||
/**
|
||||
* 处理器方法工厂
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public DefaultMessageHandlerMethodFactory handlerMethodFactory() {
|
||||
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
|
||||
// 这里的转换器设置实现了 通过 @Payload 注解 自动反序列化message body
|
||||
factory.setMessageConverter(new MappingJackson2MessageConverter());
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) {
|
||||
rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(handlerMethodFactory());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
|
||||
com.muyu.common.rabbit.config.RabbitListenerConfig
|
||||
com.muyu.common.rabbit.config.RabbitAdminConfig
|
||||
com.muyu.common.rabbit.config.RabbitMQMessageConverterConfig
|
||||
|
||||
com.muyu.common.rabbit.RabbitListenerConfigurer
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package com.muyu.common.redis.service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.BoundSetOperations;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -18,7 +20,11 @@ import java.util.concurrent.TimeUnit;
|
|||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
@Component
|
||||
public class RedisService {
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
public RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,10 @@ public class HeaderInterceptor implements AsyncHandlerInterceptor {
|
|||
}
|
||||
|
||||
SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID));
|
||||
|
||||
SecurityContextHolder.setSaasKey(ServletUtils.getHeader(request, SecurityConstants.SAAS_KEY));
|
||||
|
||||
|
||||
SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME));
|
||||
SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY));
|
||||
|
||||
|
|
|
@ -30,10 +30,13 @@ public class SecurityUtils {
|
|||
return SecurityContextHolder.getUserName();
|
||||
}
|
||||
|
||||
|
||||
public static String getSaasKey () {
|
||||
return SecurityContextHolder.getSaasKey();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户key
|
||||
*/
|
||||
|
|
|
@ -65,4 +65,7 @@ public class LoginUser implements Serializable {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,8 +34,11 @@ public class SysDept extends BaseEntity {
|
|||
*/
|
||||
private Long parentId;
|
||||
|
||||
|
||||
private String firmCode;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 祖级列表
|
||||
*/
|
||||
|
|
|
@ -36,8 +36,11 @@ public class SysRole extends BaseEntity {
|
|||
@Excel(name = "角色名称")
|
||||
private String roleName;
|
||||
|
||||
|
||||
private String firmCode;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 角色权限
|
||||
*/
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.muyu.common.system.remote;
|
|||
import com.muyu.common.core.constant.SecurityConstants;
|
||||
import com.muyu.common.core.constant.ServiceNameConstants;
|
||||
import com.muyu.common.core.domain.Result;
|
||||
|
||||
import com.muyu.common.system.domain.*;
|
||||
import com.muyu.common.system.remote.factory.RemoteUserFallbackFactory;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
|
@ -11,6 +12,14 @@ import org.springframework.web.bind.annotation.*;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
import com.muyu.common.system.domain.SysUser;
|
||||
import com.muyu.common.system.remote.factory.RemoteUserFallbackFactory;
|
||||
import com.muyu.common.system.domain.LoginUser;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
|
@ -19,6 +28,19 @@ import java.util.Set;
|
|||
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
|
||||
public interface RemoteUserService {
|
||||
|
||||
|
||||
/**
|
||||
* 通过用户名查询用户信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param source 请求来源
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/user/info/{username}")
|
||||
public Result<LoginUser> getUserInfo (@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
|
||||
/**
|
||||
* 注册用户信息
|
||||
*
|
||||
|
@ -30,6 +52,7 @@ public interface RemoteUserService {
|
|||
@PostMapping("/user/register")
|
||||
public Result<Boolean> registerUserInfo (@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
|
||||
@GetMapping("/user/companyList")
|
||||
public Result<List<SysUser>> companyList ();
|
||||
|
||||
|
@ -98,4 +121,6 @@ public interface RemoteUserService {
|
|||
*/
|
||||
@PostMapping("/user")
|
||||
public Result addUser (@RequestBody SysUser user);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
package com.muyu.common.system.remote.factory;
|
||||
|
||||
import com.muyu.common.core.domain.Result;
|
||||
|
||||
import com.muyu.common.core.web.page.TableDataInfo;
|
||||
import com.muyu.common.system.domain.*;
|
||||
import com.muyu.common.system.remote.RemoteUserService;
|
||||
|
||||
import com.muyu.common.system.remote.RemoteUserService;
|
||||
import com.muyu.common.system.domain.SysUser;
|
||||
import com.muyu.common.system.domain.LoginUser;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用户服务降级处理
|
||||
*
|
||||
|
@ -26,11 +35,19 @@ public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserServ
|
|||
log.error("用户服务调用失败:{}", throwable.getMessage());
|
||||
return new RemoteUserService() {
|
||||
|
||||
|
||||
@Override
|
||||
public Result<LoginUser> getUserInfo (String username, String source) {
|
||||
return Result.error("获取用户失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<Boolean> registerUserInfo (SysUser sysUser, String source) {
|
||||
return Result.error("注册用户失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<List<SysUser>> companyList() {
|
||||
return Result.error("获取企业列表失败:" + throwable.getMessage());
|
||||
|
@ -76,6 +93,8 @@ public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserServ
|
|||
return Result.error(throwable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
com.muyu.common.system.remote.factory.RemoteUserFallbackFactory
|
||||
com.muyu.common.system.remote.factory.RemoteLogFallbackFactory
|
||||
com.muyu.common.system.remote.factory.RemoteFileFallbackFactory
|
||||
|
||||
com.muyu.common.system.remote.factory.RemoteSaasFallbackFactory
|
||||
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Log4j2
|
||||
//@Component
|
||||
@Component
|
||||
public class XXLJobConfig {
|
||||
// @Bean
|
||||
@Bean
|
||||
public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperties xxlJobProperties) {
|
||||
if (StringUtils.isEmpty(xxlJobProperties.getAdminAddresses())){
|
||||
throw new RuntimeException("请在bootstrap.yml当中配置shared-configs项,xxl-job共享配置[application-xxl-config]");
|
||||
|
|
|
@ -81,6 +81,8 @@
|
|||
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
|
||||
<version>4.5.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -13,6 +13,9 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
|||
public class CloudGatewayApplication {
|
||||
public static void main (String[] args) {
|
||||
SpringApplication.run(CloudGatewayApplication.class, args);
|
||||
|
||||
System.out.println("CloudGateway 模块启动成功!");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package com.muyu.gateway.config;
|
||||
|
||||
import com.muyu.gateway.handler.ValidateCodeHandler;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -16,7 +20,11 @@ import org.springframework.web.reactive.function.server.RouterFunctions;
|
|||
*/
|
||||
@Configuration
|
||||
public class RouterFunctionConfiguration {
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private ValidateCodeHandler validateCodeHandler;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
|
|
@ -177,7 +177,7 @@ public class AccessLogFilter implements GlobalFilter, Ordered {
|
|||
};
|
||||
}
|
||||
|
||||
// ========== 参考 ModifyRequestBodyGatewayFilterFactory 中的方法 ==========
|
||||
// === 参考 ModifyRequestBodyGatewayFilterFactory 中的方法 ===
|
||||
|
||||
/**
|
||||
* 请求装饰器,支持重新计算 headers、body 缓存
|
||||
|
@ -210,7 +210,7 @@ public class AccessLogFilter implements GlobalFilter, Ordered {
|
|||
};
|
||||
}
|
||||
|
||||
// ========== 参考 ModifyResponseBodyGatewayFilterFactory 中的方法 ==========
|
||||
// === 参考 ModifyResponseBodyGatewayFilterFactory 中的方法 ===
|
||||
|
||||
private byte[] readContent(List<? extends DataBuffer> dataBuffers) {
|
||||
// 合并多个流集合,解决返回体分段传输
|
||||
|
|
|
@ -4,7 +4,11 @@ import com.muyu.common.core.utils.StringUtils;
|
|||
import com.muyu.common.core.utils.html.EscapeUtil;
|
||||
import com.muyu.gateway.config.properties.XssProperties;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
|
@ -31,7 +35,11 @@ import java.nio.charset.StandardCharsets;
|
|||
@ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true")
|
||||
public class XssFilter implements GlobalFilter, Ordered {
|
||||
// 跨站脚本的 xss 配置,nacos自行添加
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private XssProperties xss;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,7 +3,11 @@ package com.muyu.gateway.handler;
|
|||
import com.muyu.common.core.exception.CaptchaException;
|
||||
import com.muyu.common.core.domain.Result;
|
||||
import com.muyu.gateway.service.ValidateCodeService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
|
@ -21,7 +25,11 @@ import java.io.IOException;
|
|||
*/
|
||||
@Component
|
||||
public class ValidateCodeHandler implements HandlerFunction<ServerResponse> {
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private ValidateCodeService validateCodeService;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,7 +12,7 @@ import com.muyu.common.redis.service.RedisService;
|
|||
import com.muyu.gateway.config.properties.CaptchaProperties;
|
||||
import com.muyu.gateway.model.resp.CaptchaCodeResp;
|
||||
import com.muyu.gateway.service.ValidateCodeService;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
|
||||
|
@ -35,10 +35,10 @@ public class ValidateCodeServiceImpl implements ValidateCodeService {
|
|||
@Resource(name = "captchaProducerMath")
|
||||
private Producer captchaProducerMath;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
private CaptchaProperties captchaProperties;
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,11 @@ import cn.hutool.core.net.NetUtil;
|
|||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.gateway.route.Route;
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||
import org.springframework.core.io.buffer.DataBufferFactory;
|
||||
|
@ -16,6 +21,11 @@ import reactor.core.publisher.Mono;
|
|||
|
||||
/**
|
||||
* Web 工具类
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
|
||||
*/
|
||||
@Log4j2
|
||||
public class WebFrameworkUtils {
|
||||
|
@ -68,6 +78,11 @@ public class WebFrameworkUtils {
|
|||
|
||||
/**
|
||||
* 获得客户端 IP
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
|
||||
* @param exchange 请求
|
||||
* @param otherHeaderNames 其它 header 名字的数组
|
||||
* @return 客户端 IP
|
||||
|
@ -85,6 +100,10 @@ public class WebFrameworkUtils {
|
|||
return NetUtil.getMultistageReverseProxyIp(ip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 方式二,通过 remoteAddress 获取
|
||||
if (exchange.getRequest().getRemoteAddress() == null) {
|
||||
return null;
|
||||
|
@ -95,6 +114,10 @@ public class WebFrameworkUtils {
|
|||
|
||||
/**
|
||||
* 获得请求匹配的 Route 路由
|
||||
|
||||
|
||||
*
|
||||
|
||||
* @param exchange 请求
|
||||
* @return 路由
|
||||
*/
|
||||
|
|
|
@ -4,11 +4,15 @@ server:
|
|||
|
||||
# nacos线上地址
|
||||
nacos:
|
||||
addr: 47.116.173.119:8848
|
||||
addr: 106.54.193.225:8848
|
||||
user-name: nacos
|
||||
password: nacos
|
||||
|
||||
namespace: one-saas
|
||||
|
||||
namespace: one
|
||||
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
|
@ -22,35 +26,60 @@ spring:
|
|||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: ${nacos.addr}
|
||||
|
||||
# # nacos用户名
|
||||
# username: ${nacos.user-name}
|
||||
# # nacos密码
|
||||
# password: ${nacos.password}
|
||||
|
||||
# nacos用户名
|
||||
username: ${nacos.user-name}
|
||||
# nacos密码
|
||||
password: ${nacos.password}
|
||||
|
||||
# 命名空间
|
||||
namespace: ${nacos.namespace}
|
||||
config:
|
||||
# 服务注册地址
|
||||
server-addr: ${nacos.addr}
|
||||
|
||||
# # nacos用户名
|
||||
# username: ${nacos.user-name}
|
||||
# # nacos密码
|
||||
# password: ${nacos.password}
|
||||
|
||||
# nacos用户名
|
||||
username: ${nacos.user-name}
|
||||
# nacos密码
|
||||
password: ${nacos.password}
|
||||
|
||||
# 命名空间
|
||||
namespace: ${nacos.namespace}
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
|
||||
# 系统环境Config共享配置
|
||||
- application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
# 系统共享配置
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
|
||||
# 系统共享配置
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
# 系统环境Config共享配置
|
||||
- application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
|
||||
sentinel:
|
||||
# 取消控制台懒加载
|
||||
eager: true
|
||||
transport:
|
||||
# 控制台地址
|
||||
|
||||
dashboard: 106.54.193.225:8718
|
||||
|
||||
dashboard: 127.0.0.1:8718
|
||||
|
||||
# nacos配置持久化
|
||||
datasource:
|
||||
ds1:
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 10022
|
||||
port: 9702
|
||||
|
||||
# nacos线上地址
|
||||
nacos:
|
||||
addr: 47.116.173.119:8848
|
||||
addr: 106.54.193.225:8848
|
||||
user-name: nacos
|
||||
password: nacos
|
||||
namespace: one
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.muyu.cargateway.Aliyun;
|
||||
|
||||
import com.aliyun.ecs20140526.Client;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import com.muyu.cargateway.config.AliProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Lenovo
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-10-07-18:40
|
||||
* @ Version:1.0
|
||||
* @ Description:Ali客户端
|
||||
*/
|
||||
@Configuration
|
||||
public class AliYunConfig {
|
||||
|
||||
@Autowired
|
||||
private AliProperties aliProperties;
|
||||
|
||||
@Bean
|
||||
public Client createClient() {
|
||||
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||||
Config config = new Config()
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||
.setAccessKeyId(aliProperties.getAccessKeyId())
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||
.setAccessKeySecret(aliProperties.getAccessKeySecret());
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/Ecs
|
||||
config.endpoint = aliProperties.getEndpoint();
|
||||
try {
|
||||
return new Client(config);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
package com.muyu.cargateway.Aliyun.service;
|
||||
|
||||
import com.aliyun.ecs20140526.Client;
|
||||
import com.aliyun.ecs20140526.models.*;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.muyu.cargateway.config.AliProperties;
|
||||
import com.muyu.cargateway.domain.AliInstance;
|
||||
import com.muyu.common.core.exception.ServiceException;
|
||||
import com.muyu.common.redis.service.RedisService;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Lenovo
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-10-07-18:43
|
||||
* @ Version:1.0
|
||||
* @ Description:ali业务层
|
||||
*/
|
||||
@Log4j2
|
||||
@Service
|
||||
public class AliYunEcsService {
|
||||
/**
|
||||
* 阿里云配置
|
||||
*/
|
||||
@Autowired
|
||||
private AliProperties aliProperties;
|
||||
/**
|
||||
* 阿里云客户端
|
||||
*/
|
||||
@Autowired
|
||||
private Client client;
|
||||
/**
|
||||
* redis缓存
|
||||
*/
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 生成实例
|
||||
*
|
||||
* @param amount 生成数量
|
||||
* @return 实例id集合
|
||||
*/
|
||||
public List<String> generateInstance(Integer amount) {
|
||||
redisService.deleteObject("instanceIds");
|
||||
redisService.deleteObject("instanceList");
|
||||
// 检查生成实例的数量是否有效
|
||||
if (amount == null || amount <= 0) {
|
||||
throw new ServiceException("生成数量不能小于1");
|
||||
}
|
||||
|
||||
// 初始化系统盘配置
|
||||
RunInstancesRequest.RunInstancesRequestSystemDisk systemDisk = new RunInstancesRequest.RunInstancesRequestSystemDisk();
|
||||
systemDisk.setSize("40");
|
||||
systemDisk.setCategory("cloud_essd");
|
||||
|
||||
// 创建创建实例请求对象并设置参数
|
||||
RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
|
||||
// 设置地域ID
|
||||
.setRegionId(aliProperties.getRegionId())
|
||||
// 设置镜像ID
|
||||
.setImageId(aliProperties.getImageId())
|
||||
// 设置实例规格类型
|
||||
.setInstanceType(aliProperties.getInstanceType())
|
||||
// 设置安全组ID
|
||||
.setSecurityGroupId(aliProperties.getSecurityGroupId())
|
||||
// 设置虚拟交换机ID
|
||||
.setVSwitchId(aliProperties.getSwitchId())
|
||||
// 设置实例名称
|
||||
.setInstanceName("server-mqtt")
|
||||
// 设置付费类型 按量付费
|
||||
.setInstanceChargeType("PostPaid")
|
||||
// 设置系统盘配置
|
||||
.setSystemDisk(systemDisk)
|
||||
// 设置用户名
|
||||
.setHostName("root")
|
||||
// 设置密码
|
||||
.setPassword("10160810@a")
|
||||
// 设置要创建的实例数量
|
||||
.setAmount(amount)
|
||||
.setInternetChargeType("PayByTraffic")
|
||||
.setInternetMaxBandwidthOut(1);
|
||||
|
||||
// 创建运行时选项对象
|
||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
|
||||
// 尝试执行创建实例请求
|
||||
try {
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
RunInstancesResponse runInstancesResponse = client.runInstancesWithOptions(runInstancesRequest, runtimeOptions);
|
||||
if (runInstancesResponse.getStatusCode() != 200) {
|
||||
throw new ServiceException("查询实例状态失败");
|
||||
}
|
||||
log.info("实例创建成功: {}", runInstancesResponse.getBody().getInstanceIdSets().instanceIdSet);
|
||||
RunInstancesResponseBody body = runInstancesResponse.getBody();
|
||||
RunInstancesResponseBody.RunInstancesResponseBodyInstanceIdSets instanceIdSets = body.getInstanceIdSets();
|
||||
return new ArrayList<>(instanceIdSets.instanceIdSet);
|
||||
} catch (Exception error) {
|
||||
log.error("创建阿里云实例报错:[{}]", error.getMessage());
|
||||
throw new ServiceException(error.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据实例id查询实例信息
|
||||
*
|
||||
* @param instanceIds 实例id集合
|
||||
*/
|
||||
public List<AliInstance> selectInstance(List<String> instanceIds) throws Exception {
|
||||
// 检查实例ID列表是否为空,如果为空则抛出异常
|
||||
if (instanceIds == null || instanceIds.isEmpty()) {
|
||||
throw new ServiceException("实例id不能为空");
|
||||
}
|
||||
// 创建查询实例的请求对象
|
||||
DescribeInstancesRequest request = new DescribeInstancesRequest()
|
||||
.setRegionId(aliProperties.getRegionId());
|
||||
|
||||
// 创建运行时选项对象,用于配置请求的额外参数
|
||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
List<AliInstance> aliInstances = new ArrayList<>();
|
||||
try {
|
||||
// 发送请求并获取响应对象
|
||||
DescribeInstancesResponse describeInstancesResponse = client.describeInstancesWithOptions(request, runtimeOptions);
|
||||
// 检查响应状态码,如果为200则表示查询失败,抛出异常
|
||||
if (describeInstancesResponse.getStatusCode() != 200) {
|
||||
throw new ServiceException("查询实例状态失败");
|
||||
}
|
||||
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instance = describeInstancesResponse.getBody().getInstances().getInstance();
|
||||
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance bodyInstance : instance) {
|
||||
// 实例id
|
||||
String instanceId = bodyInstance.getInstanceId();
|
||||
log.info("实例id为:{}", instanceId);
|
||||
// ip地址
|
||||
String ipAddress = bodyInstance.getPublicIpAddress().getIpAddress().get(0);
|
||||
log.info("实例ip为:{}", ipAddress);
|
||||
// 实例状态
|
||||
String status = bodyInstance.getStatus();
|
||||
log.info("实例状态为:{}", status);
|
||||
AliInstance aliInstance = new AliInstance(instanceId, ipAddress, status);
|
||||
aliInstances.add(aliInstance);
|
||||
}
|
||||
log.info("查询成功");
|
||||
} catch (Exception e) {
|
||||
log.error("查询服务器实例错误:[{}]", e.getMessage(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return aliInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除实例
|
||||
*/
|
||||
public void deleteInstance() throws Exception {
|
||||
DescribeInstancesRequest attributeRequest = new DescribeInstancesRequest();
|
||||
attributeRequest.setRegionId(aliProperties.getRegionId());
|
||||
|
||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
|
||||
DescribeInstancesResponse instancesWithOptions = client.describeInstancesWithOptions(attributeRequest, runtimeOptions);
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
DescribeInstancesResponseBody body = instancesWithOptions.getBody();
|
||||
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : body.instances.instance) {
|
||||
list.add(instance.getInstanceId());
|
||||
}
|
||||
log.info("list:" + list);
|
||||
DeleteInstancesRequest deleteInstancesRequest = new DeleteInstancesRequest();
|
||||
deleteInstancesRequest.setRegionId(aliProperties.getRegionId())
|
||||
.setDryRun(false)
|
||||
.setForce(true)
|
||||
.setTerminateSubscription(true)
|
||||
.setInstanceId(list);
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
try {
|
||||
client.deleteInstancesWithOptions(deleteInstancesRequest, runtime);
|
||||
} catch (TeaException error) {
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
} catch (Exception _error) {
|
||||
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.muyu.cargateway;
|
||||
|
||||
import com.muyu.common.security.annotation.EnableCustomConfig;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
@ -13,6 +14,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
|||
* @ Description:故障启动类
|
||||
* @author Lenovo
|
||||
*/
|
||||
@Log4j2
|
||||
@EnableCustomConfig
|
||||
@EnableFeignClients
|
||||
@SpringBootApplication
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package com.muyu.cargateway.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Lenovo
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-10-07-18:34
|
||||
* @ Version:1.0
|
||||
* @ Description:Ali配置类
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "aliyun")
|
||||
public class AliProperties {
|
||||
/**
|
||||
* key
|
||||
*/
|
||||
private String accessKeyId;
|
||||
/**
|
||||
* secret
|
||||
*/
|
||||
private String accessKeySecret;
|
||||
/**
|
||||
* 地域
|
||||
*/
|
||||
private String endpoint;
|
||||
/**
|
||||
* 地域id
|
||||
*/
|
||||
private String regionId;
|
||||
/**
|
||||
* 镜像id
|
||||
*/
|
||||
private String imageId;
|
||||
/**
|
||||
* 实例规格
|
||||
*/
|
||||
private String instanceType;
|
||||
/**
|
||||
* 安全组id
|
||||
*/
|
||||
private String securityGroupId;
|
||||
/**
|
||||
* 虚拟交换机ID
|
||||
*/
|
||||
private String switchId;
|
||||
/**
|
||||
* 生成实例数量
|
||||
*/
|
||||
private Integer amount;
|
||||
}
|
|
@ -1,24 +1,20 @@
|
|||
package com.muyu.cargateway.config;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.Exchange;
|
||||
import org.springframework.amqp.core.ExchangeBuilder;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.amqp.core.*;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Lenovo
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-10-04-15:13
|
||||
* @ Version:1.0
|
||||
* @ Description:rabbitmq配置类
|
||||
* @author Lenovo
|
||||
*/
|
||||
@Log4j2
|
||||
@Configuration
|
||||
|
@ -91,13 +87,14 @@ public class RabbitmqConfig {
|
|||
//ROUTINGKEY_EMAIL队列绑定交换机,指定routingKey
|
||||
@Bean
|
||||
public Binding bindingQueueInformEmail(@Qualifier(QUEUE_INFORM_EMAIL) Queue queue,
|
||||
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange){
|
||||
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
|
||||
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_EMAIL).noargs();
|
||||
}
|
||||
|
||||
//ROUTINGKEY_SMS队列绑定交换机,指定routingKey
|
||||
@Bean
|
||||
public Binding bindingRoutingKeySms(@Qualifier(QUEUE_INFORM_SMS) Queue queue,
|
||||
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange){
|
||||
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
|
||||
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_SMS).noargs();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package com.muyu.cargateway.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-10-04-15:12
|
||||
* @ Version:1.0
|
||||
* @ Description:Redis配置类
|
||||
* @author Lenovo
|
||||
*/
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
@Bean
|
||||
public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory redisConnectionFactory){
|
||||
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
|
||||
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
|
||||
return redisTemplate;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package com.muyu.cargateway.config;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-10-04-15:08
|
||||
* @ Version:1.0
|
||||
* @ Description:rest配置类
|
||||
* @author Lenovo
|
||||
*/
|
||||
@Log4j2
|
||||
@Configuration
|
||||
public class RestTemplateConfig {
|
||||
@Bean
|
||||
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
|
||||
return new RestTemplate(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并配置客户端HTTP请求工厂实例。
|
||||
* 注意:这里设置了连接和读取数据的超时时间,分别设为15秒和5秒。
|
||||
* 这些值可以根据实际网络状况和应用需求进行调整。
|
||||
*
|
||||
* @return 配置好的客户端请求工厂对象
|
||||
*/
|
||||
@Bean
|
||||
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
|
||||
try {
|
||||
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
|
||||
// 设置读取超时时间为5秒
|
||||
factory.setReadTimeout(5000);
|
||||
// 设置连接超时时间为15秒
|
||||
factory.setConnectTimeout(15000);
|
||||
return factory;
|
||||
} catch (Exception e) {
|
||||
// 处理创建工厂或设置超时时间时可能出现的异常
|
||||
log.info("创建工厂失败: " + e.getMessage());
|
||||
throw new RuntimeException("初始化HTTP请求失败", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ public class CarOneClickOperationController {
|
|||
*/
|
||||
@PostMapping("/receiveMsg/connect")
|
||||
public Result<MqttServerModel> receiveMsg(@RequestBody VehicleConnectionReq vehicleConnectionReq){
|
||||
log.info("=======>"+vehicleConnectionReq);
|
||||
log.info(">"+vehicleConnectionReq);
|
||||
MqttServerModel mqttServerModel =carOneClickOperationService.getConnect(vehicleConnectionReq);
|
||||
return Result.success(mqttServerModel);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.muyu.cargateway.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
|
@ -13,6 +14,7 @@ import lombok.NoArgsConstructor;
|
|||
* @author Lenovo
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class AliInstance {
|
||||
|
@ -28,4 +30,5 @@ public class AliInstance {
|
|||
* 实例状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.muyu.cargateway.instance;
|
||||
|
||||
import com.muyu.cargateway.Aliyun.service.AliYunEcsService;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-10-07-21:51
|
||||
* @ Version:1.0
|
||||
* @ Description:删除实例方法
|
||||
* @author Lenovo
|
||||
*/
|
||||
@Log4j2
|
||||
@Component
|
||||
public class DeleteSample implements DisposableBean {
|
||||
@Autowired
|
||||
private AliYunEcsService aliYunEcsService;
|
||||
@Override
|
||||
public void destroy() {
|
||||
try {
|
||||
log.info("===开始执行删除实例方法");
|
||||
Thread.sleep(10000);
|
||||
aliYunEcsService.deleteInstance();
|
||||
} catch (Exception e) {
|
||||
log.info("删除实例失败");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
log.info("删除实例成功");
|
||||
}
|
||||
}
|
|
@ -1,229 +1,71 @@
|
|||
package com.muyu.cargateway.instance;
|
||||
|
||||
import com.aliyun.ecs20140526.Client;
|
||||
import com.aliyun.ecs20140526.models.*;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import com.aliyun.teautil.Common;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.muyu.cargateway.Aliyun.service.AliYunEcsService;
|
||||
import com.muyu.cargateway.config.AliProperties;
|
||||
import com.muyu.cargateway.domain.AliInstance;
|
||||
import com.muyu.common.redis.service.RedisService;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Lenovo
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-09-28-21:10
|
||||
* @ Version:1.0
|
||||
* @ Description:调用ali的类
|
||||
* @author Lenovo
|
||||
*/
|
||||
@Log4j2
|
||||
@Component
|
||||
public class Sample implements ApplicationRunner , DisposableBean {
|
||||
public class Sample implements ApplicationRunner{
|
||||
|
||||
@Autowired
|
||||
private AliYunEcsService aliYunEcsService;
|
||||
@Autowired
|
||||
private AliProperties aliProperties;
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
public static final String ACCESS_KEY_ID = "LTAI5tDH3FyRx4PRr6anx2TL";
|
||||
public static final String ACCESS_KEY_SECRET = "xdQnX2tDattY50raNkUWmHzE2tondP";
|
||||
|
||||
public static Client createClient() throws Exception {
|
||||
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||||
Config config = new Config()
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||
.setAccessKeyId(ACCESS_KEY_ID)
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||
.setAccessKeySecret(ACCESS_KEY_SECRET);
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/Ecs
|
||||
config.endpoint = "ecs-cn-hangzhou.aliyuncs.com";
|
||||
return new Client(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建实例
|
||||
* @throws Exception
|
||||
*/
|
||||
public void generateInstance() throws Exception {
|
||||
Client client = Sample.createClient();
|
||||
RunInstancesRequest.RunInstancesRequestSystemDisk systemDisk = new RunInstancesRequest.RunInstancesRequestSystemDisk();
|
||||
//设置系统盘的大小为40GiB
|
||||
systemDisk.setSize("40");
|
||||
//设置系统盘类型为cloud_essd
|
||||
systemDisk.setCategory("cloud_essd");
|
||||
|
||||
// 创建创建实例请求对象并设置参数
|
||||
|
||||
RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
|
||||
// 设置地域ID
|
||||
.setRegionId("cn-shanghai")
|
||||
// 设置镜像ID
|
||||
.setImageId("m-uf6ih0vnl5f51pquns11")
|
||||
// 设置实例规格类型
|
||||
.setInstanceType("ecs.t6-c1m1.large")
|
||||
// 设置安全组ID
|
||||
.setSecurityGroupId("sg-uf642d5u4ja5gsiitx8y")
|
||||
// 设置虚拟交换机ID
|
||||
.setVSwitchId("vsw-uf66lifrkhxqc94xi06v3")
|
||||
// 设置实例名称
|
||||
.setInstanceName("server-mqtt")
|
||||
// 设置付费类型 按量付费
|
||||
.setInstanceChargeType("PostPaid")
|
||||
// 设置系统盘配置
|
||||
.setSystemDisk(systemDisk)
|
||||
// 设置用户名
|
||||
.setHostName("root")
|
||||
// 设置密码
|
||||
.setPassword("10160810@a")
|
||||
// 设置要创建的实例数量
|
||||
.setAmount(1)
|
||||
.setInternetChargeType("PayByTraffic")
|
||||
.setInternetMaxBandwidthOut(1);
|
||||
|
||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
// 尝试执行创建实例请求
|
||||
try {
|
||||
|
||||
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
RunInstancesResponse runInstancesResponse = client.runInstancesWithOptions(runInstancesRequest, runtimeOptions);
|
||||
log.info("实例创建成功: {}", runInstancesResponse.getBody().getInstanceIdSets().instanceIdSet);
|
||||
RunInstancesResponseBody body = runInstancesResponse.getBody();
|
||||
RunInstancesResponseBody.RunInstancesResponseBodyInstanceIdSets instanceIdSets = body.getInstanceIdSets();
|
||||
|
||||
List<AliInstance> instanceList = new ArrayList<>();
|
||||
List<String> instanceIds = new ArrayList<>();
|
||||
//遍历实例ID
|
||||
for (String string : instanceIdSets.instanceIdSet) {
|
||||
instanceIds.add(string);
|
||||
}
|
||||
// 在获取实例详细信息时,确保获取所有必要的信息
|
||||
DescribeInstancesResponse describeInstancesResponse = getInstances(client);
|
||||
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instances = describeInstancesResponse.getBody().getInstances().getInstance();
|
||||
List<AliInstance> aliInstances = new ArrayList<>();
|
||||
instanceIds = new ArrayList<>();
|
||||
|
||||
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : instances) {
|
||||
String instanceId = instance.getInstanceId();
|
||||
String ipAddress = instance.getPublicIpAddress().getIpAddress().get(0);
|
||||
String status = instance.getStatus();
|
||||
log.info("获取到的实例ID为{} IP为{} 状态为{}", instanceId, ipAddress, status);
|
||||
aliInstances.add(new AliInstance(instanceId, ipAddress, status));
|
||||
instanceIds.add(instanceId);
|
||||
}
|
||||
//实例信息集合(实例id,ip 状态) 存储在redis中
|
||||
redisService.setCacheList("instanceList", aliInstances);
|
||||
// 实例ID集合 存储在redis中
|
||||
redisService.setCacheList("instanceIds", instanceIds);
|
||||
|
||||
} catch (TeaException error) {
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
log.info(error.getMessage());
|
||||
// 诊断地址
|
||||
log.info(error.getData().get("Recommend"));
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
} catch (Exception _error) {
|
||||
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
log.info(error.getMessage());
|
||||
// 诊断地址
|
||||
log.info(error.getData().get("Recommend"));
|
||||
Common.assertAsString(error.message);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取实例ID
|
||||
* @param client
|
||||
* @return string类型的实例ID集合
|
||||
* @throws Exception
|
||||
*/
|
||||
@NotNull
|
||||
private DescribeInstancesResponse getInstances(Client client) throws Exception {
|
||||
DescribeInstancesRequest request = new DescribeInstancesRequest();
|
||||
request.setInstanceName("server-mqtt");
|
||||
request.setRegionId("cn-shanghai");
|
||||
|
||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
return client.describeInstancesWithOptions(request, runtimeOptions);
|
||||
}
|
||||
/**
|
||||
* 删除创建的实例
|
||||
* @throws Exception
|
||||
*/
|
||||
public void deleteSample() throws Exception {
|
||||
Client client = Sample.createClient();
|
||||
DescribeInstancesRequest attributeRequest = new DescribeInstancesRequest();
|
||||
attributeRequest.setRegionId("cn-shanghai");
|
||||
|
||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
|
||||
DescribeInstancesResponse instancesWithOptions = client.describeInstancesWithOptions(attributeRequest, runtimeOptions);
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
DescribeInstancesResponseBody body = instancesWithOptions.getBody();
|
||||
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : body.instances.instance) {
|
||||
list.add(instance.getInstanceId());
|
||||
}
|
||||
log.info("list:"+list);
|
||||
DeleteInstancesRequest deleteInstancesRequest = new DeleteInstancesRequest();
|
||||
deleteInstancesRequest.setRegionId("cn-shanghai")
|
||||
.setDryRun(false)
|
||||
.setForce(true)
|
||||
.setTerminateSubscription(true)
|
||||
.setInstanceId(list);
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
try{
|
||||
client.deleteInstancesWithOptions(deleteInstancesRequest, runtime);
|
||||
}catch (TeaException error) {
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
} catch (Exception _error) {
|
||||
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args){
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
List<String> list;
|
||||
try {
|
||||
log.info("开始创建实例");
|
||||
generateInstance();
|
||||
list = aliYunEcsService.generateInstance(aliProperties.getAmount());
|
||||
} catch (Exception e) {
|
||||
log.info("创建实例失败");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
log.info("创建实例成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(){
|
||||
redisService.setCacheList("instanceIds", list);
|
||||
try {
|
||||
log.info("删除实例方法");
|
||||
Thread.sleep(10000);
|
||||
deleteSample();
|
||||
} catch (Exception e) {
|
||||
log.info("删除实例失败");
|
||||
Thread.sleep(6000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
log.info("删除实例成功");
|
||||
List<AliInstance> aliInstances = aliYunEcsService.selectInstance(list);
|
||||
log.info("查询实例信息成功:{}",aliInstances);
|
||||
// 将查询到的实例信息列表存储到Redis中
|
||||
redisService.setCacheList("instanceList", aliInstances);
|
||||
log.info("redis存储成功:{}", aliInstances);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void destroy(){
|
||||
// try {
|
||||
// log.info("===开始执行删除实例方法");
|
||||
// aliYunEcsService.deleteInstance();
|
||||
// redisService.deleteObject("instanceIds");
|
||||
// redisService.deleteObject("instanceList");
|
||||
// } catch (Exception e) {
|
||||
// log.info("删除实例失败");
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// log.info("删除实例成功");
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -17,6 +17,5 @@ import java.util.List;
|
|||
public interface CarOneClickOperationMapper {
|
||||
void addConnect(VehicleConnection vehicleConnection);
|
||||
|
||||
|
||||
List<String> selectByVehicleVin(String vehicleVin);
|
||||
}
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
//package com.muyu.cargateway.cargatewaytest;
|
||||
//
|
||||
//import com.aliyun.ecs20140526.Client;
|
||||
//import com.aliyun.ecs20140526.models.*;
|
||||
//import com.aliyun.tea.TeaException;
|
||||
//import com.aliyun.teaopenapi.models.Config;
|
||||
//import com.aliyun.teautil.models.RuntimeOptions;
|
||||
//import lombok.extern.log4j.Log4j2;
|
||||
//import org.springframework.beans.factory.DisposableBean;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//
|
||||
///**
|
||||
// * @ Tool:IntelliJ IDEA
|
||||
// * @ Author:CHX
|
||||
// * @ Date:2024-09-28-21:20
|
||||
// * @ Version:1.0
|
||||
// * @ Description:删除实例
|
||||
// * @author Lenovo
|
||||
// */
|
||||
//@Log4j2
|
||||
//@Component
|
||||
//public class DeleteSample implements DisposableBean {
|
||||
//
|
||||
// public static Client createClient() throws Exception {
|
||||
// // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||||
// Config config = new Config()
|
||||
// // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||
// .setAccessKeyId("LTAI5tDH3FyRx4PRr6anx2TL")
|
||||
// // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||
// .setAccessKeySecret("xdQnX2tDattY50raNkUWmHzE2tondP");
|
||||
// // Endpoint 请参考 https://api.aliyun.com/product/Ecs
|
||||
// config.endpoint = "ecs-cn-hangzhou.aliyuncs.com";
|
||||
// return new Client(config);
|
||||
// }
|
||||
// public static void deleteSample() throws Exception {
|
||||
// Client client = DeleteSample.createClient();
|
||||
// DescribeInstancesRequest attributeRequest = new DescribeInstancesRequest();
|
||||
// attributeRequest.setRegionId("cn-shanghai");
|
||||
//
|
||||
// RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
//
|
||||
// DescribeInstancesResponse instancesWithOptions = client.describeInstancesWithOptions(attributeRequest, runtimeOptions);
|
||||
// ArrayList<String> list = new ArrayList<>();
|
||||
// DescribeInstancesResponseBody body = instancesWithOptions.getBody();
|
||||
// for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : body.instances.instance) {
|
||||
// list.add(instance.getInstanceId());
|
||||
// }
|
||||
// log.info("list:"+list);
|
||||
// DeleteInstancesRequest deleteInstancesRequest = new DeleteInstancesRequest();
|
||||
// deleteInstancesRequest.setRegionId("cn-shanghai")
|
||||
// .setDryRun(false)
|
||||
// .setForce(true)
|
||||
// .setTerminateSubscription(true)
|
||||
// .setInstanceId(list);
|
||||
//
|
||||
// RuntimeOptions runtime = new RuntimeOptions();
|
||||
// try{
|
||||
// client.deleteInstancesWithOptions(deleteInstancesRequest, runtime);
|
||||
// }catch (TeaException error) {
|
||||
// // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// // 错误 message
|
||||
// System.out.println(error.getMessage());
|
||||
// // 诊断地址
|
||||
// System.out.println(error.getData().get("Recommend"));
|
||||
// com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
// } catch (Exception _error) {
|
||||
// TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
// // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// // 错误 message
|
||||
// System.out.println(error.getMessage());
|
||||
// // 诊断地址
|
||||
// System.out.println(error.getData().get("Recommend"));
|
||||
// com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
// }
|
||||
// }
|
||||
// @Override
|
||||
// public void destroy(){
|
||||
// try {
|
||||
// log.info("删除实例方法");
|
||||
// deleteSample();
|
||||
// } catch (Exception e) {
|
||||
// log.info("删除实例失败");
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// log.info("删除实例成功");
|
||||
// }
|
||||
//}
|
|
@ -1,120 +0,0 @@
|
|||
//package com.muyu.cargateway.test;
|
||||
//
|
||||
//import com.aliyun.ecs20140526.Client;
|
||||
//import com.aliyun.ecs20140526.models.RunInstancesRequest;
|
||||
//import com.aliyun.tea.TeaException;
|
||||
//import com.aliyun.teaopenapi.models.Config;
|
||||
//import com.aliyun.teautil.Common;
|
||||
//import com.aliyun.teautil.models.RuntimeOptions;
|
||||
//import lombok.extern.log4j.Log4j2;
|
||||
//
|
||||
//import java.util.Arrays;
|
||||
//import java.util.List;
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * @ Tool:IntelliJ IDEA
|
||||
// * @ Author:CHX
|
||||
// * @ Date:2024-09-27-23:38
|
||||
// * @ Version:1.0
|
||||
// * @ Description:调用ali的测试demo类
|
||||
// * @author Lenovo
|
||||
// */
|
||||
//@Log4j2
|
||||
//public class Sample {
|
||||
//
|
||||
// /**
|
||||
// * <b>description</b> :
|
||||
// * <p>使用AK&SK初始化账号Client</p>
|
||||
// * @return Client
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public static Client createClient() throws Exception {
|
||||
// // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||||
// Config config = new Config()
|
||||
// // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||
// .setAccessKeyId("LTAI5tDH3FyRx4PRr6anx2TL")
|
||||
// // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||
// .setAccessKeySecret("xdQnX2tDattY50raNkUWmHzE2tondP");
|
||||
// // Endpoint 请参考 https://api.aliyun.com/product/Ecs
|
||||
// config.endpoint = "ecs-cn-hangzhou.aliyuncs.com";
|
||||
// return new Client(config);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 本程序的入口点
|
||||
// * 主要功能是创建阿里云ECS实例
|
||||
// *
|
||||
// * @param args 命令行参数
|
||||
// * @throws Exception 如果执行过程中发生错误则抛出异常
|
||||
// */
|
||||
// public static void main(String[] args) throws Exception {
|
||||
// // 将命令行参数转换为字符串列表
|
||||
// List<String> arg = Arrays.asList(args);
|
||||
//
|
||||
// // 创建阿里云ECS客户端
|
||||
// Client client = Sample.createClient();
|
||||
//
|
||||
// // 配置系统盘参数
|
||||
// RunInstancesRequest.RunInstancesRequestSystemDisk systemDisk = new RunInstancesRequest.RunInstancesRequestSystemDisk()
|
||||
// // 设置系统盘大小为20G
|
||||
// .setSize("40")
|
||||
// // 设置系统盘类型为cloud_essd
|
||||
// .setCategory("cloud_essd");
|
||||
//
|
||||
// // 创建创建实例请求对象并设置参数
|
||||
//
|
||||
// RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
|
||||
// // 设置地域ID
|
||||
// .setRegionId("cn-shanghai")
|
||||
// // 设置镜像ID
|
||||
// .setImageId("m-uf65fvle9qseu9jo5jl3")
|
||||
// // 设置实例规格类型
|
||||
// .setInstanceType("ecs.t6-c1m1.large")
|
||||
// // 设置安全组ID
|
||||
// .setSecurityGroupId("sg-uf642d5u4ja5gsiitx8y")
|
||||
// // 设置虚拟交换机ID
|
||||
// .setVSwitchId("vsw-uf66lifrkhxqc94xi06v3")
|
||||
// // 设置实例名称
|
||||
// .setInstanceName("server-mqtt")
|
||||
// // 设置付费类型 按量付费
|
||||
// .setInstanceChargeType("PostPaid")
|
||||
// // 设置系统盘配置
|
||||
// .setSystemDisk(systemDisk)
|
||||
// // 设置用户名
|
||||
// .setHostName("root")
|
||||
// // 设置密码
|
||||
// .setPassword("10160810@a")
|
||||
// // 设置要创创建的实例数量
|
||||
// .setAmount(1);
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// // 创建运行时选项对象
|
||||
// RuntimeOptions runtime = new RuntimeOptions();
|
||||
//
|
||||
// // 尝试执行创建实例请求
|
||||
// try {
|
||||
// // 复制代码运行请自行打印 API 的返回值
|
||||
// client.runInstancesWithOptions(runInstancesRequest, runtime);
|
||||
// } catch (TeaException error) {
|
||||
// // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// // 错误 message
|
||||
// System.out.println(error.getMessage());
|
||||
// // 诊断地址
|
||||
// System.out.println(error.getData().get("Recommend"));
|
||||
// com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
// } catch (Exception _error) {
|
||||
// TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
// // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// // 错误 message
|
||||
// System.out.println(error.getMessage());
|
||||
// // 诊断地址
|
||||
// System.out.println(error.getData().get("Recommend"));
|
||||
// Common.assertAsString(error.message);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
|
@ -1,79 +0,0 @@
|
|||
package com.muyu.cargateway.test;
|
||||
|
||||
import com.aliyun.ecs20140526.Client;
|
||||
import com.aliyun.ecs20140526.models.DescribeInstanceAttributeRequest;
|
||||
import com.aliyun.ecs20140526.models.DescribeInstancesRequest;
|
||||
import com.aliyun.ecs20140526.models.DescribeInstancesResponse;
|
||||
import com.aliyun.ecs20140526.models.DescribeInstancesResponseBody;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import com.aliyun.teautil.Common;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.muyu.cargateway.instance.Sample;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @ Tool:IntelliJ IDEA
|
||||
* @ Author:CHX
|
||||
* @ Date:2024-09-29-20:16
|
||||
* @ Version:1.0
|
||||
* @ Description:查询实例所有信息
|
||||
* @author Lenovo
|
||||
*/
|
||||
@Log4j2
|
||||
public class SelectSample {
|
||||
public static Client createClient() throws Exception {
|
||||
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||||
// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
|
||||
Config config = new Config()
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||
.setAccessKeyId("LTAI5tDH3FyRx4PRr6anx2TL")
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||
.setAccessKeySecret("xdQnX2tDattY50raNkUWmHzE2tondP");
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/Ecs
|
||||
config.endpoint = "ecs.cn-shanghai.aliyuncs.com";
|
||||
return new Client(config);
|
||||
}
|
||||
|
||||
public static void main(String[] args_) throws Exception {
|
||||
List<String> args = Arrays.asList(args_);
|
||||
Client client = Sample.createClient();
|
||||
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
|
||||
.setRegionId("cn-shanghai");
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
try {
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
DescribeInstancesResponse instancesWithOptions = client.describeInstancesWithOptions(describeInstancesRequest, runtime);
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
DescribeInstancesResponseBody body = instancesWithOptions.getBody();
|
||||
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : body.instances.instance) {
|
||||
list.add(instance.getInstanceId());
|
||||
list.add(instance.getPublicIpAddress().ipAddress.get(0));
|
||||
list.add(instance.getStatus());
|
||||
|
||||
}
|
||||
log.info(Common.toJSONString(list));
|
||||
} catch (TeaException error) {
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
Common.assertAsString(error.message);
|
||||
} catch (Exception _error) {
|
||||
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
Common.assertAsString(error.message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -73,3 +73,13 @@ spring:
|
|||
logging:
|
||||
level:
|
||||
com.muyu.breakdown.mapper: DEBUG
|
||||
aliyun:
|
||||
access-key-id: LTAI5tDH3FyRx4PRr6anx2TL
|
||||
access-key-secret: xdQnX2tDattY50raNkUWmHzE2tondP
|
||||
endpoint: ecs-cn-hangzhou.aliyuncs.com
|
||||
region-id: cn-shanghai
|
||||
image-id: m-uf6ih0vnl5f51pquns11
|
||||
instance-type: ecs.t6-c1m1.large
|
||||
security-group-id: sg-uf642d5u4ja5gsiitx8y
|
||||
switch-id: vsw-uf66lifrkhxqc94xi06v3
|
||||
amount: 1
|
||||
|
|
|
@ -13,6 +13,9 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
|||
public class CloudFileApplication {
|
||||
public static void main (String[] args) {
|
||||
SpringApplication.run(CloudFileApplication.class, args);
|
||||
|
||||
System.out.println("CloudFile 模块启动成功!");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@ import com.muyu.file.service.ISysFileService;
|
|||
import com.muyu.common.system.domain.SysFile;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
@ -21,7 +25,11 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
public class SysFileController {
|
||||
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
||||
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private ISysFileService sysFileService;
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,10 +5,11 @@ import com.muyu.file.config.MinioConfig;
|
|||
import com.muyu.file.utils.FileUploadUtils;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.PutObjectArgs;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
|
@ -18,10 +19,13 @@ import java.io.InputStream;
|
|||
*/
|
||||
@Service
|
||||
public class MinioSysFileServiceImpl implements ISysFileService {
|
||||
|
||||
@Resource
|
||||
private MinioConfig minioConfig;
|
||||
|
||||
@Resource
|
||||
|
||||
@Autowired
|
||||
|
||||
private MinioClient client;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
# Tomcat
|
||||
server:
|
||||
|
||||
port: 9301
|
||||
|
||||
port: 9300
|
||||
|
||||
|
||||
# nacos线上地址
|
||||
nacos:
|
||||
addr: 47.116.173.119:8848
|
||||
addr: 106.54.193.225:8848
|
||||
user-name: nacos
|
||||
password: nacos
|
||||
|
||||
namespace: one-saas
|
||||
|
||||
namespace: one
|
||||
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
|
|
|
@ -4,11 +4,15 @@ server:
|
|||
|
||||
# nacos线上地址
|
||||
nacos:
|
||||
addr: 47.116.173.119:8848
|
||||
addr: 106.54.193.225:8848
|
||||
user-name: nacos
|
||||
password: nacos
|
||||
|
||||
namespace: one-saas
|
||||
|
||||
namespace: one
|
||||
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
|
|
|
@ -639,8 +639,13 @@ CREATE TABLE `sys_user` (
|
|||
-- Records of sys_user
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
|
||||
INSERT INTO `sys_user` (`user_id`, `dept_id`, `user_name`, `nick_name`, `user_type`, `email`, `phonenumber`, `sex`, `avatar`, `password`, `status`, `del_flag`, `login_ip`, `login_date`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '106.54.193.225', '2024-05-23 15:08:18', 'admin', '2024-05-23 15:08:18', '', NULL, '管理员');
|
||||
INSERT INTO `sys_user` (`user_id`, `dept_id`, `user_name`, `nick_name`, `user_type`, `email`, `phonenumber`, `sex`, `avatar`, `password`, `status`, `del_flag`, `login_ip`, `login_date`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '106.54.193.225', '2024-05-23 15:08:18', 'admin', '2024-05-23 15:08:18', '', NULL, '测试员');
|
||||
|
||||
INSERT INTO `sys_user` (`user_id`, `dept_id`, `user_name`, `nick_name`, `user_type`, `email`, `phonenumber`, `sex`, `avatar`, `password`, `status`, `del_flag`, `login_ip`, `login_date`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2024-05-23 15:08:18', 'admin', '2024-05-23 15:08:18', '', NULL, '管理员');
|
||||
INSERT INTO `sys_user` (`user_id`, `dept_id`, `user_name`, `nick_name`, `user_type`, `email`, `phonenumber`, `sex`, `avatar`, `password`, `status`, `del_flag`, `login_ip`, `login_date`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2024-05-23 15:08:18', 'admin', '2024-05-23 15:08:18', '', NULL, '测试员');
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
|
@ -200,7 +200,7 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
=======================================================================
|
||||
=
|
||||
Apache SkyWalking Subcomponents:
|
||||
|
||||
The Apache SkyWalking project contains subcomponents with separate copyright
|
||||
|
@ -208,9 +208,9 @@ notices and license terms. Your use of the source code for the these
|
|||
subcomponents is subject to the terms and conditions of the following
|
||||
licenses.
|
||||
|
||||
========================================================================
|
||||
==
|
||||
Apache 2.0 licenses
|
||||
========================================================================
|
||||
==
|
||||
|
||||
The following components are provided under the Apache License. See project link for details.
|
||||
The text of each license is the standard Apache 2.0 license.
|
||||
|
@ -223,9 +223,9 @@ The text of each license is the standard Apache 2.0 license.
|
|||
Google: guava 32.0.1: https://github.com/google/guava , Apache 2.0
|
||||
netty 4.1.100: https://github.com/netty/netty/blob/4.1/LICENSE.txt, Apache 2.0
|
||||
|
||||
========================================================================
|
||||
==
|
||||
BSD licenses
|
||||
========================================================================
|
||||
==
|
||||
|
||||
The following components are provided under a BSD license. See project link for details.
|
||||
The text of each license is also included at licenses/LICENSE-[project].txt.
|
||||
|
|
|
@ -4,11 +4,11 @@ Copyright 2017-2024 The Apache Software Foundation
|
|||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
========================================================================
|
||||
==
|
||||
|
||||
grpc-java NOTICE
|
||||
|
||||
========================================================================
|
||||
==
|
||||
Copyright 2014, gRPC Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -46,11 +46,11 @@ networking library, which can be obtained at:
|
|||
* LOCATION_IN_GRPC:
|
||||
* netty/third_party/netty
|
||||
|
||||
========================================================================
|
||||
==
|
||||
|
||||
grpc NOTICE
|
||||
|
||||
========================================================================
|
||||
==
|
||||
|
||||
Copyright 2014 gRPC authors.
|
||||
|
||||
|
@ -67,15 +67,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
|
||||
|
||||
========================================================================
|
||||
==
|
||||
|
||||
netty NOTICE
|
||||
|
||||
========================================================================
|
||||
==
|
||||
|
||||
|
||||
The Netty Project
|
||||
=================
|
||||
===
|
||||
|
||||
Please visit the Netty web site for more information:
|
||||
|
||||
|
|
Loading…
Reference in New Issue