uniquejava / blog

My notes regarding the vibrating frontend :boom and the plain old java :rofl.
Creative Commons Zero v1.0 Universal
11 stars 5 forks source link

websphere liberty #168

Open uniquejava opened 6 years ago

uniquejava commented 6 years ago

Promise. 最后一次浪费时间在IBM的垃圾上.

basic auth

feature: appSecurity-2.0

step1: configure web.xml

https://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/twlp_sec_quickstart.html

step2: configure server.xml https://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/twlp_sec_basicreg_full.html

https / ssl

feature: ssl-1.0

configure server.xml

<server>
    <featureManager>
        <feature>ssl-1.0</feature>
    </featureManager>

    <keyStore id="defaultKeyStore" password="Liberty" />
</server>

https://developer.ibm.com/wasdev/docs/configuring-ssl-liberty/

官方文档: https://www.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.wlp.nd.doc/ae/twlp_sec_ssl.html

This configuration is the minimum that is needed to create an SSL configuration. In this configuration, the server creates the keystore and certificate if it does not exist during SSL initialization. The password that is provided must be at least 6 characters long. The keystore is assumed to be a JKS keystore that is called key.jks in the server home/resources/security directory. If the file does not exist the server creates it for you. If the server creates the keystore file, it also creates the certificate inside of it. The certificate is a self-signed certificate with a validity period of 365 days, the CN value of the certificate's subjectDN is the host name of the machine where the server is running, and has a signature algorithm of SHA256withRSA.

以上说明可以通过以下启动日志验证. CWPKI0803A: SSL certificate created in 2.405 seconds. SSL key file: /usr/servers/defaultServer/resources/security/key.jks

jaxrs

1.x based on apache wink, 2.x based on apache cxf 3.x

step1: configure web.xml https://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.doc/ae/twbs_jaxrs_configwebxml.html

swagger

feature: apiDiscovery-1.0 (需要安装)

https://developer.ibm.com/wasdev/blog/2016/02/17/exposing-liberty-rest-apis-swagger/

https://stackoverflow.com/questions/46034442/using-basic-auth-with-the-apidiscovery-feature-in-liberty

https://developer.ibm.com/answers/questions/247757/questions-on-swagger-support-on-liberty-8558/

https://developer.ibm.com/answers/questions/362771/liberty-api-discovery-uses-which-version-of-swagge/

uniquejava commented 6 years ago

start, package and push

1) 在Eclipse中启动比较简单, 略过. 2) 在命令行中启动 首先在Eclipse中将项目导出成war包 然后将server.xml中的内容拷贝到WLP_HOME/usr/servers/defaultServer/server.xml中 最后将war包扔到WLP_HOME/usr/servers/defaultServer/apps目录下 最后./server run启动 应用.

./server run        # foreground
./server start      # background

3) 部署到bluemix 需要把server.xml和app打包在一起, 使用如下package命令 或者在Eclipse Severs View中右键Utilities > Package Server ...

server package defaultServer zip-name --include=all|usr|minify
cf push app-name -p zip-name

见: https://github.com/uniquejava/blog/issues/76

logging 👎

WLP的logging设计真是脑残.. 一共有12个级别. (WTF),

但是consoleLogLevel最低只能指定到INFO级别(也就是说你别想在console看到DEBUG信息), 厉害了. 我的IBM! 并且默认打印的是AUDIT级别的, 就是说默认连INFO都不会打印出来.

文件名叫console.log

并且只有通过./server start才会生成这个文件, ./server run以及通过Eclipse启动都不会生成这个文件, WTF!!

这还不够.

他只会打印出通过System.out. System.error 和 使用 JUL 输出的日志.

WTF.

好吧 我使用JUL还不行么, 那怎么才能看到debug信息? 可以.. 指定traceSpecification就行了, 比如给它设定一个*=finest, 这样日志就会出现在trace.log了..

Grrrr, 但我只是简单的想让DEBUG信息出现在console啊. 这么原始的需求.. 怎么还要到trace.log中去看.

那么, 您还需要配置traceFileName="stdout".

<logging consoleLogLevel="INFO" 
maxFileSize="20" maxFiles="3" messageFileName="hello.log" 
traceFileName="stdout | hello_trace.log" 
traceSpecification="*=audit:com.xxx.*=finest""/>

The product has a unified logging component that handles messages that are written by the product and provides First Failure Data Capture (FFDC) services.

Additionally, the logging component captures messages that are written to System.out, System.err, java.util.logging, and OSGi logging.

见: Liberty:Logging and Trace 以及 wlp/bin/server(是个sh文件) 中的注释.

