投稿者アーカイブ

EclipseLinkにおける、DB2の拡張クライアント情報の設定方法   Leave a comment

EclipseLinkを利用した、DB2の拡張クライアント情報の設定方法がなかったので、設定方法をブログに載せます。

1.SessionEventAdapterの実装
postAcquireConnectionメソッドは、DBコネクションを取得した後に呼び出されます。preReleaseConnectionメソッドは、DBコネクションを開放するときに呼び出されます。postAcquireConnectionメソッドの24~26行目で、拡張クライアント情報を設定しています。preReleaseConnectionの39~41行目で、拡張クライアント情報を初期化しています。

図 1. SessionEventAdapterの実装例(CustomSessionEventAdapter.java)

package com.wordpress.okulejp.sesstion;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;

public class CustomSessionEventAdapter extends SessionEventAdapter {
  
  @Override
  public void postAcquireConnection(SessionEvent event) {
    Logger logger = Logger.getLogger(this.getClass().getName());
    logger.fine("postAcquireConnection start");
    try {
      FacesContext fc =  FacesContext.getCurrentInstance();
      Map<String,Object> sessionMap = fc.getExternalContext().getSessionMap();
      Connection con= ((DatabaseAccessor) event.getResult()).getConnection();
      HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
      con.setClientInfo("ApplicationName", (String) sessionMap.get("ApplicationName"));
      con.setClientInfo("ClientUser", request.getRemoteUser());
      con.setClientInfo("ClientHostname", request.getRemoteAddr());
    } catch(SQLException ex) {
      throw new RuntimeException(ex.getMessage());
    }
    logger.fine("postAcquireConnection end");
  }
    
  @Override
  public void preReleaseConnection(SessionEvent event) {
    Logger logger = Logger.getLogger(this.getClass().getName());
    logger.fine("preReleaseConnection start");
    try {
      java.sql.Connection con= ((DatabaseAccessor) event.getResult()).getConnection();
      con.setClientInfo("ApplicationName", null);
      con.setClientInfo("ClientUser", null);
      con.setClientInfo("ClientHostname", null);
    } catch(SQLException ex) {
      throw new RuntimeException(ex.getMessage());
    }
    logger.fine("preReleaseConnection end");
  }
    
}

2.persistence.xmlの設定
9行目で、実装したSessionEventAdapterを呼び出す設定をしています。

図 2. persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="ngsPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/db2</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="eclipselink.session-event-listener" value="com.wordpress.okulejp.sesstion.CustomSessionEventAdapter"/>
        <property name="eclipselink.logging.level" value="FINE"/>
        <property name="eclipselink.logging.level.sql" value="FINE"/>
        <property name="eclipselink.logging.parameters" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

3.DB2監査ログ
12~14行目で、CustomSessionEventAdapter.javaで設定した拡張クライアント情報が出力されています。またDB2監査ログの設定しだいで、42~52行目のようにSQLパラメータの出力も可能です。
(※注意10,13行目で、IPアドレスを「*」でマスキングしてありますが、実際に監査ログには値が出力されます。)

図 3. DB2監査ログ出力結果

timestamp=2012-12-19-10.50.32.423000;
  category=EXECUTE;
  audit event=STATEMENT;
  event correlator=55;
  event status=0;
  database=MYDB;
  userid=OKULE;
  authid=ADMIN;
  session authid=ADMIN;
  application id=192.168.*.*.54300.121219013706;
  application name=db2jcc_application;
  client userid=test_id;
  client workstation name=192.168.*.*;
  client application name=test_appName;
  package schema=OKULE;
  package name=SYSSH200;
  package section=1;
  local transaction id=0xd7064d0000000000;
  global transaction id=0x0000000000000000000000000000000000000000;
  uow id=25;
  activity id=1;
  statement invocation id=0;
  statement nesting level=0;
  activity type=WRITE_DML;
  statement text=UPDATE DB2_AUDIT_TEST SET UPDATE_PROGRAM_ID = ? , UPDATE_USER_ID = ? , UPDATE_TIMESTAMP = SYSDATE WHERE ID = ?;
  statement isolation level=CS;
  Compilation Environment Description
    isolation: CS
    query optimization: 5
    min dec div 3: NO
    degree: 1    
    SQL rules: DB2
    refresh age: +00000000000000.000000
    resolution timestamp: 2012-12-19-10.50.30.000000
    federated asynchrony: 0
    temporal business time: 0000-00-00-00.00.00.000000000000
    temporal system time: 0000-00-00-00.00.00.000000000000
    schema: OKULE   
    maintained table type: SYSTEM;
  rows modified=1;
  rows returned=0;
  value index = 1
    type = VARCHAR 
    data = MA0304;
    extended indicator = 0;
  value index = 2
    type = VARCHAR 
    data = admin;
    extended indicator = 0;
  value index = 3
    type = VARCHAR 
    data = k3;
    extended indicator = 0;
  local start time=2012-12-19-10.50.30.772729;

4.参考URL
IBM Data Server Driver for JDBC and SQLJ によるクライアント情報プロパティーのサポート
Java Persistence API (JPA) Extensions Reference for EclipseLink session-event-listener

©中條勝徳 and okulejp.com, 2012.

okule による DB2, EclipseLink, JPA への投稿 (12月 19, 2012)

タグ: ,

Apache FOP 1.1の新機能   Leave a comment

