Compare commits
10
Commits
b63eee92a4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59c26df5e0 | ||
|
|
6bce9e99a1 | ||
|
|
4a64b081ce | ||
|
|
5535e7fd09 | ||
|
|
0853ef30fc | ||
|
|
d733830449 | ||
|
|
86010c796d | ||
|
|
95baf53861 | ||
|
|
1129afeeb1 | ||
|
|
892dd81f3c |
@@ -0,0 +1,9 @@
|
||||
.git
|
||||
.idea
|
||||
.settings
|
||||
.cache
|
||||
logs
|
||||
src
|
||||
docs
|
||||
target/*
|
||||
!target/*.jar
|
||||
+9
-10
@@ -1,16 +1,15 @@
|
||||
FROM 130.120.3.193/library/alpine-oraclejdk8:slim
|
||||
FROM reg.int.it2000.com.cn/com.gzzn.library/alpine-oraclejdk8:slim
|
||||
MAINTAINER xiunai78 <154707516@qq.com>
|
||||
|
||||
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
|
||||
&& apk add -U tzdata \
|
||||
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||
&& echo 'Asia/Shanghai' >/etc/timezone
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# Add the service itself
|
||||
ARG JAR_FILE
|
||||
ADD ${JAR_FILE} /usr/local/adminapi/myapp.jar
|
||||
|
||||
#设置时区
|
||||
RUN apk add -U tzdata
|
||||
|
||||
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||
&& echo 'Asia/Shanghai' >/etc/timezone
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/local/adminapi/myapp.jar"]
|
||||
@@ -0,0 +1,449 @@
|
||||
# admin-api
|
||||
|
||||
成都天府/双流机场 OMMS(机场运行管理系统)的**后端管理 API**,为 Web 控制台提供基础数据、数据字典、UI 个性化设置、航班季度计划、历史航班检索与 Excel 导出能力。
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 坐标 | `com.gzzn.omms:admin-api` |
|
||||
| 版本 | `1.2.1-SNAPSHOT` |
|
||||
| 技术栈 | Spring Boot 1.5.17 · Spring Cloud Edgware.SR5 · Java 8 · Maven |
|
||||
| 服务注册 | Eureka,服务名 `adminapi` |
|
||||
| 监听端口 | 8080(`Dockerfile` EXPOSE,配置文件未覆盖) |
|
||||
| 仓库 | `git@repo.windy.me:cdia/admin-api.git` |
|
||||
|
||||
> **Java 版本要求:JDK 8。** 项目基于 Spring Boot 1.5 和 JAXB 生成代码构建,未验证 JDK 11+;请使用 JDK 8 进行本地开发、构建和运行。
|
||||
|
||||
**Podman 测试镜像构建**:见 [构建说明](docs/build.md),使用 `./build.sh -t localhost/admin-api:1.2.1-pg-test`,Maven 缓存默认放在 `../chengdu-repository`。
|
||||
|
||||
**定位:只读数据服务层。** 本服务不生产业务数据,OMMS 主数据由 Oracle 侧系统维护,本服务只做查询与对外暴露;仅 MySQL 侧的 UI 设置为本服务自有写数据。
|
||||
|
||||
**不在本服务职责内**:航班动态实时推送、航班保障流程、报文收发与解析落库(由 AODB/消息中间件侧负责)。本服务不保存航班数据,历史航班从 Elasticsearch 读取。
|
||||
|
||||
---
|
||||
|
||||
## 1. 架构
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
浏览器 ──> 网关 ───>│ admin-api (adminapi) │
|
||||
注入 user 头 │ │
|
||||
│ controller → dao → convert → dto │
|
||||
└───┬──────────┬──────────┬──────────┬─────┘
|
||||
│ │ │ │
|
||||
MySQL Oracle Elasticsearch sysapi
|
||||
(自有/写) (主数据/读) (历史航班/日志) (日志开关)
|
||||
```
|
||||
|
||||
### 外部依赖与降级行为
|
||||
|
||||
| 依赖 | 用途 | 不可用时的影响 |
|
||||
|---|---|---|
|
||||
| **MySQL**(Primary) | 数据字典、UI 设置 | 字典与 UI 设置接口全部 500 |
|
||||
| **Oracle**(Secondary) | 机场基础数据、航班季度计划 | 基础数据/季度计划接口全部 500 |
|
||||
| **Elasticsearch** | 历史航班查询、操作日志写入 | 历史航班查询 500;**写日志失败被 catch 吞掉,不影响主流程** |
|
||||
| **sysapi**(Eureka 服务名 `SYSAPI`) | 拉取操作日志开关 | UI 设置已落库;日志开关查询异常会被捕获并记录,**不影响保存结果,但会丢失本次审计日志** |
|
||||
| **Eureka** | 服务注册与 `SYSAPI` 寻址 | 注册失败则不被网关发现;`SYSAPI` 调用失败 |
|
||||
|
||||
### 身份与鉴权(重要)
|
||||
|
||||
**本服务不做任何登录鉴权,也没有接口级权限控制。** 完全信任网关:
|
||||
|
||||
- `/settings/uisettings` 通过请求头 `user`(Base64 编码的 JSON)取得 `userId / userName / realName`;头缺失时,该接口抛 `UserNoLoginException`,全局处理返回 **401 + `USER_NOT_LOGGED_IN`**
|
||||
- 基础数据、字典、季度计划和历史航班接口当前**不会读取 `user` 头,可匿名访问**
|
||||
- 请求头 `remoteAddress`(同为 Base64 JSON)携带客户端来源地址,用于审计日志
|
||||
|
||||
> 因此本服务**绝不能直接暴露到公网**,必须经网关访问。否则基础数据、字典及历史航班查询接口会直接暴露;UI 设置的数据隔离也仅依赖 `userId`,属"代码层隔离"而非强制鉴权。
|
||||
|
||||
---
|
||||
|
||||
## 2. 快速开始
|
||||
|
||||
### 前置条件
|
||||
|
||||
- JDK 8、Maven 3
|
||||
- 可达的 MySQL、Oracle、Elasticsearch、Eureka(本地开发可用 `dev` 环境现有实例)
|
||||
- Oracle 驱动:pom 以 `system` scope 引用 `src/main/resources/libs/ojdbc6-11.2.0.3.jar`,该 jar 已在仓库内,**无需额外安装**
|
||||
|
||||
### 运行
|
||||
|
||||
```bash
|
||||
# 开发模式(默认 profile=dev)
|
||||
mvn spring-boot:run
|
||||
|
||||
# 打包
|
||||
mvn clean package -Dmaven.test.skip=true
|
||||
java -jar target/admin-api-1.2.1-SNAPSHOT.jar
|
||||
|
||||
# 指定环境
|
||||
java -jar target/admin-api-1.2.1-SNAPSHOT.jar --spring.profiles.active=test
|
||||
```
|
||||
|
||||
### 验证
|
||||
|
||||
```bash
|
||||
# 接口文档(swagger-bootstrap-ui)
|
||||
open http://localhost:8080/doc.html
|
||||
open http://localhost:8080/swagger-ui.html
|
||||
|
||||
# 冒烟:字典查询(当前无需 user 头)
|
||||
curl http://localhost:8080/dictionary/datadicItems/ROUTE_TYPE
|
||||
```
|
||||
|
||||
> **注意**:Swagger UI 可直接调试当前不读取 `user` 头的接口;调试 `/settings/uisettings` 时需经网关注入 `user` 头,否则会返回 401。
|
||||
|
||||
---
|
||||
|
||||
## 3. 配置
|
||||
|
||||
`application.yml`(公共)+ `application-{dev,test,pro}.yml`,通过 `spring.profiles.active` 切换(默认 `dev`)。
|
||||
|
||||
| 配置项 | 说明 |
|
||||
|---|---|
|
||||
| `spring.datasource.primary.*` | MySQL 连接 + Tomcat JDBC 连接池参数 |
|
||||
| `spring.datasource.secondary.*` | Oracle 连接,`driver: oracle.jdbc.driver.OracleDriver` |
|
||||
| `eureka.client.service-url.defaultZone` | 注册中心地址 |
|
||||
| `elasticsearch.cluster.nodes` / `cluster.name` / `maxSize` | ES 集群(9300 传输端口) |
|
||||
| `sysApi.getOpLogSwitchByLevleAndNameUrl` | 操作日志开关接口,含 `{level}` `{name}` 占位符 |
|
||||
| `logstash.host` | 日志收集地址(`host:port`) |
|
||||
|
||||
### 环境对照
|
||||
|
||||
| | dev | test | pro |
|
||||
|---|---|---|---|
|
||||
| MySQL | `130.120.3.235:3306` | `130.120.3.158:3306` | `172.17.35.162:3306` |
|
||||
| Oracle | `130.120.2.105:1521/orcl` | `130.120.3.31:1521/orcl` | `172.17.35.43:1521/omms` |
|
||||
| Eureka | `130.120.3.235:94` | `130.120.3.232:94` | `172.17.35.164:94` |
|
||||
| ES 集群 | `.234/.236/.238:9300` | `.234/.236/.238:9300` | `172.17.35.160/.161/.162:9300` |
|
||||
| Logstash | `130.120.3.234:5000` | `130.120.3.234:5000` | `172.17.35.160:5000` |
|
||||
|
||||
### 密码加密(预留但未启用)
|
||||
|
||||
`PrimaryDataSourceConfig` 中保留了加密入口,当前**被注释**:
|
||||
|
||||
```java
|
||||
//dataSource.setPassword(ConfigTools.decrypt(properties.getPassword()));//解密数据库密码
|
||||
dataSource.setPassword(properties.getPassword());
|
||||
```
|
||||
|
||||
如需启用,取消注释并引入 Druid `ConfigTools`。目前所有环境**明文口令已提交进 Git**(含生产 `root`)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据层
|
||||
|
||||
### 双数据源
|
||||
|
||||
本服务使用两套手工配置的 JPA 数据源:
|
||||
|
||||
| 数据源 | 数据库 | 当前用途 |
|
||||
|---|---|---|
|
||||
| Primary | MySQL | 数据字典、UI 设置(读写) |
|
||||
| Secondary | Oracle | 机场基础数据、航班季度计划(当前业务只读) |
|
||||
|
||||
每一侧都拥有独立的 `DataSource → EntityManagerFactory → TransactionManager`。Primary/Secondary 的 DAO 与 Entity 分别由对应配置类按包扫描并绑定,因此新增表访问时必须将 Entity 和 DAO 放到同一侧的包中。
|
||||
|
||||
> Secondary 未配置强制只读保护;跨库操作也不具备原子性。涉及写操作时必须明确指定事务管理器。
|
||||
|
||||
双数据源的实现原理、配置位置、新增 DAO/Entity 的步骤、常见错误与事务示例见 **[双数据源说明](docs/datasource.md)**。
|
||||
|
||||
### MySQL 自有表(4 张)
|
||||
|
||||
| 表 | 用途 |
|
||||
|---|---|
|
||||
| `adminapi_datadic_groups` | 字典分组(如 `FLIGHT_TASK` 航班任务、`ROUTE_TYPE` 航线类别) |
|
||||
| `adminapi_datadic_items` | 字典项 |
|
||||
| `adminapi_uisettings` | **用户** UI 设置,按 `(group_code, userid)` 唯一 |
|
||||
| `adminapi_uisettings_default` | **系统默认** UI 设置,按 `group_code` |
|
||||
|
||||
`uisettings.setting_content` 存 JSON,含 `userSettingCol`(表格列)、`userSettingColor`(配色)、`userSettingMsgAlert`(消息告警订阅)、`userSettingSelected`(查询条件默认值)等分组。
|
||||
|
||||
### Oracle 数据(当前业务只读)
|
||||
|
||||
基础数据:航司/机场/城市/国家及其分组、航站楼与区域、机位与机位类型、登机口、滑槽、值机柜台与分组、行李转盘、机型与机号、机型分组、航班状态与类型、航班代理。
|
||||
航班计划:`FIMS_FLIGHTSCHD_SEASON`(季度计划)、`FIMS_MIDAIRPORTS_SEASON`(经停航段)。
|
||||
|
||||
### Elasticsearch 索引
|
||||
|
||||
| 索引 | 用途 | 映射 |
|
||||
|---|---|---|
|
||||
| `flight_hts` | 历史航班查询 | 实为**别名**,指向 `flight_hts2`;mapping 见 `resources/es/v1.2.0_20190428_flightHstMapping.json` |
|
||||
| `oplog` | 操作日志(审计) | **无 mapping 文件**,由代码 `createIndex` 自动创建,依赖动态映射 |
|
||||
|
||||
> 索引与 mapping 需**手工创建**:ES 资源目录下的 JSON 是 Kibana/Dev Tools 可直接执行的脚本(`PUT flight_hts2` → `PUT /flight_hts2/_alias/flight_hts` → `PUT flight_hts2/_doc/_mapping`)。`oplog` 由代码首次写入时自动创建,但字段类型由 ES 动态推断,生产建议预先定义 mapping。
|
||||
|
||||
### 数据库变更
|
||||
|
||||
**没有 Flyway / Liquibase**,靠 `src/main/resources/db/migration/` 下脚本**人工执行**:
|
||||
|
||||
```
|
||||
v0.0.1.20190110_adminapi_ddl.sql 建 4 张表
|
||||
v0.0.1.20190110_adminapi_initdata.sql 字典与默认 UI 设置初始化
|
||||
v0.0.2.20190327_adminapi_updatecolorsetting.sql 更新默认配色
|
||||
v1.2.0.20190329_adminapi_addUserSettingSelected.sql 新增 userSettingSelected 分组
|
||||
v1.2.0.20190507_adminapi_updateUserSettingCol.sql 更新默认表格列(406 行)
|
||||
```
|
||||
|
||||
命名规范:`v{版本}.{日期}_{模块}_{说明}.sql`。**上线前必须确认脚本已在目标库执行**,无自动校验。
|
||||
|
||||
---
|
||||
|
||||
## 5. API 概览
|
||||
|
||||
### 统一响应契约
|
||||
|
||||
```json
|
||||
{ "is_success": true, "err_code": 1, "err_msg": "成功", "body": {} }
|
||||
```
|
||||
|
||||
成功 `err_code=1`,失败 `err_code=0`(业务细分码见 `enums/ResultCode`)。
|
||||
|
||||
### 错误码分段
|
||||
|
||||
| 段 | 含义 | 典型 |
|
||||
|---|---|---|
|
||||
| `1` / `0` | 通用成功 / 失败 | — |
|
||||
| `10001–19999` | 参数错误 | `PARAM_IS_INVALID` `PARAM_NOT_COMPLETE` |
|
||||
| `20001–29999` | 用户错误 | `USER_NOT_LOGGED_IN` `USER_NOT_EXIST` |
|
||||
| `30001–39999` | 业务错误 | `SPECIFIED_*_NOT_FOUND` |
|
||||
| `40001–49999` | 系统错误 | `SYSTEM_INNER_ERROR` |
|
||||
| `50001–59999` | 数据错误 | `RESULE_DATA_NONE` `DATA_ALREADY_EXISTED` |
|
||||
| `60001–69999` | 接口错误 | `INTERFACE_INNER_INVOKE_ERROR` |
|
||||
| `70001–79999` | 权限错误 | `PERMISSION_NO_ACCESS` |
|
||||
|
||||
> `ExceptionHandle` 兜底所有未捕获异常 → **HTTP 500 + `SYSTEM_INNER_ERROR`**,响应体 `err_msg` 形如 `requestId:xxx,errorMsg:yyy`。**`requestId` 是排障第一线索**,见第 7 节。
|
||||
|
||||
### 端点清单
|
||||
|
||||
**基础数据**(`controller/basicdata`,全部 `GET`,全量返回无分页)
|
||||
|
||||
| 领域 | 端点 |
|
||||
|---|---|
|
||||
| 航空公司 / 集团 | `/basicdata/sysAirlines`、`/basicdata/sysAirlineGroup` |
|
||||
| 机场 / 集团 | `/basicdata/sysAirports`、`/basicdata/sysAirportGroups` |
|
||||
| 城市 / 国家 | `/basicdata/sysCitys`、`/basicdata/sysCountry` |
|
||||
| 航站楼 / 区域 | `/basicdata/ormsTerminals`、`/basicdata/ormsTerminalareas` |
|
||||
| 机位 / 机位类型 | `/basicdata/ormsStands`、`/basicdata/ormsStandTypes` |
|
||||
| 登机口 / 滑槽 | `/basicdata/ormsGates`、`/basicdata/ormsChuts` |
|
||||
| 值机柜台 / 转盘 | `/basicdata/ormsCheckindesks`、`/basicdata/ormsCarousels` |
|
||||
| 值机分组 | `/basicdata/checkinGroups` |
|
||||
| 机型 / 机号 / 机型分组 | `/basicdata/sysAircrafttypes`、`/basicdata/sysAircrafts`、`/basicdata/sysAircrafttypesGroup` |
|
||||
| 航班状态 / 类型 / 代理 | `/basicdata/sysFlightStatus`、`/basicdata/sysFlightTypes`、`/basicdata/sysFlightAgents` |
|
||||
| 航班状态定义 | `/basicdata/flmsFlightStatusDefinition` |
|
||||
| 机位 → 廊桥号 | `/basicdata/ormsStands/{standCode}/airbridgeCode` |
|
||||
|
||||
**业务接口**
|
||||
|
||||
| 方法 | 端点 | 说明 |
|
||||
|---|---|---|
|
||||
| `GET` | `/dictionary/datadicItems/{groupCode}` | 按分组查字典项 |
|
||||
| `GET` | `/settings/uisettings` | 查当前用户 UI 设置(`envCode` `groupCode` 可选) |
|
||||
| `POST` | `/settings/uisettings` | 保存 UI 设置 + 写操作日志到 ES |
|
||||
| `GET` | `/schedule/flightSchdSeasons` | 航班季度计划(`startDate` 年份可选) |
|
||||
| `GET` | `/schedule/flightSchdSeason/years` | 季度计划可选年份 |
|
||||
| `POST` | `/hitFlightData/list` | 历史航班检索(ES) |
|
||||
| `POST` | `/fltrs/toExcel` | 航班动态导出 Excel |
|
||||
|
||||
---
|
||||
|
||||
## 6. 核心业务逻辑
|
||||
|
||||
### 6.1 UI 个性化设置 —— `settings/UISettingsController`
|
||||
|
||||
本项目**唯一有真正业务密度**的逻辑:**用户设置覆盖系统默认设置**的合并策略。
|
||||
|
||||
`GET /settings/uisettings`:
|
||||
|
||||
1. 取全量 `adminapi_uisettings_default` 载入 Map(key = `groupCode`)
|
||||
2. 按 `envCode` / `groupCode` 的空与非空,4 个分支走不同 DAO 查询当前用户的 `uisettings`
|
||||
3. 用户配置转 DTO;**每命中一条,从默认 Map 移除同 `groupCode` 项**(用户优先)
|
||||
4. 合并剩余默认项:仅当"两条件都为空"或"仅传 groupCode"时补回
|
||||
|
||||
`POST /settings/uisettings`:
|
||||
|
||||
1. 按 `(groupCode, userId)` 查旧值:存在则更新并复用原 id,不存在则 `CommonUtils.getUUID32()` 生成新 id
|
||||
2. `save()` 落库
|
||||
3. **写审计日志到 ES `oplog`**,记录新旧值 JSON、操作人、来源 IP、操作类型(`ADD`/`UPDATE`)
|
||||
|
||||
日志开关判定 `ifNeedMarkLog(level, name)`:经 `OplogSwithcInfoServiceImpl` 调用 `sysapi` 的 `/oplog/getOpLogSwitch/{level}/{name}` 拉取开关列表(`@LoadBalanced RestTemplate`,走 Eureka 服务名 `SYSAPI`)。规则:父级(`level` 更小)关闭则整类不记录;同级需再比对 `name`。
|
||||
|
||||
> **已知风险**:开关列表 `opLogSwitchInfos` 缓存在 Controller 实例字段中,**启动后不再刷新**,开关变更需重启本服务才生效;首次拉取失败及 ES 写入异常均会被 catch 并记录 error 日志,**不阻断主流程**(日志丢失但不影响用户)。
|
||||
|
||||
### 6.2 历史航班检索 —— `history/HistoryFlightDataController`
|
||||
|
||||
`POST /hitFlightData/list` 查 **ES** 索引 `flight_hts`,不查数据库。
|
||||
|
||||
- 时间窗:默认**前一天**全天;传 `hstFLightTime` 则查该日 `00:00:00 ~ 23:59:59`
|
||||
- `BoolQueryBuilder` 叠加:`SODT`(计划时间)range + `MVIN`(`A` 到达 / `D` 离港)term
|
||||
- 按 `SODT` 升序,条数上限 `elasticsearch.maxSize`(各环境均为 10000)
|
||||
- 映射为 `SCHD.FLTR`,**过滤掉 `MAID != null` 的共享航班**
|
||||
- 时间需经 `DateUtils.swichTimeToEn_ddMMMyyHHmm` 转英文格式(`ddMMMyyHHmm`)后查询——ES 中存的即此格式;`startSODT`、`endSODT` 均可单独传入
|
||||
|
||||
### 6.3 航班动态导出 Excel —— `fltrs/FltrController`
|
||||
|
||||
`POST /fltrs/toExcel`:前端把**已渲染在页面上的列定义与数据**回传,服务端按 `columns` 顺序用 Apache POI 拼装 xlsx 直接写 `HttpServletResponse`。**不查库**,服务端不限定导出字段(历史演进见提交 `b0ed00e`)。失败返回 JSON 错误描述。
|
||||
|
||||
> 数据量由前端决定,无服务端上限;超大导出可能引起内存与超时问题。
|
||||
|
||||
### 6.4 报文实体 —— `entity/msg`(约 130 个类)
|
||||
|
||||
按机场行业标准报文(AIDX 风格)由 **XSD 经 JAXB 生成**。**切勿手工修改**——文件头已注明重新编译 Schema 会丢失改动。`SCHD`(航班计划)下嵌套 `FLTR`(航班),是历史航班检索与 Excel 导出的返回模型。字段释义见 `resources/es/v0.0.1_20181213_hisPlaneDataDesc.json`。
|
||||
|
||||
---
|
||||
|
||||
## 7. 可观测性
|
||||
|
||||
### 日志
|
||||
|
||||
`logback-spring.xml` 三个 Appender:
|
||||
|
||||
| Appender | 说明 |
|
||||
|---|---|
|
||||
| `STDOUT` | 控制台(容器运行时进 `docker logs`) |
|
||||
| `FILE` | `logs/adminapi.log`,按 10MB 滚动,保留 60 天,总上限 20GB |
|
||||
| `SOCKET` | Logstash TCP,附带 `app_name=cdairport`、`model_name=adminapi`,由 `logstash.host` 指定 |
|
||||
|
||||
### 链路追踪
|
||||
|
||||
`ExceptionAspect`(AOP 切 `controller..*`)在**每个请求进入时**:
|
||||
|
||||
1. `MDC.clear()` 后写入 `request_id`(取请求头,缺失则生成 UUID)
|
||||
2. 记录 `url / method / content_type / body / params / remoteip`
|
||||
3. 返回时记录响应体
|
||||
|
||||
`request_id` 随 MDC 进入 Logstash,是**跨服务串联与排障的主线索**;同时被 `ExceptionHandle` 写入错误响应体,用户报错时可直接凭此 ID 检索日志。
|
||||
|
||||
### 健康检查现状
|
||||
|
||||
> **未引入 Spring Boot Actuator**,因此**没有 `/health`、`/info`、`/metrics` 端点**。容器编排与网关只能靠 TCP 8080 探活,无法感知数据库/ES 连通性。Kibana 检索建议:`model_name: "adminapi"` + `request_id`。
|
||||
|
||||
---
|
||||
|
||||
## 8. 构建与部署
|
||||
|
||||
### CI/CD(`jenkins/Jenkinsfile`)
|
||||
|
||||
两阶段流水线:
|
||||
|
||||
1. **maven build** — 在 `maven:3-alpine` 容器中 `mvn clean package -Dmaven.test.skip=true`(复用宿主 `~/.m2`)
|
||||
2. **docker build & push** — Jenkins Docker Pipeline 通过 `docker.build(...).push()` 构建并推送至 `reg.int.it2000.com.cn/com.gzzn.omms/admin-api:{version}`
|
||||
|
||||
镜像基于 `alpine-oraclejdk8:slim`,时区设为 `Asia/Shanghai`,`ENTRYPOINT` 为 `java -jar /usr/local/adminapi/myapp.jar`。
|
||||
|
||||
### 发布
|
||||
|
||||
`maven-release-plugin` 已接入。历史版本:`admin-api-1.2.0`(提交 `1129afe`)。
|
||||
|
||||
```bash
|
||||
mvn release:prepare release:perform
|
||||
```
|
||||
|
||||
> `pom.xml` 的 `<scm>` 仍指向旧地址 `git@git.int.it2000.com.cn:...`,与当前实际 remote(`git@repo.windy.me:cdia/admin-api.git`)**不一致**,执行 release 前需修正。
|
||||
|
||||
### 部署检查清单
|
||||
|
||||
- [ ] 目标环境 `db/migration/` 中**未执行过**的脚本已人工执行
|
||||
- [ ] ES 索引 `flight_hts2` + 别名 `flight_hts`、mapping 已创建
|
||||
- [ ] `application-{profile}.yml` 中数据库/Eureka/ES/Logstash 地址与实际环境一致
|
||||
- [ ] 确认 `sysapi` 服务已在 Eureka 注册(否则 UI 设置审计日志可能丢失)
|
||||
- [ ] 镜像 tag 与 `pom.xml` 版本一致
|
||||
|
||||
---
|
||||
|
||||
## 9. 运维排障
|
||||
|
||||
| 现象 | 排查方向 |
|
||||
|---|---|
|
||||
| 启动报 `Table not found` / Entity 找不到 | Entity 或 DAO 放错包(`primary` ↔ `secondary`),见第 4 节"双数据源:实现原理" |
|
||||
| 启动成功但查询报 `ORA-00942` / `Table 'xxx' doesn't exist` | Entity/DAO 放错包(`primary` ↔ `secondary`)。`ddl-auto` 未配置,Hibernate 启动时**不校验表是否存在**,错误延迟到首次查询才暴露,见第 4 节 |
|
||||
| `/settings/uisettings` 返回 401 `USER_NOT_LOGGED_IN` | 网关未注入 `user` 头,或头被中间层剥离 |
|
||||
| 500 `SYSTEM_INNER_ERROR` | 取响应体 `requestId`,到 Kibana 检索完整堆栈 |
|
||||
| UI 设置审计日志未写入 | 检查 `sysapi` 服务可用性、Eureka 注册、`oplog` 索引及 ES 日志;开关拉取或 ES 写入失败不影响 UI 设置保存 |
|
||||
| 历史航班查不到数据 | 检查 `flight_hts` 别名是否存在、ES 数据是否已同步、`SODT` 格式是否为 `ddMMMyyHHmm` |
|
||||
| 操作日志未写入 ES | 检查 `oplog` 索引与日志开关;ES 写入异常仅记 error 日志,不阻断业务 |
|
||||
| 数据库连接耗尽 | Tomcat JDBC 池 `max-active: 30`,检查慢查询与连接泄漏;`show-sql: true` 便于定位 SQL |
|
||||
| 服务未被网关发现 | `eureka.instance.hostName: adminapi` 且 `prefer-ip-address: false`,依赖主机名解析 |
|
||||
|
||||
### 已知技术债与风险
|
||||
|
||||
按处理优先级:
|
||||
|
||||
1. **明文口令入库**:三套环境(含生产 `root`)口令以明文提交进 Git。应尽快接入配置中心或环境变量,或启用已预留的 `ConfigTools.decrypt`。
|
||||
2. **无健康检查端点**:未引入 Actuator,无法探活依赖组件。建议加 `spring-boot-starter-actuator` 并暴露 `/health`。
|
||||
3. **生产开启 `show-sql: true`**:三个 profile 全开,生产环境会产生大量 SQL 日志,影响性能与日志体积。建议生产关闭。
|
||||
4. **`oplog` 索引无 mapping**:依赖 ES 动态映射,字段类型不可控,易引发类型冲突。建议补 mapping 文件。
|
||||
5. **无接口级鉴权**:基础数据、字典、季度计划和历史航班接口可匿名访问;UI 设置仅靠 `userId` 做代码层隔离。任何新接口必须补充认证授权,并在涉及用户数据时带上用户维度过滤。
|
||||
6. **日志开关不刷新**:`opLogSwitchInfos` 缓存在实例字段,开关变更需重启。
|
||||
7. **基础数据接口无分页**:全量返回,数据量增长后需改造。
|
||||
8. **`SwaggerConfig.host` 硬编码** `130.120.3.231:91/adminapi`,非当前环境地址,会导致 Swagger 调试请求发往错误主机。
|
||||
9. **无自动数据库迁移**:人工执行脚本,存在漏执行风险。建议引入 Flyway。
|
||||
10. **裸写 `@Transactional` 会静默绑定到 primary**:业务代码中目前无任何 `@Transactional`,而 primary 的 TM 带 `@Primary`。新增 Oracle 侧写逻辑时必须显式指定 `transactionManagerSecondary`,否则事务落在 MySQL 上(详见第 4 节)。
|
||||
11. **`entity/msg` 为 JAXB 生成代码**:约 130 个类,报文结构变更须改 Schema 后重新生成。
|
||||
12. **技术栈已 EOL**:Spring Boot 1.5.17(2018)、Java 8、ES TransportClient(ES 7+ 已移除)、JAXB(Java 11+ 已移除)。升级需通盘规划。
|
||||
|
||||
---
|
||||
|
||||
## 10. 二次开发指南
|
||||
|
||||
### 分层约定
|
||||
|
||||
```
|
||||
controller → dto/convert → domain.{primary|secondary}.dao → DB
|
||||
(MapStruct)
|
||||
```
|
||||
|
||||
- **基础数据类接口当前无 Service 层**(Controller 直接注入 DAO),这对纯查询转发是可接受的既定模式;**新增含业务规则的功能请引入 Service 层**,勿继续在 Controller 中堆积逻辑(参见 `UISettingsController`,其业务规则已使 Controller 明显臃肿)。
|
||||
- **对外一律返回 DTO**,禁止直接序列化 Entity——会暴露 Oracle 表结构并可能引发循环引用。MapStruct Converter 位于各 `dto/*/convert/` 包,编译期生成实现。
|
||||
|
||||
### 新增一个基础数据接口的步骤
|
||||
|
||||
1. `domain.secondary.entity.baiscdata/` 建 Entity(Oracle 表映射到 Secondary,**注意包名归属**,见第 4 节)
|
||||
2. `domain.secondary.dao.basicdata/` 建 DAO,继承 `CrudRepository<T, String>`;复杂查询用 `@Query`
|
||||
3. `dto/basicdata/` 建 DTO,`dto/basicdata/convert/` 建 MapStruct Converter
|
||||
4. `controller/basicdata/` 建 Controller,注入 DAO + Converter,返回 `ResponseDto.success(dtoList)`
|
||||
5. 补 `@ApiOperation`(Swagger)
|
||||
|
||||
### 编码注意
|
||||
|
||||
- 修改 `entity/msg` 下的类前,确认是否应改 Schema 重新生成
|
||||
- 新增配置需在**三个 profile** 的 yml 中同步(当前无默认值兜底,缺失即启动失败)
|
||||
- 涉及用户数据的查询,**必须带上 `userService.getCurrentUserId()` 条件**
|
||||
|
||||
### 测试
|
||||
|
||||
`src/test` 下 7 个测试类,**多为需要真实 Oracle/ES 的集成测试**,运行前确保环境可达:
|
||||
|
||||
`AdminApiApplicationTests`、`OrmsStandControllerTest`、`FlightSchdSeasonControllerTest`、`FltrControllerTest`、`SysAirlineGroupDaoTest`、`OrmsStandAirbridgeDaoTest`、`ElasticsearchUtilTest`
|
||||
|
||||
CI 中均以 `-Dmaven.test.skip=true` 跳过,测试未纳入质量门禁。
|
||||
|
||||
---
|
||||
|
||||
## 11. 目录结构
|
||||
|
||||
```
|
||||
src/main/java/com/gzzn/omms/adminapi/
|
||||
├── AdminApiApplication.java # 启动类(@EnableEurekaClient)
|
||||
├── config/ # 双数据源装配(见第 4 节)
|
||||
│ ├── PrimaryDataSourceConfig / SecondaryDataSourceConfig # DataSource Bean
|
||||
│ ├── PrimaryConfig / SecondaryConfig # EMF + TM + Repository 扫描
|
||||
│ ├── PrimaryDsProperties / SecondaryDsProperties # yml 属性绑定
|
||||
│ └── RestTemplateConfig / swagger/
|
||||
├── controller/ # basicdata / dictionary / fltrs / history / schedule / settings
|
||||
├── domain/ # ★ 包名决定走哪个库,勿放错
|
||||
│ ├── primary/ # → MySQL: dictionary, settings(读写)
|
||||
│ └── secondary/ # → Oracle: basicdata, schedule(当前业务只读)
|
||||
├── dto/ # DTO + MapStruct convert
|
||||
├── elasticsearch/ # TransportClient 配置、查询工具、操作日志模型
|
||||
├── entity/msg/ # JAXB 生成的报文实体(勿手改)
|
||||
├── enums/ResultCode.java # 错误码
|
||||
├── exception/handler/ # 全局异常处理 + 请求日志 AOP
|
||||
├── service/ # 当前用户解析、操作日志开关
|
||||
└── utils/ # 日期 / JSON / UUID / Excel 导出
|
||||
|
||||
src/main/resources/
|
||||
├── application{,-dev,-test,-pro}.yml
|
||||
├── logback-spring.xml
|
||||
├── db/migration/ # 手工执行的数据库变更脚本
|
||||
├── es/ # ES 索引 mapping 与字段释义
|
||||
└── libs/ojdbc6-11.2.0.3.jar # system scope 引入的 Oracle 驱动
|
||||
```
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPOSITORY="$PROJECT_DIR/../chengdu-repository"
|
||||
IMAGE='localhost/admin-api:1.2.1-pg-test'
|
||||
JAR_FILE='target/admin-api-1.2.1-SNAPSHOT.jar'
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
用法:./build.sh [-t 镜像名称:tag] [-r Maven缓存目录]
|
||||
|
||||
-t 默认 localhost/admin-api:1.2.1-pg-test,不读取 Maven 版本
|
||||
-r 默认项目旁的 ../chengdu-repository;相对路径以项目目录为基准
|
||||
-h 显示帮助
|
||||
|
||||
需要 JAVA_HOME 指向 JDK 8、Maven(或完整的 Maven Wrapper)和 Podman。
|
||||
脚本编译 JAR、检查 PostgreSQL 驱动,然后构建镜像;不会推送或启动服务。
|
||||
EOF
|
||||
}
|
||||
|
||||
die() { printf '错误:%s\n' "$*" >&2; exit 1; }
|
||||
|
||||
while getopts ':t:r:h' option; do
|
||||
case "$option" in
|
||||
t) IMAGE="$OPTARG" ;;
|
||||
r) REPOSITORY="$OPTARG" ;;
|
||||
h) usage; exit 0 ;;
|
||||
:) die "选项 -$OPTARG 缺少参数" ;;
|
||||
\?) die "未知选项 -$OPTARG" ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
[[ $# -eq 0 ]] || die '不支持额外的位置参数'
|
||||
[[ -n "$IMAGE" && -n "$REPOSITORY" ]] || die '镜像名和缓存目录不能为空'
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
[[ -n "${JAVA_HOME:-}" ]] || die '请先设置 JAVA_HOME,指向 JDK 8'
|
||||
for tool in java javac jar; do
|
||||
[[ -x "$JAVA_HOME/bin/$tool" ]] || die "JAVA_HOME 中缺少 bin/$tool"
|
||||
done
|
||||
JAVA_VERSION="$("$JAVA_HOME/bin/javac" -version 2>&1)"
|
||||
[[ "$JAVA_VERSION" == 'javac 1.8.'* ]] || die "必须使用 JDK 8,当前为 $JAVA_VERSION"
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
command -v podman >/dev/null 2>&1 || die '找不到 podman'
|
||||
|
||||
if [[ -f mvnw && -f .mvn/wrapper/maven-wrapper.properties && -f .mvn/wrapper/maven-wrapper.jar ]]; then
|
||||
MAVEN=(bash ./mvnw)
|
||||
else
|
||||
command -v mvn >/dev/null 2>&1 || die 'Maven Wrapper 不完整,请安装 Maven 3(支持 JDK 8)'
|
||||
MAVEN=(mvn)
|
||||
fi
|
||||
|
||||
mkdir -p -- "$REPOSITORY"
|
||||
REPOSITORY="$(cd -- "$REPOSITORY" && pwd)"
|
||||
printf 'Maven 缓存:%s\n镜像:%s\n' "$REPOSITORY" "$IMAGE"
|
||||
"${MAVEN[@]}" "-Dmaven.repo.local=$REPOSITORY" -DskipTests package
|
||||
|
||||
[[ -f "$JAR_FILE" ]] || die "未生成 $JAR_FILE;若修改项目版本,请同步更新脚本中的 JAR_FILE"
|
||||
# 先完整读取列表,避免 pipefail 下 grep 提前退出造成误报。
|
||||
JAR_CONTENTS="$("$JAVA_HOME/bin/jar" tf "$JAR_FILE")"
|
||||
if ! grep -E '^BOOT-INF/lib/postgresql-[^/]+\.jar$' <<< "$JAR_CONTENTS"; then
|
||||
die '应用 JAR 中缺少 PostgreSQL JDBC 驱动,停止镜像构建'
|
||||
fi
|
||||
|
||||
# Dockerfile 内嵌,通过标准输入传给 Podman,无需单独维护文件。
|
||||
podman build --pull=always \
|
||||
-f - \
|
||||
--build-arg "JAR_FILE=$JAR_FILE" \
|
||||
-t "$IMAGE" \
|
||||
. <<'DOCKERFILE'
|
||||
FROM docker.io/library/eclipse-temurin:8-jre-jammy
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||
&& echo 'Asia/Shanghai' > /etc/timezone
|
||||
|
||||
EXPOSE 8080
|
||||
ARG JAR_FILE
|
||||
COPY ${JAR_FILE} /usr/local/adminapi/myapp.jar
|
||||
ENTRYPOINT ["java", "-jar", "/usr/local/adminapi/myapp.jar"]
|
||||
DOCKERFILE
|
||||
printf '构建完成:%s\n' "$IMAGE"
|
||||
@@ -0,0 +1,26 @@
|
||||
# Podman 测试镜像构建
|
||||
|
||||
在 `admin-api` 目录执行,先把 `JAVA_HOME` 设置为本机 **JDK 8** 路径:
|
||||
|
||||
```bash
|
||||
export JAVA_HOME=/path/to/jdk8
|
||||
./build.sh -t localhost/admin-api:1.2.1-pg-test
|
||||
```
|
||||
|
||||
- Maven 依赖、插件及其元数据默认缓存到 **`../chengdu-repository`**,以脚本所在的项目目录为基准,不受调用位置影响,也不修改全局 Maven 配置。
|
||||
- 等效 Maven 参数是 `-Dmaven.repo.local=/absolute/path/to/chengdu-repository`。可以用 `./build.sh -r /other/repository -t localhost/admin-api:1.2.1-pg-test` 覆盖目录。
|
||||
- 应用构建产物仍是 `target/admin-api-1.2.1-SNAPSHOT.jar`,不会放进依赖缓存目录。修改项目版本后需同步脚本中的 `JAR_FILE`。
|
||||
- 镜像默认名为 `localhost/admin-api:1.2.1-pg-test`;`-t` 指定完整镜像名和 tag,**不会自动读取 Maven 版本**。
|
||||
- 使用完整 Maven Wrapper;仓库当前 Wrapper 不完整时回退到本机 `mvn`,请使用支持 JDK 8 的 Maven 3。
|
||||
- 编译使用 `package -DskipTests`,成功后检查 `BOOT-INF/lib/postgresql-*.jar`;驱动缺失立即停止。
|
||||
- 编译、驱动检查和镜像构建统一由 `build.sh` 完成,Dockerfile 内嵌在脚本中,通过标准输入传给 Podman,无需单独的 `Dockerfile.podman`。基础镜像为公开的 `docker.io/library/eclipse-temurin:8-jre-jammy`。`--pull=always` 强制从仓库拉取基础镜像,不依赖预先存在的本地镜像,也不访问旧私有镜像仓库;构建机器需能访问 Docker Hub 和配置的 Maven 仓库。
|
||||
- 原 `Dockerfile` 保留不变,仍属于旧的私有镜像构建流程。
|
||||
- 脚本只构建,不推送、不启动容器;中间件 Compose 不会自动启动此 API。加入 PostgreSQL 驱动不等于切换数据源,数据库配置和 SQL 兼容性仍需单独验证。
|
||||
|
||||
只编译、不构建镜像时:
|
||||
|
||||
```bash
|
||||
mvn -Dmaven.repo.local="$(pwd)/../chengdu-repository" package -DskipTests
|
||||
```
|
||||
|
||||
参考:[Temurin 官方镜像](https://hub.docker.com/_/eclipse-temurin)、[PostgreSQL JDBC 下载与 Java 兼容性](https://jdbc.postgresql.org/download/)。
|
||||
@@ -0,0 +1,161 @@
|
||||
# 双数据源说明
|
||||
|
||||
本服务使用两套手工配置的 JPA 数据源,不依赖动态数据源框架。
|
||||
|
||||
| 侧 | 数据库 | 用途 | DAO 包 | Entity 包 | 事务管理器 |
|
||||
|---|---|---|---|---|---|
|
||||
| Primary | MySQL | 数据字典、UI 设置(读写) | `domain.primary.dao` | `domain.primary.entity` | `transactionManagerPrimary` |
|
||||
| Secondary | Oracle | 机场基础数据、季度计划(当前只读) | `domain.secondary.dao` | `domain.secondary.entity` | `transactionManagerSecondary` |
|
||||
|
||||
> Secondary 没有技术上的强制只读保护;不要在其 DAO 上调用 `save()` 或 `delete()`,除非已确认 Oracle 写入需求和事务方案。
|
||||
|
||||
## 核心思路:启动时把 DAO 固定接到一套数据库
|
||||
|
||||
这不是按请求、用户或 SQL 内容动态选择数据源;**应用启动时,Spring 就已经为每个 DAO 创建好代理,并把它固定绑定到 Primary 或 Secondary。**
|
||||
|
||||
```text
|
||||
SysAirlineDao
|
||||
位于 domain.secondary.dao
|
||||
↓ 被 SecondaryConfig 的 @EnableJpaRepositories 扫描
|
||||
↓ 创建 Repository 代理,绑定 entityManagerFactorySecondary
|
||||
↓ entityManagerFactorySecondary 使用 secondaryDataSource
|
||||
↓ 此 DAO 的所有 JPA 操作都访问 Oracle
|
||||
|
||||
DatadicItemDao
|
||||
位于 domain.primary.dao
|
||||
↓ 被 PrimaryConfig 的 @EnableJpaRepositories 扫描
|
||||
↓ 创建 Repository 代理,绑定 entityManagerFactoryPrimary
|
||||
↓ entityManagerFactoryPrimary 使用 primaryDataSource
|
||||
↓ 此 DAO 的所有 JPA 操作都访问 MySQL
|
||||
```
|
||||
|
||||
Entity 的包路径服务于同一个绑定关系:Primary EMF 只认识 Primary Entity,Secondary EMF 只认识 Secondary Entity。也就是说,一个 DAO 所操作的 Entity 必须被**同一套 EMF**管理。
|
||||
|
||||
> **一句话记忆:DAO 在哪个 `*.dao` 根包,就由该包对应的 Config 创建代理;该 Config 指向哪一个 EMF / DataSource,DAO 就访问哪一个数据库。**
|
||||
|
||||
Java 包不会让 JVM 把类“加载到不同地方”——所有类仍在同一个应用进程中。包名只是 Spring/JPA 的**扫描筛选条件**;真正完成数据库路由的是 `@EnableJpaRepositories`、EMF 和 DataSource 之间的显式引用。
|
||||
|
||||
## 不同 package 的类如何被装载和绑定
|
||||
|
||||
这里的“装载”分两件事:**Entity 注册到哪个 JPA EMF**,以及 **DAO 代理使用哪个 EMF/事务管理器**。它们不是靠类名或注解自动猜测,而是由两套 Config 中的扫描包明确指定。
|
||||
|
||||
### 1. Entity:`.packages()` 决定注册到哪个 EMF
|
||||
|
||||
`PrimaryConfig` 创建 MySQL 的 EMF 时只扫描 Primary Entity 包:
|
||||
|
||||
```java
|
||||
// PrimaryConfig.java
|
||||
builder
|
||||
.dataSource(primaryDataSource)
|
||||
.packages("com.gzzn.omms.adminapi.domain.primary.entity")
|
||||
.persistenceUnit("primaryPersistenceUnit")
|
||||
.build();
|
||||
```
|
||||
|
||||
`SecondaryConfig` 创建 Oracle 的 EMF 时只扫描 Secondary Entity 包:
|
||||
|
||||
```java
|
||||
// SecondaryConfig.java
|
||||
builder
|
||||
.dataSource(secondaryDataSource)
|
||||
.packages("com.gzzn.omms.adminapi.domain.secondary.entity")
|
||||
.persistenceUnit("secondaryPersistenceUnit")
|
||||
.build();
|
||||
```
|
||||
|
||||
`.packages()` 会扫描指定包及其子包中的 `@Entity`(以及关联的 JPA 映射类)。所以:
|
||||
|
||||
- `domain.primary.entity.dictionary.DatadicItem` 会注册到 `primaryPersistenceUnit`,其 SQL 发往 MySQL。
|
||||
- `domain.secondary.entity.baiscdata.SysAirline` 会注册到 `secondaryPersistenceUnit`,其 SQL 发往 Oracle。
|
||||
- `baiscdata` 虽然是现有目录中的拼写,但它仍是 `domain.secondary.entity` 的子包,会被扫描到;**不要为了改名直接移动类**,除非同步验证所有引用和映射。
|
||||
|
||||
`@Entity` 本身不是普通 Spring Service Bean;它由对应 EMF 扫描并维护映射元数据。放错包时,它会被注册到错误一侧的 EMF,后续 SQL 会查错数据库。
|
||||
|
||||
### 2. DAO:`@EnableJpaRepositories` 决定代理绑定到哪个 EMF
|
||||
|
||||
两个配置类分别扫描不同 DAO 包,并显式引用本侧的 EMF 和事务管理器:
|
||||
|
||||
```java
|
||||
// PrimaryConfig.java
|
||||
@EnableJpaRepositories(
|
||||
basePackages = "com.gzzn.omms.adminapi.domain.primary.dao",
|
||||
entityManagerFactoryRef = "entityManagerFactoryPrimary",
|
||||
transactionManagerRef = "transactionManagerPrimary")
|
||||
|
||||
// SecondaryConfig.java
|
||||
@EnableJpaRepositories(
|
||||
basePackages = "com.gzzn.omms.adminapi.domain.secondary.dao",
|
||||
entityManagerFactoryRef = "entityManagerFactorySecondary",
|
||||
transactionManagerRef = "transactionManagerSecondary")
|
||||
```
|
||||
|
||||
应用启动时,Spring Data 会扫描这些包中的 `CrudRepository` 接口并创建代理:
|
||||
|
||||
```text
|
||||
primary.dao 中的 DAO → Primary EMF / Primary TM → MySQL
|
||||
secondary.dao 中的 DAO → Secondary EMF / Secondary TM → Oracle
|
||||
```
|
||||
|
||||
因此 Controller 或 Service 注入 `SysAirlineDao` 时,拿到的是已绑定 Oracle 的代理;业务调用方不需要、也不应根据 DAO 名称自行切换数据源。
|
||||
|
||||
### 3. 新增类时按此配对
|
||||
|
||||
```text
|
||||
MySQL: primary.entity.<业务包>.XxxEntity
|
||||
primary.dao.<业务包>.XxxDao
|
||||
|
||||
Oracle: secondary.entity.<业务包>.XxxEntity
|
||||
secondary.dao.<业务包>.XxxDao
|
||||
```
|
||||
|
||||
只要类放在上述根包或任意子包内,现有扫描配置即可发现它们,**无需新增扫描配置**。若要使用第三套根包或第三个数据源,才需要新增对应的 DataSource、EMF、事务管理器和 `@EnableJpaRepositories` 配置。
|
||||
|
||||
## 配置位置
|
||||
|
||||
| 内容 | 代码位置 |
|
||||
|---|---|
|
||||
| MySQL DataSource | `config/PrimaryDataSourceConfig.java` |
|
||||
| Oracle DataSource | `config/SecondaryDataSourceConfig.java` |
|
||||
| MySQL JPA / DAO 绑定 | `config/PrimaryConfig.java` |
|
||||
| Oracle JPA / DAO 绑定 | `config/SecondaryConfig.java` |
|
||||
| 环境连接信息 | `src/main/resources/application-{dev,test,pro}.yml` |
|
||||
|
||||
Primary 的 `DataSource`、`EntityManager`、EMF 和事务管理器均标记 `@Primary`。这只是在未明确指定 Bean 时提供默认值;Repository 实际使用哪一侧,仍由各自的 `@EnableJpaRepositories` 配置决定。
|
||||
|
||||
## 新增表访问的做法
|
||||
|
||||
### 新增 MySQL 表
|
||||
|
||||
1. Entity 放到 `domain.primary.entity` 下。
|
||||
2. DAO 放到 `domain.primary.dao` 下。
|
||||
3. 需要写操作时使用 `transactionManagerPrimary`。
|
||||
|
||||
### 新增 Oracle 表
|
||||
|
||||
1. Entity 放到 `domain.secondary.entity` 下。
|
||||
2. DAO 放到 `domain.secondary.dao` 下。
|
||||
3. 默认按只读接口实现;若确实需要写操作,显式指定 `transactionManagerSecondary`,并先确认 Oracle 权限与业务影响。
|
||||
|
||||
## 常见错误
|
||||
|
||||
| 问题 | 后果 | 排查/处理 |
|
||||
|---|---|---|
|
||||
| Entity 或 DAO 放错侧 | 可能能启动,首次查询才报目标库不存在表 | 检查 Entity、DAO 包路径及两套 Config 的扫描包 |
|
||||
| 只新增 DAO、未新增正确 Entity | JPA 找不到实体或映射不完整 | Entity 与 DAO 必须成对放在同侧 |
|
||||
| 裸写 `@Transactional` | 默认使用 Primary 事务管理器 | 显式填写事务管理器名称 |
|
||||
| 一个业务操作同时写两库 | 不具备原子性,可能部分成功 | 避免跨库写;需要原子性时引入分布式事务方案 |
|
||||
| 漏配某环境数据源 | 应用启动时 Bean 装配失败 | 三个 profile 都补齐对应数据源配置 |
|
||||
|
||||
## 事务示例
|
||||
|
||||
```java
|
||||
@Transactional(transactionManager = "transactionManagerPrimary")
|
||||
public void saveMysqlData() {
|
||||
// 调用 primary DAO
|
||||
}
|
||||
|
||||
@Transactional(transactionManager = "transactionManagerSecondary")
|
||||
public void saveOracleData() {
|
||||
// 调用 secondary DAO;仅在确认允许写 Oracle 时使用
|
||||
}
|
||||
```
|
||||
Vendored
+3
-55
@@ -10,13 +10,8 @@ pipeline {
|
||||
|
||||
environment {
|
||||
credentialsId = 'e41b57a4-436a-4617-817c-9e3f25a8a47f'
|
||||
deployName = 'airport-dev'
|
||||
deployHost = '130.120.3.231'
|
||||
mailto = '154707516@qq.com'
|
||||
dockerProtocol = "http"
|
||||
dockerRegistry = '130.120.3.193'
|
||||
containerName="adminapi"
|
||||
export=92
|
||||
dockerProtocol = "https"
|
||||
dockerRegistry = 'reg.int.it2000.com.cn'
|
||||
|
||||
GROUP = readMavenPom().getGroupId()
|
||||
ARTIFACTID = readMavenPom().getArtifactId()
|
||||
@@ -48,55 +43,8 @@ pipeline {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stage('deploy') {
|
||||
steps {
|
||||
withCredentials([sshUserPrivateKey(credentialsId: "${env.credentialsId}", keyFileVariable: 'kfIdentity', passphraseVariable: 'pVariable', usernameVariable: 'userName')]) {
|
||||
sshCommand(remote: [ name: "${env.deployName}" ,host: "${env.deployHost}" ,allowAnyHosts: true,user: "${userName}",identityFile: "${kfIdentity}" ] ,
|
||||
command: "docker stop ${env.containerName}",sudo: true ,failOnError: false)
|
||||
sshCommand(remote: [ name: "${env.deployName}" ,host: "${env.deployHost}" ,allowAnyHosts: true,user: "${userName}",identityFile: "${kfIdentity}" ] ,
|
||||
command: "docker rm ${env.containerName}",sudo: true ,failOnError: false)
|
||||
sshCommand(remote: [ name: "${env.deployName}" ,host: "${env.deployHost}" ,allowAnyHosts: true,user: "${userName}",identityFile: "${kfIdentity}" ] ,
|
||||
command: "docker rmi ${env.dockerRegistry}/${env.GROUP}/${env.ARTIFACTID}:${env.VERSION}",sudo: true ,failOnError: false)
|
||||
sshCommand(remote: [ name: "${env.deployName}" ,host: "${env.deployHost}" ,allowAnyHosts: true,user: "${userName}",identityFile: "${kfIdentity}" ] ,
|
||||
command: "docker run -d -p ${env.export}:8080 --name ${env.containerName} ${env.dockerRegistry}/${env.GROUP}/${env.ARTIFACTID}:${env.VERSION}",sudo: true ,failOnError: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
post {
|
||||
success {
|
||||
emailext (
|
||||
subject: "'${env.JOB_NAME} [${env.BUILD_NUMBER}]' 更新正常",
|
||||
body: """
|
||||
详情:
|
||||
SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'
|
||||
状态:${env.JOB_NAME} jenkins 更新运行正常
|
||||
URL :${env.BUILD_URL}
|
||||
项目名称 :${env.JOB_NAME}
|
||||
项目更新进度:${env.BUILD_NUMBER}
|
||||
""",
|
||||
to: "${env.mailto}",
|
||||
recipientProviders: [[$class: 'DevelopersRecipientProvider']]
|
||||
)
|
||||
}
|
||||
|
||||
failure {
|
||||
emailext (
|
||||
subject: "'${env.JOB_NAME} [${env.BUILD_NUMBER}]' 更新失败",
|
||||
body: """
|
||||
详情:
|
||||
FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'
|
||||
状态:${env.JOB_NAME} jenkins 运行失败
|
||||
URL :${env.BUILD_URL}
|
||||
项目名称 :${env.JOB_NAME}
|
||||
项目更新进度:${env.BUILD_NUMBER}
|
||||
""",
|
||||
to: "${env.mailto}",
|
||||
recipientProviders: [[$class: 'DevelopersRecipientProvider']]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,245 +1,261 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.gzzn.omms</groupId>
|
||||
<artifactId>admin-api</artifactId>
|
||||
<version>1.2.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>admin-api</name>
|
||||
<description>Admin Api project for CdAirPort </description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.17.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
|
||||
<m2e.apt.activation>jdt_apt</m2e.apt.activation>
|
||||
<spring-cloud.version>Edgware.SR5</spring-cloud.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>11.2.0.3</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/libs/ojdbc6-11.2.0.3.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
<version>5.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>swagger-bootstrap-ui</artifactId>
|
||||
<version>1.8.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch</groupId>
|
||||
<artifactId>elasticsearch</artifactId>
|
||||
<version>6.4.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/transport -->
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch.client</groupId>
|
||||
<artifactId>transport</artifactId>
|
||||
<version>6.4.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.elasticsearch</groupId>
|
||||
<artifactId>elasticsearch</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.15</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-eureka</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
<arg>-verbose</arg>
|
||||
<arg>-Xlint:unchecked</arg>
|
||||
<arg>-Xlint:deprecation</arg>
|
||||
<arg>-bootclasspath</arg>
|
||||
<arg>${env.JAVA_HOME}/jre/lib/rt.jar</arg>
|
||||
<arg>-extdirs</arg>
|
||||
<arg>${project.basedir}/lib</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>dockerfile-maven-plugin</artifactId>
|
||||
<version>1.4.4</version>
|
||||
<configuration>
|
||||
<username>gzzn</username>
|
||||
<password>Gzzn@2018</password>
|
||||
<!-- 镜像tag -->
|
||||
<tag>${project.version}</tag>
|
||||
|
||||
<!--useMavenSettingsForAuth>true</useMavenSettingsForAuth -->
|
||||
<!-- 禁止使用谷歌商店认证 -->
|
||||
<googleContainerRegistryEnabled>false</googleContainerRegistryEnabled>
|
||||
|
||||
<repository>130.120.3.193/${project.groupId}/${project.artifactId}</repository>
|
||||
<buildArgs>
|
||||
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
|
||||
</buildArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>lib</directory>
|
||||
<targetPath>BOOT-INF/lib</targetPath>
|
||||
<includes>
|
||||
<include>**/*.jar</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.gzzn.omms</groupId>
|
||||
<artifactId>admin-api</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>admin-api</name>
|
||||
<description>Admin Api project for CdAirPort </description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.17.RELEASE</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
|
||||
<m2e.apt.activation>jdt_apt</m2e.apt.activation>
|
||||
<spring-cloud.version>Edgware.SR5</spring-cloud.version>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@git.int.it2000.com.cn:airport-chengdu/admin-api.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.7.9</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>11.2.0.3</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/libs/ojdbc6-11.2.0.3.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
<version>5.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>swagger-bootstrap-ui</artifactId>
|
||||
<version>1.8.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch</groupId>
|
||||
<artifactId>elasticsearch</artifactId>
|
||||
<version>6.4.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/transport -->
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch.client</groupId>
|
||||
<artifactId>transport</artifactId>
|
||||
<version>6.4.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.elasticsearch</groupId>
|
||||
<artifactId>elasticsearch</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.15</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-eureka</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
<arg>-verbose</arg>
|
||||
<arg>-Xlint:unchecked</arg>
|
||||
<arg>-Xlint:deprecation</arg>
|
||||
<arg>-bootclasspath</arg>
|
||||
<arg>${env.JAVA_HOME}/jre/lib/rt.jar</arg>
|
||||
<arg>-extdirs</arg>
|
||||
<arg>${project.basedir}/lib</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>dockerfile-maven-plugin</artifactId>
|
||||
<version>1.4.10</version>
|
||||
<configuration>
|
||||
<username>gzzn</username>
|
||||
<password>Gzzn@2018</password>
|
||||
<!-- 镜像tag -->
|
||||
<tag>${project.version}</tag>
|
||||
|
||||
<!--useMavenSettingsForAuth>true</useMavenSettingsForAuth -->
|
||||
<!-- 禁止使用谷歌商店认证 -->
|
||||
<googleContainerRegistryEnabled>false</googleContainerRegistryEnabled>
|
||||
|
||||
<repository>130.120.3.193/${project.groupId}/${project.artifactId}</repository>
|
||||
<buildArgs>
|
||||
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
|
||||
</buildArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.5.3</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>lib</directory>
|
||||
<targetPath>BOOT-INF/lib</targetPath>
|
||||
<includes>
|
||||
<include>**/*.jar</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class HistoryFlightDataController {
|
||||
}
|
||||
if(StringUtils.isEmpty(startTime) && !StringUtils.isEmpty(endTime)){
|
||||
boolQuery.must(QueryBuilders.rangeQuery("SODT")
|
||||
.lte(startTime));
|
||||
.lte(endTime));
|
||||
}
|
||||
//到达or离港
|
||||
if(!StringUtils.isEmpty(MVIN)){
|
||||
|
||||
@@ -19,11 +19,11 @@ spring:
|
||||
pool-prepared-statements: false
|
||||
max-pool-prepared-statement-per-connection-size: 20
|
||||
secondary:
|
||||
username: ommsxc
|
||||
password: ommsxc
|
||||
username: omms
|
||||
password: omms
|
||||
#url: jdbc:oracle:thin:@130.120.3.236:1521/xe
|
||||
url: jdbc:oracle:thin:@130.120.3.31:1521/orcl
|
||||
#url: jdbc:oracle:thin:@130.120.2.105:1521/orcl
|
||||
#url: jdbc:oracle:thin:@130.120.3.31:1521/orcl
|
||||
url: jdbc:oracle:thin:@130.120.2.105:1521/orcl
|
||||
driver: oracle.jdbc.driver.OracleDriver
|
||||
max-active: 30
|
||||
test-on-borrow: true
|
||||
@@ -40,11 +40,12 @@ spring:
|
||||
eureka:
|
||||
client:
|
||||
service-url:
|
||||
defaultZone: http://130.120.3.231:94/eureka/
|
||||
defaultZone: http://130.120.3.235:94/eureka/
|
||||
instance:
|
||||
prefer-ip-address: true
|
||||
prefer-ip-address: false
|
||||
hostName: adminapi
|
||||
sysApi:
|
||||
host: 130.120.3.231
|
||||
host: 130.120.3.235
|
||||
port: 93
|
||||
schema: http
|
||||
#baseUrl: ${sysApi.schema}://${sysApi.host}:${sysApi.port}
|
||||
|
||||
Reference in New Issue
Block a user