7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Oracle Cloud] Apache Tomcat から ATP に接続する on CentOS

Last updated at Posted at 2019-07-21

はじめに

Oracle Cloud Infrastructure(以下OCI)では、フルマネージドな自律型データベースサービスのAutonomous DBを提供しています。
パッチ適用、DB監視、バックアップ、チューニング、障害解決など、DB管理の全ライフサクルを自動化するため、保守運用作業を軽減することが可能です。

Autonomous DB は、現時点では以下の2種類のサービスを提供しています

  • Autonomous Transaction Processing(ATP) : 汎用的なオンライントランザクション用途
  • Autonomous Data Warehouse(ADW) : データウェアハウス用途

今回の記事では、CenetOS7, Apache Tomcat9, Apache HTTP Server から、ATPへ接続する方法を記載します。

環境構築編

ATP作成

OCI上で、Autonomous Transaction Processing(ATP)を適当に作成します。
必要に応じて、Documentを参照します。
https://docs.cloud.oracle.com/iaas/Content/Database/Tasks/adbcreating.htm

以下のパラメータでCreateを実行。Create完了まで数分かかります。

  • Display name : atpdisname
  • Database name : atpdataname
  • Choose a workload type : Transaction Processing
  • Chose a deployment type : Serverless
  • CPU core count : 1
  • Storage(TB) : 1
  • Auto scaling : on
  • Create administrator credentials password : 適当に (今回の例では、passwordPassword1で作成)
  • Choose a license type : License Included

OCI の仮想ネットワークのポート開放

仮想インスタンスを作成する仮想ネットワーク上で、Security List と、Network Security Group のポートを開放します。

  • TCP 80 (Apache HTTP Server)
  • TCP 8080 (Apache Tomcat)

インスタンスの構成

インスタンス作成, Oracle JDK Install

OCI 上で Cent OS を建てて、Oracle JDK をインストールします。以下の記事を参照
https://qiita.com/sugimount/items/33c65e2f648ea46c7239

Firewalld 停止

OCIの仮想ネットワークの機能で、以下のFirewall の機能があるため、インスタンス上の Firewalld を停止します

  • Security List (サブネット単位の設定)
  • Network Security Group (NIC単位の設定)
systemctl stop firewalld
systemctl disable firewalld

Apache Tomcat を Install

yum を使えば、Repositoryからtomcatをinstallすることが出来ますが、最新版を使用したいため Apache Tomcat の最新版(9.0.22) から install を行います

まず、ユーザーを追加します

useradd -s /sbin/nologin tomcat

Tomcatの9.0.22 を Install するための tar.gz をダウンロードします。

cd ~
wget http://ftp.kddilabs.jp/infosystems/apache/tomcat/tomcat-9/v9.0.22/bin/apache-tomcat-9.0.22.tar.gz

tar.gz を解凍して、/opt 配下に格納します

tar -xzvf ~/apache-tomcat-9.0.22.tar.gz
mv ~/apache-tomcat-9.0.22 /opt
chown -R tomcat:tomcat /opt/apache-tomcat-9.0.22

systemd で管理するために、ファイルを作成します

cat <<'EOF' > /etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat 9
After=network.target

[Service]
User=tomcat
Group=tomcat
Type=oneshot
PIDFile=/opt/apache-tomcat-9.0.22/tomcat.pid
RemainAfterExit=yes

ExecStart=/opt/apache-tomcat-9.0.22/bin/startup.sh
ExecStop=/opt/apache-tomcat-9.0.22/bin/shutdown.sh
ExecReStart=/opt/apache-tomcat-9.0.22/bin/shutdown.sh;/opt/apache-tomcat-9.0.22/bin/startup.sh

[Install]
WantedBy=multi-user.target
EOF
chmod 755 /etc/systemd/system/tomcat.service
systemctl daemon-reload

tomcat を起動します。

systemctl restart tomcat
systemctl enable tomcat

仮想インスタンスの PublicIPの8080番ポートにアクセスして、Tomcat Logo が表示されることを確認します

1563681679573.png

Apache HTTP Server を Install

Apache HTTP Server をインストールします

yum install -y httpd

