HIS 架構修正GuideLine
===
[TOC]
##### Reference
* [re-structure status](https://hackmd.io/ffUpYMhPQpCHqZbDhNDWDg)
* [SecServer: application.grooy](https://hackmd.io/iAkfPaw7Soqh6gRXR7Ojzw)
* [DBConn Usage](https://hackmd.io/LyFN8_ipTq6LdRZGDTfA5w)
* [Runtime Issue](https://hackmd.io/dERAY9ZMRJaP67acERbuCQ)
* [AIR Runtime Issue](https://hackmd.io/Z27TjZfPSRmG23waKN89_A)
## Pooling
### application.groovy
* multi-dataSource
```
dataSources {
dataSource {
pooled = true
logSql = true
dbCreate = "none" // one of 'create', 'create-drop','update'
url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver"
driverClassName = "net.bull.javamelody.JdbcDriver"
username = "emr"
password = "chidapuser"
}
mrm {
pooled = true
logSql = true
url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver"
driverClassName = "net.bull.javamelody.JdbcDriver"
username = "mrm"
password = "chidapuser"
}
query {
pooled = true
logSql = true
url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver"
driverClassName = "net.bull.javamelody.JdbcDriver"
username = "reportquery"
password = "chidapuser"
}
}
```
### Javamelody Spring DataSource
* 設置default dataSource {...}, environment不需要pooled, jmxExport, jmxEnabled行為
```
dataSource {
jmxExport = true
pooled = true
dbCreate = "none" // one of 'create', 'create-drop','update'
dialect = "org.hibernate.dialect.OracleDialect"
url = ""
username = ""
password = ""
properties {
jmxEnabled = true
}
}
```

### getBean()
* 取用'dataSource' bean
* 取用'dataSourceUnproxied' bean 會產生另一個db session(不再同一個Transaction Scope)
```
DataSource ds = Holders.getGrailsApplication().getMainContext().getBean("dataSource")
```
在getConnection的時候優先以傳入參數取bean,傳入參數取不到,再以dataSource_xxxx的模式取,如果此處也取不到bean,會拋出例外。
### closeConnection, autoCommit
* 不需closeConnection(tx manager會介入), 禁止操作autoCommit等行為, 一律由dataSource設定控制
* BatchTool.closeConnection會檢查dataSource型別,屬於TransactionAwareDataSourceProxy的,不做close
## Transaction Management
### @Transactional
* Service Endpoint(標註@RemotingDestination/@GrailsCxfEndpoint)必須與Service Bean分離撰寫
* 所有*Service Bean class 都需標註(@Transactional)
* 確定cross service class, method皆能control error rollback
* 確定cross 'gorm', getBean(dataSource), getBean(dataSource_XXX)皆能control error rollback
* his服務使用Cxf提供SOAP服務,確認所有標註GrailsCxfEndpoint的service class都必須分離撰寫,以sec為例,只有下圖黃色框起來的class提供對外服務:

### RuntimeException
* Tx Rollback只有checkedException awared.
* 檢視try catch是否正確throw RuntimeException
* 以下圖為例,在catch例外之後,throw出去讓hibernete察覺例外

## JavaMelody
### Spring dataSource reference
```
url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.2.145.247)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=CHIDHIS)))?driver=oracle.jdbc.driver.OracleDriver"
driverClassName = "net.bull.javamelody.JdbcDriver"
```
## Coding Pattern
### 取號from getConnection()
透過Sequence.nextval, 禁止```max(id)+1```
``` sql
select EmrTeachingFrequent_Seq_Id.nextval id from dual
```
## Error Log
### filebeat.yaml
```
filebeat.inputs:
...
multiline.type: pattern
multiline.pattern: '^[[:space:]]+(at|\.{3})[[:space:]]+\b|^Caused by:'
multiline.negate: false
multiline.match: after
```
```
[tsengeagle@TP-HISHA1-APL03 ~]$ cat /etc/filebeat/inputs.d/EventServer1_input.yml
- type: log
paths:
- /home/tomcat/server/EventServer/logs/catalina.out
fields:
service_name: EventServer1
server_name: EventServer
log_type: process
tags: ["EventServer","EventServer1","process"]
multiline.pattern: '^[[:space:]]|^#|^[[:space:]]+(at|\.{3})\b|^Caused by:'
multiline.negate: false
multiline.match: after
```
## Hibernate Reference
https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#flushing