From 95150b6be781d1d0b0a429cd60df7065d0044e48 Mon Sep 17 00:00:00 2001 From: ljh01459796 Date: Tue, 20 Jun 2023 16:05:15 +0800 Subject: [PATCH] init commit. --- .gitignore | 34 +++ LICENSE | 289 ++++++++++++++++++ README.md | 2 + http-client.env.json | 8 + orion-ops-dependencies/pom.xml | 76 +++++ orion-ops-framework/orion-ops-common/pom.xml | 31 ++ .../common/annotation/IgnoreLog.java | 16 + .../common/annotation/IgnoreWrapper.java | 16 + .../common/annotation/RestWrapper.java | 17 ++ .../common/enums/ExceptionMessageConst.java | 50 +++ .../common/enums/FilterOrderConst.java | 16 + .../common/enums/InterceptorOrderConst.java | 14 + .../common/enums/OrionOpsProConst.java | 20 ++ .../framework/common/meta/TraceIdHolder.java | 33 ++ .../ops/framework/common/utils/AnsiCode.java | 265 ++++++++++++++++ .../pom.xml | 31 ++ .../config/OrionBannerAutoConfiguration.java | 25 ++ .../banner/core/BannerApplicationRunner.java | 44 +++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../src/main/resources/banner.txt | 11 + .../orion-ops-spring-boot-starter-web/pom.xml | 43 +++ .../config/OrionLogPrinterConfiguration.java | 33 ++ .../web/config/OrionWebAutoConfiguration.java | 136 +++++++++ .../web/core/filter/TraceIdFilter.java | 39 +++ .../core/handler/GlobalExceptionHandler.java | 185 +++++++++++ .../core/handler/WrapperResultHandler.java | 54 ++++ .../core/interceptor/LogPrintInterceptor.java | 154 ++++++++++ ...ot.autoconfigure.AutoConfiguration.imports | 2 + orion-ops-framework/pom.xml | 24 ++ orion-ops-server/pom.xml | 88 ++++++ .../orion/ops/server/OrionOpsApplication.java | 20 ++ .../config/ApplicationConfiguration.java | 25 ++ .../controller/BootstrapController.java | 23 ++ .../src/main/resources/application-dev.yaml | 0 .../src/main/resources/application-prod.yaml | 0 .../src/main/resources/application.yaml | 31 ++ .../controller/BootstrapController.http | 5 + pom.xml | 104 +++++++ 38 files changed, 1965 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 http-client.env.json create mode 100644 orion-ops-dependencies/pom.xml create mode 100644 orion-ops-framework/orion-ops-common/pom.xml create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreLog.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreWrapper.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/RestWrapper.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/ExceptionMessageConst.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/FilterOrderConst.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/InterceptorOrderConst.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/OrionOpsProConst.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/meta/TraceIdHolder.java create mode 100644 orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/utils/AnsiCode.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-banner/pom.xml create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/config/OrionBannerAutoConfiguration.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/core/BannerApplicationRunner.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/banner.txt create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/pom.xml create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionLogPrinterConfiguration.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/WrapperResultHandler.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/interceptor/LogPrintInterceptor.java create mode 100644 orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 orion-ops-framework/pom.xml create mode 100644 orion-ops-server/pom.xml create mode 100644 orion-ops-server/src/main/java/com/orion/ops/server/OrionOpsApplication.java create mode 100644 orion-ops-server/src/main/java/com/orion/ops/server/config/ApplicationConfiguration.java create mode 100644 orion-ops-server/src/main/java/com/orion/ops/server/controller/BootstrapController.java create mode 100644 orion-ops-server/src/main/resources/application-dev.yaml create mode 100644 orion-ops-server/src/main/resources/application-prod.yaml create mode 100644 orion-ops-server/src/main/resources/application.yaml create mode 100644 orion-ops-server/src/test/java/com/orion/ops/server/controller/BootstrapController.http create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2b78e4ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +.log + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..b2d3628b --- /dev/null +++ b/LICENSE @@ -0,0 +1,289 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Apache Dubbo Submodules: + +Apache Dubbo includes a number of submodules with separate copyright notices +and license terms. Your use of these submodules is subject to the terms and +conditions of the following licenses. + +For the package org.apache.dubbo.common.threadlocal and org.apache.dubbo.common.timer: + +This product contains a modified portion of 'Netty', an event-driven asynchronous network application framework also + under a "Apache License 2.0" license, see https://github.com/netty/netty/blob/4.1/LICENSE.txt: + + * io.netty.util.concurrent.FastThreadLocal + * io.netty.util.internal.InternalThreadLocalMap + * io.netty.util.Timer + * io.netty.util.TimerTask + * io.netty.util.Timeout + * io.netty.util.HashedWheelTimer + +For the org.apache.dubbo.common.utils.CIDRUtils : + +This product contains a modified portion of 'edazdarevic.commons.net.CIDRUtils' published at +https://github.com/edazdarevic/CIDRUtils. The project is licensed under a MIT License: + * The MIT License + * + * Copyright (c) 2013 Edin Dazdarevic (edin.dazdarevic@gmail.com) + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + +For the file org.apache.dubbo.common.utils.Utf8Utils.java: + +This product contains a portion of the Protocol Buffers project, which is published at +https://developers.google.com/protocol-buffers/ and is licensed under the following License: + + Copyright 2008 Google Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Code generated by the Protocol Buffer compiler is owned by the owner + of the input file used when generating it. This code is not + standalone and requires a support library to be linked with it. This + support library is itself covered by the above license. + +For the ca.proto in dubbo-registry-xds: + +This product contains a modified portion of 'Istio', an open platform to connect, manage, and secure microservices also + under a "Apache License 2.0" license, see https://github.com/istio/api/blob/master/LICENSE: + + * security/v1alpha1/ca.proto diff --git a/README.md b/README.md new file mode 100644 index 00000000..815e5f61 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +### orion-ops-pro (orion-ops重构版) +### 开发中 \ No newline at end of file diff --git a/http-client.env.json b/http-client.env.json new file mode 100644 index 00000000..d0f084ce --- /dev/null +++ b/http-client.env.json @@ -0,0 +1,8 @@ +{ + "local": { + "baseUrl": "http://127.0.0.1:9200/orion-api" + }, + "gateway": { + "baseUrl": "http://127.0.0.1:9200/orion-api" + } +} diff --git a/orion-ops-dependencies/pom.xml b/orion-ops-dependencies/pom.xml new file mode 100644 index 00000000..e8403ec2 --- /dev/null +++ b/orion-ops-dependencies/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + com.orion.ops + orion-ops-dependencies + ${revision} + pom + ${project.artifactId} + + 项目所有依赖 + https://github.com/lijiahangmax/orion-ops-pro + + + 1.0.0 + 2.7.11 + 1.0.5 + 1.18.26 + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + io.github.lijiahangmax + orion-all + ${orion.all.version} + + + orion-log + io.github.lijiahangmax + + + + + + + com.orion.ops + orion-ops-common + ${revision} + + + com.orion.ops + orion-ops-spring-boot-starter-banner + ${revision} + + + com.orion.ops + orion-ops-spring-boot-starter-web + ${revision} + + + + + + + org.projectlombok + lombok + ${lombok.version} + + + + + + \ No newline at end of file diff --git a/orion-ops-framework/orion-ops-common/pom.xml b/orion-ops-framework/orion-ops-common/pom.xml new file mode 100644 index 00000000..28f0a91c --- /dev/null +++ b/orion-ops-framework/orion-ops-common/pom.xml @@ -0,0 +1,31 @@ + + + + com.orion.ops + orion-ops-framework + ${revision} + + + 4.0.0 + orion-ops-common + ${project.artifactId} + jar + + 项目公共基准包 + https://github.com/lijiahangmax/orion-ops-pro + + + + io.github.lijiahangmax + orion-all + + + + org.projectlombok + lombok + + + + \ No newline at end of file diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreLog.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreLog.java new file mode 100644 index 00000000..1e9b5682 --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreLog.java @@ -0,0 +1,16 @@ +package com.orion.ops.framework.common.annotation; + +import java.lang.annotation.*; + +/** + * 不执行统一日志打印 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/4/20 10:33 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface IgnoreLog { +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreWrapper.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreWrapper.java new file mode 100644 index 00000000..9ea2e2fb --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/IgnoreWrapper.java @@ -0,0 +1,16 @@ +package com.orion.ops.framework.common.annotation; + +import java.lang.annotation.*; + +/** + * 无需包装返回 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2021/4/2 10:36 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface IgnoreWrapper { +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/RestWrapper.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/RestWrapper.java new file mode 100644 index 00000000..36de889b --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/annotation/RestWrapper.java @@ -0,0 +1,17 @@ +package com.orion.ops.framework.common.annotation; + +import java.lang.annotation.*; + +/** + * 统一返回包装 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2021/4/2 12:34 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RestWrapper { + +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/ExceptionMessageConst.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/ExceptionMessageConst.java new file mode 100644 index 00000000..d64d4943 --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/ExceptionMessageConst.java @@ -0,0 +1,50 @@ +package com.orion.ops.framework.common.enums; + +/** + * 消息常量 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2021/6/4 18:26 + */ +public interface ExceptionMessageConst { + + String INVALID_PARAM = "非法参数"; + + String OPERATOR_ERROR = "操作失败"; + + String HTTP_API = "api 调用异常"; + + String NETWORK_FLUCTUATION = "当前环境网路波动"; + + String OPEN_TEMPLATE_ERROR = "模板解析失败 请检查模板和密码"; + + String PARSE_TEMPLATE_DATA_ERROR = "模板解析失败 请检查模板数据"; + + String REPOSITORY_OPERATOR_ERROR = "应用版本仓库操作执行失败"; + + String TASK_ERROR = "任务执行异常"; + + String CONNECT_ERROR = "建立连接失败"; + + String TIMEOUT_ERROR = "处理超时"; + + String INTERRUPT_ERROR = "操作中断"; + + String UNSAFE_OPERATOR = "不安全的操作"; + + String ENCRYPT_ERROR = "数据加密异常"; + + String DECRYPT_ERROR = "数据解密异常"; + + String EXCEPTION_MESSAGE = "系统异常"; + + String IO_EXCEPTION_MESSAGE = "网络异常"; + + String SQL_EXCEPTION_MESSAGE = "数据异常"; + + String FILE_TOO_LARGE = "文件过大"; + + String ERROR_EXPRESSION = "表达式错误"; + +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/FilterOrderConst.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/FilterOrderConst.java new file mode 100644 index 00000000..e60b1578 --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/FilterOrderConst.java @@ -0,0 +1,16 @@ +package com.orion.ops.framework.common.enums; + +/** + * 过滤器排序常量 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/16 17:04 + */ +public interface FilterOrderConst { + + int CORS_FILTER = Integer.MIN_VALUE; + + int TRICE_ID_FILTER = Integer.MIN_VALUE + 10; + +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/InterceptorOrderConst.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/InterceptorOrderConst.java new file mode 100644 index 00000000..c5a1640b --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/InterceptorOrderConst.java @@ -0,0 +1,14 @@ +package com.orion.ops.framework.common.enums; + +/** + * 拦截器排序常量 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/16 18:15 + */ +public interface InterceptorOrderConst { + + int LOG_FILTER = Integer.MIN_VALUE; + +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/OrionOpsProConst.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/OrionOpsProConst.java new file mode 100644 index 00000000..c426330d --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/enums/OrionOpsProConst.java @@ -0,0 +1,20 @@ +package com.orion.ops.framework.common.enums; + +/** + * 项目常量 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/19 18:56 + */ +public interface OrionOpsProConst { + + String GITHUB = "https://github.com/lijiahangmax/orion-ops-pro"; + + String GITEE = "https://gitee.com/lijiahangmax/orion-ops-pro"; + + String ISSUES = "https://gitee.com/lijiahangmax/orion-ops-pro/issues"; + + String VERSION = "1.0.0"; + +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/meta/TraceIdHolder.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/meta/TraceIdHolder.java new file mode 100644 index 00000000..2c663ea9 --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/meta/TraceIdHolder.java @@ -0,0 +1,33 @@ +package com.orion.ops.framework.common.meta; + +/** + * traceId 持有者 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/16 17:35 + */ +public class TraceIdHolder { + + private TraceIdHolder() { + } + + /** + * 请求序列 + */ + private static final ThreadLocal HOLDER = new ThreadLocal<>(); + ; + + public static String get() { + return HOLDER.get(); + } + + public static void set(String traceId) { + HOLDER.set(traceId); + } + + public static void remove() { + HOLDER.remove(); + } + +} diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/utils/AnsiCode.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/utils/AnsiCode.java new file mode 100644 index 00000000..5a0624fb --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/utils/AnsiCode.java @@ -0,0 +1,265 @@ +package com.orion.ops.framework.common.utils; + +/** + * ANSI 高亮颜色转义码 + *