依存関係解決memo

===========================================================================================================================================================
Package                             Arch                           Version                                       Repository                          Size 
===========================================================================================================================================================
Installing:
 httpd                               x86_64                         2.4.6-89.0.1.el7_6                            ol7_latest                         1.2 M 
Installing for dependencies:
 apr                                 x86_64                         1.4.8-3.el7_4.1                               ol7_latest                         103 k 
 apr-util                            x86_64                         1.5.2-6.0.1.el7                               ol7_latest                          91 k 
 httpd-tools                         x86_64                         2.4.6-89.0.1.el7_6                            ol7_latest                          90 k 
 mailcap                             noarch                         2.1.41-2.el7                                  ol7_latest                          30 k 

Transaction Summary
===========================================================================================================================================================

起動

systemctl restart httpd
systemctl enable httpd

仮想インスタンスに紐づいている Public IPの80番ポートにアクセスすると、以下のページが表示されます

1563379863890.png

Apache HTTP Server と Tomcat の連携

Apache HTTP Server と Tomcat 間の通信は、AJP(Apache JServ Protocol) という名前のプロトコルが使用されています。
Apache HTTP ServerからTomcat宛に ASP のリクエストを送付すると、リクエスト情報に従って、Tomcat は Servlet を起動します。

Tomcatの設定ファイルを確認します。

less /etc/tomcat/server.xml

以下のように、8080ポートと、8009ポートを受け付ける設定となっています。8080ポートは、TomcatとしてHTTPのアクセスを受け付けるポートとなっており、8009はServletを起動するためのポートとなっています。
Apache HTTP Server から Tomcatを呼びだすためには、8009ポート宛にAJP通信を行えば良いことが分かりました。

.... 省略 ...
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
.... 省略 ...
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
.... 省略 ...

Apache HTTP Server から、Tomcat へ通信するためには、mod_proxy_ajpmod_proxyのモジュールが必要になります。
Apache HTTP Server のモジュール読み込み設定ファイルを確認します

less /etc/httpd/conf.modules.d/00-proxy.conf

下記のように、2種類のモジュールが有効になっていることが分かります。

# This file configures all the proxy modules:
LoadModule proxy_module modules/mod_proxy.so <============== mod_proxyが有効になっている
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so <====== mod_proxy_ajpが有効になっている
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

では次に、どんなパスにアクセスされた時に、Tomcat と連携するのか、ProxyPass の設定を行います
以下の書式で設定する必要があります。

ProxyPass httpdでのパス ajp://サーバー名:8009/Tomcat上のパス/

例えば、Apache HTTP Server で受け付けたすべてのリクエストを Tomcat で処理したい場合は、次のようになります(httpd と Tomcat が同一ホストにある場合)

ProxyPass / ajp://localhost:8009/

また sample ディレクトリへのアクセスを Tomcat 上の example と連携したい場合は次のようになります。

ProxyPass /sample/ ajp://localhost:8009/example/

それでは、今回は全てのパスをProxyとして転送するために、以下の設定を入れましょう

echo "ProxyPass / ajp://localhost:8009/" > /etc/httpd/conf.d/proxy.conf

Apache HTTP Server の再起動を行います

systemctl restart httpd

Tomcat のテストページが、Apache の 80 ポートで表示されていればOKです
1563681679573.png

Oracle JDBC Driver の ダウンロード

Javaアプリケーションから、Oracle DB にアクセスを行うためには、Oracle JDBC Driver を Installする必要があります。

Oracle JDBC Driverには、大きく分けて以下2種類があります。

  1. Oracle Call Interface(OCI) Driverを使って接続する。Oracle JDBC Driver と Oracle Instant Clientを導入する必要がある
  2. Thin Driver を使って接続する。Javaのライブラリで接続するため、Oracle JDBC Driver の導入だけでOK

基本的に、Oracle Interface Driver の固有の機能(TAFなど)を使う必要がなければ、Thin Driverを使用します。
Oracle Call Interface Driver と Thin Driver の違いは以下の表に記載があります。
https://docs.oracle.com/cd/F19136_01/jjdbc/introducing-JDBC.html#GUID-696E8F49-4B61-4520-8557-318320CE7A66

