├── .gitignore ├── LICENSE ├── example ├── feego-common-example-api-starter │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── lvyahui8 │ │ │ └── example │ │ │ └── .gitignore │ │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── example │ │ └── .gitignore ├── feego-common-example-api │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── lvyahui8 │ │ │ └── example │ │ │ └── api │ │ │ ├── .gitignore │ │ │ ├── dto │ │ │ └── UserDTO.java │ │ │ └── facade │ │ │ └── UserQueryFacade.java │ │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── example │ │ └── .gitignore ├── feego-common-example-client │ ├── pom.xml │ ├── signature_test.http │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── lvyahui8 │ │ │ │ └── example │ │ │ │ └── client │ │ │ │ ├── ClientApplication.java │ │ │ │ └── service │ │ │ │ ├── OrderService.java │ │ │ │ └── impl │ │ │ │ └── OrderServiceImpl.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── dubbo-consumer.properties │ │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── example │ │ └── .gitignore ├── feego-common-example-service │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── lvyahui8 │ │ │ └── example │ │ │ ├── code │ │ │ └── Code.java │ │ │ ├── configuration │ │ │ ├── BeanConfiguration.java │ │ │ ├── CacheKey.java │ │ │ ├── CustomLogHandler.java │ │ │ ├── CustomLogger.java │ │ │ ├── LoggingConfiguration.java │ │ │ └── RuntimeSettings.java │ │ │ ├── facade │ │ │ └── impl │ │ │ │ └── UserQueryFacadeImpl.java │ │ │ ├── package-info.java │ │ │ ├── reddot │ │ │ └── AppRedDot.java │ │ │ ├── service │ │ │ ├── UserCacheObject.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ └── UserServiceImpl.java │ │ │ └── task │ │ │ └── UserProfileReloadTask.java │ │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── AppTest.java ├── feego-common-example-start │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── lvyahui8 │ │ │ │ └── example │ │ │ │ ├── ServerApplication.java │ │ │ │ ├── configuration │ │ │ │ ├── .gitignore │ │ │ │ ├── CustomWebMvcConfigurer.java │ │ │ │ └── HttpRequestLogContextFilter.java │ │ │ │ └── resources │ │ │ │ └── MainController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── dubbo-provider.properties │ │ │ └── strings │ │ │ ├── homepage.json │ │ │ └── member │ │ │ └── account.json │ │ └── test │ │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── lvyahui8 │ │ │ └── example │ │ │ ├── BasicTest.java │ │ │ ├── DistributedLockTest.java │ │ │ ├── MsgCodeTest.java │ │ │ ├── NamedLockExecutorTest.java │ │ │ ├── RedDotTest.java │ │ │ ├── ResourceStringsTest.java │ │ │ └── SystemLoggerTest.java │ │ └── resources │ │ └── .gitignore └── keys │ ├── sign_request_pri.key │ ├── sign_response_pri.key │ ├── verify_request_pub.key │ └── verify_response_pub.key ├── feego-common-configuration-processor ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── lvyahui8 │ │ │ └── configuration │ │ │ ├── annotations │ │ │ ├── ModuleLoggerAutoGeneration.java │ │ │ ├── ResourceStrings.java │ │ │ ├── RuntimeConfiguration.java │ │ │ └── Singleton.java │ │ │ ├── processor │ │ │ ├── ModuleLoggerProcessor.java │ │ │ ├── ResourceStringsProcessor.java │ │ │ ├── RuntimeConfigurationProcessor.java │ │ │ └── SingletonProcessor.java │ │ │ └── utils │ │ │ └── BuildUtils.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── javax.annotation.processing.Processor │ └── test │ └── java │ └── io │ └── github │ └── lvyahui8 │ └── configuration │ └── .gitignore ├── feego-common-logging ├── feego-common-logging-autoconfigure │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── lvyahui8 │ │ │ │ └── sdk │ │ │ │ └── logging │ │ │ │ └── autoconfigure │ │ │ │ ├── ModuleLoggerAutoConfiguration.java │ │ │ │ └── ModuleLoggerProperties.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── spring.factories │ │ └── test │ │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── lvyahui8 │ │ │ └── sdk │ │ │ └── logging │ │ │ ├── .gitignore │ │ │ ├── BaseTest.java │ │ │ ├── LoggingTestCase.java │ │ │ ├── TestApplication.java │ │ │ └── TestLogger.java │ │ └── resources │ │ └── application.properties ├── feego-common-logging-starter │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── lvyahui8 │ │ │ │ └── sdk │ │ │ │ └── logging │ │ │ │ └── .gitignore │ │ └── resources │ │ │ └── META-INF │ │ │ └── spring.provides │ │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── sdk │ │ └── logging │ │ └── .gitignore └── feego-common-logging │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── sdk │ │ └── logging │ │ ├── configuration │ │ ├── DefaultLogConfiguration.java │ │ └── LogConstants.java │ │ ├── context │ │ ├── LogContext.java │ │ └── LogContextHolder.java │ │ ├── event │ │ └── LogEvent.java │ │ ├── factory │ │ ├── AbstractLoggerFactory.java │ │ ├── Log4j2ModuleLoggerFactory.java │ │ ├── LogbackModuleLoggerFactory.java │ │ └── ModuleLoggerFactory.java │ │ ├── handler │ │ ├── AbstractLogHandler.java │ │ ├── DefaultLogHandler.java │ │ └── LogHandler.java │ │ └── logger │ │ ├── DefaultModuleLogger.java │ │ ├── EnumModuleLogger.java │ │ ├── LogEventReactor.java │ │ ├── LogSchema.java │ │ ├── ModuleLogger.java │ │ ├── ModuleLoggerRepository.java │ │ └── RootLogger.java │ └── test │ └── java │ └── io │ └── github │ └── lvyahui8 │ └── sdk │ └── logging │ ├── .gitignore │ ├── RepeatModuleTestApplication.java │ ├── TestApplication.java │ ├── TestLogger.java │ └── TestLogger2.java ├── feego-common-service ├── feego-common-service-starter │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── lvyahui8 │ │ │ │ └── sdk │ │ │ │ ├── .gitignore │ │ │ │ ├── autoconfigure │ │ │ │ ├── CoreAutoConfiguration.java │ │ │ │ ├── DistributeLockAutoConfiguration.java │ │ │ │ └── GroupServiceAutoConfiguration.java │ │ │ │ └── properties │ │ │ │ ├── ExecutorProperties.java │ │ │ │ └── ServiceProperties.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── spring.factories │ │ │ └── logback-spring.xml.backup │ │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── sdk │ │ └── .gitignore └── feego-common-service │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── lvyahui8 │ │ │ └── sdk │ │ │ ├── .gitignore │ │ │ ├── cache │ │ │ └── AsyncRefreshableCacheObject.java │ │ │ ├── constants │ │ │ └── Constant.java │ │ │ ├── guid │ │ │ └── GUIDGenerator.java │ │ │ ├── lock │ │ │ ├── DistributedLock.java │ │ │ ├── LockFactory.java │ │ │ ├── NamedLockExecutor.java │ │ │ ├── RedisDistributedLock.java │ │ │ └── RedisLockFactory.java │ │ │ ├── proxy │ │ │ ├── DecisionMaker.java │ │ │ ├── GroupService.java │ │ │ └── GroupServiceProxy.java │ │ │ ├── reddot │ │ │ ├── DefaultRedDotManager.java │ │ │ ├── RedDot.java │ │ │ ├── RedDotInstance.java │ │ │ └── RedDotManager.java │ │ │ ├── security │ │ │ └── CryptologySecurityUtils.java │ │ │ ├── utils │ │ │ ├── AsyncTaskExecutor.java │ │ │ ├── AsyncTaskExecutorInitializer.java │ │ │ ├── RetryUtils.java │ │ │ └── SystemUtils.java │ │ │ └── weak │ │ │ ├── OnException.java │ │ │ └── WeakDependencyGroup.java │ └── resources │ │ └── .gitignore │ └── test │ └── java │ └── io │ └── github │ └── lvyahui8 │ ├── .gitignore │ ├── sdk │ └── guid │ │ └── GUIDGeneratorTest.java │ └── security │ └── CryptologySecurityUtilsTest.java ├── feego-common-web ├── feego-common-web-starter │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── github │ │ │ │ └── lvyahui8 │ │ │ │ └── web │ │ │ │ ├── .gitignore │ │ │ │ ├── autoconfigure │ │ │ │ ├── WebAutoConfiguration.java │ │ │ │ └── WebMvcBeanPostProcessor.java │ │ │ │ └── properties │ │ │ │ ├── SecurityProperties.java │ │ │ │ └── WebProperties.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── spring.factories │ │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── web │ │ └── .gitignore └── feego-common-web │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── io │ │ └── github │ │ └── lvyahui8 │ │ └── web │ │ ├── .gitignore │ │ ├── code │ │ ├── C.java │ │ ├── Code.java │ │ ├── CodePrefix.java │ │ ├── CodeRepository.java │ │ └── MsgCode.java │ │ ├── constant │ │ └── WebConstant.java │ │ ├── context │ │ ├── RequestContext.java │ │ └── RequestMessage.java │ │ ├── request │ │ └── SignedRequest.java │ │ ├── response │ │ ├── RestResponseFormatter.java │ │ └── StandardResponse.java │ │ ├── signature │ │ ├── .gitignore │ │ ├── SignatureService.java │ │ ├── SignatureSettings.java │ │ └── impl │ │ │ └── SignatureServiceImpl.java │ │ └── wrapper │ │ ├── .gitignore │ │ ├── ResettableHttpServletRequest.java │ │ ├── SignatureFilter.java │ │ ├── TeeHttpServletResponse.java │ │ └── TraceFilter.java │ └── test │ └── java │ └── io │ └── github │ └── lvyahui8 │ └── .gitignore ├── feego-common.jmx ├── pom.xml ├── readme.assets ├── guid.assets │ ├── image-20201003000028945.png │ └── image-20201004223800706.png ├── guid.md ├── image-20201013232937970.png ├── image-20201013233502251.png ├── lock.assets │ └── image-20200321185855112.png ├── lock.md ├── logging.assets │ ├── image-20200307233100343.png │ └── image-20200307233522279.png ├── logging.md └── signature.md ├── readme.md ├── release.bat └── release.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | *.log 4 | target 5 | *.class 6 | *.zip 7 | *.tar.gz 8 | *.tgz 9 | *.versionsBackup -------------------------------------------------------------------------------- /example/feego-common-example-api-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-example-api-starter 14 | 15 | feego-common-example-api-starter 16 | 17 | 18 | true 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | test 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/feego-common-example-api-starter/src/main/java/io/github/lvyahui8/example/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-api-starter/src/main/java/io/github/lvyahui8/example/.gitignore -------------------------------------------------------------------------------- /example/feego-common-example-api-starter/src/test/java/io/github/lvyahui8/example/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-api-starter/src/test/java/io/github/lvyahui8/example/.gitignore -------------------------------------------------------------------------------- /example/feego-common-example-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-example-api 14 | 15 | feego-common-example-api 16 | 17 | 18 | true 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | test 26 | 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/feego-common-example-api/src/main/java/io/github/lvyahui8/example/api/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-api/src/main/java/io/github/lvyahui8/example/api/.gitignore -------------------------------------------------------------------------------- /example/feego-common-example-api/src/main/java/io/github/lvyahui8/example/api/dto/UserDTO.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.api.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 9 | * @since 2020/3/21 11:18 10 | */ 11 | @Data 12 | public class UserDTO implements Serializable { 13 | private static final long serialVersionUID = 2386235266784577053L; 14 | Long id; 15 | String username; 16 | String email; 17 | } 18 | -------------------------------------------------------------------------------- /example/feego-common-example-api/src/main/java/io/github/lvyahui8/example/api/facade/UserQueryFacade.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.api.facade; 2 | 3 | import io.github.lvyahui8.example.api.dto.UserDTO; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/3/21 11:17 8 | */ 9 | public interface UserQueryFacade { 10 | /** 11 | * 根据用户id查询用户信息 12 | * @param userId 用户id 13 | * @return 用户信息 14 | */ 15 | UserDTO getUserById(Long userId); 16 | } 17 | -------------------------------------------------------------------------------- /example/feego-common-example-api/src/test/java/io/github/lvyahui8/example/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-api/src/test/java/io/github/lvyahui8/example/.gitignore -------------------------------------------------------------------------------- /example/feego-common-example-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-example-client 14 | 15 | feego-common-example-client 16 | 17 | 18 | true 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | test 26 | 27 | 28 | 29 | io.github.lvyahui8 30 | feego-common-service-starter 31 | 32 | 33 | org.springframework.data 34 | spring-data-redis 35 | 36 | 37 | 38 | 39 | 40 | org.apache.dubbo 41 | dubbo 42 | 43 | 44 | 45 | org.apache.dubbo 46 | dubbo-dependencies-zookeeper 47 | pom 48 | 49 | 50 | org.slf4j 51 | slf4j-log4j12 52 | 53 | 54 | 55 | 56 | 57 | io.github.lvyahui8 58 | feego-common-example-api 59 | 60 | 61 | 62 | org.apache.httpcomponents 63 | httpclient 64 | 65 | 66 | 67 | io.github.lvyahui8 68 | feego-common-configuration-processor 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /example/feego-common-example-client/signature_test.http: -------------------------------------------------------------------------------- 1 | POST /save HTTP/1.1 2 | Host: 127.0.0.1:8080 3 | X-Feego-Signature: signature= 4 | Content-Type: application/json 5 | 6 | { 7 | "username" : "feego" 8 | } 9 | 10 | ### -------------------------------------------------------------------------------- /example/feego-common-example-client/src/main/java/io/github/lvyahui8/example/client/ClientApplication.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.client; 2 | 3 | import io.github.lvyahui8.configuration.annotations.ModuleLoggerAutoGeneration; 4 | import io.github.lvyahui8.sdk.security.CryptologySecurityUtils; 5 | import io.github.lvyahui8.example.client.service.OrderService; 6 | import io.netty.handler.codec.http.HttpHeaderNames; 7 | import io.netty.handler.codec.http.HttpHeaderValues; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.apache.commons.codec.binary.Base64; 10 | import org.apache.commons.io.IOUtils; 11 | import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; 12 | import org.apache.http.HttpResponse; 13 | import org.apache.http.client.HttpClient; 14 | import org.apache.http.client.methods.HttpPost; 15 | import org.apache.http.entity.StringEntity; 16 | import org.apache.http.impl.client.HttpClientBuilder; 17 | import org.springframework.boot.SpringApplication; 18 | import org.springframework.boot.autoconfigure.SpringBootApplication; 19 | import org.springframework.context.ConfigurableApplicationContext; 20 | import org.springframework.context.annotation.PropertySource; 21 | 22 | import java.nio.charset.StandardCharsets; 23 | 24 | /** 25 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 26 | * @since 2020/3/21 11:15 27 | */ 28 | @SpringBootApplication 29 | @EnableDubbo(scanBasePackages = "io.github.lvyahui8.example.client") 30 | @PropertySource("classpath:dubbo-consumer.properties") 31 | @ModuleLoggerAutoGeneration({"order"}) 32 | @Slf4j 33 | public class ClientApplication { 34 | public static void main(String[] args) throws Exception { 35 | ConfigurableApplicationContext context = SpringApplication.run(ClientApplication.class, args); 36 | OrderService orderService = context.getBean(OrderService.class); 37 | orderService.createOrder(1L); 38 | 39 | String httpBody = "{\n" + 40 | " \"username\" : \"feego\"\n" + 41 | "}"; 42 | String key = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANMQDJAjncKfZ+Hw\nlNB2sW01AiSzuD77bnf3YF3Iy/J3+8a5mmm1u4fEDwlc9Vkm6doY1ExWoVt8e/eG\nxH7UgViGm2MC0RVcmwSQEf/YGl2iv+YXFgWhN/4LLrSbekFV2m9zPUAdifRMMo0v\nffDlG4xtdTngVhliA4i4zs/+I2ZBAgMBAAECgYEAuR5FdpLWhuIbUi8ZxvGj0t4A\nYEKFIjCTBoOhMQCx6JvV58nYpkjwDzcl3Rd8VdJsn47RfZcp9Tzs2gCJDZjDTFJj\nwWsIWIRE77YX1K3TezBDdFh1rc2zUIy0u3jvbkPJguZeKFYtff2ACrVTnGybfpbS\ns04e4WnjPJmgivmnazECQQD2moEgZjlaILQuURE59baY5TYqltZRRFvt+PrerJ5H\nzWUNbD//bcsTSbDEw1+s7g654InPZvvjkbHL3AWBsj79AkEA2xrcgDzkEWrxzdmg\n6qEeU3l/PcxKI66S7DEY74fdf8V1ZIQEHG1iyAAqfyADdXyofHqhABE4Bnub0mUn\nSAjBlQJAbnMrDIDchSKKsQf8KDKGUxquVQrz+LgeWIqgiiVUSyKSdR2b2GKrhvsF\nYkuDSafiDpyj/LHKddWmhYEJMlrMXQJBAMJ+1b4AT3Qmuv9AcNfWrlTrRUhWUHnc\nPg/shXYb5UPGxK61gfC6KTXg79hpUqi4P9hAAytMHa+jim753CTVoQECQQDD3myY\nEOdz7JGlfcXaavtPRQlfo5FRQI8iR82rpUZ6H0ZoXpw+n1F+4X720g2ah76eMB7B\nJbeETpR4PBckfjo1"; 43 | Base64 base64 = new Base64(); 44 | byte[] decodeKey = base64.decode(key); 45 | HttpClient httpClient = HttpClientBuilder.create().build(); 46 | HttpPost httpPost = new HttpPost("http://127.0.0.1:8080/save"); 47 | String headerKey = "X-Feego-Signature"; 48 | httpPost.setHeader(HttpHeaderNames.CONTENT_TYPE.toString(), HttpHeaderValues.APPLICATION_JSON.toString()); 49 | httpPost.setHeader(headerKey, "signature=" + base64.encodeAsString(CryptologySecurityUtils.sign(('.' + httpBody).getBytes(),decodeKey,"SHA1withRSA"))); 50 | httpPost.setEntity(new StringEntity(httpBody)); 51 | for (int i = 0; i < 100; i++) { 52 | HttpResponse response = httpClient.execute(httpPost); 53 | log.info("status:{}",response.getStatusLine()); 54 | log.info("sign header:{}",response.getFirstHeader(headerKey).getValue()); 55 | log.info(IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8)); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /example/feego-common-example-client/src/main/java/io/github/lvyahui8/example/client/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.client.service; 2 | 3 | /** 4 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 5 | * @since 2020/3/21 12:31 6 | */ 7 | public interface OrderService { 8 | /** 9 | * 创建订单 10 | * @param buyerId 买家id 11 | */ 12 | void createOrder(Long buyerId); 13 | } 14 | -------------------------------------------------------------------------------- /example/feego-common-example-client/src/main/java/io/github/lvyahui8/example/client/service/impl/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.client.service.impl; 2 | 3 | import feego.common.io.github.lvyahui8.example.client.SystemLogger; 4 | import io.github.lvyahui8.example.api.dto.UserDTO; 5 | import io.github.lvyahui8.example.api.facade.UserQueryFacade; 6 | import io.github.lvyahui8.example.client.service.OrderService; 7 | import org.apache.dubbo.config.annotation.Reference; 8 | import org.springframework.stereotype.Service; 9 | 10 | /** 11 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 12 | * @since 2020/3/21 12:32 13 | */ 14 | @Service 15 | public class OrderServiceImpl implements OrderService { 16 | 17 | @Reference 18 | private UserQueryFacade userQueryFacade; 19 | 20 | @Override 21 | public void createOrder(Long buyerId) { 22 | UserDTO user = userQueryFacade.getUserById(buyerId); 23 | SystemLogger.order.info("create order for user: {}",user); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example/feego-common-example-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.main.allow-bean-definition-overriding=true -------------------------------------------------------------------------------- /example/feego-common-example-client/src/main/resources/dubbo-consumer.properties: -------------------------------------------------------------------------------- 1 | dubbo.application.name=annotation-consumer 2 | dubbo.registry.address=zookeeper://127.0.0.1:2181?timeout=60000 3 | dubbo.consumer.timeout=3000 -------------------------------------------------------------------------------- /example/feego-common-example-client/src/test/java/io/github/lvyahui8/example/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-client/src/test/java/io/github/lvyahui8/example/.gitignore -------------------------------------------------------------------------------- /example/feego-common-example-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-example-service 14 | 15 | feego-common-example-service 16 | 17 | 18 | true 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | test 26 | 27 | 28 | 29 | io.github.lvyahui8 30 | feego-common-web-starter 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-data-redis 41 | 42 | 43 | 44 | io.github.lvyahui8 45 | feego-common-example-api 46 | 47 | 48 | 49 | org.apache.dubbo 50 | dubbo 51 | 52 | 53 | 54 | org.apache.dubbo 55 | dubbo-dependencies-zookeeper 56 | pom 57 | 58 | 59 | org.slf4j 60 | slf4j-log4j12 61 | 62 | 63 | 64 | 65 | 66 | io.github.lvyahui8 67 | feego-common-configuration-processor 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/code/Code.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.code; 2 | 3 | import io.github.lvyahui8.web.code.C; 4 | import io.github.lvyahui8.web.code.CodePrefix; 5 | import io.github.lvyahui8.web.code.MsgCode; 6 | 7 | /** 8 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 9 | * @since 2020/3/18 21:42 10 | */ 11 | public interface Code { 12 | enum General implements MsgCode { 13 | /** 14 | * 成功 15 | */ 16 | @C(0) success, 17 | @C(value = -1,msg = "unknown exception") unknown, 18 | ; 19 | } 20 | 21 | @CodePrefix("4") 22 | enum Client implements MsgCode { 23 | /** 24 | * 客户端相关错误 25 | */ 26 | no_permit, 27 | @C(301) no_login_session, 28 | ; 29 | } 30 | 31 | @CodePrefix("5") 32 | enum Component implements MsgCode { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/configuration/BeanConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | import io.github.lvyahui8.configuration.annotations.ModuleLoggerAutoGeneration; 4 | import io.github.lvyahui8.example.service.UserService; 5 | import io.github.lvyahui8.example.service.impl.UserServiceImpl; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 11 | * @since 2020/2/22 10:44 12 | */ 13 | @Configuration 14 | @ModuleLoggerAutoGeneration({"member","rebate","item"}) 15 | public class BeanConfiguration { 16 | @Bean 17 | public UserService userService() { 18 | return new UserServiceImpl(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/configuration/CacheKey.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | /** 4 | * @author feego lvyahui8@gmail.com 5 | * @date 2021/1/20 6 | */ 7 | public enum CacheKey { 8 | user_profile("up"), 9 | ; 10 | 11 | String key; 12 | 13 | CacheKey(String key) { 14 | this.key = key; 15 | } 16 | 17 | public String getKey() { 18 | return key; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/configuration/CustomLogHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | import io.github.lvyahui8.sdk.logging.handler.AbstractLogHandler; 4 | import io.github.lvyahui8.sdk.logging.handler.DefaultLogHandler; 5 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 6 | import io.github.lvyahui8.web.context.RequestContext; 7 | import org.slf4j.event.Level; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author feego lvyahui8@gmail.com 14 | * @date 2020/10/10 15 | */ 16 | public class CustomLogHandler extends DefaultLogHandler { 17 | 18 | /** 19 | * 可以结合一些运行时配置系统,使得level运行时可以动态调整 20 | */ 21 | public static final Map levelMap = new HashMap<>(); 22 | static { 23 | levelMap.put(CustomLogger.uc,Level.ERROR); 24 | } 25 | 26 | @Override 27 | public Level innerRuntimeLevel(String enumLoggerName) { 28 | CustomLogger customLogger = null; 29 | try { 30 | customLogger = CustomLogger.valueOf(enumLoggerName); 31 | } catch (Exception ignored) {} 32 | if (customLogger != null) { 33 | return levelMap.containsKey(customLogger) ? 34 | levelMap.get(customLogger) : super.runtimeLevel(enumLoggerName); 35 | } 36 | return super.innerRuntimeLevel(enumLoggerName); 37 | } 38 | 39 | @Override 40 | public LogSchema innerBeforeOutput(LogSchema logSchema) { 41 | logSchema.prepend("tid",Thread.currentThread().getId()) 42 | .prepend("rid", RequestContext.getTraceId()); 43 | return super.innerBeforeOutput(logSchema); 44 | } 45 | 46 | @Override 47 | public LogSchema monitor(LogSchema logSchema) { 48 | logSchema.of("user_id","lyh"); 49 | return super.monitor(logSchema); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/configuration/CustomLogger.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.EnumModuleLogger; 4 | import io.github.lvyahui8.sdk.logging.logger.ModuleLogger; 5 | 6 | /** 7 | * @author feego lvyahui8@gmail.com 8 | * @date 2020/9/23 9 | */ 10 | public enum CustomLogger implements EnumModuleLogger { 11 | uc, 12 | ; 13 | } 14 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/configuration/LoggingConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | import io.github.lvyahui8.configuration.annotations.ModuleLoggerAutoGeneration; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | /** 7 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 8 | * @since 2020/2/22 10:58 9 | */ 10 | @Configuration 11 | @ModuleLoggerAutoGeneration({"promotion"}) 12 | public class LoggingConfiguration { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/configuration/RuntimeSettings.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | import io.github.lvyahui8.configuration.annotations.RuntimeConfiguration; 4 | import io.github.lvyahui8.example.api.dto.UserDTO; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yahui.lv lvyahui8@gmail.com 9 | * @date 2020/4/8 21:05 10 | */ 11 | @RuntimeConfiguration 12 | @Data 13 | public class RuntimeSettings { 14 | String homepageUrl = "https://www.cnblogs.com/lvyahui"; 15 | Boolean entrySwitch = false; 16 | boolean open; 17 | UserDTO commonUserDTO = new UserDTO(); 18 | } 19 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/facade/impl/UserQueryFacadeImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.facade.impl; 2 | 3 | import io.github.lvyahui8.example.api.dto.UserDTO; 4 | import io.github.lvyahui8.example.api.facade.UserQueryFacade; 5 | import io.github.lvyahui8.example.service.UserCacheObject; 6 | import org.apache.dubbo.config.annotation.Service; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | /** 10 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 11 | * @since 2020/3/21 11:21 12 | */ 13 | @Service 14 | public class UserQueryFacadeImpl implements UserQueryFacade { 15 | 16 | UserCacheObject userCacheObject; 17 | 18 | public void setUserCacheObject(UserCacheObject userCacheObject) { 19 | this.userCacheObject = userCacheObject; 20 | } 21 | 22 | @Override 23 | public UserDTO getUserById(Long userId) { 24 | return userCacheObject.get(userId); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/package-info.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/package-info.java -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/reddot/AppRedDot.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.reddot; 2 | 3 | import io.github.lvyahui8.sdk.reddot.RedDot; 4 | 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2021/1/22 11 | */ 12 | @SuppressWarnings({"unused"}) 13 | public enum AppRedDot implements RedDot { 14 | root(null), 15 | hp(root), 16 | channels(hp), 17 | my_account(root), 18 | profile(my_account), 19 | asset(profile), 20 | ; 21 | 22 | AppRedDot parent; 23 | 24 | List children = new LinkedList<>(); 25 | 26 | AppRedDot(AppRedDot parent) { 27 | this.parent = parent; 28 | if (parent != null) { 29 | parent.children.add(this); 30 | } 31 | } 32 | 33 | @Override 34 | public String id() { 35 | return name(); 36 | } 37 | 38 | @Override 39 | public RedDot parent() { 40 | return parent; 41 | } 42 | 43 | @Override 44 | public boolean isLeaf() { 45 | return children.isEmpty(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/service/UserCacheObject.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.service; 2 | 3 | import io.github.lvyahui8.example.api.dto.UserDTO; 4 | import io.github.lvyahui8.example.configuration.CacheKey; 5 | import io.github.lvyahui8.sdk.cache.AsyncRefreshableCacheObject; 6 | import org.springframework.data.redis.core.StringRedisTemplate; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author feego lvyahui8@gmail.com 11 | * @date 2021/1/20 12 | */ 13 | @Component 14 | public class UserCacheObject extends AsyncRefreshableCacheObject { 15 | 16 | final UserService userService; 17 | 18 | public UserCacheObject(StringRedisTemplate redisTemplate, UserService userService) { 19 | super(redisTemplate); 20 | this.userService = userService; 21 | } 22 | 23 | @Override 24 | protected UserDTO syncLoad(Long userId) { 25 | return userService.getUser(userId); 26 | } 27 | 28 | @Override 29 | protected boolean preventBreakdown() { 30 | return true; 31 | } 32 | 33 | @Override 34 | protected String getRedisKey(Long userId) { 35 | return CacheKey.user_profile.getKey() + userId; 36 | } 37 | 38 | @Override 39 | protected int getLogicTimeoutSecond() { 40 | return 1; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/service/UserService.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.service; 2 | 3 | 4 | import io.github.lvyahui8.example.api.dto.UserDTO; 5 | 6 | /** 7 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 8 | * @since 2020/2/22 10:43 9 | */ 10 | public interface UserService { 11 | UserDTO getUser(Long id) ; 12 | } 13 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.service.impl; 2 | 3 | import io.github.lvyahui8.example.api.dto.UserDTO; 4 | import io.github.lvyahui8.example.service.UserService; 5 | 6 | /** 7 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 8 | * @since 2020/2/22 10:43 9 | */ 10 | public class UserServiceImpl implements UserService { 11 | @Override 12 | public UserDTO getUser(Long id) { 13 | UserDTO userDTO = new UserDTO(); 14 | userDTO.setEmail("lvyahui8@gmai.com"); 15 | userDTO.setUsername("feego" + System.currentTimeMillis()); 16 | userDTO.setId(id); 17 | try { 18 | Thread.sleep(1000L); 19 | } catch (InterruptedException ignored) { } 20 | return userDTO; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/main/java/io/github/lvyahui8/example/task/UserProfileReloadTask.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.task; 2 | 3 | import io.github.lvyahui8.example.api.dto.UserDTO; 4 | import io.github.lvyahui8.example.service.UserCacheObject; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.scheduling.annotation.Scheduled; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * @author feego lvyahui8@gmail.com 12 | * @date 2021/1/21 13 | */ 14 | @Component 15 | @RequiredArgsConstructor(onConstructor = @__({@Autowired})) 16 | public class UserProfileReloadTask { 17 | 18 | final UserCacheObject userCacheObject; 19 | 20 | boolean loaded = false; 21 | 22 | @Scheduled(cron = "*/5 * * * * ?") 23 | public void reload() { 24 | if (! loaded) { 25 | for (long i = 0; i < 10; i++) { 26 | userCacheObject.load(i); 27 | } 28 | loaded = true; 29 | } 30 | 31 | for (long i = 0; i < 10; i++) { 32 | long begin = System.currentTimeMillis(); 33 | UserDTO userDTO = userCacheObject.get(i); 34 | System.out.println(userDTO + ". cost:" + (System.currentTimeMillis() - begin) ); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /example/feego-common-example-service/src/test/java/io/github/lvyahui8/AppTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | { 12 | /** 13 | * Rigorous Test :-) 14 | */ 15 | @Test 16 | public void shouldAnswerWithTrue() 17 | { 18 | assertTrue( true ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/feego-common-example-start/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-example-start 14 | 15 | feego-common-example-start 16 | 17 | 18 | true 19 | true 20 | 21 | 22 | 23 | 24 | junit 25 | junit 26 | test 27 | 28 | 29 | io.github.lvyahui8 30 | feego-common-example-service 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/java/io/github/lvyahui8/example/ServerApplication.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example; 2 | 3 | import io.github.lvyahui8.configuration.annotations.ModuleLoggerAutoGeneration; 4 | import io.github.lvyahui8.configuration.annotations.ResourceStrings; 5 | import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.context.annotation.PropertySource; 9 | import org.springframework.scheduling.annotation.EnableScheduling; 10 | 11 | /** 12 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 13 | * @since 2020/2/16 22:08 14 | */ 15 | @SpringBootApplication 16 | @ModuleLoggerAutoGeneration({"campaign","status"}) 17 | @EnableScheduling 18 | @EnableDubbo(scanBasePackages = "io.github.lvyahui8.example") 19 | @PropertySource("classpath:dubbo-provider.properties") 20 | @ResourceStrings("strings/") 21 | public class ServerApplication { 22 | public static void main(String[] args) throws Exception { 23 | SpringApplication.run(ServerApplication.class,args); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/java/io/github/lvyahui8/example/configuration/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-start/src/main/java/io/github/lvyahui8/example/configuration/.gitignore -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/java/io/github/lvyahui8/example/configuration/CustomWebMvcConfigurer.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | 4 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | /** 10 | * @author feego lvyahui8@gmail.com 11 | * @date 2021/5/15 12 | */ 13 | @Configuration 14 | public class CustomWebMvcConfigurer implements WebMvcConfigurer { 15 | @Bean 16 | public FilterRegistrationBean httpRequestLogContextFilter() { 17 | FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); 18 | registrationBean.setFilter(new HttpRequestLogContextFilter()); 19 | registrationBean.setName("httpRequestLogContextFilter"); 20 | registrationBean.addUrlPatterns("/*"); 21 | return registrationBean; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/java/io/github/lvyahui8/example/configuration/HttpRequestLogContextFilter.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.configuration; 2 | 3 | 4 | import io.github.lvyahui8.sdk.logging.context.LogContextHolder; 5 | import io.github.lvyahui8.sdk.logging.logger.LogEventReactor; 6 | 7 | import javax.servlet.*; 8 | import java.io.IOException; 9 | 10 | /** 11 | * @author feego lvyahui8@gmail.com 12 | * @date 2021/5/15 13 | */ 14 | public class HttpRequestLogContextFilter implements Filter { 15 | 16 | @Override 17 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 18 | try { 19 | LogContextHolder.initDiscardedEventQueue(null); 20 | chain.doFilter(request,response); 21 | } finally { 22 | LogEventReactor.replayDiscardedEventsIfHasError(); 23 | LogContextHolder.resetLogContext(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/java/io/github/lvyahui8/example/resources/MainController.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example.resources; 2 | 3 | import feego.common.io.github.lvyahui8.example.SystemLogger; 4 | import io.github.lvyahui8.example.api.dto.UserDTO; 5 | import io.github.lvyahui8.sdk.lock.DistributedLock; 6 | import io.github.lvyahui8.sdk.lock.LockFactory; 7 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.data.redis.core.StringRedisTemplate; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import java.util.UUID; 14 | 15 | /** 16 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 17 | * @since 2020/2/16 22:04 18 | */ 19 | @RequestMapping("/") 20 | @RestController 21 | @Slf4j 22 | public class MainController { 23 | private static int n = 0 ; 24 | 25 | @Autowired 26 | LockFactory lockFactory; 27 | 28 | @Autowired 29 | StringRedisTemplate redisTemplate; 30 | 31 | 32 | @RequestMapping("/update") 33 | public Object update() { 34 | DistributedLock lock = lockFactory.newDistributeLock("feego:common:update.key", UUID.randomUUID().toString()); 35 | boolean locked = false; 36 | try { 37 | if (locked = lock.tryLock()) { 38 | SystemLogger.campaign.info("Got the lock"); 39 | return n++; 40 | } else { 41 | SystemLogger.campaign.warn("Didn't get the lock"); 42 | return 0; 43 | } 44 | } finally { 45 | if (locked) { 46 | lock.unlock(); 47 | } 48 | } 49 | } 50 | 51 | @RequestMapping("/status") 52 | public Object status() { 53 | SystemLogger.status.info(LogSchema.empty().of("status","ok")); 54 | SystemLogger.status.trace("trace log example"); 55 | SystemLogger.status.debug("debug log example"); 56 | SystemLogger.status.warn("warn log example"); 57 | SystemLogger.status.error("error log example"); 58 | // 出现error级别的日志, 之前的内容会被回朔 59 | for (int i = 0; i < 20; i++) { 60 | SystemLogger.status.trace("trace after error"); 61 | } 62 | return "ok"; 63 | } 64 | 65 | @PostMapping("/save") 66 | public Object save(@RequestBody UserDTO userDTO) { 67 | log.info(userDTO.toString()); 68 | return "success"; 69 | } 70 | 71 | @GetMapping("/query") 72 | public Object query() { 73 | /// log.info("query"); 74 | return redisTemplate.opsForValue().get("main"); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=80 2 | spring.mvc.favicon.enabled=true 3 | 4 | feego.common.logging.module-logger-enums=io.github.lvyahui8.example.configuration.CustomLogger 5 | feego.common.logging.log-handler=io.github.lvyahui8.example.configuration.CustomLogHandler 6 | feego.common.logging.storage-path=logs/ 7 | 8 | feego.common.web.format-response=false 9 | feego.common.web.security.signature.default-verify-request-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTEAyQI53Cn2fh8JTQdrFtNQIk\ns7g++25392BdyMvyd/vGuZpptbuHxA8JXPVZJunaGNRMVqFbfHv3hsR+1IFYhptj\nAtEVXJsEkBH/2Bpdor/mFxYFoTf+Cy60m3pBVdpvcz1AHYn0TDKNL33w5RuMbXU5\n4FYZYgOIuM7P/iNmQQIDAQAB\n 10 | feego.common.web.security.signature.default-sign-response-private-key=MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKTz6YhUNP7kGNAa\nFEJ1fymu/J6ddwVU6D8IkWvJq78DHemh3Pg4SvDdxGUSunV1m3CMnoJKU2QoqOcO\njnlQa4CYIL5/f3a8LFBaytcmPTJ+4YPug1Aki6xxd0O5pPtcZDTvz8FJIwdpFEz1\ng9LTSEHOSaruSYWpKs5mMzXXKDrfAgMBAAECgYEAmlitHWaFzDeMzDSK3oDpAwz8\nzkJTW0bOpiSTRgOH1AzLkZBmnlC2Ntmb6mNy23O3hcHek9WOYDr3iHSDdhp8629B\nv2H/KlpZKBFLwOdakwrD5vNPoBZEg17vmrNAzETPtuiz0/l20bi6f3JvRJqwLJ+e\ni7MlYHxdU10fYEgncSkCQQDSUqHGuXEuqU8Gb4Nuh+EUiUFFc4Qu/pMi3161KtqP\n/HHZv3HfL5tIr2Wc4l65jlfsaTJ3ubOGdrj3FI5Tyb97AkEAyMbVSn2KYOqWlSsd\nETfpMMXahhFSrb23y2B8hwYJyABMrgd5UURovikMHMJv3y2bjPoZ83uSQbR2+e1E\nVrkC7QJAMvMZhY5+wJL7Nc/lwuzftZ3aVfy51LiO5C/APZr3/1FkMx+RckOSFnWG\n5A5ibAjze62wMBioSLaR8CjmoZ2J6QJAHvwgeoh5TI+ngYnPyJJ6WF6QZNRTkCCR\nNr/DOAtEgysYqlrY7CPEjmRDTETtguHE+bK3Qo41ehJhshxdyYxv2QI/elo5+Gz1\nVNkdHze9oyL5zzePagAM5nb3SyLtnmCiGgN8Nf0T3jdLQMta4E9vpQaZbyC54JAw\nq6jcjhQxj1hW\n 11 | feego.common.web.security.signature.open=true 12 | feego.common.web.security.signature.clients[0].app-id=default 13 | feego.common.web.security.signature.clients[0].verify-request-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTEAyQI53Cn2fh8JTQdrFtNQIk\ns7g++25392BdyMvyd/vGuZpptbuHxA8JXPVZJunaGNRMVqFbfHv3hsR+1IFYhptj\nAtEVXJsEkBH/2Bpdor/mFxYFoTf+Cy60m3pBVdpvcz1AHYn0TDKNL33w5RuMbXU5\n4FYZYgOIuM7P/iNmQQIDAQAB\n 14 | 15 | spring.main.allow-bean-definition-overriding=true 16 | 17 | spring.redis.database=0 18 | spring.redis.host=127.0.0.1 19 | spring.redis.port=6379 20 | spring.redis.password=admin888 -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/resources/dubbo-provider.properties: -------------------------------------------------------------------------------- 1 | dubbo.application.name=annotation-provider 2 | dubbo.registry.address=zookeeper://127.0.0.1:2181?timeout=60000 3 | dubbo.protocol.name=dubbo 4 | dubbo.protocol.port=20880 -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/resources/strings/homepage.json: -------------------------------------------------------------------------------- 1 | { 2 | "success" : true, 3 | "code" : 0, 4 | "data" : { 5 | "domain" : "www.google.com" 6 | } 7 | } -------------------------------------------------------------------------------- /example/feego-common-example-start/src/main/resources/strings/member/account.json: -------------------------------------------------------------------------------- 1 | { 2 | "success" : true, 3 | "code" : 0, 4 | "data" : { 5 | "uid" : 123434, 6 | "username" : "feego" 7 | } 8 | } -------------------------------------------------------------------------------- /example/feego-common-example-start/src/test/java/io/github/lvyahui8/example/BasicTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | import java.util.UUID; 9 | 10 | /** 11 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 12 | * @since 2020/2/28 23:06 13 | */ 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | @Slf4j 17 | public class BasicTest { 18 | public static void main(String[] args) { 19 | System.out.println(UUID.randomUUID().toString()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/test/java/io/github/lvyahui8/example/MsgCodeTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example; 2 | 3 | import io.github.lvyahui8.example.code.Code; 4 | import org.junit.Test; 5 | 6 | import java.text.DecimalFormat; 7 | 8 | /** 9 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 10 | * @since 2020/3/18 21:56 11 | */ 12 | public class MsgCodeTest { 13 | 14 | enum SimpleMsgCode { 15 | success(0,"success"), 16 | unknown(-1 , "unknown exception"), 17 | ; 18 | String msg; 19 | Integer code; 20 | 21 | SimpleMsgCode(Integer code,String msg) { 22 | this.msg = msg; 23 | this.code = code; 24 | } 25 | 26 | public Integer getCode() { 27 | return code; 28 | } 29 | 30 | public String getMsg() { 31 | return msg; 32 | } 33 | } 34 | 35 | enum Client { 36 | reqest_illegal, 37 | traffic_limmit, 38 | } 39 | 40 | enum TPB { 41 | member_system_err, 42 | 43 | } 44 | 45 | @Test 46 | public void testBasic() throws Exception { 47 | System.out.println(Code.General.success.getCode()); 48 | System.out.println(Code.General.success.getMsg()); 49 | System.out.println(Code.General.unknown.getCode()); 50 | System.out.println(Code.General.unknown.getMsg()); 51 | System.out.println(Code.Client.no_permit.getCode()); 52 | System.out.println(Code.Client.no_permit.getMsg()); 53 | System.out.println(Code.Client.no_login_session.getCode()); 54 | System.out.println(Code.Client.no_login_session.getMsg()); 55 | } 56 | 57 | @Test 58 | public void testPerformance() throws Exception { 59 | /// final int n = new DecimalFormat(",####").parse("1,0000,0000").intValue(); 60 | final int n = new DecimalFormat(",####").parse("100,0000").intValue(); 61 | System.out.println("loop times:" + n); 62 | long begin = System.currentTimeMillis(); 63 | /// // 预先加载到缓存, 实际测试并没有太大区别 64 | /// Code.General.success.getCode(); 65 | for (int i = 0 ;i < n ; i ++) { 66 | SimpleMsgCode.success.getCode(); 67 | } 68 | System.out.println("simpleMsgCode.getCode cost time:" + (System.currentTimeMillis() - begin) + " ms"); 69 | begin = System.currentTimeMillis(); 70 | for (int i = 0 ; i < n ; i ++) { 71 | Code.General.success.getCode(); 72 | } 73 | System.out.println("MsgCode.getCode cost time:" + (System.currentTimeMillis() - begin) + " ms"); 74 | begin = System.currentTimeMillis(); 75 | for (int i = 0 ;i < n ; i ++) { 76 | SimpleMsgCode.success.getMsg(); 77 | } 78 | System.out.println("simpleMsgCode.getMsg cost time:" + (System.currentTimeMillis() - begin) + " ms"); 79 | begin = System.currentTimeMillis(); 80 | for (int i = 0 ; i < n ; i ++) { 81 | Code.General.success.getMsg(); 82 | } 83 | System.out.println("MsgCode.getMsg cost time:" + (System.currentTimeMillis() - begin) + " ms"); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/test/java/io/github/lvyahui8/example/NamedLockExecutorTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example; 2 | 3 | import io.github.lvyahui8.sdk.lock.NamedLockExecutor; 4 | import lombok.Data; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import java.util.concurrent.ExecutorService; 9 | import java.util.concurrent.Executors; 10 | import java.util.concurrent.atomic.AtomicBoolean; 11 | import java.util.concurrent.atomic.AtomicInteger; 12 | import java.util.concurrent.atomic.AtomicLong; 13 | 14 | /** 15 | * @author feego lvyahui8@gmail.com 16 | * @date 2021/2/3 17 | */ 18 | public class NamedLockExecutorTest { 19 | @Data 20 | class Resource { 21 | int state = 0; 22 | } 23 | @Test 24 | public void testExec() throws Exception { 25 | ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 26 | 27 | final Resource resource = new Resource(); 28 | final AtomicBoolean flag = new AtomicBoolean(true); 29 | final AtomicInteger reloadCount = new AtomicInteger(0); 30 | final AtomicLong accessCount = new AtomicLong(0); 31 | long begin = System.currentTimeMillis(); 32 | for (int i = 0; i < 10; i++) { 33 | service.submit(() -> { 34 | while(flag.get()) { 35 | try { 36 | Resource k = NamedLockExecutor.exec("" + (101 % 100),() -> { 37 | // 访问资源 38 | // System.out.println("state=" + resource.state); 39 | accessCount.incrementAndGet(); 40 | return resource.state <= 0 ? null : resource; 41 | } ,() -> { 42 | // 加载资源 43 | resource.state += 1; 44 | 45 | System.out.println("reloaded:" + reloadCount.incrementAndGet()); 46 | return resource; 47 | }); 48 | Assert.assertEquals(k.state,1); 49 | } catch (Exception e) { 50 | e.printStackTrace(); 51 | } 52 | } 53 | }); 54 | } 55 | for (int i = 0; i < 1000; i++) { 56 | Thread.sleep(1000); 57 | // 将资源失效掉 (过期) 58 | resource.state = 0; 59 | } 60 | System.out.printf("refresh done, cost:%dms\n",System.currentTimeMillis() - begin); 61 | 62 | 63 | 64 | flag.set(false); 65 | service.shutdownNow(); 66 | System.out.printf("access cnt:%d,reload cnt:%d, cost:%dms%n", 67 | accessCount.get(), 68 | reloadCount.get(), 69 | System.currentTimeMillis() - begin); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/test/java/io/github/lvyahui8/example/RedDotTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example; 2 | 3 | import io.github.lvyahui8.example.reddot.AppRedDot; 4 | import io.github.lvyahui8.sdk.reddot.RedDotManager; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.apache.dubbo.rpc.cluster.router.condition.config.AppRouter; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.data.redis.core.RedisTemplate; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | 15 | import java.util.Map; 16 | 17 | /** 18 | * @author feego lvyahui8@gmail.com 19 | * @date 2021/1/23 20 | */ 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | @Slf4j 24 | public class RedDotTest { 25 | 26 | @Autowired 27 | RedDotManager redDotManager; 28 | 29 | @Autowired 30 | public RedisTemplate redisTemplate; 31 | 32 | @Test 33 | public void testBasic() throws Exception { 34 | Object userId = 123L; 35 | redisTemplate.delete(userId.toString()); 36 | 37 | redDotManager.enable(userId, AppRedDot.asset); 38 | Map activeMap = redDotManager.isActiveMap(userId, 39 | AppRedDot.asset, AppRedDot.profile, AppRedDot.my_account, AppRedDot.root); 40 | for (Map.Entry entry : activeMap.entrySet()) { 41 | Assert.assertTrue(entry.getValue()); 42 | } 43 | 44 | redDotManager.enable(userId,AppRedDot.channels); 45 | activeMap = redDotManager.isActiveMap(userId, AppRedDot.channels, AppRedDot.hp, AppRedDot.root); 46 | for (Map.Entry entry : activeMap.entrySet()) { 47 | Assert.assertTrue(entry.getValue()); 48 | } 49 | 50 | redDotManager.disable(userId,AppRedDot.channels); 51 | activeMap = redDotManager.isActiveMap(userId,AppRedDot.values()); 52 | Assert.assertTrue(activeMap.get(AppRedDot.root.id())); 53 | Assert.assertTrue(activeMap.get(AppRedDot.my_account.id())); 54 | Assert.assertTrue(activeMap.get(AppRedDot.profile.id())); 55 | Assert.assertTrue(activeMap.get(AppRedDot.asset.id())); 56 | Assert.assertFalse(activeMap.get(AppRedDot.hp.id())); 57 | Assert.assertFalse(activeMap.get(AppRedDot.channels.id())); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/test/java/io/github/lvyahui8/example/ResourceStringsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.example; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | /** 10 | * @author yahui.lv lvyahui8@gmail.com 11 | * @date 2020/4/14 23:41 12 | */ 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | @Slf4j 16 | public class ResourceStringsTest { 17 | @Test 18 | public void testBasic() throws Exception { 19 | System.out.println(MultipleLienStrings.homepage_json.getContent()); 20 | System.out.println(MultipleLienStrings.member_account_json); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/feego-common-example-start/src/test/resources/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/example/feego-common-example-start/src/test/resources/.gitignore -------------------------------------------------------------------------------- /example/keys/sign_request_pri.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANMQDJAjncKfZ+Hw 3 | lNB2sW01AiSzuD77bnf3YF3Iy/J3+8a5mmm1u4fEDwlc9Vkm6doY1ExWoVt8e/eG 4 | xH7UgViGm2MC0RVcmwSQEf/YGl2iv+YXFgWhN/4LLrSbekFV2m9zPUAdifRMMo0v 5 | ffDlG4xtdTngVhliA4i4zs/+I2ZBAgMBAAECgYEAuR5FdpLWhuIbUi8ZxvGj0t4A 6 | YEKFIjCTBoOhMQCx6JvV58nYpkjwDzcl3Rd8VdJsn47RfZcp9Tzs2gCJDZjDTFJj 7 | wWsIWIRE77YX1K3TezBDdFh1rc2zUIy0u3jvbkPJguZeKFYtff2ACrVTnGybfpbS 8 | s04e4WnjPJmgivmnazECQQD2moEgZjlaILQuURE59baY5TYqltZRRFvt+PrerJ5H 9 | zWUNbD//bcsTSbDEw1+s7g654InPZvvjkbHL3AWBsj79AkEA2xrcgDzkEWrxzdmg 10 | 6qEeU3l/PcxKI66S7DEY74fdf8V1ZIQEHG1iyAAqfyADdXyofHqhABE4Bnub0mUn 11 | SAjBlQJAbnMrDIDchSKKsQf8KDKGUxquVQrz+LgeWIqgiiVUSyKSdR2b2GKrhvsF 12 | YkuDSafiDpyj/LHKddWmhYEJMlrMXQJBAMJ+1b4AT3Qmuv9AcNfWrlTrRUhWUHnc 13 | Pg/shXYb5UPGxK61gfC6KTXg79hpUqi4P9hAAytMHa+jim753CTVoQECQQDD3myY 14 | EOdz7JGlfcXaavtPRQlfo5FRQI8iR82rpUZ6H0ZoXpw+n1F+4X720g2ah76eMB7B 15 | JbeETpR4PBckfjo1 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /example/keys/sign_response_pri.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKTz6YhUNP7kGNAa 3 | FEJ1fymu/J6ddwVU6D8IkWvJq78DHemh3Pg4SvDdxGUSunV1m3CMnoJKU2QoqOcO 4 | jnlQa4CYIL5/f3a8LFBaytcmPTJ+4YPug1Aki6xxd0O5pPtcZDTvz8FJIwdpFEz1 5 | g9LTSEHOSaruSYWpKs5mMzXXKDrfAgMBAAECgYEAmlitHWaFzDeMzDSK3oDpAwz8 6 | zkJTW0bOpiSTRgOH1AzLkZBmnlC2Ntmb6mNy23O3hcHek9WOYDr3iHSDdhp8629B 7 | v2H/KlpZKBFLwOdakwrD5vNPoBZEg17vmrNAzETPtuiz0/l20bi6f3JvRJqwLJ+e 8 | i7MlYHxdU10fYEgncSkCQQDSUqHGuXEuqU8Gb4Nuh+EUiUFFc4Qu/pMi3161KtqP 9 | /HHZv3HfL5tIr2Wc4l65jlfsaTJ3ubOGdrj3FI5Tyb97AkEAyMbVSn2KYOqWlSsd 10 | ETfpMMXahhFSrb23y2B8hwYJyABMrgd5UURovikMHMJv3y2bjPoZ83uSQbR2+e1E 11 | VrkC7QJAMvMZhY5+wJL7Nc/lwuzftZ3aVfy51LiO5C/APZr3/1FkMx+RckOSFnWG 12 | 5A5ibAjze62wMBioSLaR8CjmoZ2J6QJAHvwgeoh5TI+ngYnPyJJ6WF6QZNRTkCCR 13 | Nr/DOAtEgysYqlrY7CPEjmRDTETtguHE+bK3Qo41ehJhshxdyYxv2QI/elo5+Gz1 14 | VNkdHze9oyL5zzePagAM5nb3SyLtnmCiGgN8Nf0T3jdLQMta4E9vpQaZbyC54JAw 15 | q6jcjhQxj1hW 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /example/keys/verify_request_pub.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTEAyQI53Cn2fh8JTQdrFtNQIk 3 | s7g++25392BdyMvyd/vGuZpptbuHxA8JXPVZJunaGNRMVqFbfHv3hsR+1IFYhptj 4 | AtEVXJsEkBH/2Bpdor/mFxYFoTf+Cy60m3pBVdpvcz1AHYn0TDKNL33w5RuMbXU5 5 | 4FYZYgOIuM7P/iNmQQIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /example/keys/verify_response_pub.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCk8+mIVDT+5BjQGhRCdX8prvye 3 | nXcFVOg/CJFryau/Ax3podz4OErw3cRlErp1dZtwjJ6CSlNkKKjnDo55UGuAmCC+ 4 | f392vCxQWsrXJj0yfuGD7oNQJIuscXdDuaT7XGQ078/BSSMHaRRM9YPS00hBzkmq 5 | 7kmFqSrOZjM11yg63wIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | 10 | 4.0.0 11 | 12 | feego-common-configuration-processor 13 | 14 | feego-common-configuration-processor 15 | 16 | 17 | 18 | 19 | 20 | 21 | junit 22 | junit 23 | test 24 | 25 | 26 | commons-io 27 | commons-io 28 | 29 | 30 | 31 | org.apache.commons 32 | commons-lang3 33 | 34 | 35 | 36 | com.sun 37 | tools 38 | 1.8 39 | system 40 | ${java.home}/../lib/tools.jar 41 | 42 | 43 | 44 | 45 | 46 | 47 | maven-compiler-plugin 48 | 49 | 1.8 50 | 1.8 51 | 52 | -proc:none 53 | none 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/main/java/io/github/lvyahui8/configuration/annotations/ModuleLoggerAutoGeneration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.configuration.annotations; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/2/21 20:14 8 | */ 9 | @Target({ElementType.TYPE}) 10 | @Retention(RetentionPolicy.SOURCE) 11 | @Documented 12 | public @interface ModuleLoggerAutoGeneration { 13 | String [] value() default {}; 14 | } 15 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/main/java/io/github/lvyahui8/configuration/annotations/ResourceStrings.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.configuration.annotations; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author yahui.lv lvyahui8@gmail.com 7 | * @date 2020/4/14 22:25 8 | */ 9 | @Target({ElementType.TYPE}) 10 | @Retention(RetentionPolicy.SOURCE) 11 | @Documented 12 | public @interface ResourceStrings { 13 | String value(); 14 | } 15 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/main/java/io/github/lvyahui8/configuration/annotations/RuntimeConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.configuration.annotations; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author yahui.lv lvyahui8@gmail.com 7 | * @date 2020/4/12 21:14 8 | */ 9 | @Target({ElementType.TYPE}) 10 | @Retention(RetentionPolicy.SOURCE) 11 | @Documented 12 | public @interface RuntimeConfiguration { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/main/java/io/github/lvyahui8/configuration/annotations/Singleton.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.configuration.annotations; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author yahui.lv lvyahui8@gmail.com 7 | * @date 2020/4/8 21:02 8 | */ 9 | @Target({ElementType.TYPE}) 10 | @Retention(RetentionPolicy.SOURCE) 11 | @Documented 12 | public @interface Singleton { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/main/java/io/github/lvyahui8/configuration/processor/ModuleLoggerProcessor.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.configuration.processor; 2 | 3 | import io.github.lvyahui8.configuration.annotations.ModuleLoggerAutoGeneration; 4 | import io.github.lvyahui8.configuration.utils.BuildUtils; 5 | 6 | import javax.annotation.processing.*; 7 | import javax.lang.model.SourceVersion; 8 | import javax.lang.model.element.Element; 9 | import javax.lang.model.element.TypeElement; 10 | import javax.tools.Diagnostic; 11 | import javax.tools.JavaFileObject; 12 | import java.io.IOException; 13 | import java.io.Writer; 14 | import java.util.*; 15 | 16 | /** 17 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 18 | * @since 2020/2/21 20:08 19 | */ 20 | @SuppressWarnings("unused") 21 | public class ModuleLoggerProcessor extends AbstractProcessor { 22 | 23 | public static final String LOGGER_ENUM_CLASS = "io.github.lvyahui8.sdk.logging.SystemLogger"; 24 | 25 | private Messager messager; 26 | private Filer filer; 27 | 28 | @Override 29 | public synchronized void init(ProcessingEnvironment processingEnv) { 30 | super.init(processingEnv); 31 | messager = processingEnv.getMessager(); 32 | filer = processingEnv.getFiler(); 33 | } 34 | 35 | @Override 36 | public boolean process(Set annotations, RoundEnvironment roundEnv) { 37 | Set elements = roundEnv.getElementsAnnotatedWith( 38 | ModuleLoggerAutoGeneration.class); 39 | messager.printMessage(Diagnostic.Kind.NOTE, "process module loggers, size:" + elements.size()); 40 | if (!elements.isEmpty()) { 41 | String packageName = "feego.common." + BuildUtils.getCommonPackagePrefix(elements); 42 | 43 | JavaFileObject sourceFile; 44 | Writer writer; 45 | try { 46 | sourceFile = filer.createSourceFile(packageName + ".SystemLogger"); 47 | writer = sourceFile.openWriter(); 48 | } catch (Exception e) { 49 | messager.printMessage(Diagnostic.Kind.ERROR, "create java file failed. eMsg:" + e.getMessage()); 50 | return false; 51 | } 52 | 53 | 54 | try { 55 | writer.write("package " + packageName + ";\n\n"); 56 | writer.write("import io.github.lvyahui8.sdk.logging.logger.EnumModuleLogger;\n"); 57 | writer.write("import org.slf4j.Logger;\n"); 58 | writer.write("import java.util.*;\n\n"); 59 | writer.write("public enum SystemLogger implements EnumModuleLogger { \n"); 60 | for (Element element : elements) { 61 | ModuleLoggerAutoGeneration moduleLoggerAutoGeneration = element.getAnnotation(ModuleLoggerAutoGeneration.class); 62 | List moduleNames = Arrays.asList(moduleLoggerAutoGeneration.value()); 63 | for (String module : moduleNames) { 64 | writer.write(" " + module + ",\n"); 65 | } 66 | } 67 | writer.write(" ;\n\n"); 68 | writer.write("}\n"); 69 | writer.flush(); 70 | } catch (Exception e) { 71 | messager.printMessage(Diagnostic.Kind.ERROR, "handle element failed. eMsg:" + e.getMessage()); 72 | return false; 73 | } finally { 74 | try { 75 | writer.close(); 76 | } catch (IOException ignored) { 77 | // 78 | } 79 | } 80 | } 81 | 82 | /* 返回false表示这个源文件需要后续的Processor继续处理 , 返回为true表示不需要 */ 83 | return false; 84 | } 85 | 86 | @Override 87 | public Set getSupportedAnnotationTypes() { 88 | return new HashSet<>(Collections.singletonList(ModuleLoggerAutoGeneration.class.getCanonicalName())); 89 | } 90 | 91 | @Override 92 | public SourceVersion getSupportedSourceVersion() { 93 | return SourceVersion.latestSupported(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/main/java/io/github/lvyahui8/configuration/utils/BuildUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.configuration.utils; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import javax.lang.model.element.Element; 6 | import javax.lang.model.element.ElementKind; 7 | import javax.lang.model.element.PackageElement; 8 | import javax.tools.Diagnostic; 9 | import java.util.LinkedList; 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | /** 14 | * @author yahui.lv lvyahui8@gmail.com 15 | * @date 2020/4/12 21:24 16 | */ 17 | public class BuildUtils { 18 | public static String getPackageName(Element element) { 19 | Element enclosing = element; 20 | while (enclosing.getKind() != ElementKind.PACKAGE) { 21 | enclosing = enclosing.getEnclosingElement(); 22 | } 23 | PackageElement packageElement = (PackageElement) enclosing; 24 | return packageElement.getQualifiedName().toString(); 25 | } 26 | 27 | public static String getCommonPackagePrefix(Set elements) { 28 | List classes = new LinkedList<>(); 29 | for (Element element : elements) { 30 | classes.add(getPackageName(element)); 31 | } 32 | 33 | String [] items = new String[classes.size()]; 34 | classes.toArray(items); 35 | return StringUtils.getCommonPrefix(items); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor: -------------------------------------------------------------------------------- 1 | io.github.lvyahui8.configuration.processor.ModuleLoggerProcessor 2 | io.github.lvyahui8.configuration.processor.SingletonProcessor 3 | #io.github.lvyahui8.configuration.processor.RuntimeConfigurationProcessor 4 | io.github.lvyahui8.configuration.processor.ResourceStringsProcessor -------------------------------------------------------------------------------- /feego-common-configuration-processor/src/test/java/io/github/lvyahui8/configuration/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-configuration-processor/src/test/java/io/github/lvyahui8/configuration/.gitignore -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | 8 | feego-common 9 | io.github.lvyahui8 10 | 1.2.2 11 | ../../pom.xml 12 | 13 | 14 | feego-common-logging-autoconfigure 15 | 16 | feego-common-logging-autoconfigure 17 | 18 | 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | test 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-configuration-processor 31 | true 32 | compile 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-autoconfigure 39 | 40 | 41 | 42 | org.reflections 43 | reflections 44 | 45 | 46 | 47 | org.projectlombok 48 | lombok 49 | 50 | 51 | 52 | io.github.lvyahui8 53 | feego-common-logging 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-test 59 | test 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/main/java/io/github/lvyahui8/sdk/logging/autoconfigure/ModuleLoggerAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.autoconfigure; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.ModuleLogger; 4 | import io.github.lvyahui8.sdk.logging.factory.Log4j2ModuleLoggerFactory; 5 | import io.github.lvyahui8.sdk.logging.factory.LogbackModuleLoggerFactory; 6 | import io.github.lvyahui8.sdk.logging.factory.ModuleLoggerFactory; 7 | import org.reflections.Reflections; 8 | import org.slf4j.ILoggerFactory; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.context.event.ApplicationReadyEvent; 12 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 13 | import org.springframework.context.ApplicationListener; 14 | import org.springframework.context.annotation.Configuration; 15 | 16 | import java.util.Set; 17 | 18 | /** 19 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 20 | * @since 2020/2/22 12:12 21 | */ 22 | @Configuration 23 | @EnableConfigurationProperties(ModuleLoggerProperties.class) 24 | public class ModuleLoggerAutoConfiguration implements ApplicationListener { 25 | 26 | @Autowired 27 | ModuleLoggerProperties loggingProperties; 28 | 29 | @Override 30 | public void onApplicationEvent(ApplicationReadyEvent event) { 31 | ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory(); 32 | 33 | ModuleLoggerFactory factory ; 34 | if ("ch.qos.logback.classic.LoggerContext".equals(loggerFactory.getClass().getName())) { 35 | factory = new LogbackModuleLoggerFactory(loggingProperties); 36 | } else if ("org.apache.logging.slf4j.Log4jLoggerFactory".equals(loggerFactory.getClass().getName())){ 37 | factory = new Log4j2ModuleLoggerFactory(loggingProperties); 38 | } else { 39 | throw new UnsupportedOperationException("Only logback and log4j2 are supported"); 40 | } 41 | 42 | Reflections reflections = new Reflections("feego.common."); 43 | Set> allModuleLoggers = reflections.getSubTypesOf(ModuleLogger.class); 44 | allModuleLoggers.addAll(loggingProperties.getModuleLoggerEnums()); 45 | factory.initModuleLogger(allModuleLoggers.toArray(new Class[0])); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/main/java/io/github/lvyahui8/sdk/logging/autoconfigure/ModuleLoggerProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.autoconfigure; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.DefaultLogConfiguration; 4 | import io.github.lvyahui8.sdk.logging.logger.ModuleLogger; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | 9 | import java.util.Collections; 10 | import java.util.Set; 11 | 12 | /** 13 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 14 | * @since 2020/2/22 12:15 15 | */ 16 | @ConfigurationProperties(prefix = "feego.common.logging") 17 | @Data 18 | @EqualsAndHashCode(callSuper = true) 19 | public class ModuleLoggerProperties extends DefaultLogConfiguration { 20 | /** 21 | * 是否开启模块化日志 22 | */ 23 | boolean open = true; 24 | /** 25 | * 自定义的日志枚举类 26 | */ 27 | Set> moduleLoggerEnums = Collections.emptySet(); 28 | } 29 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.github.lvyahui8.sdk.logging.autoconfigure.ModuleLoggerAutoConfiguration -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/test/java/io/github/lvyahui8/sdk/logging/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-logging/feego-common-logging-autoconfigure/src/test/java/io/github/lvyahui8/sdk/logging/.gitignore -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/test/java/io/github/lvyahui8/sdk/logging/BaseTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | @Slf4j 11 | public class BaseTest { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/test/java/io/github/lvyahui8/sdk/logging/LoggingTestCase.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 4 | import org.junit.Test; 5 | 6 | public class LoggingTestCase extends BaseTest { 7 | @Test 8 | public void testRootLogger() { 9 | TestLogger._root.info("hello"); 10 | TestLogger._root.info(LogSchema.biz("hello").of("suc",true).of("cost",1)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/test/java/io/github/lvyahui8/sdk/logging/TestApplication.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TestApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(TestApplication.class,args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/test/java/io/github/lvyahui8/sdk/logging/TestLogger.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.EnumModuleLogger; 4 | 5 | public enum TestLogger implements EnumModuleLogger { 6 | _root, 7 | ; 8 | } 9 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-autoconfigure/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | feego.common.logging.module-logger-enums=io.github.lvyahui8.sdk.logging.TestLogger -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-logging-starter 14 | 15 | feego-common-logging-starter 16 | 17 | 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | test 25 | 26 | 27 | 28 | io.github.lvyahui8 29 | feego-common-logging-autoconfigure 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-starter/src/main/java/io/github/lvyahui8/sdk/logging/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-logging/feego-common-logging-starter/src/main/java/io/github/lvyahui8/sdk/logging/.gitignore -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-starter/src/main/resources/META-INF/spring.provides: -------------------------------------------------------------------------------- 1 | provides: feego-common-logging-autoconfigure -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging-starter/src/test/java/io/github/lvyahui8/sdk/logging/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-logging/feego-common-logging-starter/src/test/java/io/github/lvyahui8/sdk/logging/.gitignore -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-logging 14 | 15 | feego-common-logging 16 | 17 | 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | test 25 | 26 | 27 | 28 | org.slf4j 29 | slf4j-api 30 | 31 | 32 | 33 | 34 | ch.qos.logback 35 | logback-classic 36 | 37 | 38 | 39 | org.apache.logging.log4j 40 | log4j-core 41 | 42 | 43 | 44 | org.apache.commons 45 | commons-collections4 46 | 47 | 48 | 49 | ch.qos.logback 50 | logback-core 51 | 52 | 53 | 54 | 55 | org.apache.commons 56 | commons-lang3 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/configuration/DefaultLogConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.configuration; 2 | 3 | import io.github.lvyahui8.sdk.logging.handler.AbstractLogHandler; 4 | 5 | /** 6 | * @author feego lvyahui8@gmail.com 7 | * @date 2020/9/20 8 | */ 9 | public class DefaultLogConfiguration { 10 | /** 11 | * 存储路径 12 | */ 13 | String storagePath; 14 | /** 15 | * 日志文件切片大小 16 | */ 17 | String maxFileSize = "100MB"; 18 | /** 19 | * 日志文件允许的最大大小 20 | */ 21 | String totalSizeCap = "20GB"; 22 | /** 23 | * 允许存多少天历史的日志 24 | */ 25 | Integer maxHistory = 14; 26 | /** 27 | * 日志kv内容分隔符 28 | */ 29 | String fieldSeparator = LogConstants.Config.FIELD_SP; 30 | /** 31 | * 日志格式 32 | */ 33 | String pattern = "%d{yyyy-MM-dd HH:mm:ss.SSS} %5level %m%n"; 34 | /** 35 | * monitor 日志格式。去掉了日志级别。 36 | */ 37 | String monitorLogPattern = "%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"; 38 | /** 39 | * 文件名滚动规则 40 | */ 41 | String fileRollingPattern = ".%d{yyyy-MM-dd}.%i"; 42 | /** 43 | * 文件存放规则 44 | */ 45 | String fileName = "$logType/$module"; 46 | /** 47 | * 日志文件单独输出error、warn级别的日志 48 | */ 49 | boolean separateErrorLog = false; 50 | 51 | private static DefaultLogConfiguration configurationInstance ; 52 | 53 | public static DefaultLogConfiguration getInstance() { 54 | if (configurationInstance == null){ 55 | throw new IllegalStateException("The instance has not been initialized."); 56 | } 57 | return configurationInstance; 58 | } 59 | 60 | public DefaultLogConfiguration() { 61 | synchronized (DefaultLogConfiguration.class) { 62 | if (configurationInstance != null) { 63 | throw new UnsupportedOperationException("Each application can only have one configuration instance."); 64 | } 65 | configurationInstance = this; 66 | } 67 | } 68 | 69 | /** 70 | * 日志处理工具 71 | */ 72 | Class logHandler; 73 | 74 | public String getMaxFileSize() { 75 | return maxFileSize; 76 | } 77 | 78 | public void setMaxFileSize(String maxFileSize) { 79 | this.maxFileSize = maxFileSize; 80 | } 81 | 82 | public Integer getMaxHistory() { 83 | return maxHistory; 84 | } 85 | 86 | public void setMaxHistory(Integer maxHistory) { 87 | this.maxHistory = maxHistory; 88 | } 89 | 90 | public String getStoragePath() { 91 | return storagePath; 92 | } 93 | 94 | public void setStoragePath(String storagePath) { 95 | this.storagePath = storagePath; 96 | } 97 | 98 | public String getTotalSizeCap() { 99 | return totalSizeCap; 100 | } 101 | 102 | public void setTotalSizeCap(String totalSizeCap) { 103 | this.totalSizeCap = totalSizeCap; 104 | } 105 | 106 | public String getFieldSeparator() { 107 | return fieldSeparator; 108 | } 109 | 110 | public void setFieldSeparator(String fieldSeparator) { 111 | this.fieldSeparator = fieldSeparator; 112 | } 113 | 114 | public String getGeneralLogPattern() { 115 | return pattern; 116 | } 117 | 118 | public void setPattern(String pattern) { 119 | this.pattern = pattern; 120 | } 121 | 122 | public String getMonitorLogPattern() { 123 | return monitorLogPattern; 124 | } 125 | 126 | public void setMonitorLogPattern(String monitorLogPattern) { 127 | this.monitorLogPattern = monitorLogPattern; 128 | } 129 | 130 | public String getFileRollingPattern() { 131 | return fileRollingPattern; 132 | } 133 | 134 | public void setFileRollingPattern(String fileRollingPattern) { 135 | this.fileRollingPattern = fileRollingPattern; 136 | } 137 | 138 | public String getFileName() { 139 | return fileName; 140 | } 141 | 142 | public void setFileName(String fileName) { 143 | this.fileName = fileName; 144 | } 145 | 146 | public Class getLogHandler() { 147 | return logHandler; 148 | } 149 | 150 | public void setLogHandler(Class logHandler) { 151 | this.logHandler = logHandler; 152 | } 153 | 154 | public String getPattern() { 155 | return pattern; 156 | } 157 | 158 | public boolean isSeparateErrorLog() { 159 | return separateErrorLog; 160 | } 161 | 162 | public void setSeparateErrorLog(boolean separateErrorLog) { 163 | this.separateErrorLog = separateErrorLog; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/configuration/LogConstants.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.configuration; 2 | 3 | /** 4 | * @author feego lvyahui8@gmail.com 5 | * @date 2021/5/1 6 | */ 7 | public interface LogConstants { 8 | interface ReversedKey { 9 | String BUSINESS = "biz"; 10 | String TRACE_ID = "tid"; 11 | String MESSAGE = "msg"; 12 | String SUCCESS = "suc"; 13 | String IS_REPLAY = "__isReplay"; 14 | String ACTUAL_TIME = "__logActualTime"; 15 | } 16 | 17 | interface Config { 18 | String FIELD_SP = "|#|"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/context/LogContext.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.context; 2 | 3 | import io.github.lvyahui8.sdk.logging.event.LogEvent; 4 | import org.slf4j.event.Level; 5 | 6 | import java.util.Queue; 7 | 8 | /** 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2021/4/30 11 | */ 12 | public class LogContext { 13 | String biz; 14 | 15 | /** 16 | * transaction id/request id/trace id 17 | */ 18 | String tid; 19 | 20 | Level level; 21 | 22 | boolean hasError; 23 | 24 | Queue discardedEventQueue; 25 | 26 | public String getBiz() { 27 | return biz; 28 | } 29 | 30 | public void setBiz(String biz) { 31 | this.biz = biz; 32 | } 33 | 34 | public String getTid() { 35 | return tid; 36 | } 37 | 38 | public void setTid(String tid) { 39 | this.tid = tid; 40 | } 41 | 42 | public Queue getDiscardedEventQueue() { 43 | return discardedEventQueue; 44 | } 45 | 46 | public void setDiscardedEventQueue(Queue discardedEventQueue) { 47 | this.discardedEventQueue = discardedEventQueue; 48 | } 49 | 50 | public Level getLevel() { 51 | return level; 52 | } 53 | 54 | public void setLevel(Level level) { 55 | this.level = level; 56 | } 57 | 58 | public boolean isHasError() { 59 | return hasError; 60 | } 61 | 62 | public void setHasError(boolean hasError) { 63 | this.hasError = hasError; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/context/LogContextHolder.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.context; 2 | 3 | 4 | import io.github.lvyahui8.sdk.logging.event.LogEvent; 5 | import org.slf4j.event.Level; 6 | 7 | import java.util.ArrayDeque; 8 | import java.util.Queue; 9 | 10 | /** 11 | * @author feego lvyahui8@gmail.com 12 | * @date 2021/4/30 13 | */ 14 | public class LogContextHolder { 15 | public static final ThreadLocal contextHolder = new ThreadLocal<>(); 16 | 17 | public static void resetLogContext() { 18 | contextHolder.remove(); 19 | } 20 | 21 | public static void putLogContext(LogContext logContext){ 22 | if (logContext == null) { 23 | resetLogContext(); 24 | } else { 25 | contextHolder.set(logContext); 26 | } 27 | } 28 | 29 | public static LogContext getLogContext() { 30 | LogContext logContext = contextHolder.get(); 31 | if (logContext == null) { 32 | putLogContext(logContext = new LogContext()); 33 | } 34 | return logContext; 35 | } 36 | 37 | public static String getBiz() { 38 | return getLogContext().getBiz(); 39 | } 40 | 41 | public static String getTid() { 42 | return getLogContext().getTid(); 43 | } 44 | 45 | public static Level getLevel() { 46 | return getLogContext().getLevel(); 47 | } 48 | 49 | public static void shelveLogEvent(LogEvent logEvent) { 50 | LogContext logContext = getLogContext(); 51 | if (logContext.getDiscardedEventQueue() != null) { 52 | logContext.getDiscardedEventQueue().offer(logEvent); 53 | } 54 | } 55 | 56 | public static Queue getDiscardedEventQueue() { 57 | return getLogContext().getDiscardedEventQueue(); 58 | } 59 | 60 | public static void initDiscardedEventQueue(Queue eventQueue) { 61 | LogContext logContext = getLogContext(); 62 | if (eventQueue != null) { 63 | logContext.setDiscardedEventQueue(eventQueue); 64 | } else { 65 | logContext.setDiscardedEventQueue(new ArrayDeque<>()); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/event/LogEvent.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.event; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 4 | import org.slf4j.Logger; 5 | import org.slf4j.event.Level; 6 | 7 | /** 8 | * @author feego lvyahui8@gmail.com 9 | * @date 2021/5/15 10 | */ 11 | public class LogEvent { 12 | LogSchema schema; 13 | Level level; 14 | Logger logger; 15 | Throwable throwable; 16 | long ts; 17 | 18 | { 19 | ts = System.currentTimeMillis(); 20 | } 21 | 22 | public LogEvent(LogSchema schema, Level level, Logger logger) { 23 | this.schema = schema; 24 | this.level = level; 25 | this.logger = logger; 26 | } 27 | 28 | public LogEvent(LogSchema schema, Level level, Logger logger, Throwable throwable) { 29 | this.schema = schema; 30 | this.level = level; 31 | this.logger = logger; 32 | this.throwable = throwable; 33 | } 34 | 35 | public LogSchema getSchema() { 36 | return schema; 37 | } 38 | 39 | public void setSchema(LogSchema schema) { 40 | this.schema = schema; 41 | } 42 | 43 | public Level getLevel() { 44 | return level; 45 | } 46 | 47 | public void setLevel(Level level) { 48 | this.level = level; 49 | } 50 | 51 | public Logger getLogger() { 52 | return logger; 53 | } 54 | 55 | public void setLogger(Logger logger) { 56 | this.logger = logger; 57 | } 58 | 59 | public Throwable getThrowable() { 60 | return throwable; 61 | } 62 | 63 | public void setThrowable(Throwable throwable) { 64 | this.throwable = throwable; 65 | } 66 | 67 | public long getTs() { 68 | return ts; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/factory/AbstractLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.factory; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.DefaultLogConfiguration; 4 | import io.github.lvyahui8.sdk.logging.handler.LogHandler; 5 | import io.github.lvyahui8.sdk.logging.logger.ModuleLogger; 6 | import io.github.lvyahui8.sdk.logging.logger.ModuleLoggerRepository; 7 | import io.github.lvyahui8.sdk.logging.logger.DefaultModuleLogger; 8 | import io.github.lvyahui8.sdk.logging.logger.RootLogger; 9 | import org.slf4j.ILoggerFactory; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.io.File; 14 | 15 | /** 16 | * @author feego lvyahui8@gmail.com 17 | * @date 2020/9/20 18 | */ 19 | public abstract class AbstractLoggerFactory implements ModuleLoggerFactory { 20 | 21 | protected DefaultLogConfiguration configuration; 22 | 23 | public AbstractLoggerFactory(DefaultLogConfiguration configuration) { 24 | this.configuration = configuration; 25 | } 26 | 27 | @Override 28 | @SafeVarargs 29 | public final void initModuleLogger(Class ... moduleEnumClasses) { 30 | for (Class moduleEnumClass : moduleEnumClasses) { 31 | if (! moduleEnumClass.isEnum()) { 32 | continue; 33 | /// throw new RuntimeException("The log module class must be an enum."); 34 | } 35 | LogHandler logHandler = null; 36 | if (configuration.getLogHandler() != null) { 37 | try { 38 | logHandler = configuration.getLogHandler().newInstance(); 39 | } catch (Exception e) { 40 | throw new RuntimeException("Failed to create SchemaHandler",e); 41 | } 42 | } 43 | /* 使用代理类替换代理枚举实现 */ 44 | for (Object enumInstance : moduleEnumClass.getEnumConstants()) { 45 | Enum loggerEnum = (Enum) enumInstance; 46 | if (ModuleLoggerRepository.getModuleLogger(loggerEnum.name()) != null) { 47 | // 相同模块不重复创建logger 48 | continue; 49 | } 50 | if (loggerEnum.name().equals("_root")) { 51 | continue; 52 | } 53 | Logger generalLogger = createSlf4jLogger(loggerEnum.name(), "general", configuration.getGeneralLogPattern()); 54 | Logger monitorLogger = createSlf4jLogger(loggerEnum.name(), "monitor", configuration.getMonitorLogPattern()); 55 | Logger errorLogger = generalLogger; 56 | if (configuration.isSeparateErrorLog()) { 57 | errorLogger = createSlf4jLogger(loggerEnum.name(), "error", configuration.getMonitorLogPattern()); 58 | } 59 | ModuleLogger realModuleLogger = new DefaultModuleLogger( 60 | loggerEnum.name(), 61 | generalLogger, 62 | errorLogger, 63 | monitorLogger, 64 | configuration.getFieldSeparator(), 65 | logHandler 66 | ); 67 | ModuleLoggerRepository.put(loggerEnum.name(), realModuleLogger); 68 | } 69 | if (logHandler != null){ 70 | RootLogger.getInstance().setLogHandler(logHandler); 71 | } 72 | } 73 | } 74 | 75 | private Logger createSlf4jLogger(String moduleName, String logType, String logPattern) { 76 | if (! configuration.getFileName().contains("$module") || ! configuration.getFileName().contains("$logType")) { 77 | throw new RuntimeException("Illegal file name declaration :" + configuration.getFileName()); 78 | } 79 | String storagePath = (configuration.getStoragePath() == null ? 80 | System.getProperty("user.home") : configuration.getStoragePath()) + File.separator + "logs"; 81 | 82 | String fileName = storagePath + File.separator + 83 | configuration.getFileName().replaceAll("\\$module", moduleName).replaceAll("\\$logType",logType) + ".log"; 84 | String fileNamePattern = fileName + configuration.getFileRollingPattern(); 85 | 86 | File file = new File(fileName); 87 | if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { 88 | throw new RuntimeException("No permission to create log path!"); 89 | } 90 | 91 | return createSlf4jLogger0(logPattern, moduleName + '-' + logType, LoggerFactory.getILoggerFactory(), 92 | fileName, fileNamePattern); 93 | } 94 | 95 | abstract org.slf4j.Logger createSlf4jLogger0(String pattern, String loggerName, ILoggerFactory loggerFactory, String fileName, String fileNamePattern); 96 | } 97 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/factory/Log4j2ModuleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.factory; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.DefaultLogConfiguration; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.core.LoggerContext; 6 | import org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender; 7 | import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy; 8 | import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy; 9 | import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy; 10 | import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy; 11 | import org.apache.logging.log4j.core.config.AppenderRef; 12 | import org.apache.logging.log4j.core.config.LoggerConfig; 13 | import org.apache.logging.log4j.core.layout.PatternLayout; 14 | import org.slf4j.ILoggerFactory; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | /** 19 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 20 | * @since 2020/2/23 19:24 21 | */ 22 | public class Log4j2ModuleLoggerFactory extends AbstractLoggerFactory { 23 | 24 | public Log4j2ModuleLoggerFactory(DefaultLogConfiguration configuration) { 25 | super(configuration); 26 | } 27 | 28 | @Override 29 | public Logger createSlf4jLogger0(String pattern, String loggerName, ILoggerFactory loggerFactory, String fileName, String fileNamePattern) { 30 | org.apache.logging.log4j.core.LoggerContext context = (LoggerContext) LogManager.getContext(false); 31 | 32 | org.apache.logging.log4j.core.config.Configuration configuration = context.getConfiguration(); 33 | 34 | PatternLayout layout = PatternLayout.newBuilder() 35 | .withConfiguration(configuration) 36 | .withPattern(pattern) 37 | .build(); 38 | 39 | RollingRandomAccessFileAppender appender = RollingRandomAccessFileAppender.newBuilder() 40 | .setConfiguration(configuration) 41 | .withName(loggerName + "Appender") 42 | .withFileName(fileName) 43 | .withFilePattern(fileNamePattern) 44 | .withBufferedIo(true) 45 | .withAppend(true) 46 | .withLayout(layout) 47 | .withPolicy(CompositeTriggeringPolicy.createPolicy( 48 | TimeBasedTriggeringPolicy.newBuilder().withInterval(1).withModulate(true).build(), 49 | SizeBasedTriggeringPolicy.createPolicy(this.configuration.getMaxFileSize()) 50 | )) 51 | .withStrategy(DefaultRolloverStrategy.newBuilder() 52 | .withMax(this.configuration.getMaxHistory().toString()).withConfig(configuration).build()) 53 | .build(); 54 | 55 | appender.start(); 56 | 57 | configuration.addAppender(appender); 58 | 59 | AppenderRef ref = AppenderRef.createAppenderRef(loggerName + "Appender",null,null); 60 | LoggerConfig loggerConfig = LoggerConfig.createLogger(false, org.apache.logging.log4j.Level.TRACE,loggerName, 61 | "false",new AppenderRef[]{ref},null,configuration,null); 62 | loggerConfig.addAppender(appender,null,null); 63 | configuration.addLogger(loggerName,loggerConfig); 64 | context.updateLoggers(); 65 | return LoggerFactory.getLogger(loggerName); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/factory/LogbackModuleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.factory; 2 | 3 | import ch.qos.logback.classic.Level; 4 | import ch.qos.logback.classic.encoder.PatternLayoutEncoder; 5 | import ch.qos.logback.classic.spi.ILoggingEvent; 6 | import ch.qos.logback.core.rolling.RollingFileAppender; 7 | import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; 8 | import ch.qos.logback.core.util.FileSize; 9 | import io.github.lvyahui8.sdk.logging.configuration.DefaultLogConfiguration; 10 | import org.slf4j.ILoggerFactory; 11 | import org.slf4j.Logger; 12 | 13 | /** 14 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 15 | * @since 2020/2/23 19:24 16 | */ 17 | public class LogbackModuleLoggerFactory extends AbstractLoggerFactory { 18 | 19 | public LogbackModuleLoggerFactory(DefaultLogConfiguration configuration) { 20 | super(configuration); 21 | } 22 | 23 | @Override 24 | public Logger createSlf4jLogger0(String pattern, String loggerName, ILoggerFactory loggerFactory, String fileName, String fileNamePattern) { 25 | ch.qos.logback.classic.LoggerContext context = (ch.qos.logback.classic.LoggerContext) loggerFactory; 26 | 27 | PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder(); 28 | patternLayoutEncoder.setContext(context); 29 | patternLayoutEncoder.setPattern(pattern); 30 | patternLayoutEncoder.start(); 31 | 32 | RollingFileAppender rollingFileAppender = new RollingFileAppender<>(); 33 | rollingFileAppender.setName(loggerName + "Appender"); 34 | 35 | rollingFileAppender.setFile(fileName); 36 | rollingFileAppender.setContext(context); 37 | rollingFileAppender.setAppend(true); 38 | SizeAndTimeBasedRollingPolicy sizeAndTimeBasedRollingPolicy = new SizeAndTimeBasedRollingPolicy(); 39 | sizeAndTimeBasedRollingPolicy.setContext(context); 40 | sizeAndTimeBasedRollingPolicy.setMaxFileSize(FileSize.valueOf(configuration.getMaxFileSize())); 41 | sizeAndTimeBasedRollingPolicy.setTotalSizeCap(FileSize.valueOf(configuration.getTotalSizeCap())); 42 | sizeAndTimeBasedRollingPolicy.setMaxHistory(configuration.getMaxHistory()); 43 | sizeAndTimeBasedRollingPolicy.setParent(rollingFileAppender); 44 | sizeAndTimeBasedRollingPolicy.setFileNamePattern(fileNamePattern); 45 | sizeAndTimeBasedRollingPolicy.start(); 46 | 47 | rollingFileAppender.setEncoder(patternLayoutEncoder); 48 | rollingFileAppender.setRollingPolicy(sizeAndTimeBasedRollingPolicy); 49 | rollingFileAppender.start(); 50 | 51 | ch.qos.logback.classic.Logger logger = context.getLogger(loggerName); 52 | logger.setAdditive(false); 53 | logger.setLevel(Level.TRACE); 54 | 55 | logger.addAppender(rollingFileAppender); 56 | return logger; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/factory/ModuleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.factory; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.ModuleLogger; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/2/22 13:01 8 | */ 9 | public interface ModuleLoggerFactory { 10 | void initModuleLogger(Class ... moduleEnumClasses); 11 | } 12 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/handler/AbstractLogHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.handler; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.LogConstants; 4 | import io.github.lvyahui8.sdk.logging.context.LogContext; 5 | import io.github.lvyahui8.sdk.logging.context.LogContextHolder; 6 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.slf4j.event.Level; 9 | 10 | /** 11 | * @author feego lvyahui8@gmail.com 12 | * @date 2020/10/10 13 | */ 14 | public abstract class AbstractLogHandler implements LogHandler { 15 | @Override 16 | public final Level runtimeLevel(String enumLoggerName) { 17 | Level level = LogContextHolder.getLevel(); 18 | if (level != null) { 19 | return level; 20 | } 21 | return innerRuntimeLevel(enumLoggerName); 22 | } 23 | 24 | public abstract Level innerRuntimeLevel(String enumLoggerName); 25 | 26 | @Override 27 | public final LogSchema beforeOutput(LogSchema logSchema) { 28 | LogContext logContext = LogContextHolder.getLogContext(); 29 | if (logContext != null) { 30 | if (StringUtils.isNotBlank(logContext.getBiz())) { 31 | logSchema.of(LogConstants.ReversedKey.BUSINESS,logContext.getBiz()); 32 | } 33 | if (StringUtils.isNotBlank(logContext.getTid())) { 34 | logSchema.of(LogConstants.ReversedKey.TRACE_ID,logContext.getTid()); 35 | } 36 | } 37 | return innerBeforeOutput(logSchema); 38 | } 39 | 40 | public abstract LogSchema innerBeforeOutput(LogSchema logSchema); 41 | 42 | @Override 43 | public LogSchema monitor(LogSchema logSchema) { 44 | return logSchema; 45 | } 46 | } -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/handler/DefaultLogHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.handler; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 4 | import org.slf4j.event.Level; 5 | 6 | /** 7 | * @author feego lvyahui8@gmail.com 8 | * @date 2021/5/1 9 | */ 10 | public class DefaultLogHandler extends AbstractLogHandler { 11 | 12 | @Override 13 | public Level innerRuntimeLevel(String enumLoggerName) { 14 | return Level.INFO; 15 | } 16 | 17 | @Override 18 | public LogSchema innerBeforeOutput(LogSchema logSchema) { 19 | return logSchema; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/handler/LogHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.handler; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 4 | import org.slf4j.event.Level; 5 | 6 | /** 7 | * @author feego lvyahui8@gmail.com 8 | * @date 2020/10/9 9 | */ 10 | public interface LogHandler { 11 | Level runtimeLevel(String enumLoggerName); 12 | LogSchema beforeOutput(LogSchema logSchema); 13 | 14 | LogSchema monitor(LogSchema logSchema); 15 | } 16 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/logger/EnumModuleLogger.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.logger; 2 | 3 | 4 | import org.slf4j.event.Level; 5 | 6 | /** 7 | * @author feego lvyahui8@gmail.com 8 | * @date 2020/9/18 9 | */ 10 | public interface EnumModuleLogger extends ModuleLogger{ 11 | @Override 12 | default ModuleLogger getInnerLogger() { 13 | if (!(this instanceof Enum)) { 14 | throw new UnsupportedOperationException("This interface must be implemented by Enum."); 15 | } 16 | Enum em = (Enum) this; 17 | ModuleLogger moduleLogger = ModuleLoggerRepository.getModuleLogger(em.name()); 18 | return moduleLogger != null ? moduleLogger : RootLogger.getInstance(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/logger/LogEventReactor.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.logger; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.LogConstants; 4 | import io.github.lvyahui8.sdk.logging.context.LogContext; 5 | import io.github.lvyahui8.sdk.logging.context.LogContextHolder; 6 | import io.github.lvyahui8.sdk.logging.event.LogEvent; 7 | import org.slf4j.Logger; 8 | import org.slf4j.event.Level; 9 | 10 | import java.util.Queue; 11 | 12 | /** 13 | * @author feego lvyahui8@gmail.com 14 | * @date 2021/5/15 15 | */ 16 | public class LogEventReactor { 17 | public static void recordingEvent(LogEvent logEvent) { 18 | Level level = logEvent.getLevel(); 19 | Throwable throwable = logEvent.getThrowable(); 20 | LogSchema.Detail detail ; 21 | if (throwable == null) { 22 | detail = logEvent.getSchema().buildDetail(null); 23 | } else { 24 | // https://stackoverflow.com/questions/45054154/logger-format-and-throwable-slf4j-arguments/45054272#45054272 25 | // 关键代码: 26 | // org.apache.logging.log4j.message.ParameterizedMessage.initThrowable 27 | // if (usedParams < argCount && this.throwable == null && params[argCount - 1] instanceof Throwable) { 28 | detail = logEvent.getSchema().buildDetail(null,1); 29 | detail.getArgs()[detail.getArgs().length - 1] = throwable; 30 | } 31 | Logger logger = logEvent.getLogger(); 32 | switch (level) { 33 | case TRACE: 34 | logger.trace(detail.getPattern(),detail.getArgs()); 35 | break; 36 | case DEBUG: 37 | logger.debug(detail.getPattern(),detail.getArgs()); 38 | break; 39 | case INFO: 40 | logger.info(detail.getPattern(),detail.getArgs()); 41 | break; 42 | case WARN: 43 | logger.warn(detail.getPattern(),detail.getArgs()); 44 | break; 45 | case ERROR: 46 | LogContextHolder.getLogContext().setHasError(true); 47 | logger.error(detail.getPattern(),detail.getArgs()); 48 | break; 49 | default: 50 | break; 51 | } 52 | } 53 | 54 | public static void replayDiscardedEventsIfHasError() { 55 | Queue queue = LogContextHolder.getDiscardedEventQueue(); 56 | if (queue != null) { 57 | if (LogContextHolder.getLogContext().isHasError()) { 58 | LogEvent event ; 59 | while((event = queue.poll()) != null) { 60 | event.getSchema().of(LogConstants.ReversedKey.IS_REPLAY,true) 61 | .of(LogConstants.ReversedKey.ACTUAL_TIME,event.getTs()); 62 | recordingEvent(event); 63 | } 64 | } else { 65 | queue.clear(); 66 | } 67 | LogContextHolder.getLogContext().setDiscardedEventQueue(null); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/logger/LogSchema.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.logger; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.LogConstants; 4 | import org.apache.commons.collections4.map.ListOrderedMap; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 10 | * @since 2020/2/22 0:12 11 | */ 12 | @SuppressWarnings({"unused"}) 13 | public final class LogSchema { 14 | /// private Map items = Collections.synchronizedMap(new ListOrderedMap<>()); 15 | private final ListOrderedMap items = new ListOrderedMap<>(); 16 | 17 | private String fieldSeparator; 18 | 19 | private String msgPattern; 20 | 21 | private Object [] msgArgs; 22 | 23 | private LogSchema() { 24 | init(); 25 | } 26 | 27 | public void init() { 28 | } 29 | 30 | public static LogSchema empty() { 31 | return new LogSchema(); 32 | } 33 | 34 | public static LogSchema biz(String biz) { 35 | return empty().of(LogConstants.ReversedKey.BUSINESS,biz); 36 | } 37 | 38 | public LogSchema of(String key,Object value) { 39 | items.put(key,simplifyValue(value)); 40 | return this; 41 | } 42 | 43 | public LogSchema traceId(String traceId) { 44 | return of(LogConstants.ReversedKey.TRACE_ID,traceId); 45 | } 46 | 47 | public LogSchema prepend(String key,Object value) { 48 | items.put(0,key,simplifyValue(value)); 49 | return this; 50 | } 51 | 52 | public LogSchema success(boolean suc) { 53 | return of(LogConstants.ReversedKey.SUCCESS,suc); 54 | } 55 | 56 | public LogSchema suc(boolean suc) { 57 | return success(suc); 58 | } 59 | 60 | public LogSchema cost(long costMs) { 61 | return of("cost",costMs); 62 | } 63 | 64 | public LogSchema clear() { 65 | items.clear(); 66 | return this; 67 | } 68 | 69 | private Object simplifyValue(Object value) { 70 | if (value instanceof Boolean) { 71 | return ((Boolean) value) ? 'Y' : 'N' ; 72 | } 73 | return value; 74 | } 75 | 76 | LogSchema msgPattern(String msgPattern) { 77 | this.msgPattern = msgPattern; 78 | return this; 79 | } 80 | 81 | LogSchema msgArgs(Object ... msgArgs) { 82 | this.msgArgs = msgArgs; 83 | return this; 84 | } 85 | 86 | Detail buildDetail(String sp) { 87 | return buildDetail(sp,0); 88 | } 89 | 90 | Detail buildDetail(String sp,int reserved) { 91 | if (sp == null) { 92 | sp = fieldSeparator; 93 | } 94 | Detail detail = new Detail(); 95 | detail.args = new Object[items.size() + reserved ]; 96 | StringBuilder sb = new StringBuilder(); 97 | int i = 0 ; 98 | for (Map.Entry item : items.entrySet()) { 99 | sb.append(item.getKey()).append(":{}"); 100 | if (i < items.size() - 1 || reserved > 0) { 101 | sb.append(sp); 102 | } 103 | detail.args[i++] = item.getValue(); 104 | } 105 | detail.pattern = sb.toString(); 106 | if (this.msgPattern != null) { 107 | String pattern = detail.getPattern() + sp + LogConstants.ReversedKey.MESSAGE + ":" + msgPattern; 108 | Object[] args ; 109 | if (msgArgs != null && msgArgs.length > 0 ) { 110 | args = new Object[detail.getArgs().length + msgArgs.length]; 111 | System.arraycopy(detail.getArgs(),0,args,0,detail.getArgs().length); 112 | System.arraycopy(msgArgs,0,args,detail.getArgs().length,msgArgs.length); 113 | } else { 114 | args = detail.getArgs(); 115 | } 116 | detail.pattern = pattern; 117 | detail.args = args; 118 | } 119 | return detail; 120 | } 121 | 122 | LogSchema setFieldSeparator(String fieldSeparator) { 123 | this.fieldSeparator = fieldSeparator; 124 | return this; 125 | } 126 | 127 | static class Detail { 128 | String pattern; 129 | Object [] args; 130 | 131 | public Object[] getArgs() { 132 | return args; 133 | } 134 | 135 | public String getPattern() { 136 | return pattern; 137 | } 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/logger/ModuleLogger.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.logger; 2 | 3 | import org.slf4j.event.Level; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/2/20 22:08 8 | */ 9 | public interface ModuleLogger { 10 | default void monitor(LogSchema schema) { ((ModuleLogger) getInnerLogger()).monitor(schema); } 11 | 12 | default void trace(LogSchema schema) { 13 | ((ModuleLogger) getInnerLogger()).trace(schema); 14 | } 15 | 16 | default void debug(LogSchema schema) { 17 | ((ModuleLogger) getInnerLogger()).debug(schema); 18 | } 19 | 20 | default void info(LogSchema schema) { 21 | ((ModuleLogger) getInnerLogger()).info(schema); 22 | } 23 | 24 | default void warn(LogSchema schema) { 25 | ((ModuleLogger) getInnerLogger()).warn(schema); 26 | } 27 | 28 | default void warn(LogSchema schema,Throwable t) { 29 | ((ModuleLogger) getInnerLogger()).warn(schema,t); 30 | } 31 | 32 | default void error(LogSchema schema) { 33 | ((ModuleLogger) getInnerLogger()).error(schema); 34 | } 35 | 36 | default void error(LogSchema schema,Throwable t) { 37 | ((ModuleLogger) getInnerLogger()).error(schema,t); 38 | } 39 | 40 | 41 | default boolean isTraceEnabled() { 42 | return getInnerLogger().isTraceEnabled(); 43 | } 44 | 45 | 46 | default boolean isDebugEnabled() { 47 | return getInnerLogger().isDebugEnabled(); 48 | } 49 | 50 | 51 | default boolean isInfoEnabled() { 52 | return getInnerLogger().isInfoEnabled(); 53 | } 54 | 55 | 56 | default boolean isWarnEnabled() { 57 | return getInnerLogger().isWarnEnabled(); 58 | } 59 | 60 | 61 | default void trace(String msg) { 62 | getInnerLogger().trace(msg); 63 | } 64 | 65 | 66 | default void trace(String format, Object arg) { 67 | getInnerLogger().trace(format,arg); 68 | } 69 | 70 | 71 | default void trace(String format, Object arg1, Object arg2) { 72 | getInnerLogger().trace(format,arg1,arg2); 73 | } 74 | 75 | 76 | default void trace(String format, Object... arguments) { 77 | getInnerLogger().trace(format, arguments); 78 | } 79 | 80 | 81 | default void debug(String msg) { 82 | getInnerLogger().debug(msg); 83 | } 84 | 85 | 86 | default void debug(String format, Object arg) { 87 | getInnerLogger().debug(format,arg); 88 | } 89 | 90 | 91 | default void debug(String format, Object arg1, Object arg2) { 92 | getInnerLogger().debug(format, arg1, arg2); 93 | } 94 | 95 | 96 | default void debug(String format, Object... arguments) { 97 | getInnerLogger().debug(format, arguments); 98 | } 99 | 100 | 101 | 102 | default void info(String msg) { 103 | getInnerLogger().info(msg); 104 | } 105 | 106 | 107 | default void info(String format, Object arg) { 108 | getInnerLogger().info(format,arg); 109 | } 110 | 111 | 112 | default void info(String format, Object arg1, Object arg2) { 113 | getInnerLogger().info(format, arg1, arg2); 114 | } 115 | 116 | 117 | default void info(String format, Object... arguments) { 118 | getInnerLogger().info(format, arguments); 119 | } 120 | 121 | 122 | default void warn(String msg) { 123 | getInnerLogger().warn(msg); 124 | } 125 | 126 | 127 | default void warn(String format, Object arg) { 128 | getInnerLogger().warn(format,arg); 129 | } 130 | 131 | 132 | default void warn(String format, Object... arguments) { 133 | getInnerLogger().warn(format,arguments); 134 | } 135 | 136 | 137 | default void warn(String format, Object arg1, Object arg2) { 138 | getInnerLogger().warn(format, arg1, arg2); 139 | } 140 | 141 | 142 | default void warn(String msg, Throwable t) { 143 | getInnerLogger().warn(msg,t); 144 | } 145 | 146 | 147 | 148 | default void error(String msg) { 149 | getInnerLogger().error(msg); 150 | } 151 | 152 | 153 | default void error(String format, Object arg) { 154 | getInnerLogger().error(format,arg); 155 | } 156 | 157 | 158 | default void error(String format, Object arg1, Object arg2) { 159 | getInnerLogger().error(format, arg1, arg2); 160 | } 161 | 162 | 163 | default void error(String format, Object... arguments) { 164 | getInnerLogger().error(format, arguments); 165 | } 166 | 167 | 168 | default void error(String msg, Throwable t) { 169 | getInnerLogger().error(msg,t); 170 | } 171 | 172 | /** 173 | * get actual logger 174 | * @return actual logger 175 | */ 176 | ModuleLogger getInnerLogger() ; 177 | } 178 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/logger/ModuleLoggerRepository.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.logger; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | /** 7 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 8 | * @since 2020/2/21 23:39 9 | */ 10 | public class ModuleLoggerRepository { 11 | private static final Map LOGGER_MAP = new ConcurrentHashMap<>(1); 12 | 13 | public static void put(String moduleName,ModuleLogger moduleLogger) { 14 | LOGGER_MAP.put(moduleName,moduleLogger); 15 | } 16 | 17 | public static ModuleLogger getModuleLogger(String moduleName){ 18 | return LOGGER_MAP.get(moduleName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/main/java/io/github/lvyahui8/sdk/logging/logger/RootLogger.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging.logger; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.LogConstants; 4 | import io.github.lvyahui8.sdk.logging.handler.DefaultLogHandler; 5 | import io.github.lvyahui8.sdk.logging.handler.LogHandler; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | /** 10 | * @author feego lvyahui8@gmail.com 11 | * @date 2021/5/1 12 | */ 13 | public class RootLogger extends DefaultModuleLogger { 14 | private RootLogger(String enumLoggerName, Logger logger, Logger monitorLogger, 15 | String fieldSeparator, LogHandler logHandler) { 16 | super(enumLoggerName, logger,logger, monitorLogger, fieldSeparator, logHandler); 17 | } 18 | 19 | private static RootLogger instance ; 20 | 21 | public static RootLogger getInstance() { 22 | if (instance == null) { 23 | Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); 24 | instance = new RootLogger("$rootLogger", 25 | logger,logger, LogConstants.Config.FIELD_SP,new DefaultLogHandler()); 26 | } 27 | return instance; 28 | } 29 | 30 | @Override 31 | public void setLogHandler(LogHandler logHandler) { 32 | super.setLogHandler(logHandler); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/test/java/io/github/lvyahui8/sdk/logging/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-logging/feego-common-logging/src/test/java/io/github/lvyahui8/sdk/logging/.gitignore -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/test/java/io/github/lvyahui8/sdk/logging/RepeatModuleTestApplication.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.DefaultLogConfiguration; 4 | import io.github.lvyahui8.sdk.logging.factory.LogbackModuleLoggerFactory; 5 | 6 | /** 7 | * @author feego lvyahui8@gmail.com 8 | * @date 2020/9/23 9 | */ 10 | public class RepeatModuleTestApplication { 11 | public static void main(String[] args) { 12 | LogbackModuleLoggerFactory factory = new LogbackModuleLoggerFactory(new DefaultLogConfiguration()); 13 | factory.initModuleLogger(TestLogger.class,TestLogger2.class); 14 | TestLogger.db.info("from testLogger"); 15 | TestLogger2.db.info("from testLogger2"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/test/java/io/github/lvyahui8/sdk/logging/TestApplication.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import io.github.lvyahui8.sdk.logging.configuration.DefaultLogConfiguration; 4 | import io.github.lvyahui8.sdk.logging.factory.LogbackModuleLoggerFactory; 5 | import io.github.lvyahui8.sdk.logging.factory.ModuleLoggerFactory; 6 | import io.github.lvyahui8.sdk.logging.logger.LogSchema; 7 | 8 | /** 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2020/9/23 11 | */ 12 | public class TestApplication { 13 | public static void main(String[] args) { 14 | // 只需初始化一次 15 | ModuleLoggerFactory factory = new LogbackModuleLoggerFactory(new DefaultLogConfiguration()); 16 | factory.initModuleLogger(TestLogger.class); 17 | // 在任意地方使用日志类 18 | TestLogger.cache.info("hello world"); 19 | TestLogger.db.info(LogSchema.biz("sql-trace").of("sql","select 1:").of("suc",true).of("cost",100)); 20 | TestLogger.mq.monitor(LogSchema.biz("order-topic-consume").of("body","{}")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/test/java/io/github/lvyahui8/sdk/logging/TestLogger.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.EnumModuleLogger; 4 | 5 | /** 6 | * @author feego lvyahui8@gmail.com 7 | * @date 2020/9/23 8 | */ 9 | public enum TestLogger implements EnumModuleLogger { 10 | cache, 11 | db, 12 | mq 13 | ; 14 | } 15 | -------------------------------------------------------------------------------- /feego-common-logging/feego-common-logging/src/test/java/io/github/lvyahui8/sdk/logging/TestLogger2.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.logging; 2 | 3 | import io.github.lvyahui8.sdk.logging.logger.EnumModuleLogger; 4 | 5 | /** 6 | * @author feego lvyahui8@gmail.com 7 | * @date 2020/9/23 8 | */ 9 | public enum TestLogger2 implements EnumModuleLogger { 10 | db, 11 | ; 12 | } 13 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-service-starter 14 | 15 | feego-common-service-starter 16 | 17 | 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | test 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-autoconfigure 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-configuration-processor 35 | true 36 | 37 | 38 | 39 | io.github.lvyahui8 40 | feego-common-service 41 | 42 | 43 | 44 | org.reflections 45 | reflections 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/java/io/github/lvyahui8/sdk/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-service/feego-common-service-starter/src/main/java/io/github/lvyahui8/sdk/.gitignore -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/java/io/github/lvyahui8/sdk/autoconfigure/CoreAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.autoconfigure; 2 | 3 | 4 | import io.github.lvyahui8.sdk.constants.Constant; 5 | import io.github.lvyahui8.sdk.properties.ExecutorProperties; 6 | import io.github.lvyahui8.sdk.properties.ServiceProperties; 7 | import io.github.lvyahui8.sdk.reddot.DefaultRedDotManager; 8 | import io.github.lvyahui8.sdk.reddot.RedDotManager; 9 | import io.github.lvyahui8.sdk.utils.AsyncTaskExecutorInitializer; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 12 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 13 | import org.springframework.boot.context.event.ApplicationReadyEvent; 14 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 15 | import org.springframework.context.ApplicationListener; 16 | import org.springframework.context.ConfigurableApplicationContext; 17 | import org.springframework.context.annotation.Bean; 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.data.redis.connection.RedisConnectionFactory; 20 | import org.springframework.data.redis.core.RedisTemplate; 21 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 22 | import org.springframework.data.redis.serializer.StringRedisSerializer; 23 | import org.springframework.scheduling.concurrent.CustomizableThreadFactory; 24 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 25 | 26 | import java.lang.ref.Reference; 27 | import java.util.concurrent.Executor; 28 | 29 | /** 30 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 31 | * @since 2020/2/12 18:00 32 | */ 33 | @Configuration 34 | @EnableConfigurationProperties({ServiceProperties.class}) 35 | public class CoreAutoConfiguration implements ApplicationListener { 36 | 37 | @Autowired 38 | ServiceProperties serviceProperties; 39 | 40 | 41 | @Bean("applicationTaskExecutor") 42 | public Executor applicationTaskExecutor(){ 43 | return taskExecutor(); 44 | } 45 | 46 | @Bean("taskScheduler") 47 | public Executor taskScheduler() { 48 | return taskExecutor(); 49 | } 50 | 51 | @Bean("taskExecutor") 52 | @ConditionalOnProperty(prefix = Constant.CONFIG_PREFIX ,name = ".executor.open",matchIfMissing = true) 53 | public Executor taskExecutor() { 54 | ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 55 | ExecutorProperties executorProperties = serviceProperties.getExecutor(); 56 | taskExecutor.setMaxPoolSize(executorProperties.getMaxPoolSize()); 57 | taskExecutor.setCorePoolSize(executorProperties.getCorePoolSize()); 58 | taskExecutor.setAllowCoreThreadTimeOut(executorProperties.isAllowCoreThreadTimeOut()); 59 | taskExecutor.setQueueCapacity(executorProperties.getQueueCapacity()); 60 | taskExecutor.setKeepAliveSeconds(executorProperties.getKeepAliveSeconds()); 61 | taskExecutor.setThreadFactory(new CustomizableThreadFactory("tp_")); 62 | AsyncTaskExecutorInitializer.initAsyncTaskExecutor(taskExecutor); 63 | 64 | return taskExecutor; 65 | } 66 | 67 | @Bean 68 | @ConditionalOnClass(RedisConnectionFactory.class) 69 | public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { 70 | RedisTemplate template = new RedisTemplate<>(); 71 | template.setConnectionFactory(connectionFactory); 72 | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 73 | GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); 74 | template.setDefaultSerializer(genericJackson2JsonRedisSerializer); 75 | template.setKeySerializer(stringRedisSerializer); 76 | template.setHashKeySerializer(stringRedisSerializer); 77 | template.setValueSerializer(genericJackson2JsonRedisSerializer); 78 | return template; 79 | } 80 | 81 | @Bean 82 | @ConditionalOnClass(RedisTemplate.class) 83 | public RedDotManager redDotManager(RedisTemplate redisTemplate) { 84 | return new DefaultRedDotManager(redisTemplate); 85 | } 86 | 87 | @Override 88 | public void onApplicationEvent(ApplicationReadyEvent event) { 89 | ConfigurableApplicationContext applicationContext = event.getApplicationContext(); 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/java/io/github/lvyahui8/sdk/autoconfigure/DistributeLockAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.autoconfigure; 2 | 3 | import io.github.lvyahui8.sdk.lock.LockFactory; 4 | import io.github.lvyahui8.sdk.lock.RedisLockFactory; 5 | import io.github.lvyahui8.sdk.properties.ServiceProperties; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.beans.factory.annotation.Qualifier; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.data.redis.core.RedisOperations; 12 | import org.springframework.data.redis.core.StringRedisTemplate; 13 | 14 | import java.util.concurrent.TimeUnit; 15 | 16 | /** 17 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 18 | * @since 2020/3/21 16:32 19 | */ 20 | @Configuration 21 | @ConditionalOnClass(RedisOperations.class) 22 | public class DistributeLockAutoConfiguration { 23 | @Autowired 24 | private ServiceProperties serviceProperties; 25 | 26 | @Bean 27 | public LockFactory lockFactory(@Qualifier("stringRedisTemplate") StringRedisTemplate stringRedisTemplate) { 28 | return new RedisLockFactory(stringRedisTemplate, 29 | serviceProperties.getDistributeLockTimeout(), TimeUnit.SECONDS); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/java/io/github/lvyahui8/sdk/autoconfigure/GroupServiceAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.autoconfigure; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.config.BeanPostProcessor; 5 | import org.springframework.boot.context.event.ApplicationReadyEvent; 6 | import org.springframework.context.ApplicationListener; 7 | 8 | /** 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2021/7/12 11 | */ 12 | public class GroupServiceAutoConfiguration implements BeanPostProcessor, ApplicationListener { 13 | 14 | @Override 15 | public void onApplicationEvent(ApplicationReadyEvent event) { 16 | 17 | } 18 | 19 | @Override 20 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 21 | 22 | return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/java/io/github/lvyahui8/sdk/properties/ExecutorProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.properties; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/2/12 18:17 8 | */ 9 | @Data 10 | public class ExecutorProperties { 11 | /** 12 | * 是否初始化线程池 13 | */ 14 | private boolean open = true; 15 | /** 16 | * 线程池核心线程数 17 | */ 18 | private int corePoolSize = Runtime.getRuntime().availableProcessors() * 2; 19 | /** 20 | * 线程池最大线程数 21 | */ 22 | private int maxPoolSize = Runtime.getRuntime().availableProcessors() * 7; 23 | /** 24 | * 非核心线程空闲存活时间, 单位为秒(s) 25 | */ 26 | private int keepAliveSeconds = 60; 27 | /** 28 | * 任务等待队列容量 29 | */ 30 | private int queueCapacity = Integer.MAX_VALUE; 31 | /** 32 | * 是否允许核心线程池也超时 33 | */ 34 | private boolean allowCoreThreadTimeOut = false; 35 | } 36 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/java/io/github/lvyahui8/sdk/properties/ServiceProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.properties; 2 | 3 | import io.github.lvyahui8.sdk.constants.Constant; 4 | import lombok.Data; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.boot.context.properties.NestedConfigurationProperty; 7 | 8 | /** 9 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 10 | * @since 2020/2/12 18:01 11 | */ 12 | @ConfigurationProperties(prefix = Constant.CONFIG_PREFIX) 13 | @Data 14 | public class ServiceProperties { 15 | @NestedConfigurationProperty 16 | ExecutorProperties executor = new ExecutorProperties(); 17 | 18 | Boolean distributeLockOpen = true; 19 | /** 20 | * redis 分布式失效时间, 单位秒(s) 21 | */ 22 | Long distributeLockTimeout = 30L; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.github.lvyahui8.sdk.autoconfigure.CoreAutoConfiguration,\ 3 | io.github.lvyahui8.sdk.autoconfigure.DistributeLockAutoConfiguration -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/main/resources/logback-spring.xml.backup: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service-starter/src/test/java/io/github/lvyahui8/sdk/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-service/feego-common-service-starter/src/test/java/io/github/lvyahui8/sdk/.gitignore -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-service 14 | 15 | feego-common-service 16 | 17 | 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | test 25 | 26 | 27 | 28 | org.projectlombok 29 | lombok 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-aop 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | 44 | 45 | io.github.lvyahui8 46 | spring-boot-data-aggregator-starter 47 | 48 | 49 | 50 | io.github.lvyahui8 51 | feego-common-logging-starter 52 | 53 | 54 | 55 | org.springframework.data 56 | spring-data-redis 57 | 58 | 59 | 60 | commons-codec 61 | commons-codec 62 | 63 | 64 | 65 | com.google.code.gson 66 | gson 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/.gitignore -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/constants/Constant.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.constants; 2 | 3 | /** 4 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 5 | * @since 2020/2/12 18:10 6 | */ 7 | public interface Constant { 8 | String CONFIG_PREFIX = "feego.common"; 9 | } 10 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/guid/GUIDGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.guid; 2 | 3 | import io.github.lvyahui8.sdk.utils.SystemUtils; 4 | 5 | import java.util.Random; 6 | import java.util.concurrent.atomic.AtomicInteger; 7 | import java.util.concurrent.atomic.AtomicLong; 8 | 9 | /** 10 | * 11 | * 12 | * 13 | * @author feego lvyahui8@gmail.com 14 | * @date 2020/10/1 15 | */ 16 | public class GUIDGenerator { 17 | 18 | private static final long IP_BITS = getIpBits(); 19 | 20 | private static final String HEX_IPV4_ADDR = getHexIpV4Addr(); 21 | 22 | private static final String RANDOM_SEED = getHexRandomSeed(); 23 | 24 | private static final long STR_GUID_MAX_SEQUENCE = 0xFFFFF; 25 | 26 | private static final long STR_GUID_MIN_SEQUENCE = 0x10000; 27 | 28 | private static final AtomicLong stringGuidCounter = new AtomicLong(STR_GUID_MIN_SEQUENCE); 29 | 30 | private static final AtomicInteger longGuidCounter = new AtomicInteger(0); 31 | 32 | private static final int SVR_ID_TYPE_GUID_MAX_SEQUENCE = ~(-1 << 12); 33 | 34 | private static String getHexRandomSeed() { 35 | Random r = new Random(System.nanoTime()); 36 | return Integer.toHexString( r.nextInt(0xEFF) + 0x100); 37 | } 38 | 39 | private static String getHexIpV4Addr() { 40 | String hexIpAddr = Long.toHexString(IP_BITS); 41 | if (hexIpAddr.length() != 8) { 42 | return "0" + hexIpAddr; 43 | } 44 | return hexIpAddr; 45 | } 46 | 47 | private static long getIpBits() { 48 | long ipBits = 0; 49 | String hostAddress = SystemUtils.getLocalAddress().getHostAddress(); 50 | String [] items = hostAddress.split("\\."); 51 | for (int i = 0; i < items.length; i++) { 52 | ipBits = ipBits | (Long.parseLong(items[i]) << (24 - (i << 3))); 53 | } 54 | return ipBits; 55 | } 56 | 57 | private static String hexCycleSequence() { 58 | while(true) { 59 | long current = stringGuidCounter.get(); 60 | long update = current + 1; 61 | if (update > STR_GUID_MAX_SEQUENCE) { 62 | update = STR_GUID_MIN_SEQUENCE; 63 | } 64 | if (stringGuidCounter.compareAndSet(current,update)) { 65 | return Long.toHexString(current); 66 | } 67 | } 68 | } 69 | 70 | private static int cycleSequence(int maxValue) { 71 | while(true) { 72 | int current = longGuidCounter.get(); 73 | int update = current + 1; 74 | if (update > maxValue) { 75 | update = 0; 76 | } 77 | if (longGuidCounter.compareAndSet(current,update)) { 78 | return current; 79 | } 80 | } 81 | } 82 | 83 | public static String createStringTypeGUID() { 84 | return HEX_IPV4_ADDR + RANDOM_SEED + Long.toHexString(System.currentTimeMillis()) + hexCycleSequence(); 85 | } 86 | 87 | public static long createLongTypeGUID(){ 88 | return createLongTypeGUID(32); 89 | } 90 | 91 | public static long createLongTypeGUID(int ipDigits) { 92 | return createLongTypeGUID(ipDigits,33 - ipDigits); 93 | } 94 | 95 | private static long createLongTypeGUID(int ipDigits,int seqDigits) { 96 | if (ipDigits <= 0 || seqDigits <=0 ) { 97 | throw new IllegalArgumentException("param > 0"); 98 | } 99 | if (ipDigits > 32) { 100 | throw new IllegalArgumentException("ipDigits <= 32"); 101 | } 102 | if (ipDigits + seqDigits != 33) { 103 | throw new IllegalArgumentException("ipDigits + seqDigits must be equal to 33."); 104 | } 105 | 106 | return (((System.currentTimeMillis() >> 10) & 0x3FFFFFFF) << 33) 107 | | ((IP_BITS & (0xFFFFFFFF >>> (32 - ipDigits))) << seqDigits) 108 | | cycleSequence(~(-1 << seqDigits)); 109 | } 110 | 111 | 112 | public static long createLongTypeGUIDBySvrId(int svrId) { 113 | if (svrId >= 1024 || svrId < 0) { 114 | throw new IllegalArgumentException("svrId >= 1024 || svrId < 0"); 115 | } 116 | 117 | return (System.currentTimeMillis() << 22) | (svrId << 12) | cycleSequence(SVR_ID_TYPE_GUID_MAX_SEQUENCE); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/lock/DistributedLock.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.lock; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | import java.util.concurrent.locks.Lock; 5 | 6 | /** 7 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 8 | * @since 2020/2/28 22:31 9 | */ 10 | public interface DistributedLock extends Lock { 11 | 12 | /** 13 | * 修改锁的超时释放时间 14 | * 15 | * @param timeout 超时时间 16 | * @param timeUnit 超时时间单位 17 | */ 18 | void setExpireTime(long timeout, TimeUnit timeUnit); 19 | } 20 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/lock/LockFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.lock; 2 | 3 | /** 4 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 5 | * @since 2020/2/28 22:45 6 | */ 7 | public interface LockFactory { 8 | /** 9 | * 获取分布式锁实例 10 | * - 此分布式锁并没有可重入特性。 11 | * - 为保证进程crash后, 占用的分布式锁释放掉, 锁必须超时失效 12 | * - 业务代码需要保证执行时间不超过锁的失效时间 13 | * 14 | * @param lockKey 锁的唯一标识 15 | * @param ns 每次为锁分配不同的值,以保证不会unlock掉别人的锁。如果没有很好的选择, 可以使用UUID 16 | * @return 锁实例 17 | */ 18 | DistributedLock newDistributeLock(String lockKey,Object ns) ; 19 | } 20 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/lock/NamedLockExecutor.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.lock; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.Callable; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | import java.util.concurrent.locks.Lock; 7 | import java.util.concurrent.locks.ReentrantLock; 8 | 9 | /** 10 | * @author feego lvyahui8@gmail.com 11 | * @date 2021/2/3 12 | */ 13 | public class NamedLockExecutor { 14 | private static final Map lockMap = new ConcurrentHashMap<>(); 15 | 16 | private static final ReentrantLock [] stripes = new ReentrantLock[1024]; 17 | 18 | static { 19 | for (int i = 0; i < stripes.length; i++) { 20 | stripes[i] = new ReentrantLock(); 21 | } 22 | } 23 | 24 | private static Lock getKeyLock(final String key) { 25 | ReentrantLock lock = lockMap.get(key); 26 | if (lock == null) { 27 | ReentrantLock stripeLock = getStripeLock(key); 28 | stripeLock.lock(); 29 | try { 30 | lock = lockMap.get(key); 31 | if (lock == null) { 32 | lockMap.put(key,lock = new ReentrantLock()); 33 | } 34 | } finally { 35 | stripeLock.unlock(); 36 | } 37 | } 38 | return lock; 39 | } 40 | 41 | private static void releaseKeyLock(final String key) { 42 | ReentrantLock stripeLock = getStripeLock(key); 43 | stripeLock.lock(); 44 | try { 45 | lockMap.remove(key); 46 | } finally { 47 | stripeLock.unlock(); 48 | } 49 | } 50 | 51 | 52 | private static ReentrantLock getStripeLock(String key) { 53 | return stripes[Math.abs(key.hashCode()) % stripes.length]; 54 | } 55 | 56 | public static RET exec(String key, Callable accessFunc,Callable loadFunc) throws Exception { 57 | RET ret = accessFunc.call(); 58 | if (ret == null) { 59 | ret = execWithNamedLock(key, accessFunc, loadFunc); 60 | } 61 | return ret; 62 | } 63 | 64 | public static RET execWithNamedLock(String key, Callable accessFunc, Callable loadFunc) throws Exception { 65 | RET ret; 66 | Lock lock = getKeyLock(key); 67 | lock.lock(); 68 | try { 69 | ret = accessFunc.call(); 70 | if (ret == null) { 71 | ret = loadFunc.call(); 72 | } 73 | return ret; 74 | } finally { 75 | lock.unlock(); 76 | releaseKeyLock(key); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/lock/RedisLockFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.lock; 2 | 3 | import org.springframework.data.redis.core.StringRedisTemplate; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 9 | * @since 2020/2/28 23:01 10 | */ 11 | public class RedisLockFactory implements LockFactory { 12 | 13 | private final StringRedisTemplate redisTemplate; 14 | 15 | private final Long defaultTimeout; 16 | 17 | private final TimeUnit defaultTimeUnit; 18 | 19 | public RedisLockFactory(StringRedisTemplate redisTemplate, Long defaultTimeout, TimeUnit defaultTimeUnit) { 20 | this.redisTemplate = redisTemplate; 21 | this.defaultTimeout = defaultTimeout; 22 | this.defaultTimeUnit = defaultTimeUnit; 23 | } 24 | 25 | @Override 26 | public DistributedLock newDistributeLock(String lockKey,Object ns) { 27 | return new RedisDistributedLock(redisTemplate,lockKey,ns,defaultTimeout,defaultTimeUnit); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/proxy/DecisionMaker.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.proxy; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.Type; 5 | 6 | /** 7 | * 实现类必须具备无参构造函数 8 | * 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2021/7/12 11 | */ 12 | public interface DecisionMaker { 13 | String decide(Type itf, Method method,Object [] methodArgs); 14 | } -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/proxy/GroupService.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.proxy; 2 | 3 | import org.springframework.core.annotation.AliasFor; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2021/7/12 11 | */ 12 | 13 | @Target(ElementType.TYPE) 14 | @Documented 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Service 17 | public @interface GroupService { 18 | Class value(); 19 | } 20 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/proxy/GroupServiceProxy.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.proxy; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Type; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2021/7/12 11 | */ 12 | public class GroupServiceProxy implements InvocationHandler { 13 | DecisionMaker decisionMaker; 14 | Map targetMap ; 15 | Type groupItf; 16 | 17 | public GroupServiceProxy(DecisionMaker decisionMaker, Map targetMap, Type groupItf) { 18 | this.decisionMaker = decisionMaker; 19 | this.targetMap = targetMap; 20 | this.groupItf = groupItf; 21 | } 22 | 23 | @Override 24 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 25 | String targetName = decisionMaker.decide(groupItf, method, args); 26 | return method.invoke(targetMap.get(targetName),args); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/reddot/RedDot.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.reddot; 2 | 3 | 4 | /** 5 | * @author feego lvyahui8@gmail.com 6 | * @date 2021/1/22 7 | */ 8 | public interface RedDot { 9 | String id(); 10 | 11 | RedDot parent(); 12 | 13 | boolean isLeaf(); 14 | } 15 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/reddot/RedDotInstance.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.reddot; 2 | 3 | import java.util.List; 4 | import java.util.Set; 5 | 6 | /** 7 | * @author feego lvyahui8@gmail.com 8 | * @date 2021/1/23 9 | */ 10 | public class RedDotInstance { 11 | Boolean active; 12 | /** 13 | * dimension key 14 | */ 15 | String dimKey; 16 | /** 17 | * redDot id 18 | */ 19 | String rid; 20 | /** 21 | * 实例版本号 22 | */ 23 | Long v; 24 | /** 25 | * 激活的时间戳 26 | */ 27 | Long activatedTs; 28 | /** 29 | * 引起此红点激活的原因 30 | */ 31 | Set cause; 32 | 33 | public Boolean getActive() { 34 | return active; 35 | } 36 | 37 | public void setActive(Boolean active) { 38 | this.active = active; 39 | } 40 | 41 | public String getDimKey() { 42 | return dimKey; 43 | } 44 | 45 | public void setDimKey(String dimKey) { 46 | this.dimKey = dimKey; 47 | } 48 | 49 | public String getRid() { 50 | return rid; 51 | } 52 | 53 | public void setRid(String rid) { 54 | this.rid = rid; 55 | } 56 | 57 | public Long getV() { 58 | return v; 59 | } 60 | 61 | public void setV(Long v) { 62 | this.v = v; 63 | } 64 | 65 | public Long getActivatedTs() { 66 | return activatedTs; 67 | } 68 | 69 | public void setActivatedTs(Long activatedTs) { 70 | this.activatedTs = activatedTs; 71 | } 72 | 73 | public Set getCause() { 74 | return cause; 75 | } 76 | 77 | public void setCause(Set cause) { 78 | this.cause = cause; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/reddot/RedDotManager.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.reddot; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @author feego lvyahui8@gmail.com 7 | * @date 2021/1/22 8 | */ 9 | public interface RedDotManager { 10 | /** 11 | * 激活key对应的红点 12 | * 13 | * @param key 红点维度 14 | * @param redDots 待激活红点列表 15 | */ 16 | void enable(Object key, RedDot... redDots); 17 | 18 | /** 19 | * 带版本号激活红点,只有版本号比记录的红点大才能激活红点 20 | * 21 | * @param key 红点维度 22 | * @param redDot 红点 23 | * @param version 版本号 24 | */ 25 | void enable(Object key, RedDot redDot,Long version); 26 | 27 | /** 28 | * 判断某个红点是否被激活 29 | * 30 | * @param key 红点维度 31 | * @param redDot 红点 32 | * @return 是否激活 33 | */ 34 | boolean isActive(Object key, RedDot redDot); 35 | 36 | /** 37 | * 一次性查询多个红点是否激活 38 | * 39 | * @param key 红点维度 40 | * @param redDots 红点列表 41 | * @return 激活map 42 | */ 43 | Map isActiveMap(Object key, RedDot... redDots); 44 | 45 | /** 46 | * 消除红点 47 | * 48 | * @param key 红点维度 49 | * @param redDots 红点列表 50 | */ 51 | void disable(Object key, RedDot ... redDots); 52 | } 53 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/security/CryptologySecurityUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.security; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.security.*; 6 | import java.security.spec.PKCS8EncodedKeySpec; 7 | import java.security.spec.X509EncodedKeySpec; 8 | 9 | /** 10 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 11 | * @since 2020/3/13 21:55 12 | */ 13 | @SuppressWarnings({"unused"}) 14 | public class CryptologySecurityUtils { 15 | public static byte [] sign(byte [] textBytes,byte[] encodedPrivateKey,String signatureAlgorithm) throws GeneralSecurityException { 16 | String keyAlgorithm = getKeyAlgorithm(signatureAlgorithm); 17 | PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); 18 | KeyFactory factory = KeyFactory.getInstance(keyAlgorithm); 19 | PrivateKey privateKey = factory.generatePrivate(keySpec); 20 | Signature signature = Signature.getInstance(signatureAlgorithm); 21 | signature.initSign(privateKey); 22 | signature.update(textBytes); 23 | return signature.sign(); 24 | } 25 | 26 | public static boolean verify(byte [] textBytes,byte [] signedBytes,byte [] encodedPublicKey,String signatureAlgorithm) throws GeneralSecurityException { 27 | String keyAlgorithm = getKeyAlgorithm(signatureAlgorithm); 28 | X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedPublicKey); 29 | KeyFactory factory = KeyFactory.getInstance(keyAlgorithm); 30 | PublicKey publicKey = factory.generatePublic(keySpec); 31 | Signature signature = Signature.getInstance(signatureAlgorithm); 32 | signature.initVerify(publicKey); 33 | signature.update(textBytes); 34 | return signature.verify(signedBytes); 35 | } 36 | 37 | public static String getKeyAlgorithm(String signAlgorithm) { 38 | /* 39 | * MD2withRSA,SHA1withRSA,SHA256withRSA,SHA384withRSA,SHA512withRSA.... 40 | * SHA1withDSA,SHA256withDSA,SHA512withDSA... 41 | */ 42 | return StringUtils.substringAfter(signAlgorithm, "with"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/utils/AsyncTaskExecutor.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.utils; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import java.util.concurrent.Callable; 8 | import java.util.concurrent.Executor; 9 | import java.util.concurrent.ExecutorService; 10 | import java.util.concurrent.Future; 11 | 12 | /** 13 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 14 | * @since 2020/2/12 18:21 15 | */ 16 | @SuppressWarnings("unused") 17 | public class AsyncTaskExecutor { 18 | 19 | @Setter(AccessLevel.PACKAGE) 20 | @Getter(AccessLevel.PUBLIC) 21 | private static Executor executor; 22 | 23 | public static void execute(Runnable r) { 24 | executor.execute(r); 25 | } 26 | 27 | public static Future submit(Callable c) { 28 | if (executor instanceof org.springframework.core.task.AsyncTaskExecutor) { 29 | return ((org.springframework.core.task.AsyncTaskExecutor) executor).submit(c); 30 | } else if (executor instanceof ExecutorService) { 31 | return ((ExecutorService) executor).submit(c); 32 | } else { 33 | throw new UnsupportedOperationException("Tasks that return data in the future are not supported."); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/utils/AsyncTaskExecutorInitializer.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.utils; 2 | 3 | import java.util.concurrent.Executor; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/2/18 21:51 8 | */ 9 | public class AsyncTaskExecutorInitializer { 10 | public static void initAsyncTaskExecutor(Executor executor) { 11 | if (AsyncTaskExecutor.getExecutor() != null) { 12 | throw new UnsupportedOperationException("The asynchronous task executor can only be initialized once."); 13 | } 14 | AsyncTaskExecutor.setExecutor(executor); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/utils/RetryUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.utils; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | /** 6 | * @author feego lvyahui8@gmail.com 7 | * @date 2021/1/20 8 | */ 9 | public abstract class RetryUtils { 10 | public static RET_TYPE retryGet(Callable func,int retryNum) throws Exception { 11 | while(retryNum-- > 0) { 12 | try { 13 | return func.call(); 14 | } catch (Exception e) { 15 | if (retryNum == 0) { 16 | throw e; 17 | } 18 | } 19 | } 20 | // 不可达 21 | throw new IllegalArgumentException("retryNum must be greater than 0"); 22 | } 23 | 24 | public static void retryDo(Runnable func,int retryNum) { 25 | try { 26 | retryGet(() -> {func.run(); return null;},retryNum); 27 | } catch (Exception e) { 28 | // Runnable 只能抛出 RuntimeException 29 | throw (RuntimeException) e; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/utils/SystemUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.utils; 2 | 3 | import java.net.InetAddress; 4 | import java.net.NetworkInterface; 5 | import java.net.SocketException; 6 | import java.util.Enumeration; 7 | 8 | /** 9 | * @author feego lvyahui8@gmail.com 10 | * @date 2020/10/2 11 | */ 12 | public class SystemUtils { 13 | public static InetAddress getLocalAddress() { 14 | InetAddress localHost; 15 | 16 | try { 17 | localHost = InetAddress.getLocalHost(); 18 | } catch (Exception e) { 19 | throw new RuntimeException("",e); 20 | } 21 | 22 | if (localHost.isLoopbackAddress()) { 23 | Enumeration interfaces; 24 | try { 25 | interfaces = NetworkInterface.getNetworkInterfaces(); 26 | } catch (SocketException e) { 27 | throw new RuntimeException("",e); 28 | } 29 | while(interfaces.hasMoreElements()) { 30 | NetworkInterface element = interfaces.nextElement(); 31 | Enumeration addresses = element.getInetAddresses(); 32 | while(addresses.hasMoreElements()) { 33 | InetAddress address = addresses.nextElement(); 34 | if (address.isLoopbackAddress()) { 35 | continue; 36 | } 37 | 38 | if (address.getHostAddress().contains(":")) { 39 | // ipv6 40 | continue; 41 | } 42 | return address; 43 | } 44 | } 45 | } 46 | return localHost; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/weak/OnException.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.weak; 2 | 3 | /** 4 | * @author feego lvyahui8@gmail.com 5 | * @date 2021/9/18 6 | */ 7 | @FunctionalInterface 8 | public interface OnException { 9 | R apply(Exception e); 10 | } 11 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/java/io/github/lvyahui8/sdk/weak/WeakDependencyGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.weak; 2 | 3 | import io.github.lvyahui8.sdk.utils.AsyncTaskExecutor; 4 | 5 | import java.lang.reflect.ParameterizedType; 6 | import java.lang.reflect.Type; 7 | import java.util.HashMap; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.concurrent.*; 12 | import java.util.function.Supplier; 13 | 14 | /** 15 | * @author feego lvyahui8@gmail.com 16 | * @date 2021/9/18 17 | */ 18 | public class WeakDependencyGroup { 19 | 20 | public List> futures = new LinkedList<>(); 21 | 22 | public static class WeakDependencyItem { 23 | CompletableFuture future; 24 | OnException onException; 25 | } 26 | 27 | public List> weakDependencyItems; 28 | 29 | public WeakDependencyGroup add(Supplier weakDependency, OnException onException) { 30 | WeakDependencyItem weakDependencyItem = new WeakDependencyItem<>(); 31 | try { 32 | weakDependencyItem.future = CompletableFuture.supplyAsync(() -> { 33 | try { 34 | return weakDependency.get(); 35 | } catch (Exception e) { 36 | return onException.apply(e); 37 | } 38 | }, AsyncTaskExecutor.getExecutor()); 39 | futures.add(weakDependencyItem.future); 40 | } catch (Exception ignored) { 41 | } 42 | weakDependencyItem.onException = onException; 43 | return this; 44 | } 45 | 46 | public Map get(long timeoutMs) { 47 | if (timeoutMs > 0){ 48 | CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); 49 | try { 50 | future.get(timeoutMs, TimeUnit.MICROSECONDS); 51 | } catch (Exception ignored) { 52 | } 53 | } 54 | Map res = new HashMap<>(); 55 | for (WeakDependencyItem weakDependencyItem : weakDependencyItems) { 56 | Type retType = ((ParameterizedType) weakDependencyItem.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 57 | Object ret = null; 58 | if (weakDependencyItem.future == null) { 59 | ret = weakDependencyItem.onException.apply(new TimeoutException()); 60 | } else { 61 | try { 62 | ret = weakDependencyItem.future.getNow(null); 63 | } catch (Exception e) { 64 | ret = weakDependencyItem.onException.apply(e); 65 | } 66 | } 67 | res.put(retType,ret); 68 | } 69 | return res; 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/main/resources/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-service/feego-common-service/src/main/resources/.gitignore -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/test/java/io/github/lvyahui8/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-service/feego-common-service/src/test/java/io/github/lvyahui8/.gitignore -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/test/java/io/github/lvyahui8/sdk/guid/GUIDGeneratorTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.sdk.guid; 2 | 3 | import io.github.lvyahui8.sdk.utils.SystemUtils; 4 | import org.junit.After; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.util.concurrent.CountDownLatch; 9 | 10 | /** 11 | * @author feego lvyahui8@gmail.com 12 | * @date 2020/10/2 13 | */ 14 | public class GUIDGeneratorTest { 15 | 16 | static 17 | class Worker extends Thread { 18 | CountDownLatch latch ; 19 | long target ; 20 | public Worker(CountDownLatch latch,long target) { 21 | this.latch = latch; 22 | this.target = target; 23 | } 24 | 25 | @Override 26 | public void run() { 27 | int i = 0; 28 | try { 29 | while(i++ < target) { 30 | GUIDGenerator.createStringTypeGUID(); 31 | } 32 | } finally { 33 | latch.countDown(); 34 | } 35 | } 36 | } 37 | 38 | @Before 39 | public void setUp() throws Exception { 40 | } 41 | 42 | @After 43 | public void tearDown() throws Exception { 44 | 45 | } 46 | 47 | @Test 48 | public void testCreateStringTypeGUIDBasic() throws Exception { 49 | for (int i = 0; i < 10; i++) { 50 | System.out.println(GUIDGenerator.createStringTypeGUID()); 51 | } 52 | 53 | for (int i = 0; i < 0xFFFFF; i++) { 54 | GUIDGenerator.createStringTypeGUID(); 55 | } 56 | } 57 | 58 | @Test 59 | public void testCreateLongTypeGUIDBasic() throws Exception { 60 | System.out.println(SystemUtils.getLocalAddress().getHostAddress()); 61 | for (int i = 0; i < 10; i++) { 62 | long guid = GUIDGenerator.createLongTypeGUID(); 63 | System.out.println(Long.toBinaryString(guid) + ' ' + guid); 64 | } 65 | System.out.println(); 66 | for (int i = 0; i < 10; i++) { 67 | System.out.println(Long.toBinaryString(GUIDGenerator.createLongTypeGUID(24))); 68 | } 69 | System.out.println(); 70 | for (int i = 0; i < 100; i++) { 71 | /* 72 | * 节点不多时,很可能节点ip的差异只在低16位,此时可以设置ipDigits为16位,递增值扩大到了 73 | */ 74 | System.out.println(Long.toBinaryString(GUIDGenerator.createLongTypeGUID(16))); 75 | } 76 | } 77 | 78 | @Test 79 | public void testCreateLongTypeGUIDBySvrId() throws Exception { 80 | for (int i = 0; i < 10; i++) { 81 | System.out.println(Long.toHexString(GUIDGenerator.createLongTypeGUIDBySvrId(10))); 82 | System.out.println(Long.toHexString(GUIDGenerator.createLongTypeGUIDBySvrId(23))); 83 | } 84 | } 85 | 86 | @Test 87 | public void testCreateStringTypeGUIDPerformance() throws Exception { 88 | int n = Runtime.getRuntime().availableProcessors() * 3; 89 | CountDownLatch latch = new CountDownLatch(n); 90 | long target = 10000000; 91 | long begin = System.currentTimeMillis(); 92 | // 单线程 1千万 93 | for (int i = 0; i < target * 10; i++) { 94 | GUIDGenerator.createStringTypeGUID(); 95 | } 96 | System.out.println("cost time:" + (System.currentTimeMillis() - begin) + " ms"); 97 | // 多线程 98 | begin = System.currentTimeMillis(); 99 | for (int i = 0 ; i < n ; i++) { 100 | Worker worker = new Worker(latch,target); 101 | worker.start(); 102 | } 103 | latch.await(); 104 | System.out.println("cost time:" + (System.currentTimeMillis() - begin) + " ms"); 105 | } 106 | } -------------------------------------------------------------------------------- /feego-common-service/feego-common-service/src/test/java/io/github/lvyahui8/security/CryptologySecurityUtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.security; 2 | 3 | import io.github.lvyahui8.sdk.security.CryptologySecurityUtils; 4 | import org.apache.commons.codec.binary.Base64; 5 | import org.junit.Assert; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import java.security.KeyPair; 10 | import java.security.KeyPairGenerator; 11 | 12 | /** 13 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 14 | * @since 2020/3/13 22:34 15 | */ 16 | public class CryptologySecurityUtilsTest 17 | { 18 | 19 | public static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; 20 | 21 | private KeyPair keyPair; 22 | 23 | @Before 24 | public void setUp() throws Exception { 25 | KeyPairGenerator kpGen = KeyPairGenerator.getInstance(CryptologySecurityUtils.getKeyAlgorithm(SIGNATURE_ALGORITHM)); 26 | kpGen.initialize(1024); 27 | this.keyPair = kpGen.generateKeyPair(); 28 | } 29 | 30 | @Test 31 | public void testSignature() throws Exception { 32 | String text = "hello, world"; 33 | byte[] sign = CryptologySecurityUtils.sign(text.getBytes(), keyPair.getPrivate().getEncoded(), SIGNATURE_ALGORITHM); 34 | System.out.println(new String(new Base64().encode(sign))); 35 | Assert.assertTrue(CryptologySecurityUtils.verify(text.getBytes(),sign,keyPair.getPublic().getEncoded(),SIGNATURE_ALGORITHM)); 36 | Assert.assertFalse(CryptologySecurityUtils.verify(text.substring(1).getBytes(), sign, keyPair.getPublic().getEncoded(), SIGNATURE_ALGORITHM)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-web-starter 14 | 15 | feego-common-web-starter 16 | 17 | 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | test 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-autoconfigure 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-configuration-processor 35 | true 36 | 37 | 38 | 39 | io.github.lvyahui8 40 | feego-common-web 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/src/main/java/io/github/lvyahui8/web/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-web/feego-common-web-starter/src/main/java/io/github/lvyahui8/web/.gitignore -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/src/main/java/io/github/lvyahui8/web/autoconfigure/WebAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.autoconfigure; 2 | 3 | import io.github.lvyahui8.sdk.constants.Constant; 4 | import io.github.lvyahui8.web.properties.WebProperties; 5 | import io.github.lvyahui8.web.response.RestResponseFormatter; 6 | import io.github.lvyahui8.web.signature.SignatureService; 7 | import io.github.lvyahui8.web.signature.impl.SignatureServiceImpl; 8 | import io.github.lvyahui8.web.wrapper.SignatureFilter; 9 | import io.github.lvyahui8.web.wrapper.TraceFilter; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 12 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 13 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 14 | import org.springframework.context.annotation.Bean; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 17 | 18 | /** 19 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 20 | * @since 2020/2/16 22:33 21 | */ 22 | @Configuration 23 | @EnableConfigurationProperties({WebProperties.class}) 24 | public class WebAutoConfiguration implements WebMvcConfigurer { 25 | 26 | @Autowired 27 | WebProperties webProperties; 28 | 29 | @Bean 30 | public WebMvcBeanPostProcessor webMvcBeanPostProcessor() { 31 | return new WebMvcBeanPostProcessor(); 32 | } 33 | 34 | @Bean 35 | @ConditionalOnProperty(prefix = Constant.CONFIG_PREFIX,name = ".web.formatResponse") 36 | public RestResponseFormatter restResponseFormatter() { 37 | return new RestResponseFormatter(); 38 | } 39 | 40 | @Bean 41 | @ConditionalOnProperty(prefix = Constant.CONFIG_PREFIX,name = ".web.security.signature.open",matchIfMissing = false) 42 | public SignatureService signatureService() { 43 | return new SignatureServiceImpl(webProperties.getSecurity().getSignature()); 44 | } 45 | 46 | /// @Bean 47 | public FilterRegistrationBean filterRegistrationBean(SignatureService signatureService) { 48 | FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); 49 | registrationBean.setFilter(new SignatureFilter(signatureService)); 50 | registrationBean.setName("feegoSignatureFilter"); 51 | registrationBean.addUrlPatterns("/*"); 52 | return registrationBean; 53 | } 54 | 55 | @Bean 56 | public FilterRegistrationBean traceFilter() { 57 | FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); 58 | registrationBean.setFilter(new TraceFilter()); 59 | registrationBean.setName("traceFilter"); 60 | registrationBean.addUrlPatterns("/*"); 61 | return registrationBean; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/src/main/java/io/github/lvyahui8/web/autoconfigure/WebMvcBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.autoconfigure; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.config.BeanPostProcessor; 5 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 6 | 7 | /** 8 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 9 | * @since 2020/2/16 23:30 10 | */ 11 | public class WebMvcBeanPostProcessor implements BeanPostProcessor { 12 | 13 | @Override 14 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 15 | return bean; 16 | } 17 | 18 | @Override 19 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 20 | if (bean instanceof RequestMappingHandlerAdapter) { 21 | RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean; 22 | 23 | } 24 | return bean; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/src/main/java/io/github/lvyahui8/web/properties/SecurityProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.properties; 2 | 3 | import io.github.lvyahui8.web.signature.SignatureSettings; 4 | import lombok.Data; 5 | import org.springframework.boot.context.properties.NestedConfigurationProperty; 6 | 7 | /** 8 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 9 | * @since 2020/3/14 0:39 10 | */ 11 | @Data 12 | public class SecurityProperties { 13 | @NestedConfigurationProperty 14 | SignatureSettings signature; 15 | } 16 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/src/main/java/io/github/lvyahui8/web/properties/WebProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.properties; 2 | 3 | import io.github.lvyahui8.sdk.constants.Constant; 4 | import lombok.Data; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.boot.context.properties.NestedConfigurationProperty; 7 | 8 | /** 9 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 10 | * @since 2020/2/16 22:46 11 | */ 12 | @ConfigurationProperties(prefix = Constant.CONFIG_PREFIX + ".web") 13 | @Data 14 | public class WebProperties { 15 | /** 16 | * 格式化响应 17 | */ 18 | boolean formatResponse = true; 19 | 20 | @NestedConfigurationProperty 21 | SecurityProperties security; 22 | } 23 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.github.lvyahui8.web.autoconfigure.WebAutoConfiguration -------------------------------------------------------------------------------- /feego-common-web/feego-common-web-starter/src/test/java/io/github/lvyahui8/web/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-web/feego-common-web-starter/src/test/java/io/github/lvyahui8/web/.gitignore -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | feego-common 7 | io.github.lvyahui8 8 | 1.2.2 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | feego-common-web 14 | 15 | feego-common-web 16 | 17 | 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | test 25 | 26 | 27 | io.github.lvyahui8 28 | feego-common-service-starter 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-validation 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | 42 | commons-io 43 | commons-io 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/.gitignore -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/code/C.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.code; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 10 | * @since 2020/3/18 21:39 11 | */ 12 | @Target(ElementType.FIELD) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface C { 15 | int value(); 16 | String msg() default ""; 17 | } 18 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/code/Code.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.code; 2 | 3 | /** 4 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 5 | * @since 2020/3/19 21:57 6 | */ 7 | class Code { 8 | private String code; 9 | private String msg; 10 | 11 | String getCode() { 12 | return code; 13 | } 14 | 15 | void setCode(String code) { 16 | this.code = code; 17 | } 18 | 19 | String getMsg() { 20 | return msg; 21 | } 22 | 23 | public void setMsg(String msg) { 24 | this.msg = msg; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/code/CodePrefix.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.code; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 10 | * @since 2020/3/19 21:48 11 | */ 12 | @Target(ElementType.TYPE) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface CodePrefix { 15 | String value(); 16 | } 17 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/code/CodeRepository.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.code; 2 | 3 | 4 | import java.util.Map; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | /** 8 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 9 | * @since 2020/3/18 21:48 10 | */ 11 | class CodeRepository { 12 | private static final Map CODE_MAP = new ConcurrentHashMap<>(); 13 | 14 | private static final String LEFT_PAD = System.getProperty("feego.common.msgCode.leftPad", "5"); 15 | 16 | static Code get(Object object) { 17 | if (CODE_MAP.containsKey(object)) { 18 | return CODE_MAP.get(object); 19 | } 20 | try { 21 | Enum codeEnum = (Enum) object; 22 | CodePrefix codePrefix = object.getClass().getAnnotation(CodePrefix.class); 23 | C c = object.getClass().getField(codeEnum.name()).getAnnotation(C.class); 24 | Code code = new Code(); 25 | int cod = c != null ? c.value() : codeEnum.ordinal(); 26 | code.setCode(codePrefix != null ? String.format("%s%0"+LEFT_PAD+"d", codePrefix.value(), cod) 27 | : String.valueOf(cod)); 28 | code.setMsg(c != null && c.msg().length() > 0 ? c.msg() : codeEnum.name()); 29 | CODE_MAP.put(object,code); 30 | return code; 31 | } catch (NoSuchFieldException e) { 32 | throw new Error(e); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/code/MsgCode.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.code; 2 | 3 | 4 | /** 5 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 6 | * @since 2020/3/18 21:38 7 | */ 8 | public interface MsgCode { 9 | /** 10 | * 获取消息 11 | * 12 | * @return msg 13 | */ 14 | default String getMsg() { 15 | return CodeRepository.get(this).getMsg(); 16 | } 17 | 18 | /** 19 | * 获取code 20 | * 21 | * @return code 22 | */ 23 | default String getCode() { 24 | return CodeRepository.get(this).getCode(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/constant/WebConstant.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.constant; 2 | 3 | /** 4 | * @author yahui.lv lvyahui8@gmail.com 5 | * @date 2020/4/4 23:36 6 | */ 7 | public interface WebConstant { 8 | public enum HttpHeader { 9 | /** 10 | * 常用头 11 | */ 12 | X_SIGNATURE("X-Feego-Signature"), 13 | ; 14 | 15 | private String key; 16 | 17 | HttpHeader(String key) { 18 | this.key = key; 19 | } 20 | 21 | public String getKey() { 22 | return key; 23 | } 24 | } 25 | 26 | public interface SignatureHeaderKey { 27 | String CLIENT_ID = "clientId"; 28 | String ALGORITHM = "algorithm"; 29 | String SIGNATURE = "signature"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/context/RequestContext.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.context; 2 | 3 | /** 4 | * @author feego lvyahui8@gmail.com 5 | * @date 2020/10/1 6 | */ 7 | public class RequestContext { 8 | public static final ThreadLocal REQUEST_LOCAL = new ThreadLocal<>(); 9 | 10 | public static void putRequest(RequestMessage message) { 11 | REQUEST_LOCAL.set(message); 12 | } 13 | 14 | public static String getTraceId() { 15 | RequestMessage message = REQUEST_LOCAL.get(); 16 | return message != null ? message.getTraceId() : ""; 17 | } 18 | 19 | public static boolean isStressTraffic() { 20 | return REQUEST_LOCAL.get().isStressTraffic(); 21 | } 22 | 23 | public static void clean() { 24 | REQUEST_LOCAL.remove(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/context/RequestMessage.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.context; 2 | 3 | /** 4 | * @author feego lvyahui8@gmail.com 5 | * @date 2020/10/10 6 | */ 7 | public class RequestMessage { 8 | String traceId; 9 | boolean stressTraffic; 10 | 11 | public String getTraceId() { 12 | return traceId; 13 | } 14 | 15 | public void setTraceId(String traceId) { 16 | this.traceId = traceId; 17 | } 18 | 19 | public boolean isStressTraffic() { 20 | return stressTraffic; 21 | } 22 | 23 | public void setStressTraffic(boolean stressTraffic) { 24 | this.stressTraffic = stressTraffic; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/request/SignedRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.request; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/3/14 0:30 8 | */ 9 | @Data 10 | public class SignedRequest { 11 | Object body; 12 | String signature; 13 | } 14 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/response/RestResponseFormatter.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.response; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.core.MethodParameter; 8 | import org.springframework.http.HttpHeaders; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.http.server.ServerHttpRequest; 11 | import org.springframework.http.server.ServerHttpResponse; 12 | import org.springframework.http.server.ServletServerHttpResponse; 13 | import org.springframework.web.bind.annotation.ExceptionHandler; 14 | import org.springframework.web.bind.annotation.ResponseBody; 15 | import org.springframework.web.bind.annotation.RestControllerAdvice; 16 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | 20 | /** 21 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 22 | * @since 2020/2/16 23:06 23 | */ 24 | @RestControllerAdvice 25 | @Slf4j 26 | public class RestResponseFormatter implements ResponseBodyAdvice { 27 | 28 | @Autowired 29 | ObjectMapper objectMapper ; 30 | 31 | @Override 32 | public boolean supports(MethodParameter methodParameter, Class aClass) { 33 | return true; 34 | } 35 | 36 | @Override 37 | public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { 38 | if (o instanceof String) { 39 | try { 40 | ((ServletServerHttpResponse) serverHttpResponse).getServletResponse().setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); 41 | return objectMapper.writeValueAsString(StandardResponse.success(o)); 42 | } catch (JsonProcessingException e) { 43 | throw new RuntimeException("Serialized response failed",e); 44 | } 45 | } 46 | if (o instanceof StandardResponse) { 47 | return o; 48 | } 49 | return StandardResponse.success(o); 50 | } 51 | 52 | @ExceptionHandler(Exception.class) 53 | public @ResponseBody Object handle(HttpServletRequest request,Exception e) { 54 | log.error("request uri:" +request.getRequestURL() ,e); 55 | return StandardResponse.success(null); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/response/StandardResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.response; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 7 | * @since 2020/2/18 21:58 8 | */ 9 | @Data 10 | public class StandardResponse { 11 | private String code; 12 | private String msg; 13 | private Object data; 14 | private int cost; 15 | 16 | public static StandardResponse success(Object data) { 17 | StandardResponse response = new StandardResponse(); 18 | response.setCode("0"); 19 | response.setMsg("success"); 20 | response.setData(data); 21 | return response; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/signature/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/signature/.gitignore -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/signature/SignatureService.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.signature; 2 | 3 | /** 4 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 5 | * @since 2020/3/12 21:20 6 | */ 7 | public interface SignatureService { 8 | /** 9 | * 对响应加签 10 | * 11 | * @param text 待签名内容 12 | * @return encodedSignature 13 | */ 14 | String signResponse(String text); 15 | 16 | /** 17 | * 对请求验签 18 | * 19 | * @param text 待签名内容 20 | * @param encodedSignature 已编码签名 21 | * @return 签名是否匹配 22 | */ 23 | boolean verifyRequest(String text,String encodedSignature); 24 | } 25 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/signature/SignatureSettings.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.signature; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 9 | * @since 2020/3/15 1:26 10 | */ 11 | @Data 12 | public class SignatureSettings { 13 | Boolean open = false; 14 | 15 | List clients; 16 | 17 | String algorithm = "SHA1withRSA"; 18 | 19 | String defaultSignResponsePrivateKey; 20 | 21 | String defaultVerifyRequestPublicKey; 22 | 23 | @Data 24 | public static class ClientApplication { 25 | String appId; 26 | String verifyRequestPublicKey; 27 | String signResponsePrivateKey; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/signature/impl/SignatureServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.signature.impl; 2 | 3 | import io.github.lvyahui8.sdk.security.CryptologySecurityUtils; 4 | import io.github.lvyahui8.web.signature.SignatureService; 5 | import io.github.lvyahui8.web.signature.SignatureSettings; 6 | import org.apache.commons.codec.binary.Base64; 7 | 8 | import java.security.GeneralSecurityException; 9 | 10 | /** 11 | * @author lvyahui (lvyahui8@gmail.com,lvyahui8@126.com) 12 | * @since 2020/3/15 1:23 13 | */ 14 | public class SignatureServiceImpl implements SignatureService { 15 | 16 | private SignatureSettings signatureSettings; 17 | 18 | private byte [] verifyRequestKey ; 19 | 20 | private byte [] signResponseKey; 21 | 22 | Base64 base64 ; 23 | 24 | public SignatureServiceImpl(SignatureSettings signatureSettings) { 25 | this.signatureSettings = signatureSettings; 26 | this.base64 = new Base64(); 27 | verifyRequestKey = base64.decode(signatureSettings.getDefaultVerifyRequestPublicKey()); 28 | signResponseKey = base64.decode(signatureSettings.getDefaultSignResponsePrivateKey()); 29 | } 30 | 31 | @Override 32 | public String signResponse(String text) { 33 | try { 34 | return base64.encodeAsString(CryptologySecurityUtils.sign(text.getBytes(),signResponseKey,signatureSettings.getAlgorithm())); 35 | } catch (GeneralSecurityException e) { 36 | return null; 37 | } 38 | } 39 | 40 | @Override 41 | public boolean verifyRequest(String text, String encodedSignature) { 42 | try { 43 | return CryptologySecurityUtils.verify(text.getBytes(),base64.decode(encodedSignature),verifyRequestKey,signatureSettings.getAlgorithm()); 44 | } catch (GeneralSecurityException e) { 45 | return false; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/wrapper/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/wrapper/.gitignore -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/wrapper/ResettableHttpServletRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.wrapper; 2 | 3 | 4 | import org.apache.commons.io.IOUtils; 5 | 6 | import javax.servlet.ReadListener; 7 | import javax.servlet.ServletInputStream; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletRequestWrapper; 10 | import java.io.BufferedReader; 11 | import java.io.ByteArrayInputStream; 12 | import java.io.IOException; 13 | import java.io.InputStreamReader; 14 | import java.nio.charset.StandardCharsets; 15 | 16 | /** 17 | * @author yahui.lv lvyahui8@gmail.com 18 | * @date 2020/4/4 23:23 19 | */ 20 | public class ResettableHttpServletRequest extends HttpServletRequestWrapper { 21 | 22 | String httpBody; 23 | 24 | public ResettableHttpServletRequest(HttpServletRequest request) throws IOException { 25 | super(request); 26 | httpBody = IOUtils.toString(request.getReader()); 27 | } 28 | 29 | @Override 30 | public ServletInputStream getInputStream() throws IOException { 31 | ByteArrayInputStream inputStream = new ByteArrayInputStream(httpBody.getBytes()); 32 | return new ServletInputStream() { 33 | @Override 34 | public boolean isFinished() { 35 | return inputStream.available() == 0; 36 | } 37 | 38 | @Override 39 | public boolean isReady() { 40 | return true; 41 | } 42 | 43 | @Override 44 | public void setReadListener(ReadListener readListener) { 45 | 46 | } 47 | 48 | @Override 49 | public int read() throws IOException { 50 | return inputStream.read(); 51 | } 52 | }; 53 | } 54 | 55 | @Override 56 | public BufferedReader getReader() throws IOException { 57 | return new BufferedReader(new InputStreamReader(this.getInputStream(),StandardCharsets.UTF_8)); 58 | } 59 | 60 | public String getHttpBody() { 61 | return httpBody; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/wrapper/SignatureFilter.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.wrapper; 2 | 3 | import com.google.common.base.Joiner; 4 | import com.google.common.base.Splitter; 5 | import io.github.lvyahui8.web.constant.WebConstant; 6 | import io.github.lvyahui8.web.signature.SignatureService; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.core.Ordered; 10 | import org.springframework.core.annotation.Order; 11 | 12 | import javax.servlet.*; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | import java.io.IOException; 16 | import java.util.Collections; 17 | import java.util.Iterator; 18 | import java.util.LinkedHashMap; 19 | import java.util.Map; 20 | 21 | /** 22 | * @author yahui.lv lvyahui8@gmail.com 23 | * @date 2020/4/4 23:06 24 | */ 25 | @Slf4j 26 | @Order(Ordered.LOWEST_PRECEDENCE) 27 | public class SignatureFilter implements Filter { 28 | 29 | SignatureService signatureService; 30 | 31 | public SignatureFilter(SignatureService signatureService) { 32 | this.signatureService = signatureService; 33 | } 34 | 35 | @Override 36 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 37 | throws IOException, ServletException { 38 | ResettableHttpServletRequest wrappedRequest = new ResettableHttpServletRequest((HttpServletRequest) servletRequest); 39 | TeeHttpServletResponse copiedResponse = new TeeHttpServletResponse((HttpServletResponse) servletResponse); 40 | String signatureHeadValue = wrappedRequest.getHeader(WebConstant.HttpHeader.X_SIGNATURE.getKey()); 41 | String httpBody = wrappedRequest.getHttpBody(); 42 | String queryString = wrappedRequest.getQueryString(); 43 | boolean noData = StringUtils.isBlank(queryString) && StringUtils.isBlank(httpBody); 44 | if (noData && StringUtils.isBlank(signatureHeadValue)) { 45 | filterChain.doFilter(wrappedRequest,copiedResponse); 46 | } else if (StringUtils.isNotBlank(signatureHeadValue)) { 47 | Iterator trimResults = Splitter.on(',').omitEmptyStrings().trimResults().split(signatureHeadValue).iterator(); 48 | Map signatureParams = new LinkedHashMap<>(); 49 | while(trimResults.hasNext()) { 50 | String item = trimResults.next().trim(); 51 | if (item.length() < 2) { 52 | continue; 53 | } 54 | int index = item.indexOf('='); 55 | signatureParams.put(item.substring(0,index).trim(),item.substring(index + 1).trim()); 56 | } 57 | String encodedSignature = signatureParams.get(WebConstant.SignatureHeaderKey.SIGNATURE); 58 | String text = null; 59 | boolean validSignature = false; 60 | if(! noData) { 61 | text = (queryString != null ? queryString : "") + '.' + (httpBody != null ? httpBody : ""); 62 | try { 63 | validSignature = signatureService.verifyRequest(text, encodedSignature); 64 | } catch (Exception ignored) { 65 | } 66 | } 67 | if (validSignature) { 68 | filterChain.doFilter(wrappedRequest,copiedResponse); 69 | } else { 70 | throw new SecurityException("Illegal signature"); 71 | } 72 | } else { 73 | throw new SecurityException("Illegal signature"); 74 | } 75 | String responseHttpBody = copiedResponse.getHttpBody(); 76 | log.info("resp:{}" ,responseHttpBody); 77 | // - too later 78 | copiedResponse.addHeader(WebConstant.HttpHeader.X_SIGNATURE.getKey(), Joiner.on(',') 79 | .withKeyValueSeparator('=').join(Collections.singletonMap(WebConstant.SignatureHeaderKey.SIGNATURE, 80 | signatureService.signResponse(responseHttpBody)))); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/wrapper/TeeHttpServletResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.wrapper; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import javax.servlet.ServletOutputStream; 6 | import javax.servlet.WriteListener; 7 | import javax.servlet.http.HttpServletResponse; 8 | import javax.servlet.http.HttpServletResponseWrapper; 9 | import java.io.*; 10 | import java.nio.charset.Charset; 11 | 12 | /** 13 | * @author yahui.lv lvyahui8@gmail.com 14 | * @date 2020/4/5 11:49 15 | */ 16 | @Slf4j 17 | public class TeeHttpServletResponse extends HttpServletResponseWrapper { 18 | 19 | TeeServletOutputStream teeOutputStream; 20 | 21 | HttpServletResponse response; 22 | 23 | PrintWriter writer; 24 | 25 | ServletOutputStream rawOutputStream; 26 | 27 | public TeeHttpServletResponse(HttpServletResponse response) throws IOException { 28 | super(response); 29 | this.response = response; 30 | } 31 | 32 | @Override 33 | public ServletOutputStream getOutputStream() throws IOException { 34 | if (writer != null) { 35 | throw new IllegalStateException("getWriter() has already been called on this response."); 36 | } 37 | 38 | if (rawOutputStream == null) { 39 | rawOutputStream = response.getOutputStream(); 40 | teeOutputStream = new TeeServletOutputStream(rawOutputStream); 41 | } 42 | 43 | return teeOutputStream; 44 | } 45 | 46 | @Override 47 | public PrintWriter getWriter() throws IOException { 48 | if (rawOutputStream != null) { 49 | throw new IllegalStateException("getOutputStream() has already been called on this response."); 50 | } 51 | 52 | if (writer == null) { 53 | teeOutputStream = new TeeServletOutputStream(response.getOutputStream()); 54 | writer = new PrintWriter(new OutputStreamWriter(teeOutputStream,response.getCharacterEncoding()),true); 55 | } 56 | return writer; 57 | } 58 | 59 | 60 | @Override 61 | public void flushBuffer() throws IOException { 62 | if (writer != null) { 63 | writer.flush(); 64 | } else if (teeOutputStream != null) { 65 | teeOutputStream.flush(); 66 | } 67 | } 68 | 69 | public String getHttpBody() throws UnsupportedEncodingException { 70 | return new String(teeOutputStream.getCopy(), response.getCharacterEncoding()); 71 | } 72 | 73 | static class TeeServletOutputStream extends ServletOutputStream { 74 | ServletOutputStream outputStream; 75 | ByteArrayOutputStream copy; 76 | 77 | public TeeServletOutputStream(ServletOutputStream outputStream) { 78 | this.outputStream = outputStream; 79 | this.copy = new ByteArrayOutputStream(2048); 80 | } 81 | 82 | @Override 83 | public boolean isReady() { 84 | return outputStream.isReady(); 85 | } 86 | 87 | @Override 88 | public void setWriteListener(WriteListener writeListener) { 89 | outputStream.setWriteListener(writeListener); 90 | } 91 | 92 | @Override 93 | public void write(int b) throws IOException { 94 | outputStream.write(b); 95 | copy.write(b); 96 | } 97 | 98 | public byte[] getCopy() { 99 | return copy.toByteArray(); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/main/java/io/github/lvyahui8/web/wrapper/TraceFilter.java: -------------------------------------------------------------------------------- 1 | package io.github.lvyahui8.web.wrapper; 2 | 3 | import io.github.lvyahui8.sdk.guid.GUIDGenerator; 4 | import io.github.lvyahui8.web.context.RequestContext; 5 | import io.github.lvyahui8.web.context.RequestMessage; 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.springframework.core.Ordered; 8 | import org.springframework.core.annotation.Order; 9 | 10 | import javax.servlet.*; 11 | import javax.servlet.http.HttpServletRequest; 12 | import java.io.IOException; 13 | 14 | /** 15 | * @author feego lvyahui8@gmail.com 16 | * @date 2020/10/1 17 | */ 18 | @Order(Ordered.HIGHEST_PRECEDENCE) 19 | public class TraceFilter implements Filter { 20 | 21 | @Override 22 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 23 | try { 24 | RequestMessage message = new RequestMessage(); 25 | message.setStressTraffic(StringUtils.isNotBlank(((HttpServletRequest) request).getHeader("X-Stress-Test"))); 26 | message.setTraceId(GUIDGenerator.createStringTypeGUID()); 27 | RequestContext.putRequest(message); 28 | chain.doFilter(request, response); 29 | } finally { 30 | RequestContext.clean(); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /feego-common-web/feego-common-web/src/test/java/io/github/lvyahui8/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/feego-common-web/feego-common-web/src/test/java/io/github/lvyahui8/.gitignore -------------------------------------------------------------------------------- /readme.assets/guid.assets/image-20201003000028945.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/readme.assets/guid.assets/image-20201003000028945.png -------------------------------------------------------------------------------- /readme.assets/guid.assets/image-20201004223800706.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/readme.assets/guid.assets/image-20201004223800706.png -------------------------------------------------------------------------------- /readme.assets/guid.md: -------------------------------------------------------------------------------- 1 | # GUID 生成 2 | 3 | 参考雪花算法 4 | 5 | ## 字符串类型的GUID生成策略 6 | 7 | ``` 8 | String 类型的GUID,兼顾长度和可读性,所有数据转成16进制 9 | 10 | 16进制IP(8个字符)+ 固定随机值(3个字符)+ 16进制ms时间戳(11个字符) + 循环递增值(5个字符)-> 27个字符 11 | ``` 12 | 13 | ![image-20201004223800706](guid.assets/image-20201004223800706.png) 14 | 15 | ## Long类型的GUID生成策略 16 | 17 | ``` 18 | Long 类型的GUID,63位可用 19 | 策略1 : 41位给ms时间戳(可以用到2074年),10位给svrId(即支持1024个节点),剩余12位给循环递增值,即1ms内4096个。需要考虑svrId的生成,适合大流量系统。 20 | 策略2 : 30位给s级时间戳的低30位(可以用到2038-01-19),32位给IP地址(视情况可以去掉一些位),剩余1位给循环递增值,即1s内支持2个。无需考虑svrId,适合小流量系统,实现上可以视使用情况,通过参数分别控制三者的位数。 21 | 节点不多时,很可能节点ip的差异只在低16位,此时可以设置ipDigits为16位,则递增值扩大到了17位,即支持2^17 qps 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /readme.assets/image-20201013232937970.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/readme.assets/image-20201013232937970.png -------------------------------------------------------------------------------- /readme.assets/image-20201013233502251.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/readme.assets/image-20201013233502251.png -------------------------------------------------------------------------------- /readme.assets/lock.assets/image-20200321185855112.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/readme.assets/lock.assets/image-20200321185855112.png -------------------------------------------------------------------------------- /readme.assets/lock.md: -------------------------------------------------------------------------------- 1 | # Redis分布式锁 2 | 3 | ## 原理 4 | 5 | 分布式锁的实现原理大同小异。一种,是把对锁的争抢,通过网络请求从多机(分布式)转移到单机,然后借助单机中保证原子性的API争抢资源;另一种,是借助集群分布式事务的原子性来争抢资源。 6 | 7 | 各种基于redis、mysql、zookeeper等等分布式锁实现,本质上的原理同上面是一样的 8 | 9 | - redis的高可用集群是多主多从模型,而且每个key落在hash槽(主节点)的位置是固定的,所以同一个锁(key)的争抢请求实际会在单个主节点中争抢。 10 | - zookeeper集群,表面上看,它是通过临时节点的序列号做比较来判断到底谁抢到了锁,但临时节点序号的生成又是怎么保证原子性的呢?一样的道理, zookeeper集群会有唯一的一个leader节点处理所有的写请求,follower节点的写请求也会被转发到leader节点,leader节点处理完后广播给个follower节点。 11 | - mysql的高可用模型非常多, 最常见的是主从模型,这种情况下,实际也是借助mysql单机事务的原子性来实现对资源(分布式锁)的争抢。 12 | 13 | ## 基于Redis的分布式锁 14 | 15 | 基于redis实现一把高可用的锁, 必须实现以下逻辑 16 | 17 | ### 锁必须有过期逻辑 18 | 19 | 为防止在进程抢占锁之后,在未释放锁之前进程crash造成锁永远被占用(死锁),分布式锁必须有过期时间 20 | 21 | ### 锁副本必须有唯一标识 22 | 23 | 分布式系统中,每个节点都按照锁的key构造了一把锁实例,此时每个节点拿的应该叫锁的副本。 24 | 25 | 1. 拿到同一个锁副本的线程要支持可重入 26 | 2. 不能释放非自身占用的锁(别人的锁副本) 27 | 28 | 要支持这两点,每一个锁副本必须具备一个唯一标识,所以,锁的结构应该是这样 29 | 30 | ```json 31 | { 32 | "key" : "uid:1234:create_order", // 锁的唯一标识,所有节点相同 33 | "ns" : "cebf8e72-18be-4d9d-98ad", // 锁副本的唯一标识 34 | "expireTime" : 36000 // 超时过期时间 35 | } 36 | ``` 37 | 38 | 可重入这点好理解,虽然使用的并不多,但不代表不存在,因此必须支持。 39 | 40 | 那什么时候会去释放别人占用的锁副本呢? 41 | 42 | 假如锁副本没有唯一标识。 试想这样一种情况: 节点A先拿到锁,但是执行时间突然超长,在此之前锁自动过期了。此时节点B冲进来(这其实也是不应该的)拿到锁开始执行自己的业务,意外的是,节点A在节点B没执行完之前,先一步执行到了unlock,此时就会把节点B的锁给释放掉,此时节点B就变得不安全。(比如你正在房间里换衣服,你舍友没注意到,去把门打开了,此时外面一大群豺狼虎豹正抢着进来,后果可想而知)。流程如下图 43 | 44 | ![image-20200321185855112](lock.assets/image-20200321185855112.png) 45 | 46 | 47 | 48 | ### 锁不能提前过期 49 | 50 | 前面提到的当前节点,其它节点乱入的根本原因, 是因为锁提前过期了。前面提到的锁的默认超时时间是固定的,那么不论你设置成多长的超时时间,都会有问题。如果超时时间太短,则很容易因为运行时间过长出现提前过期的情况;如果设置的时间太短,则一旦进程出现crash,锁将被占用很长时间,这不一定是上层业务想看到的。 51 | 52 | 那么怎么解决这个问题呢? 53 | 54 | 答案自然是:非固定的过期时间,而且是视业务代码执行效率自动延长的过期时间。 55 | 56 | 假如业务代码平时执行只需要200ms,我们把初始超时时间设置为3s,并且每隔1s检查一下业务代码是否执行完毕,若没有则重新设置超时时间为3s。直到业务代码执行完毕主动释放锁,或者进程crash掉了,那么超时过期时间就从最后一次检查开始算3s 57 | 58 | -------------------------------------------------------------------------------- /readme.assets/logging.assets/image-20200307233100343.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/readme.assets/logging.assets/image-20200307233100343.png -------------------------------------------------------------------------------- /readme.assets/logging.assets/image-20200307233522279.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvyahui8/feego-common/1c77080c6641c7d49d9dc0aaa3cb2cac053a7fb3/readme.assets/logging.assets/image-20200307233522279.png -------------------------------------------------------------------------------- /readme.assets/signature.md: -------------------------------------------------------------------------------- 1 | # 加签验签 2 | 3 | ## 签名的意义 4 | 5 | 我们已经有了https, 为什么还要做签名? 简单的把两者做下对比 6 | 7 | | 项目 | 签名 | HTTPS(HTTP+SSL/TLS) | 8 | | ------------------ | ------------------------------------ | --------------------- | 9 | | 网络层级 | 应用层 | 传输层 | 10 | | 主要目的和用途 | 防篡改,证明原文的合法性 | 防窃取、防窥视、保密 | 11 | | 对待原始内容的态度 | 可以明文 | 绝不能泄漏明文 | 12 | | 秘钥对的用法 | 私钥加签、公钥验签 | 公钥加密、私钥解密 | 13 | | 保障对象 | 发送方与接收方,不管中间经过多少节点 | 两个通信节点之间 | 14 | 15 | [^note]: 实际没有HTTPS这个协议,HTTPS实际是HTTP+SSL/TLS,真正的加密是依靠介于HTTP和TCP之间的SSL/TLS模块 16 | 17 | ## 签名方案 18 | 19 | ### 签名对象 20 | 21 | 鉴于许多的中间件、代理类服务, 会修改或附加HTTP Header,或者修改Request PATH。 因此, Feego Common框架只对关键的数据内容加签, 业务方不能依赖HTTP头部无篡改。 22 | 23 | 对请求, 要求客户端按照约定对如下字段加签 24 | 25 | - 客户端标识(keyId/clientId) 26 | - 请求发起时间戳 27 | - queryString 28 | - httpReqeustBody 29 | 30 | 即 31 | 32 | ```java 33 | signature = base64encode(SHA1-RSA(客户端标识.请求发起时间戳.queryString.httpReqeustBody)) 34 | ``` 35 | 36 | 客户端可以使用SDK发送加签请求 37 | 38 | 对于响应,服务端对以下字段加签 39 | 40 | - 响应的时间戳 41 | - httpResponseBody 42 | 43 | 即 44 | 45 | ``` 46 | signature = base64encode(SHA1-RSA(响应的时间戳.httpResponseBody)) 47 | ``` 48 | 49 | ### 传输签名结果 50 | 51 | 签名结果放在http header中传输。 52 | 53 | header name为`X-Feego-Signature` 54 | 55 | header value为key-value格式的键值列表,以`,`分隔,其中键有以下几个 56 | 57 | - clientId :表示客户端标识,可以为空 58 | - algorithm :表示签名算法,可以为空 59 | - signature :表示签名结果,必选。 60 | 61 | 一个完整的签名header示例: 62 | 63 | ### 秘钥对的维护 64 | 65 | 一次请求。 完整的签名方案应该涉及到两次签名 66 | 67 | - 客户端发送给服务端请求的签名处理 68 | - 服务端发送给客户端响应的签名处理 69 | 70 | 因此, 完整的一次请求, 应该涉及到两个秘钥对, 一个是处理请求的秘钥对, 一个是处理响应的秘钥对。 71 | 72 | 针对响应,由服务端使用私钥加签, 因为服务端只有一个, 只需要一个秘钥对即可自证身份。因此,所有客户端可以共用同一个公钥对响应验签。 73 | 74 | 对于请求而言, 客户端可能有非常多个, 每一个客户端的身份是不同的, 服务端应该跟每一个客户端之间, 维护一个秘钥对。 75 | 76 | 目前Feego commn使用配置维护秘钥对,配置格式如下 77 | 78 | ```java 79 | @Data 80 | public class SignatureSettings { 81 | Boolean open = false; 82 | 83 | List clients; 84 | 85 | String algorithm = "SHA1withRSA"; 86 | 87 | String defaultSignResponsePrivateKey; 88 | 89 | String defaultVerifyRequestPublicKey; 90 | 91 | @Data 92 | public static class ClientApplication { 93 | String appId; 94 | String verifyRequestPublicKey; 95 | String signResponsePrivateKey; 96 | } 97 | } 98 | ``` 99 | 100 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Feego Common 2 | 3 | [![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) 4 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.lvyahui8/feego-common-web-starter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.lvyahui8/feego-common-web-starter) 5 | [![GitHub release](https://img.shields.io/github/release/lvyahui8/feego-common.svg)](https://github.com/lvyahui8/feego-common/releases) 6 | 7 | ## 基础能力列表 8 | 9 | - [x] [模块化日志](/readme.assets/logging.md) 10 | - [x] 统一的异常处理/响应封装 11 | - [ ] [统一的加签验签](/readme.assets/signature.md) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | - [ ] 敏感报文加密 33 | - [x] [基于redis的分布式锁](/readme.assets/lock.md) 34 | - [ ] Dubbo扩展 35 | - [ ] 基于注解的分级权限控制 36 | - [ ] JWT颁发与验证 37 | - [ ] HTTP与RPC接口Mock能力 38 | - [x] [GUID Generator](/readme.assets/guid.md) 39 | - [x] 异步Reload缓存 40 | - [x] 通用应用红点 41 | - [x] Named Lock 42 | 43 | ## 模块说明 44 | 45 | - feego-common-configuration-processor : 编译器相关的注解处理器 46 | - feego-common-logging : 模块化日志核心 47 | - feego-common-logging-starter:模块化日志自动配置 48 | - feego-common-service 49 | - feego-common-service : 其它通用功能。代码量不足以独立成一个module的都放在这里面 50 | - feego-common-service-starter : 相关的bean自动配置 51 | - feego-common-web 52 | - feego-common-web:web http相关的通用能力核心 53 | - feego-common-web-starter:web http相关通用能力自动配置 54 | 55 | 测试模块 56 | 57 | - example/feego-common-example-api:主要作为依赖包提供给第三方,声明系统暴露的API 58 | - example/feego-common-example-api-starter:自动配置系统暴露的API,第三方引用此包 59 | - example/feego-common-example-service:测试服务核心代码 60 | - example/feego-common-example-start:测试服务启动类 61 | - example/feego-common-example-client:消费测试服务的客户端程序 62 | 63 | ## Common Logging 64 | 65 | ```java 66 | public enum CustomModuleLogger implements EnumModuleLogger { 67 | campaign, 68 | status, 69 | ; 70 | } 71 | CustomModuleLogger.campaign.debug(LogSchema.biz("qrcode-pay") 72 | .of("orderId",1234).of("amount",100).of("suc",'Y')); 73 | CustomModuleLogger.campaign.debug("hello"); 74 | CustomModuleLogger.campaign.debug("hello {}","dj"); 75 | CustomModuleLogger.campaign.debug("hello {} {}","d,","j"); 76 | CustomModuleLogger.campaign.debug("hello {} {} {} {}",'d','j','b','j'); 77 | 78 | // output to file ${user.home}/logs/general/campaign.log 79 | 2020-10-13 23:38:20.505 [DEBUG] - tid:c0a8006b36b175229cc3c410000|#|biz:qrcode-pay|#|orderId:1234|#|amount:100|#|suc:Y|#| 80 | 2020-10-13 23:38:20.505 [DEBUG] - tid:c0a8006b36b175229cc3c410000|#|msg:hello|#| 81 | 2020-10-13 23:38:20.505 [DEBUG] - tid:c0a8006b36b175229cc3c410000|#|msg:hello dj|#| 82 | 2020-10-13 23:38:20.505 [DEBUG] - tid:c0a8006b36b175229cc3c410000|#|msg:hello d, j|#| 83 | 2020-10-13 23:38:20.505 [DEBUG] - tid:c0a8006b36b175229cc3c410000|#|msg:hello d j b j|#| 84 | ``` 85 | 86 | ![image-20201013233502251](readme.assets/image-20201013233502251.png) -------------------------------------------------------------------------------- /release.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mvn -pl !feego-common-example-start,\ 3 | !feego-common-example-service \ 4 | !feego-common-example-api \ 5 | !feego-common-example-api-starter \ 6 | !feego-common-example-client \ 7 | clean install deploy -P release -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # mvn versions:set -DnewVersion="1.2.0" 3 | mvn -pl !feego-common-example-start,\ 4 | !feego-common-example-service \ 5 | !feego-common-example-api \ 6 | !feego-common-example-api-starter \ 7 | !feego-common-example-client \ 8 | clean install deploy -P release --------------------------------------------------------------------------------