+ * \u001B = \x1b = 27 = esc + *

+ * 基本8色 基本高对比色 xterm 256 色 + * 30 ~ 37 90 ~ 97 0 ~ 256 + *

+ * \033[0m 关闭所有属性 + * \033[1m 设置高亮度 + * \033[4m 下划线 + * \033[5m 闪烁 + * \033[7m 反显 + * \033[8m 消隐 + * \033[30m 至 \33[37m 设置前景色 + * \033[40m 至 \33[47m 设置背景色 + * \033[nA 光标上移n行 + * \033[nB 光标下移n行 + * \033[nC 光标右移n行 + * \033[nD 光标左移n行 + * \033[y;xH 设置光标位置 + * \033[2J 清屏 + * \033[K 清除从光标到行尾的内容 + * \033[s 保存光标位置 + * \033[u 恢复光标位置 + * \033[?25l 隐藏光标 + * \033[?25h 显示光标 + *

+ * TODO 后续直接使用kit + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/20 10:51 + */ +public enum AnsiCode { + + /** + * 黑色 + */ + BLACK(30), + + /** + * 红色 + */ + RED(31), + + /** + * 绿色 + */ + GREEN(32), + + /** + * 黄色 + */ + YELLOW(33), + + /** + * 蓝色 + */ + BLUE(34), + + /** + * 紫色 + */ + PURPLE(35), + + /** + * 青色 + */ + CYAN(36), + + /** + * 白色 + */ + WHITE(37), + + // -------------------- 背景色 -------------------- + + /** + * 黑色 背景色 + */ + BG_BLACK(40), + + /** + * 红色 背景色 + */ + BG_RED(41), + + /** + * 绿色 背景色 + */ + BG_GREEN(42), + + /** + * 黄色 背景色 + */ + BG_YELLOW(43), + + /** + * 蓝色 背景色 + */ + BG_BLUE(44), + + /** + * 紫色 背景色 + */ + BG_PURPLE(45), + + /** + * 青色 背景色 + */ + BG_CYAN(46), + + /** + * 白色 背景色 + */ + BG_WHITE(47), + + // -------------------- 亮色 -------------------- + + /** + * 亮黑色 (灰) + */ + GLOSS_BLACK(90), + + /** + * 亮红色 + */ + GLOSS_RED(91), + + /** + * 亮绿色 + */ + GLOSS_GREEN(92), + + /** + * 亮黄色 + */ + GLOSS_YELLOW(93), + + /** + * 亮蓝色 + */ + GLOSS_BLUE(94), + + /** + * 亮紫色 + */ + GLOSS_PURPLE(95), + + /** + * 亮青色 + */ + GLOSS_CYAN(96), + + /** + * 亮白色 + */ + GLOSS_WHITE(97), + + // -------------------- 亮背景色 -------------------- + + /** + * 亮黑色 (灰) 背景色 + */ + BG_GLOSS_BLACK(100), + + /** + * 亮红色 背景色 + */ + BG_GLOSS_RED(101), + + /** + * 亮绿色 背景色 + */ + BG_GLOSS_GREEN(102), + + /** + * 亮黄色 背景色 + */ + BG_GLOSS_YELLOW(103), + + /** + * 亮蓝色 背景色 + */ + BG_GLOSS_BLUE(104), + + /** + * 亮紫色 背景色 + */ + BG_GLOSS_PURPLE(105), + + /** + * 亮青色 背景色 + */ + BG_GLOSS_CYAN(106), + + /** + * 亮白色 背景色 + */ + BG_GLOSS_WHITE(107), + + ; + + /** + * 颜色码 + */ + public final int code; + + /** + * 前缀 + */ + public final String prefix; + + /** + * 后缀 + * \x1b[0m + */ + public static final String SUFFIX = (char) 27 + "[0m"; + + AnsiCode(int code) { + this.code = code; + this.prefix = getPrefix(code); + } + + /** + * 文字着色 + * + * @param s s + * @return s + */ + public String stain(String s) { + return prefix + s + SUFFIX; + } + + /** + * 获取颜色前缀 + * .e.g \x1b[31m + * + * @param code code + * @return 前缀 + */ + public static String getPrefix(int code) { + return (char) 27 + "[" + code + "m"; + } + + /** + * 文字着色 + * + * @param s s + * @param code code + * @return s + */ + public static String getStain(String s, int code) { + return getPrefix(code) + s + SUFFIX; + } + + @Override + public String toString() { + return prefix; + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-banner/pom.xml b/orion-ops-framework/orion-ops-spring-boot-starter-banner/pom.xml new file mode 100644 index 00000000..23ef729f --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-banner/pom.xml @@ -0,0 +1,31 @@ + + + + com.orion.ops + orion-ops-framework + ${revision} + + + 4.0.0 + orion-ops-spring-boot-starter-banner + ${project.artifactId} + jar + + 项目 banner 打印包 + https://github.com/lijiahangmax/orion-ops-pro + + + + com.orion.ops + orion-ops-common + + + + org.springframework.boot + spring-boot-starter + + + + \ No newline at end of file diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/config/OrionBannerAutoConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/config/OrionBannerAutoConfiguration.java new file mode 100644 index 00000000..b4c5e651 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/config/OrionBannerAutoConfiguration.java @@ -0,0 +1,25 @@ +package com.orion.ops.framework.banner.config; + +import com.orion.ops.framework.banner.core.BannerApplicationRunner; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; + +/** + * banner 自动配置类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/15 16:16 + */ +@AutoConfiguration +public class OrionBannerAutoConfiguration { + + /** + * @return banner 打印器 + */ + @Bean + public BannerApplicationRunner bannerApplicationRunner() { + return new BannerApplicationRunner(); + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/core/BannerApplicationRunner.java b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/core/BannerApplicationRunner.java new file mode 100644 index 00000000..0b4f203b --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/java/com/orion/ops/framework/banner/core/BannerApplicationRunner.java @@ -0,0 +1,44 @@ +package com.orion.ops.framework.banner.core; + +import com.orion.ops.framework.common.utils.AnsiCode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; + +/** + * banner printer + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/15 16:18 + */ +@Slf4j +public class BannerApplicationRunner implements ApplicationRunner { + + @Value("${spring.profiles.active}") + private String env; + + @Value("${orion.version}") + private String version; + + @Value("${server.port}") + private String port; + + @Value("${orion.api.prefix}") + private String apiPrefix; + + @Override + public void run(ApplicationArguments args) { + String line = AnsiCode.GLOSS_GREEN.stain(":: orion-ops-server v" + version + " 服务已启动(" + env + ") ::\n") + + AnsiCode.GLOSS_GREEN.stain(":: swagger 文档 ") + + // TODO swagger 地址 + AnsiCode.GLOSS_BLUE.stain("http://127.0.0.1:xxxx/dox.html\n") + + AnsiCode.GLOSS_GREEN.stain(":: server 心跳检测 ") + + AnsiCode.GLOSS_BLUE + + "curl -X GET --location \"http://127.0.0.1:" + port + apiPrefix + "/server/bootstrap/health\"" + + AnsiCode.SUFFIX; + System.out.println(line); + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..aeac5dbc --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.orion.ops.framework.banner.config.OrionBannerAutoConfiguration \ No newline at end of file diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/banner.txt b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/banner.txt new file mode 100644 index 00000000..96ff95f2 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-banner/src/main/resources/banner.txt @@ -0,0 +1,11 @@ +${AnsiColor.BRIGHT_GREEN} _ ${AnsiColor.BLUE} +${AnsiColor.BRIGHT_GREEN} ____ _____(_)___ ____ ____ ____ _____ ${AnsiColor.BLUE} ____ _________ +${AnsiColor.BRIGHT_GREEN} / __ \/ ___/ / __ \/ __ \ / __ \/ __ \/ ___/ ${AnsiColor.BLUE} / __ \/ ___/ __ \ +${AnsiColor.BRIGHT_GREEN}/ /_/ / / / / /_/ / / / / / /_/ / /_/ (__ ) ${AnsiColor.BLUE} / /_/ / / / /_/ / +${AnsiColor.BRIGHT_GREEN}\____/_/ /_/\____/_/ /_/ \____/ .___/____/ ${AnsiColor.BLUE} / .___/_/ \____/ +${AnsiColor.BRIGHT_GREEN} /_/ ${AnsiColor.BLUE} /_/ + +${AnsiColor.BRIGHT_GREEN}:: Application Name ${AnsiColor.BLUE}${spring.application.name} +${AnsiColor.BRIGHT_GREEN}:: Application Version ${AnsiColor.BLUE}${orion.version} +${AnsiColor.BRIGHT_GREEN}:: SpringBoot Version ${AnsiColor.BLUE}${spring-boot.version} +${AnsiColor.BRIGHT_GREEN}:: Active Profile ${AnsiColor.BLUE}${spring.profiles.active} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/pom.xml b/orion-ops-framework/orion-ops-spring-boot-starter-web/pom.xml new file mode 100644 index 00000000..b7f5b1a1 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/pom.xml @@ -0,0 +1,43 @@ + + + + com.orion.ops + orion-ops-framework + ${revision} + + + 4.0.0 + orion-ops-spring-boot-starter-web + ${project.artifactId} + jar + + 项目 web 包 + https://github.com/lijiahangmax/orion-ops-pro + + + + com.orion.ops + orion-ops-common + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-jdbc + provided + + + + \ No newline at end of file diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionLogPrinterConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionLogPrinterConfiguration.java new file mode 100644 index 00000000..c3e41711 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionLogPrinterConfiguration.java @@ -0,0 +1,33 @@ +package com.orion.ops.framework.web.config; + +import com.orion.ops.framework.common.enums.InterceptorOrderConst; +import com.orion.ops.framework.web.core.interceptor.LogPrintInterceptor; +import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; + +/** + * 全局日志打印配置类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/16 18:18 + */ +@AutoConfiguration +public class OrionLogPrinterConfiguration { + + @Bean + public LogPrintInterceptor logPrintInterceptor() { + return new LogPrintInterceptor(); + } + + @Bean + public AspectJExpressionPointcutAdvisor logPrinterAdvisor(LogPrintInterceptor logPrintInterceptor) { + AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor(); + advisor.setExpression("execution (* com.orion.ops.**.controller.*.*(..)) && !@annotation(com.orion.ops.framework.common.annotation.IgnoreLog)"); + advisor.setAdvice(logPrintInterceptor); + advisor.setOrder(InterceptorOrderConst.LOG_FILTER); + return advisor; + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java new file mode 100644 index 00000000..383e9577 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java @@ -0,0 +1,136 @@ +package com.orion.ops.framework.web.config; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import com.orion.lang.utils.collect.Lists; +import com.orion.ops.framework.common.enums.FilterOrderConst; +import com.orion.ops.framework.web.core.filter.TraceIdFilter; +import com.orion.ops.framework.web.core.handler.GlobalExceptionHandler; +import com.orion.ops.framework.web.core.handler.WrapperResultHandler; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.servlet.Filter; +import java.util.List; + +/** + * web 配置类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/16 16:26 + */ +@AutoConfiguration +public class OrionWebAutoConfiguration implements WebMvcConfigurer { + + @Value("${orion.api.prefix}") + private String orionApiPrefix; + + // TODO XSS + + @Override + public void configurePathMatch(PathMatchConfigurer configurer) { + // 公共 api 前缀 + configurer.addPathPrefix(orionApiPrefix, clazz -> clazz.isAnnotationPresent(RestController.class)); + } + + /** + * @return 全局异常处理器 + */ + @Bean + public GlobalExceptionHandler globalExceptionHandler() { + return new GlobalExceptionHandler(); + } + + /** + * @return 通用返回结果处理器 + */ + @Bean + public WrapperResultHandler wrapperResultHandler() { + return new WrapperResultHandler(); + } + + /** + * @return http json 转换器 + */ + @Bean + public HttpMessageConverters fastJsonHttpMessageConverters() { + // 转换器 + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + // 配置 + FastJsonConfig config = new FastJsonConfig(); + // 支持的类型 + List mediaTypes = Lists.of( + MediaType.APPLICATION_JSON, + MediaType.APPLICATION_FORM_URLENCODED, + MediaType.APPLICATION_XHTML_XML, + MediaType.TEXT_PLAIN, + MediaType.TEXT_HTML, + MediaType.TEXT_XML + ); + converter.setSupportedMediaTypes(mediaTypes); + // 序列化配置 + config.setSerializerFeatures( + SerializerFeature.DisableCircularReferenceDetect, + SerializerFeature.WriteMapNullValue, + SerializerFeature.WriteNullListAsEmpty, + SerializerFeature.IgnoreNonFieldGetter + ); + converter.setFastJsonConfig(config); + return new HttpMessageConverters(converter); + } + + /** + * @return 跨域配置 + */ + @Bean + @ConditionalOnProperty(value = "orion.api.cors", havingValue = "true") + public FilterRegistrationBean corsFilterBean() { + // 跨域配置 + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOriginPattern("*"); + config.addAllowedMethod("*"); + config.addAllowedHeader("*"); + config.setMaxAge(3600L); + // 创建 UrlBasedCorsConfigurationSource 对象 + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + return createFilterBean(new CorsFilter(source), FilterOrderConst.CORS_FILTER); + } + + /** + * @return traceId 配置 + */ + @Bean + public FilterRegistrationBean traceIdFilterBean() { + return createFilterBean(new TraceIdFilter(), FilterOrderConst.TRICE_ID_FILTER); + } + + /** + * 创建过滤器 + * + * @param filter filter + * @param order order + * @param type + * @return filter bean + */ + public static FilterRegistrationBean createFilterBean(T filter, Integer order) { + FilterRegistrationBean bean = new FilterRegistrationBean<>(filter); + bean.setOrder(order); + return bean; + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java new file mode 100644 index 00000000..03444136 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java @@ -0,0 +1,39 @@ +package com.orion.ops.framework.web.core.filter; + +import com.orion.lang.id.UUIds; +import com.orion.ops.framework.common.meta.TraceIdHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * traceId 过滤器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/16 17:45 + */ +public class TraceIdFilter extends OncePerRequestFilter { + + private static final String TRACE_ID_HEADER = "trace-id"; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + try { + // 获 traceId + String traceId = UUIds.random32(); + TraceIdHolder.set(traceId); + // 设置响应头 + response.setHeader(TRACE_ID_HEADER, traceId); + // 执行请求 + filterChain.doFilter(request, response); + } finally { + TraceIdHolder.remove(); + } + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java new file mode 100644 index 00000000..48d02438 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/GlobalExceptionHandler.java @@ -0,0 +1,185 @@ +package com.orion.ops.framework.web.core.handler; + +import com.orion.lang.define.wrapper.HttpWrapper; +import com.orion.lang.exception.*; +import com.orion.lang.exception.argument.CodeArgumentException; +import com.orion.lang.exception.argument.HttpWrapperException; +import com.orion.lang.exception.argument.InvalidArgumentException; +import com.orion.lang.exception.argument.RpcWrapperException; +import com.orion.lang.utils.Exceptions; +import com.orion.ops.framework.common.enums.ExceptionMessageConst; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.EncryptedDocumentException; +import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import org.springframework.web.multipart.MaxUploadSizeExceededException; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.sql.SQLException; + +/** + * 全局异常处理器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/15 17:19 + */ +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(value = Exception.class) + public HttpWrapper normalExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("normalExceptionHandler url: {}, 抛出异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.EXCEPTION_MESSAGE).data(ex.getMessage()); + } + + @ExceptionHandler(value = ApplicationException.class) + public HttpWrapper applicationExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("applicationExceptionHandler url: {}, 抛出异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ex.getMessage()); + } + + // TODO datasource starter + // @ExceptionHandler(value = DataAccessResourceFailureException.class) + public HttpWrapper dataAccessResourceFailureExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("dataAccessResourceFailureExceptionHandler url: {}, 抛出异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.NETWORK_FLUCTUATION); + } + + @ExceptionHandler(value = {HttpMessageNotReadableException.class, MethodArgumentTypeMismatchException.class, + HttpMessageNotReadableException.class, MethodArgumentNotValidException.class, BindException.class}) + public HttpWrapper httpRequestExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("httpRequestExceptionHandler url: {}, http请求异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.INVALID_PARAM); + } + + @ExceptionHandler(value = {HttpRequestException.class}) + public HttpWrapper httpApiRequestExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("httpApiRequestExceptionHandler url: {}, http-api请求异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.HTTP_API); + } + + @ExceptionHandler(value = {InvalidArgumentException.class, IllegalArgumentException.class, DisabledException.class}) + public HttpWrapper invalidArgumentExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("invalidArgumentExceptionHandler url: {}, 参数异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ex.getMessage()); + } + + @ExceptionHandler(value = {IOException.class, IORuntimeException.class}) + public HttpWrapper ioExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("ioExceptionHandler url: {}, io异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.IO_EXCEPTION_MESSAGE).data(ex.getMessage()); + } + + @ExceptionHandler(value = SQLException.class) + public HttpWrapper sqlExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("sqlExceptionHandler url: {}, sql异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.SQL_EXCEPTION_MESSAGE); + } + + @ExceptionHandler(value = {SftpException.class, com.jcraft.jsch.SftpException.class}) + public HttpWrapper sftpExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("sftpExceptionHandler url: {}, sftp处理异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.OPERATOR_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = ParseRuntimeException.class) + public HttpWrapper parseExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("parseExceptionHandler url: {}, 解析异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + if (Exceptions.isCausedBy(ex, EncryptedDocumentException.class)) { + // excel 密码错误 + return HttpWrapper.error(ExceptionMessageConst.OPEN_TEMPLATE_ERROR).data(ex.getMessage()); + } else { + return HttpWrapper.error(ExceptionMessageConst.PARSE_TEMPLATE_DATA_ERROR).data(ex.getMessage()); + } + } + + @ExceptionHandler(value = EncryptException.class) + public HttpWrapper encryptExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("encryptExceptionHandler url: {}, 数据加密异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.ENCRYPT_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = DecryptException.class) + public HttpWrapper decryptExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("decryptExceptionHandler url: {}, 数据解密异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.DECRYPT_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = VcsException.class) + public HttpWrapper vcsExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("vcsExceptionHandler url: {}, vcs处理异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.REPOSITORY_OPERATOR_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = {TaskExecuteException.class, ExecuteException.class}) + public HttpWrapper taskExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("taskExceptionHandler url: {}, task处理异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.TASK_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = ConnectionRuntimeException.class) + public HttpWrapper connectionExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("connectionExceptionHandler url: {}, connect异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.CONNECT_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = {TimeoutException.class, java.util.concurrent.TimeoutException.class}) + public HttpWrapper timeoutExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("timeoutExceptionHandler url: {}, timeout异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.TIMEOUT_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = {InterruptedException.class, InterruptedRuntimeException.class, InterruptedIOException.class}) + public HttpWrapper interruptExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("interruptExceptionHandler url: {}, interrupt异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.INTERRUPT_ERROR).data(ex.getMessage()); + } + + @ExceptionHandler(value = UnsafeException.class) + public HttpWrapper unsafeExceptionHandler(HttpServletRequest request, Exception ex) { + log.error("unsafeExceptionHandler url: {}, unsafe异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.UNSAFE_OPERATOR).data(ex.getMessage()); + } + + @ExceptionHandler(value = LogException.class) + public HttpWrapper logExceptionHandler(HttpServletRequest request, LogException ex) { + log.error("logExceptionHandler url: {}, 处理异常打印日志: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.EXCEPTION_MESSAGE).data(ex.getMessage()); + } + + @ExceptionHandler(value = ParseCronException.class) + public HttpWrapper parseCronExceptionHandler(ParseCronException ex) { + return HttpWrapper.error(ExceptionMessageConst.ERROR_EXPRESSION).data(ex.getMessage()); + } + + @ExceptionHandler(value = MaxUploadSizeExceededException.class) + public HttpWrapper maxUploadSizeExceededExceptionHandler(HttpServletRequest request, MaxUploadSizeExceededException ex) { + log.error("maxUploadSizeExceededExceptionHandler url: {}, 上传异常: {}, message: {}", request.getRequestURI(), ex.getClass(), ex.getMessage(), ex); + return HttpWrapper.error(ExceptionMessageConst.FILE_TOO_LARGE).data(ex.getMessage()); + } + + @ExceptionHandler(value = CodeArgumentException.class) + public HttpWrapper codeArgumentExceptionHandler(CodeArgumentException ex) { + return HttpWrapper.error(ex.getCode(), ex.getMessage()); + } + + @ExceptionHandler(value = HttpWrapperException.class) + public HttpWrapper httpWrapperExceptionHandler(HttpWrapperException ex) { + return ex.getWrapper(); + } + + @ExceptionHandler(value = RpcWrapperException.class) + public HttpWrapper rpcWrapperExceptionHandler(RpcWrapperException ex) { + return ex.getWrapper().toHttpWrapper(); + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/WrapperResultHandler.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/WrapperResultHandler.java new file mode 100644 index 00000000..743a1803 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/handler/WrapperResultHandler.java @@ -0,0 +1,54 @@ +package com.orion.ops.framework.web.core.handler; + +import com.orion.lang.constant.StandardContentType; +import com.orion.lang.define.wrapper.HttpWrapper; +import com.orion.lang.define.wrapper.RpcWrapper; +import com.orion.ops.framework.common.annotation.IgnoreWrapper; +import com.orion.ops.framework.common.annotation.RestWrapper; +import org.jetbrains.annotations.NotNull; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +/** + * 返回值处理器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/15 17:38 + */ +@ControllerAdvice +public class WrapperResultHandler implements ResponseBodyAdvice { + + @Override + public boolean supports(MethodParameter methodParameter, @NotNull Class converterType) { + // 统一返回值 + if (!methodParameter.getContainingClass().isAnnotationPresent(RestWrapper.class)) { + return false; + } + return !methodParameter.hasMethodAnnotation(IgnoreWrapper.class); + // && methodParameter.getExecutable().getAnnotatedReturnType().getType() != Void.TYPE; + } + + @Override + public Object beforeBodyWrite(Object body, @NotNull MethodParameter methodParameter, @NotNull MediaType selectedContentType, @NotNull Class selectedConverterType, + @NotNull ServerHttpRequest request, @NotNull ServerHttpResponse response) { + HttpWrapper wrapper; + if (body instanceof HttpWrapper) { + wrapper = (HttpWrapper) body; + } else if (body instanceof RpcWrapper) { + wrapper = ((RpcWrapper) body).toHttpWrapper(); + } else { + wrapper = new HttpWrapper<>().data(body); + } + if (response instanceof ServletServerHttpResponse) { + ((ServletServerHttpResponse) response).getServletResponse().setContentType(StandardContentType.APPLICATION_JSON); + } + return wrapper; + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/interceptor/LogPrintInterceptor.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/interceptor/LogPrintInterceptor.java new file mode 100644 index 00000000..660b4514 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/interceptor/LogPrintInterceptor.java @@ -0,0 +1,154 @@ +package com.orion.ops.framework.web.core.interceptor; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.PropertyFilter; +import com.orion.lang.constant.Const; +import com.orion.lang.utils.Arrays1; +import com.orion.lang.utils.Exceptions; +import com.orion.lang.utils.time.Dates; +import com.orion.ops.framework.common.meta.TraceIdHolder; +import com.orion.web.servlet.web.Servlets; +import lombok.extern.slf4j.Slf4j; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.lang.reflect.Method; +import java.util.Date; +import java.util.Optional; + +/** + * 日志打印拦截器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/7/14 18:25 + */ +@Slf4j +@Order(10) +public class LogPrintInterceptor implements MethodInterceptor { + + // TODO @OperatorLog(bizName = "") + // TODO 日志规格模型 SIMPLIFY FULL + + // https://blog.csdn.net/gaojie_csdn/article/details/127810618 + // 加注解 + + // TODO 改为正则? + @Value("#{'${log.interceptor.ignore.fields:}'.split(',')}") + private String[] ignoreFields; + + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + Date startTime = new Date(); + String traceId = TraceIdHolder.get(); + // 打印开始日志 + this.beforeLogPrint(startTime, traceId, invocation); + try { + // 执行方法 + Object ret = invocation.proceed(); + // 返回打印 + this.afterReturnLogPrint(startTime, traceId, ret); + return ret; + } catch (Throwable t) { + // 异常打印 + this.afterThrowingLogPrint(startTime, traceId, t); + throw t; + } + } + + /** + * 方法进入打印 + * + * @param startTime 开始时间 + * @param traceId trace + * @param invocation invocation + */ + public void beforeLogPrint(Date startTime, String traceId, MethodInvocation invocation) { + StringBuilder requestLog = new StringBuilder("\napi请求-开始-traceId: ").append(traceId).append('\n'); + // TODO 登陆用户 + // requestLog.append("\t当前用户: ").append(JSON.toJSONString(UserHolder.get())).append('\n'); + // TODO @OperatorLog + // http请求信息 + Optional.ofNullable(RequestContextHolder.getRequestAttributes()) + .map(s -> (ServletRequestAttributes) s) + .map(ServletRequestAttributes::getRequest) + .ifPresent(request -> { + // url + requestLog.append("\t").append(Servlets.getMethod(request)).append(" ") + .append(Servlets.getRequestUrl(request)).append('\n'); + // query + requestLog.append("\tip: ").append(Servlets.getRemoteAddr(request)).append('\n') + .append("\tquery: ").append(Servlets.getQueryString(request)).append('\n'); + // header + Servlets.getHeaderMap(request).forEach((hk, hv) -> requestLog.append('\t') + .append(hk).append(": ") + .append(hv).append('\n')); + }); + // 方法信息 + Method method = invocation.getMethod(); + requestLog.append("\t开始时间: ").append(Dates.format(startTime, Dates.YMD_HMSS)).append('\n') + .append("\t方法签名: ").append(method.getDeclaringClass().getName()).append('#') + .append(method.getName()).append("\n") + .append("\t请求参数: ").append(this.argsToString(invocation.getArguments())); + log.info(requestLog.toString()); + } + + /** + * 返回打印 + * + * @param startTime 开始时间 + * @param traceId traceId + * @param ret return + */ + private void afterReturnLogPrint(Date startTime, String traceId, Object ret) { + Date endTime = new Date(); + // 响应日志 + StringBuilder responseLog = new StringBuilder("\napi请求-结束-traceId: ").append(traceId).append('\n'); + responseLog.append("\t结束时间: ").append(Dates.format(endTime, Dates.YMD_HMSS)) + .append(" used: ").append(endTime.getTime() - startTime.getTime()).append("ms \n") + .append("\t响应结果: ").append(this.argsToString(ret)); + log.info(responseLog.toString()); + } + + /** + * 异常打印 + * + * @param startTime 开始时间 + * @param traceId trace + * @param throwable ex + */ + private void afterThrowingLogPrint(Date startTime, String traceId, Throwable throwable) { + Date endTime = new Date(); + // 响应日志 + StringBuilder responseLog = new StringBuilder("\napi请求-异常-traceId: ").append(traceId).append('\n'); + responseLog.append("\t结束时间: ").append(Dates.format(endTime, Dates.YMD_HMSS)) + .append(" used: ").append(endTime.getTime() - startTime.getTime()).append("ms \n") + .append("\t异常摘要: ").append(Exceptions.getDigest(throwable)); + log.error(responseLog.toString()); + } + + /** + * 参数转json + * + * @param o object + * @return json + */ + private String argsToString(Object o) { + try { + if (ignoreFields.length == 1 && Const.EMPTY.equals(ignoreFields[0])) { + // 不过滤 + return JSON.toJSONString(o); + } else { + return JSON.toJSONString(o, (PropertyFilter) (object, name, value) -> !Arrays1.contains(ignoreFields, name)); + } + } catch (Exception e) { + return String.valueOf(o); + } + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..eecdce8e --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +com.orion.ops.framework.web.config.OrionWebAutoConfiguration +com.orion.ops.framework.web.config.OrionLogPrinterConfiguration \ No newline at end of file diff --git a/orion-ops-framework/pom.xml b/orion-ops-framework/pom.xml new file mode 100644 index 00000000..22553a66 --- /dev/null +++ b/orion-ops-framework/pom.xml @@ -0,0 +1,24 @@ + + + + com.orion.ops + orion-ops-pro + ${revision} + + + 4.0.0 + orion-ops-framework + pom + + 项目组件包 + https://github.com/lijiahangmax/orion-ops-pro + + + orion-ops-common + orion-ops-spring-boot-starter-banner + orion-ops-spring-boot-starter-web + + + \ No newline at end of file diff --git a/orion-ops-server/pom.xml b/orion-ops-server/pom.xml new file mode 100644 index 00000000..af498e60 --- /dev/null +++ b/orion-ops-server/pom.xml @@ -0,0 +1,88 @@ + + + + com.orion.ops + orion-ops-pro + ${revision} + + + 4.0.0 + orion-ops-server + jar + + 后端服务主项目容器 按需引用 orion-ops-module-xxx 依赖 + https://github.com/lijiahangmax/orion-ops-pro + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + com.orion.ops + orion-ops-spring-boot-starter-banner + + + com.orion.ops + orion-ops-spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-web + + + + + + + + + ${project.artifactId} + + + src/main/resources + true + + + + + + org.springframework.boot + spring-boot-maven-plugin + + 2.7.11 + + true + + + + + + repackage + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.7 + + + @ + + false + + + + + + \ No newline at end of file diff --git a/orion-ops-server/src/main/java/com/orion/ops/server/OrionOpsApplication.java b/orion-ops-server/src/main/java/com/orion/ops/server/OrionOpsApplication.java new file mode 100644 index 00000000..042798dc --- /dev/null +++ b/orion-ops-server/src/main/java/com/orion/ops/server/OrionOpsApplication.java @@ -0,0 +1,20 @@ +package com.orion.ops.server; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +/** + * application 启动类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/19 16:55 + */ +@SpringBootApplication(scanBasePackages = {"com.orion.ops.server", "com.orion.ops.module"}) +public class OrionOpsApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(OrionOpsApplication.class).run(args); + } + +} diff --git a/orion-ops-server/src/main/java/com/orion/ops/server/config/ApplicationConfiguration.java b/orion-ops-server/src/main/java/com/orion/ops/server/config/ApplicationConfiguration.java new file mode 100644 index 00000000..7011ecdf --- /dev/null +++ b/orion-ops-server/src/main/java/com/orion/ops/server/config/ApplicationConfiguration.java @@ -0,0 +1,25 @@ +package com.orion.ops.server.config; + +import com.orion.spring.SpringHolder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 应用配置类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/20 10:34 + */ +@Configuration +public class ApplicationConfiguration { + + /** + * @return spring 容器工具类 + */ + @Bean + public SpringHolder.ApplicationContextAwareStore springHolderAware() { + return new SpringHolder.ApplicationContextAwareStore(); + } + +} diff --git a/orion-ops-server/src/main/java/com/orion/ops/server/controller/BootstrapController.java b/orion-ops-server/src/main/java/com/orion/ops/server/controller/BootstrapController.java new file mode 100644 index 00000000..4ec4d490 --- /dev/null +++ b/orion-ops-server/src/main/java/com/orion/ops/server/controller/BootstrapController.java @@ -0,0 +1,23 @@ +package com.orion.ops.server.controller; + +import com.orion.ops.framework.common.annotation.RestWrapper; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/19 17:08 + */ +@RestWrapper +@RestController +@RequestMapping("/server/bootstrap") +public class BootstrapController { + + @GetMapping("/health") + public String health() { + return "server ok"; + } + +} diff --git a/orion-ops-server/src/main/resources/application-dev.yaml b/orion-ops-server/src/main/resources/application-dev.yaml new file mode 100644 index 00000000..e69de29b diff --git a/orion-ops-server/src/main/resources/application-prod.yaml b/orion-ops-server/src/main/resources/application-prod.yaml new file mode 100644 index 00000000..e69de29b diff --git a/orion-ops-server/src/main/resources/application.yaml b/orion-ops-server/src/main/resources/application.yaml new file mode 100644 index 00000000..a35fdf78 --- /dev/null +++ b/orion-ops-server/src/main/resources/application.yaml @@ -0,0 +1,31 @@ +server: + port: 9200 + +spring: + application: + name: orion-ops-server + profiles: + active: dev + main: + # 允许循环依赖 + allow-circular-references: true + # Servlet 配置 + servlet: + # 文件上传相关配置项 + multipart: + # 单个文件大小 + max-file-size: 16MB + # 设置总上传的文件大小 + max-request-size: 32MB + mvc: + pathmatch: + matching-strategy: ANT_PATH_MATCHER + +orion: + # 版本 + version: @revision@ + api: + # 公共api前缀 + prefix: /orion-api + # 是否开启跨域 + cors: true diff --git a/orion-ops-server/src/test/java/com/orion/ops/server/controller/BootstrapController.http b/orion-ops-server/src/test/java/com/orion/ops/server/controller/BootstrapController.http new file mode 100644 index 00000000..2134ac2f --- /dev/null +++ b/orion-ops-server/src/test/java/com/orion/ops/server/controller/BootstrapController.http @@ -0,0 +1,5 @@ +### 心跳检测 +GET http://{{baseUrl}}/server/bootstrap/health +Accept: application/json + +### diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..2865a376 --- /dev/null +++ b/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + com.orion.ops + orion-ops-pro + ${revision} + pom + ${project.artifactId} + + 项目脚手架 + https://github.com/lijiahangmax/orion-ops-pro + + + orion-ops-dependencies + orion-ops-framework + orion-ops-server + + + + 1.0.0 + 8 + 8 + 3.0.0-M5 + 3.8.1 + 1.18.26 + 2.7.11 + 1.5.5.Final + UTF-8 + + + + + + com.orion.ops + orion-ops-dependencies + ${revision} + pom + import + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + + org.springframework.boot + spring-boot-configuration-processor + ${spring.boot.version} + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + + + + + + + aliyun-repos + https://maven.aliyun.com/nexus/content/groups/public/ + + false + + + + + + + aliyun-plugin + https://maven.aliyun.com/nexus/content/groups/public/ + + false + + + + + \ No newline at end of file