また、My Oracle Support の Knowledge ページに、Oracle JDBC Driver の説明や、Install方法、バージョン互換性などが記載されているため、一度読んでおくと勉強になります。(My Oracle Supportのアカウントが必要になります)
https://support.oracle.com/epmos/faces/DocumentDisplay?id=1999901.1

OTN(Oracle Technology Network) から、Oracle JDBC Driver の Jar ファイルを ダウンロードします。以下のページから、ダウンロードしたいバージョンを選択します。基本的には最新で問題ないと思います。
https://www.oracle.com/technetwork/database/application-development/jdbc/downloads/index.html

ojdbc10-full.tar.gz ファイルをダウンロードして、OCI上のCentOSインスタンスに格納します。

tar.gz ファイルを解凍します

cd /home/opc
tar xfvz ojdbc10-full.tar.gz

今回の例では、以下のディレクトリに解凍をしています。

$ ls -la /home/opc/ojdbc10-full 
total 8668 
drwxr-xr-x. 2 opc opc     211 Apr 29 22:15 .
drwx------. 7 opc opc     183 Jul 20 03:00 ..
-rw-r--r--. 1 opc opc    2625 Apr 29 22:15 README.txt
-r-xr-xr-x. 1 opc opc   11596 Apr 24 21:07 ojdbc.policy
-r--r--r--. 1 opc opc 4243140 Apr 24 21:07 ojdbc10.jar
-r--r--r--. 1 opc opc  144681 Apr 24 21:07 ons.jar
-r--r--r--. 1 opc opc  306004 Apr 24 21:07 oraclepki.jar
-r--r--r--. 1 opc opc 1661488 Apr 24 21:07 orai18n.jar
-r--r--r--. 1 opc opc  205154 Apr 24 21:07 osdt_cert.jar
-r--r--r--. 1 opc opc  306854 Apr 24 21:07 osdt_core.jar
-r-xr-xr-x. 1 opc opc   29205 Apr 24 21:07 simplefan.jar
-r--r--r--. 1 opc opc 1680074 Apr 24 21:07 ucp.jar
-r--r--r--. 1 opc opc  262664 Apr 24 21:07 xdb.jar

(Skip)Oracle Instant ClientのInstall

今回の手順では、Oracle DB に接続するための、Oracle Instant Client はインストールしません。

JDBC Oracle Call Interface Driver 固有の機能を使用したい場合は、Oracle Instant Client を インストールする必要がありますので、ご注意ください。

ATP の Wallet をダウンロード

rootユーザーとなり、ATPから wallet をダウンロードして、以下のディレクトリに解凍します。

sudo su -
mkdir /opt/wallet
cp -p /home/opc/Wallet_atpdataname.zip /opt/wallet/
cd /opt/wallet/
unzip Wallet_atpdataname.zip
rm -f Wallet_atpdataname.zip

以下のディレクトリ構成になっていればOKです

# ls -la /opt/wallet
total 36 
drwxr-xr-x. 2 root root  148 Jul 20 16:27 .
drwxr-xr-x. 4 root root   30 Jul 20 16:26 ..
-rw-r--r--. 1 root root 6661 Jul 20 16:27 cwallet.sso
-rw-r--r--. 1 root root 6616 Jul 20 16:27 ewallet.p12
-rw-r--r--. 1 root root 3242 Jul 20 16:27 keystore.jks
-rw-r--r--. 1 root root   87 Jul 20 16:27 ojdbc.properties
-rw-r--r--. 1 root root  114 Jul 20 16:27 sqlnet.ora
-rw-r--r--. 1 root root 1744 Jul 20 16:27 tnsnames.ora
-rw-r--r--. 1 root root 3335 Jul 20 16:27 truststore.jks

ATPにSampleDataを格納

ATPに接続して、以下のSQLを流すことでSampleDataを格納します。
自分の場合は、Vistual Studio Code から接続を行ってSQLを流しています。
以下のURLに導入方法を記載しています。

-- Create a new Relational table with 3 columns