logging中的三文件

console.log只有通过./server start才会生成, 文档中说是intended for direct human consumption 所以不包含timestamp信息 👎 , 也不包含DEBUG信息 👎 .

message.log和console.log的内容完全一样, 但是包含timestamp, 不包含DEBUG. 👎

trace.log 只有加了traceFileName才会出现, 包含message.log中的全部内容, 并且还包含DEBUG信息. 如果将traceFileName设置为stdout, 那么trace文件不再生成, 所有的内容都会出现在console.log, 但是server一旦重启, console.log会被覆盖, 先前的日志会全部丢失, 小心! 👎

即使你指定了messageFileName和traceFileName, Liberty还是莫名其妙的会生成messages.log和trace.log 👎 ... 理由是在读你的server.xml之前, 他有些日志要生成. 所以看到这两个很空很空的文件, 不要感到意外.. (强迫症要命 )

重启server会备份先前的message.log和trace.log, 但是不会备份console.log.

Liberty - Messages.log / Console.log / trace.log not getting rotated on server

一句话, 要看到按文件大小滚动包含DEBUG信息的日志请到trace.log中去看. 😭

logging 集成其它log lib.

既然liberty会接管System.out中的信息. 那么理论上应该可以集成 log4j, logback等, 只要配置这些日志库, 让它们把日志输出到stdout中.

实践结果: 可以.

[12/23/17 17:53:21:448 CST] 0000002d id= SystemOut O [12-23 17:53:21 INFO ] mock login ... [12/23/17 17:59:42:241 CST] 0000001b SystemOut O [12-23 17:59:42 INFO ] mock login ...

但是Liberty的trace格式是固定的, ... 提供的三个traceFormat选项 BASIC, ENHANCED, ADVANCED都TMD不能去掉时间信息, 也不能去掉SystemOut那几个字符. (难受)

所以在log4j中如果你配置了时间信息, 就会在日志中出现两次, 并且所有来自app的log关于类的部分全部变成 了SystemOut.

liberty中为什么能打印出第3方库的INFO信息

这些第3方库用的commons-logging, 它能自动发现classpath中的log4j等, 没有的话就会用JUL,

so commons-logging is the last straw that I can use.

best practice

既然Liberty logging这么难用.. 不用就可以了. 可以:

  1. 不要在server.xml中加logging.
  2. 不要看server的console.log
  3. log4j或logback不输出在stdout(因为Liberty会接管并且会copy到console.log和messages.log并且日志格式混乱)
  4. log4j或logback按日期滚动输出日志.
  5. 代码中不要使用System.out

以如下log4j.properties文件为例, 去掉 stdout, 然后最终会出现一个和messages/trace平级的hello.log日志文件

log4j.rootLogger=INFO,stdout,C

log4j.logger.com.xxx.app=DEBUG

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.conversionPattern=[%d{MM-dd HH:mm:ss} %-5p] %m %n

log4j.appender.C=org.apache.log4j.DailyRollingFileAppender
log4j.appender.C.File=logs/hello.log
log4j.appender.C.Threshold=DEBUG
log4j.appender.C.DatePattern=.yyyy-MM-dd
log4j.appender.C.layout=org.apache.log4j.PatternLayout
log4j.appender.C.layout.ConversionPattern=[%d{MM-dd HH:mm:ss} %-5p] %m %n

FFDC

First failure data capture (FFDC), 只有在server启动异常时log才会生成.

uniquejava commented 6 years ago

理解liberty中basic auth的配置过程

我的理解, 和RBAC模型对比. RBAC中有User, Role, Resource. 他们之间都是多对多关联关系.

那么在server.xml中注册user如下:

    <basicRegistry id="basic" realm="WebRealm">
        <user name="user1" password="user1pwd"></user>
    </basicRegistry>

在server.xml中配置user_role relationship

    <webApplication id="hello" location="hello.war" name="hello">
        <application-bnd>
            <security-role name="enduser">
                <user name="user1"></user>
            </security-role>
        </application-bnd>
    </webApplication>

在web.xml中配置role

    <!-- SECURITY ROLES -->
    <security-role>
        <role-name>enduser</role-name>
    </security-role>

在web.xml中配置 resource以及 role resource relationship.

    <!-- SECURITY CONSTRAINTS -->
    <security-constraint>
        <web-resource-collection>
            <url-pattern>/api/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>enduser</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- AUTHENTICATION METHOD: Basic authentication -->
    <login-config>
        <auth-method>BASIC</auth-method>
    </login-config>
uniquejava commented 6 years ago

JPA and data source