1.Apache FOP1.1の新機能
Apache FOP 1.1が、ついにリリースされました。私にとって一番の目玉は、暗号化鍵の鍵長が、RC4 40bit から,高強度のRC4 128bitを利用できるようになったことです。巷には、PDFのセキュリティを解除するソフトや、オンラインのサービスが展開されていますので、PDFのパスワードの管理はしっかりしたいところです。デフォルトでは、暗号鍵の長さは、40bitなので、明示的に指定しなければなりません。図 1. EncryptPDF.javaでは、42行目で高強度のRC4 128bitを使用するようにしています。また、38行目で、印刷の品質を設定しています。「Apache™ FOP: PDF encryption.」にて、レンダラのオプションで設定できる項目が記載されています。文書を開くパスワードで、PDFを開いた場合と、権限パスワードで、PDFを開いた場合で、PDFの文書プロパティの「PDFの文書に関する制限の概要」に違いがあります。
(SyntaxHighlighterを使用して、プログラムを掲載しています。ブラウザー上で、各々の図の右上のアイコンをマウスでクリックすることで、ソースを表示したり、クリップボードにコピーしたり、印刷したりできます。注意点として、「さらに記事を読み込む」のリンクで、この記事を読み込んだ場合に、SyntaxHighlighterによる表示が不正になる場合がありますので、恐れ入りますが、タイトルをクリックして再表示して下さい。)

図 1. EncryptPDF.java

package com.wordpress.okulejp.encryptpdf;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.pdf.PDFEncryptionParams;

public class EncryptPDF {
  public static void main(String[] args) {
    OutputStream out = null;
    try {
      FopFactory fopFactory = FopFactory.newInstance();
      FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
      fopFactory.setUserConfig(new File("fop.xconf"));
      out = new FileOutputStream("src/com/wordpress/okulejp/encryptpdf/encrypt.pdf");
      out = new BufferedOutputStream(out);

      //セキュリティ設定。
      PDFEncryptionParams encryptionParams = new PDFEncryptionParams();
      //文書を開くパスワード設定。
      encryptionParams.setUserPassword("user");
      //権限パスワード設定。
      encryptionParams.setOwnerPassword("owner");
      //印刷可否設定。
      encryptionParams.setAllowPrint(true);
      //高解像度印刷可否設定。
      encryptionParams.setAllowPrintHq(true);
      //内容のコピー可否設定。
      encryptionParams.setAllowCopyContent(false);      
      //暗号鍵の鍵長の指定。
      encryptionParams.setEncryptionLengthInBits(128);
      
      //レンダラのオプションを設定する。
      foUserAgent.getRendererOptions().put("encryption-params", encryptionParams);
      
      Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
      File fofile = new File("src/com/wordpress/okulejp/encryptpdf/encryptPDF.fo");
      Result result = new SAXResult(fop.getDefaultHandler());
      StreamSource streamSource = new StreamSource(fofile);
      TransformerFactory trf = TransformerFactory.newInstance();
      Transformer transformer = trf.newTransformer();
      
      //PDF出力。
      transformer.transform(streamSource, result);
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    } finally {
      try {
        if (out != null) {
          out.close();
        }
      } catch (IOException io) {
        io.printStackTrace();
        System.exit(1);
      }
    }
  }
}

図 2. encryptPDF.fo

<?xml version="1.0" encoding="Shift_JIS"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" language="ja">
  <fo:layout-master-set>
    <fo:simple-page-master page-width="210mm" page-height="297mm" margin-top="0mm" margin-left="0mm"
      margin-right="0mm" margin-bottom="0mm" master-name="PageMaster">
      <fo:region-body margin-top="15mm" margin-left="15mm" margin-right="15mm" margin-bottom="15mm" />
      <fo:region-before extent="15mm" />
      <fo:region-after extent="15mm" />
      <fo:region-start extent="15mm" />
      <fo:region-end extent="15mm" />
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference="PageMaster">
    <fo:flow flow-name="xsl-region-body">
      <fo:block font-family="MS 明朝" font-size="xx-large">Hellow encrypted PDF</fo:block>
    </fo:flow>
  </fo:page-sequence>
</fo:root>

図 3. 暗号化したPDF(クリックするとPDFを表示します。権限パスワードは、「owner」です。文書を開くパスワードは、「user」です。)

2.最後に
このブログ記事が、実際のシステム開発に役立った方は、ぜひいいねボタンを押してください。またコメントもよろしくお願いいたします。(コメントするのに電子メールアドレス、名前、ウェブサイトは必須ではありません。入力なしで匿名でコメント可能です。)

©中條勝徳 and okulejp.com, 2012.

okule による FOP, XML, XSLT への投稿 (11月 16, 2012)

タグ: , , , , , ,

GoogleChrome最新版(22.0.1229.79)の不具合とダウングレード   Leave a comment

xhtmlの表示で、ボタン名の表示がおかしくなりました。プログラムソースを変更していないのに、 JSF2.0コンポーネントであるprimefacesの<p:commandButton>のボタン名が、一部の日本語表示において、1行で表示されていましたが、突然2行で表示されました。原因を調べたら、GoogleChrome最新版(22.0.1229.79)の不具合のように思われます(断定ではありません)。IEとFirefoxでは、ボタン名の表示は正しいです。使用しているOSは、Windows 7 64bitです。
私の環境では、Chromeのバージョンを以前のものに戻したら、改行されずに正しく表示されましたが、GoogleChrome最新版(22.0.1229.79)にもどしたら、複数行に表示されました。複数行に表示されるのは日本語のみで、英語では正しく表示されました。下記サイトに、Chromeのバージョンを元に戻す方法が掲載されています。今の時点で、そのような不具合は報告されていませんが、私と同じような不具合が発生した人は要注意です。

Chromeのバージョンを元に戻す方法を掲載したサイト
GoogleChrome最新版(22.0.1229.79)でGmail印刷不具合とChromeのバージョンを元に戻す方法

©中條勝徳 and okulejp.com, 2012.

okule による XML への投稿 (9月 29, 2012)