CREATE TABLE SAMPLE_TABLE 
(
  id VARCHAR2(255) NOT NULL,
  name VARCHAR2(1024)
);

-- Insert rows in a Table

INSERT INTO SAMPLE_TABLE 
VALUES
(
  '001',
  'suzuki'
);

-- Insert rows in a Table

INSERT INTO SAMPLE_TABLE 
VALUES
(
  '002',
  'satou'
);

-- Insert rows in a Table

INSERT INTO SAMPLE_TABLE 
VALUES
(
  '003',
  'tanaka'
);

Javaアプリケーション編

純粋なJavaアプリから接続

動作確認のために、Tomcat を使用しない純粋なJavaアプリケーションから動作確認をします。

mkdir /home/opc/java/
cat <<'EOF' > /home/opc/java/SampleRun.java
import java.sql.*;

public class SampleRun {
    public static void main(String[] args) {
        final String path = "jdbc:oracle:thin:@atpdataname_high";
        final String id = "ADMIN";  //ID
        final String pw = "passwordPassword1";  //password

        try (
            Connection conn = DriverManager.getConnection(path, id, pw);
            Statement  stmt = conn.createStatement();
            ResultSet  rs   = stmt.executeQuery("SELECT NAME FROM SAMPLE_TABLE");
        ) {
            while (rs.next()) {
                String cn = rs.getString("name");
                System.out.println("Name => " + cn);
            }
        } catch(SQLException ex) {
            ex.printStackTrace();  //Error
        }
    }
}
EOF

コンパイル

javac /home/opc/java/SampleRun.java

実行
Walletの格納先を環境変数に指定

cd /home/opc/java

export TNS_ADMIN=/opt/wallet

java -classpath /home/opc/ojdbc10-full/ojdbc10.jar:\
/home/opc/ojdbc10-full/ucp.jar:\
/home/opc/ojdbc10-full/oraclepki.jar:\
/home/opc/ojdbc10-full/osdt_core.jar:\
/home/opc/ojdbc10-full/osdt_cert.jar:. \
SampleRun

実行例

# java -classpath /home/opc/ojdbc10-full/ojdbc10.jar:\
> /home/opc/ojdbc10-full/ucp.jar:\
> /home/opc/ojdbc10-full/oraclepki.jar:\
> /home/opc/ojdbc10-full/osdt_core.jar:\
> /home/opc/ojdbc10-full/osdt_cert.jar:. \
> SampleRun
Name => satou 
Name => tanaka
Name => suzuki

Apache HTTP Server + Apache Tomcatから接続

Tomcat の webapps ディレクトリは、下のディレクトリになっています

/opt/apache-tomcat-9.0.22/webapps

demoアプリ作成のために、ディレクトリを作成します

mkdir /opt/apache-tomcat-9.0.22/webapps/demo
mkdir /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF
mkdir /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/lib
mkdir /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/classes

Tomcat の Servlet から、ATPに接続するための demo アプリを格納します

cat <<'EOF' > /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/classes/DemoServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import java.sql.DatabaseMetaData;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class JDBCSample_Servlet
 */
@WebServlet("/demo")
public class DemoServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;     
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DemoServlet() {
        super();
    }

  /**
   * Method to get a connection to the Oracle Database and perform few 
   * database operations and display the results on a web page. 
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
    PrintWriter out = response.getWriter();
    out.print("Sample JDBC Servlet\n");
    try {
      // Get a context for the JNDI look up
      DataSource ds = getDataSource();
      // With AutoCloseable, the connection is closed automatically.
      try (Connection connection = ds.getConnection()) {
        out.print("The database user is " 
           + executeBusinessLogicOnDatabase(connection, out));
        out.print("\n Sample JDBC Servlet Request was successful");
        response.setStatus(200);
      }
    } catch (Exception e) {
      response.setStatus(500);
      response.setHeader("Exception", e.toString());
      out.print("\n Web Request failed");
      out.print("\n "+e.toString());
      e.printStackTrace();
    }
  }

 /*
  * Method to create a datasource after the JNDI lookup
  */

  private DataSource getDataSource() throws NamingException {
    Context ctx;
    ctx = new InitialContext();
    Context envContext = (Context) ctx.lookup("java:/comp/env");
    // Look up a data source
    javax.sql.DataSource ds
          = (javax.sql.DataSource) envContext.lookup ("tomcat/UCP_atp");
    return ds;
  }

 /*
  * Method to showcase database operations using the database connection 
  */
  private String executeBusinessLogicOnDatabase(Connection conn, 
    PrintWriter out) throws SQLException {
    // Get the JDBC driver name and version 
    DatabaseMetaData dbmd = conn.getMetaData();       
    out.println("Driver Name: " + dbmd.getDriverName());
    out.println("Driver Version: " + dbmd.getDriverVersion());
    
    String user = "";	
    String query = "SELECT NAME FROM SAMPLE_TABLE"; 
    Statement stmt = conn.createStatement(); 
    ResultSet rs = stmt.executeQuery(query); 
    while (rs.next()) { 
     user = user + " " + rs.getString(1);
    }          
    stmt.close();
    rs.close();
    return user;
  }

  public void destroy() { }
  
}
EOF