在src/config/META-INF/persistence.xml中增加如下配置

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
    version="2.1">

    <persistence-unit name="my_pu" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <non-jta-data-source>jdbc/my_datasource</non-jta-data-source>
        <class>com.xxx.model.AwesomeUser</class>
        <class>com.xxx.model.AwesomeProduct</class>

        <properties>
            <property name="eclipselink.logging.level" value="ALL" />
            <property name="eclipselink.logging.level.sql" value="FINE" />
            <property name="eclipselink.logging.parameters" value="true" />
        </properties>
    </persistence-unit>
</persistence>

在server.xml中增加datasource的配置.

<server description="new server">

    <!-- Enable features -->
    <featureManager>
        <feature>webProfile-7.0</feature>
        <feature>localConnector-1.0</feature>
        <feature>ssl-1.0</feature>
        <feature>appSecurity-2.0</feature>
    </featureManager>

    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>

    <applicationMonitor updateTrigger="mbean"/>

    <!-- Basic auth configuration -->
    <basicRegistry id="basic" realm="WebRealm">
        <user name="cool_admin" password="cool_password"/>
    </basicRegistry>

    <!-- Data source -->
    <jdbcDriver id="DB2JCC" libraryRef="DB2JCCLib"/>
    <library filesetRef="DB2JCCFileset" id="DB2JCCLib"/>
    <fileset dir="${shared.resource.dir}/db2jars" id="DB2JCCFileset" includes="db2jcc4.jar,db2jcc_license_cu.jar"/>
    <dataSource id="jdbc/my_datasource" jdbcDriverRef="DB2JCC" jndiName="jdbc/my_datasource" transactional="true" isolationLevel="TRANSACTION_READ_COMMITTED">
        <connectionManager maxIdleTime="18m" maxPoolSize=“5”/>
        <properties.db2.jcc databaseName="BLUDB" driverType="4" password="xxxxx" portNumber="50000" serverName="xxxx.services.dal.bluemix.net" user="dash1234" />
    </dataSource>

    <!-- Custom logging configuration -->
    <logging consoleLogLevel="INFO" maxFileSize="10" maxFiles="5" messageFileName="messages.log" traceFileName="trace.log" traceSpecification="*=info:com.xxx.*=finest"/>

    <!-- HTTPS configuration -->
    <keyStore id="defaultKeyStore" password="Liberty"/>

    <webApplication id="xxx" location="xxx.war" name="xxx">
        <application-bnd>
            <security-role name="enduser">
                <user name="cool_admin"></user>
            </security-role>
        </application-bnd>
    </webApplication>
</server>

References

https://developer.ibm.com/wasdev/docs/changing-liberty-application-use-dashdb-instead-db2/

https://developer.ibm.com/answers/questions/24832/jpa-problem-entitymanager-is-not-injected/

https://developer.ibm.com/wasdev/docs/developing-jpa-2-1-applications-websphere-developer-tools-liberty/

https://developer.ibm.com/answers/questions/190404/issue-enabling-jpa-and-jdbc-in-websphere-liberty.html

uniquejava commented 6 years ago

classloader

Sharing a library across multiple Java EE applications

Deploying Spring Boot Applications in IBM WebSphere Application Server

How to deploy Spring Boot application in IBM Liberty and WAS 8.5

<library id="springLib">
 <fileset dir="${server.config.dir}/libs/spring/" includes="*.jar"/>
</library>

<application location ="restService.war">
  <classloader commonLibraryRef="springLib"/>
</application>
<application location="cbe3.ear">
   <classloader delegation="parentLast" privateLibraryRef="global" />
 </application>
<enterpriseApplication location="myApp.ear" name="MyApp">
    <classloader delegation="parentLast"/>
</enterpriseApplication>
<application id="test" name="test" location="test.war" type="war">
   <classloader delegation="parentLast" privateLibraryRef="global" />
 </application>
uniquejava commented 5 years ago

session timeout设置

<server description="new server">

    <!-- Enable features -->
    <featureManager>
        <feature>webProfile-7.0</feature>
        <feature>localConnector-1.0</feature>
    </featureManager>

    <!-- To access this server from a remote client add a host attribute 
        to the following element, e.g. host="*" -->
    <httpEndpoint host="*" httpPort="8393" httpsPort="9443" id="defaultHttpEndpoint"/>
    <httpSession cookieHttpOnly="false" cookieName="JSESSIONID" invalidationTimeout="30m"/>

    <applicationMonitor updateTrigger="mbean"/>
</server>

image

文档: https://www.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.liberty.autogen.nd.doc/ae/rwlp_config_httpSession.html