web.xml を作成します

cat <<'EOF' > /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> 
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <display-name>Demo Application</display-name>
    <description>
        This is a demo web application.
    </description>

    <servlet>
        <servlet-name>DemoServlet</servlet-name>
        <servlet-class>DemoServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>DemoServlet</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>

</web-app>
EOF

コンパイルします

javac -classpath /opt/apache-tomcat-9.0.22/lib/servlet-api.jar /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/classes/DemoServlet.java

Oracle JDBC Driverを格納します

cp /home/opc/ojdbc10-full/* /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/lib

Tomcat から ATP に接続するために、context.xml を新規作成し、Resouce を定義します。

mkdir /opt/apache-tomcat-9.0.22/webapps/demo/META-INF
cat <<'EOF' > /opt/apache-tomcat-9.0.22/webapps/demo/META-INF/context.xml
<Context> 
<Resource name="tomcat/UCP_atp" auth="Container"
   factory="oracle.ucp.jdbc.PoolDataSourceImpl"
   type="oracle.ucp.jdbc.PoolDataSource"
   description="UCP Pool in Tomcat"
   connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource"
   minPoolSize="5"
   maxPoolSize="50"
   initialPoolSize="15"
   user="ADMIN"
   password="passwordPassword1"
   url="jdbc:oracle:thin:@atpdataname_high?TNS_ADMIN=/opt/wallet"
 />
</Context>
EOF

JAVA_OPTS を編集し、fanEnabledを無効化します

vim /opt/apache-tomcat-9.0.22/bin/catalina.sh
JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS"
JAVA_OPTS="$JAVA_OPTS -Doracle.jdbc.fanEnabled=false"

↑追加

Tomcat 再起動

systemctl restart tomcat

http://ipaddress/demo/demo
にアクセスして、Demoページが表示されていることを確認します。
The database user is ... と記載されている箇所が、ATPか取得してきたUserを表示しています

1563683485361.png

参考URL

Oracle JDBC Driverについて
https://support.oracle.com/epmos/faces/DocumentDisplay?id=1999901.1

Java開発者ガイド
https://docs.oracle.com/cd/F19136_01/jjdev/index.html

JDCB開発者ガイド
https://docs.oracle.com/cd/F19136_01/jjdbc/index.html

Java Connectivity to ATP
https://www.oracle.com/technetwork/database/application-development/jdbc/documentation/atp-5073445.html

Apache httpd と Tomcat を連携させる方法
https://weblabo.oscasierra.net/tomcat-mod-proxy-ajp/

GitHubでJavaアプリケーション
https://github.com/syobochim/code19-coding-hol/tree/master/spring-boot

上記GitHubの解説ブログ
https://syobochim.hatenablog.com/entry/2019/05/20/002555

IntelliJ IDEA で ATP に接続
https://syobochim.hatenablog.com/entry/2019/04/11/082800

Autonomous DB(ADW/ATP) に Java の JDBC Thin Driver で接続してみる。(OCI, Oracle Cloud Infrastructure)
https://qiita.com/ora_gonsuke777/items/91ec0e15848a78ede385

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?