2012年7月5日木曜日

Windows Server 2008でGladinetを使う

Gladinet(Gladinet Desktop)は、Amazon S3やGoogle Driveなどのオンラインストレージを、Windowsのネットワークドライブとしてマウントすることができるアプリケーションです。

Gladinet はオンラインストレージへのプロキシーとなる、WebDAVサーバーとして動作する様で、ドライブとしてマウントするためには、WindowsのWeb Clientサービスが動作している必要があります。

Windows 7などのクライアント系のWindowsでは標準で動作しているのではないかと思いますが、サーバー系のWindowsではインストールされていないようです。そのため、Gladinetをインストールしただけでは、マウントすることができません。

WebClientサービスのインストールは、サーバーマネージャーで、「機能の追加」を実行し、「デスクトップエクスペリエンス」を選択します。ただし、デスクトップエクスペリエンスには、WebClient以外にもWindows Media PlayerなどデスクトップPC向けの機能が含まれています。

こんな感じで、ドライブ一覧に表示されるようになります。あとは通常のドライブと同じようにアクセスできるので便利です。



2012年6月6日水曜日

JBoss Forgeを試してみた

ForgeはJava EE6を利用したWebアプリケーション(のひな形)の作成 〜 アプリケーションサーバへのディプロイまで可能なコマンドラインツールです。作成されるアプリケーションはMavenプロジェクトのため、そのままIDE等で開くことができます。

また、プラグインによりサポートするフレームワークやAPサーバが追加できします。自分でプラグインを作成することもできます。

今回はForgeでJPAとJSFを使ったサンプルアプリケーションを作ってみます。

まず、Forgeをダウンロードして展開します。

$ https://repository.jboss.org/nexus/service/local/artifact/maven/redirect?r=releases&g=org.jboss.forge&a=forge-distribution&v=1.0.5.Final&e=zip
$ unzip Downloads/forge-distribution-1.0.5.Final.zip 

環境変数を設定します。

export FORGE_HOME=~/forge-distribution-1.0.5.Final/
export PATH=$PATH:$FORGE_HOME/bin

forgeコマンドでforgeのシェルを起動します。

list-commandで利用可能なコマンドを確認できます。–allを付けないと現在のコンテキストで利用可能なコマンドのみ表示されます。OSのコマンドやgit、mavenもforgeから呼び出すことができます。

$ forge
    _____                    
   |  ___|__  _ __ __ _  ___ 
   | |_ / _ \| `__/ _` |/ _ \  \\
   |  _| (_) | | | (_| |  __/  //
   |_|  \___/|_|  \__, |\___| 
                   |___/      
 
[no project] kenichiro22 $ list-commands --all 

[FILE & RESOURCES]
cat*                                    cd*
edit*                                   find*
fingerprint*                            grep*
list-web-resources*                     ls
ls*                                     mkdir*
mv*                                     open*
pick-up*                                pwd*
pwr*                                    rm*
wc*                                     

[OTHER]
alias*                                  beans list-alternatives*
beans list-decorators*                  beans list-interceptors*
beans new-bean*                         beans new-conversation
beans setup*                            constraint AssertFalse
constraint AssertTrue                   constraint DecimalMax
constraint DecimalMin                   constraint Digits
constraint Future                       constraint Max
constraint Min                          constraint NotNull
constraint Null                         constraint Past
constraint Pattern                      constraint Size
constraint Valid                        ejb setup*
entity*                                 faces new-view*
faces project-stage*                    faces setup*
faces*                                  field
field boolean                           field custom
field int                               field long
field manyToMany                        field manyToOne
field number                            field oneToMany
field oneToOne                          field string
field temporal                          git clone*
git git-checkout*                       git setup*
i18n add-locale*                        i18n faces-setup*
i18n get*                               i18n put*
i18n remove*                            i18n setup*
java list-imports                       java new-class*
java new-enum-const                     java new-enum-type*
java new-field                          java new-method
java*                                   jms setup*
jstl setup*                             jta setup*
persistence setup*                      persistence*
plugins new-plugin*                     plugins setup*
remove-constraint                       rest endpoint-from-entity*
rest setup*                             servlet setup*
servlet*                                soap setup*
unalias*                                validation setup*

[PROJECT]
build*                                  execute-java*
maven remove-parent*                    maven set-artifactid*
maven set-groupid*                      maven set-parent*
maven set-version*                      mvn*
new-project*                            project add-dependency*
project add-known-plugin-repository*    project add-known-repository*
project add-managed-dependency*         project add-plugin-repository*
project add-repository*                 project find-dependency*
project find-managed-dependency*        project install-facet*
project list-dependencies*              project list-facets*
project list-managed-dependencies*      project list-plugin-repositories*
project list-properties*                project list-repositories*
project remove-dependency*              project remove-facet*
project remove-managed-dependency*      project remove-plugin-repository*
project remove-property*                project remove-repository*
project set-property*                   project*
setup*                                  shade exclude*
shade include*                          shade make-executable*
shade relocate*                         shade remove*
shade reset*                            shade setup*
test*                                   

[SHELL ENVIRONMENT]
about*                                  clear*
echo*                                   exec*
exit*                                   forge find-plugin*
forge git-plugin*                       forge install-plugin*
forge list-plugins*                     forge remove-plugin*
forge restart*                          forge source-plugin*
forge*                                  help*
less*                                   list-commands*
list-config*                            list-properties*
more*                                   reset*
run*                                    run-url*
set*                                    version*
wait*                                   

[UI GENERATION & SCAFFOLDING]
list-scaffold-providers*                scaffold from-entity*
scaffold indexes*                       scaffold setup*
scaffold templates*                     

[VERSION CONTROL]
git*                                    

(* = command accessible from current context)

プロジェクトを作成します。

[no project] kenichiro22 $ new-project --named try-forge --topLevelPackage com.azuki3.forge --projectFolder workspace/try-forge
***SUCCESS*** Created project [try-forge] in new working directory [/Users/kenichiro22/workspace/try-forge]
scaffoldの設定を行います。JSFを使います。
[try-forge] try-forge $ scaffold setup --scaffoldType faces
 ? Scaffold provider [faces] is not installed. Install it? [Y/n] Y
 ? Facet [forge.maven.WebResourceFacet] requires packaging type(s) [war], but is currently [jar]. Update packaging? (Note: this could deactivate other plugins in your project.) [Y/n] Y
***SUCCESS*** Installed [forge.maven.WebResourceFacet] successfully.

JPAの設定を行います。 JPAプロバイダーとコンテナを指定します。JPAプロバイダーはHibernateをコンテナはJBoss AS7を指定してみます。

[try-forge] try-forge $ persistence setup --provider HIBERNATE --container JBOSS_AS7
***INFO*** Setting transaction-type="JTA"
***INFO*** Using example data source [java:jboss/datasources/ExampleDS]
 ? The JPA provider [HIBERNATE], also supplies extended APIs. Install these as well? [y/N] 
***SUCCESS*** Persistence (JPA) is installed.

ここから実際のアプリケーションを作成します。

まず、Entityを作成します。今回はリレーションを試してみたいので、User - Blog - Tagという3つのEntityを作成します。BlogとUserがManyToOneでBlogとTagがManyToManyです。

[try-forge] try-forge $ entity --named User
 ? In which package you'd like to create this @Entity, or enter for default [com.azuki3.forge.model] 
Created @Entity [com.azuki3.forge.model.User]
Picked up type : com.azuki3.forge.model.User

[try-forge] User.java $ field string --named name
Added field to com.azuki3.forge.model.User: @Column private String name;

[try-forge] User.java $ field string --named email
Added field to com.azuki3.forge.model.User: @Column private String email;

[try-forge] User.java $ entity --named Blog
Created @Entity [com.azuki3.forge.model.Blog]
Picked up type : com.azuki3.forge.model.Blog

[try-forge] Blog.java $ field string --named title
Added field to com.azuki3.forge.model.Blog: @Column private String title;

[try-forge] Blog.java $ field string --named content
Added field to com.azuki3.forge.model.Blog: @Column private String content;

[try-forge] Blog.java $ field temporal --named createdAt --type TIMESTAMP 
Added field to com.azuki3.forge.model.Blog: private @Temporal(TemporalType.TIMESTAMP) Date createdAt;

[try-forge] Blog.java $ field manyToOne --named user --fieldType com.azuki3.forge.model.User

[try-forge] Blog.java $ entity --named Tag
Created @Entity [com.azuki3.forge.model.Tag]
Picked up type : com.azuki3.forge.model.Tag

[try-forge] Tag.java $ field string --named name
Added field to com.azuki3.forge.model.Tag: @Column private String name;

[try-forge] User.java $ field manyToMany --named tag --fieldType com.azuki3.forge.model.Tag.java

Blogにバリデーションを追加します。

[try-forge] Blog.java $ validation setup --provider JAVA_EE
***SUCCESS*** Installed [forge.spec.validation] successfully.

[try-forge] Blog.java $ constraint NotNull --onProperty title 
Constraint NotNull has been successfully added on property named 'title'

[try-forge] Blog.java $ constraint NotNull --onProperty content 
Constraint NotNull has been successfully added on property named 'content'

[try-forge] Blog.java $ constraint Size --onProperty title --min 1 --max 256
Constraint Size has been successfully added on property named 'title'

[try-forge] Blog.java $ constraint Size --onProperty content --min 1 --max 256
Constraint Size has been successfully added on property named 'content'

[try-forge] Blog.java $ constraint NotNull --onProperty user 
Constraint NotNull has been successfully added on property named 'user'

EntityからJSFのscaffoldを作成します。

[try-forge] try-forge $ scaffold from-entity com.azuki3.forge.model.Blog.java ***INFO*** Using currently installed scaffold [faces]
 ? [/Users/kenichiro22/workspace/try-forge/src/main/webapp/resources/scaffold/pageTemplate.xhtml] File exists, overwrite? [Y/n] 
***SUCCESS*** Generated UI for [com.azuki3.forge.model.Blog]

ビルドしてJBoss AS7にディプロイします。JBoss AS7は別途起動しておきます。

[try-forge] try-forge $ build 
[try-forge] try-forge $ as7 deploy

こんな感じの画面ができます。ManyToOne, ManyToManyの関連も自動作成されます。ただ、バリデーションは動作しませんでした。もともとサポートされていないのか、私の使い方が悪いのかはわかりません。。

これくらいできれば、PlayやGrailsのscaffoldと同じくらいのことはできるでしょうか。

ついでにREST APIも作成します。

[try-forge] try-forge $ rest setup --activatorType APP_CLASS 
 ? What root path do you want to use for your resources? [/rest] 
 ? In what package do you want to store the Application class? com.azuki3.forge.
rest
 ? How do you want to name the Application class? [RestApplication] 
***SUCCESS*** Installed [forge.spec.jaxrs.applicationclass] successfully.
***SUCCESS*** Rest Web Services (JAX-RS) is installed.

[try-forge] try-forge $ rest endpoint-from-entity com.azuki3.forge.model.Blog.java
***SUCCESS*** Generated REST endpoint for [com.azuki3.forge.model.Blog]
他にもi18n用のファイルの作成や、JAX-RSからEJBまでなどひと通りのJavaEE用のコマンドがあるようです。

今回使ってみた感想ですが、、コマンドの補完機能を備えているので非常に使いやすいです。Scaffoldまで使わなくても、Java EE6をサポートしたコンテナを使い場合でもpom.xmlに各APIのライブラリを追加するのは結構面倒なので、それだけでも助かります。プラグインがどんどん増えてJava EE6以外のライブラリも簡単に使えるようになるといいですね。プラグインは、"find-plugin"コマンドで検索できるようなのですが、どこかで一覧でも見られるページはないのでしょうか。

あとscaffoldのテンプレートにTwitter bootstrapが使えたらいいですね。さらに、JSFの他にGWTでCRUDが作れたりすると助かるのですが。GWT用プラグインもあるので、どんなものかはそのうち試してみたいと思います。

今回のサンプルアプリケーションのコードは以下にあります。
https://github.com/kenichiro22/try-forge-scaffold

2012年6月1日金曜日

JBoss Erraiを試してみた

JBoss Erraiは、GWTをベースに次のような機能を追加した、RIA開発向けのフレームワークです。最近2.0がリリースされました。

  • 独自の非同期メッセージング(Errai bus)
  • RPC(not GWT-RPC)
  • JAX-RS対応
  • Beanのマーシャリング
  • クライアントでのDIとCDI(JSR-299/JSR-330)のサポート(一部)
  • CDIベースののクライアント・サーバ間のイベント機構

GWTをベースにしていますが、GWTの一部やGINを置き換えとなる多くの機能があります。

個人的に気になっているのはJAX-RS対応で、クライアントから直接サーバのJAX-RSのインタフェースを呼び出すことができます。また、Beanのマーシャリング機能を備えるため、GWT-RPCと同様にクライアント・サーバで同一のモデルを使用することができます。

GWTののRequestFactoryやAutoBeanではモデルに対してもインタフェースを定義する必要があり煩雑なので、GWT-RPCの大体として有望ではないでしょうか。ただ、同一のモデルを使用するため、GWTをの制約はかかってきますが。

また、JAX-RSのサービスを利用する場合、RequestBuilderとJavaScriptObjectを使用する必要がありましたが、Erraiを使うとサーバのJAX-RSインタフェースがそのまま使えるのでかなり楽になりそうです。

ErraiはManve archetypeがあるので(Errai Quickstart guide)、サンプルとしてJAX-RSを使ったプロジェクトを作ってみました。

mvn archetype:generate \
-DarchetypeGroupId=org.jboss.errai.archetypes \
-DarchetypeArtifactId=jaxrs-quickstart \
-DarchetypeVersion=2.0.0.Final \
-DarchetypeRepository=https://repository.jboss.org/nexus/content/groups/public/

JAX-RSのサービスインタフェースとして以下のようなクラスが作成されます。

@Path("customers")
public interface CustomerService {
  @GET
  @Produces("application/json")
  public List listAllCustomers();

  @POST
  @Consumes("application/json")
  @Produces("text/plain")
  public long createCustomer(Customer customer);

  @PUT
  @Path("/{id}")
  @Consumes("application/json")
  @Produces("application/json")
  public Customer updateCustomer(@PathParam("id") long id, Customer customer);

  @DELETE
  @Path("/{id}")
  public void deleteCustomer(@PathParam("id") long id);

  @GET
  @Path("/{id}")
  @Produces("application/json")
  public Customer retrieveCustomerById(@PathParam("id") long id);
}

JAX-RSのアノテーションのみでErraiのためのコードはありません。実装クラスの方は省略します。

JAX-RSでやり取りされるモデルクラスは以下のようになります。

@Portable
@Entity
public class Customer implements Serializable, Comparable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private long id;

    @NotNull
    @Size(min = 1)
    private String firstName;

    @NotNull
    @Size(min = 1)
    private String lastName;

    @NotNull
    @Size(min = 1)
    private String postalCode;

    private Date lastChanged;

    public Customer() {
    }

    // setter/getter ...
}

@Portableというアノテーションがあるクラスがマーシャリングの対象になります。アノテーションを付けられないようなケースやマーシャリング方法を変更したい場合の対応方法も用意されています。

実際にJAX-RSにアクセスするクライアントのコードは以下のようになります。

@EntryPoint
public class App {

    @Inject
    private Caller customerService;
    
    // ….
    
    final RemoteCallback creationCallback = new RemoteCallback() {
        @Override
        public void callback(Long id) {
            // レスポンスの処理
            // ...
        }
    };
    
    @PostConstruct
    public void init() {
        final Button create = new Button("Create", new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                Customer customer = new Customer(custFirstName.getText(), custLastName.getText(), custPostalCode.getText());
                customerService.call(creationCallback).createCustomer(customer);
            }
        });
        
    // …..
    }
}

サービスの呼び出しは非同期処理のためCallerというProxyを経由します。Proxyのcallメソッドに、レスポンスを処理するRemoteCallbackを渡します(サービスの戻り値が渡されます)。customerServiceは@Injectアノテーションがついているので、DI対象になります。

GWTのEntryPointは@EntryPointアノテーションで指定します。initメソッドには@PostConstructアノテーションが付いているので、インスタンスが生成されDIが行われた後に呼び出されます。ここでUIの初期化も行います。

ちょっと見た感じかなりよさそうなErraiですが、以下は2.0では提供されていないようです。MVPについてはGWTの標準もしくは、GWTPと組み合わせることになりそうです。どちらもGINを使用しているので、次はDIにErraiを使うように変更できるか試してみたいと思います。

  • MVPパターンのサポート
  • Widget類

2012年5月31日木曜日

Amazon RDS の MySQL でトランザクション分離レベルを変更する

Amazon RDSのMySQLインスタンスはデフォルトで、トランザクション分離レベル(tx_isolation)が、"REPEATABLE READ"になっています。これは、RDSのMySQLはInnoDBしか選択できず、InnoDBのトランザクション分離レベルのデフォルトが"REPEATABLE READ"。
今回必要があり"READ COMMITTED"に変更する手順を調べました。

mysqlのクライアントから以下のコマンドを実行しても権限がないということで拒否されます。GLOBALでない場合は可能。
mysql>SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
RDSではデータベースの設定はパラメーターグループで管理されています。現在、パラメータグループはAWS Consoleから変更できないようなので、CLIを使って変更します。

また、デフォルトのパラメーターグループは変更できないので、あらかじめ新しいパラメータグループを作成し、変更したいインスタンスのパラメータグループを変更しておきます。

まず、RDS CLIインストールします。
Amazon RDS Command Line Toolkitをダウンロードします(今回は 1.8.002)。展開したフォルダを適当な場所に移動し、以下の環境変数を追加します。

  • AWS_RDS_HOME : C:\RDSCli-1.8.002
  • PATH : %PATH%;%AWS_RDS_HOME%\bin

認証情報は以下のいずれかの方法で指定します(証明書を使用することも可能)。
  1. 環境変数AWS_CREDENTIAL_FILE でキーを記載したファイルを指定
  2. --aws-credential-file オプションでキーを記載したファイルを指定
  3. --I <ACCESS_KEY> --S  <SECRET_KEY> のようにオプションで直接指定
1,2で使用するファイルは以下のような形式で記載します。
AWSAccessKeyId=<Write your AWS access ID> AWSSecretKey=<Write your AWS secret key>

rds-describe-db-instancesコマンドを実行して動作確認します。

C:\> rds-describe-db-instances --region ap-northeast-1 --headers
DBINSTANCE  DBInstanceId  Created                   Class        Engine  Storage  Master Username  Status     Endpoint Address          Port  AZ               Backup Retention  Multi-AZ Version  License

DBINSTANCE  mysql-master  2012-05-29T08:20:33.655Z  db.m1.small  mysql   10  user              available  mysql.xxxxxxxxxx.ap-northeast-1.rds.amazonaws.com  3306  ap-northeast-1a  7                 n         5.5.20   general-pu
blic-license
      SECGROUP  Name          Status
      SECGROUP  default       active
      PARAMGRP  Group Name        Apply Status
      PARAMGRP  default.mysql5.5  in-sync
      OPTIONGROUP  Name               Status
      OPTIONGROUP  default:mysql-5-5  in-sync
リージョンは、--region オプションで指定しますが、環境変数AWS_REGIONで指定することも可能です。

tx_isolationを変更します。gourp1の部分がパラメータグループです。method=immediateを指定すると変更は再起動を待たずすぐに反映されます。
C:\> rds-modify-db-parameter-group gourp1 --region ap-northeast-1 --parameters="name=tx_isolation, value=READ-COMMITTED, method=immediate"
DBPARAMETERGROUP group1

mysqlコマンドでtx_isolationが変更されていることを確認します。
mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
+-----------------------+----------------+
| @@GLOBAL.tx_isolation | @@tx_isolation |
+-----------------------+----------------+
| READ-COMMITTED        | READ-COMMITTED |
+-----------------------+----------------+
ただし、変更の反映は少し時間(1分未満くらい?)がかかるようです。

2012年5月30日水曜日

mod_log_sql でアクセスログをMySQLに保存する

Apacheのmod_log_sqlモジュールを使うとアクセスログをデータベースに保存することができます。

mod_authn_dbdの場合と同様にOSはubuntu serverで、MySQLはRDSのインスタンスを使用しました。

MySQLの設定

RDSのインスタンスにてログ保存用のデータベースを作成しておきます。
create database logs;
create user apache identified by 'パスワード';
grant all on logs .* to apache;

mod_log_sqlのインストール

ubuntuのapt-getでインストールされるバージョンは古いので(確か1.10?)、ソースから1.99をインストールします。まずapt-getでapxs2をインストールします。
sudo apt-get install apache2-prefork-dev
mod_log_sql をインストールします。ソースとパッチをダウンロードし、makeしてインストールします。
$ wget http://www.outoforder.cc/downloads/mod_log_sql/mod_log_sql-1.99.tar.gz
$ tar -xzvf mod_log_sql-1.99.tar.gz
$ cd mod_log_sql-1.99
$ wget http://www.outoforder.cc/downloads/mod_log_sql/mod_log_sql-1.99.diff
$ patch -p0 < mod_log_sql-1.99.diff
$ wget http://www.outoforder.cc/downloads/mod_log_sql/mod_log_sql-1.99-2.diff
$ patch -p0 < mod_log_sql-1.99-2.diff
$ ./configure --with-apxs=/usr/bin/apxs2
$ make
$ sudo make install

以下の内容で/etc/apache2/mods-available/log_sql.loadを作成します。
LoadModule log_sql_module /usr/lib/apache2/modules/mod_log_sql.so
LoadModule log_sql_mysql_module /usr/lib/apache2/modules/mod_log_sql_mysql.so
モジュールをロードするよう設定します。
$ sudo a2enmod log_sql

ログ出力の設定

apacheの設定にて以下の記述を追加します。この設定では、access_logテーブルにデータを保存します。テーブルが存在しない場合には初回のアクセスログ記録時に作成されます。
LogSQLLoginInfo mysql://apache:パスワード@RDSのエンドポイント/logs
LogSQLCreateTables on
LogSQLTransferLogFormat AbHhmRSsTUuv
LogSQLTransferLogTable access_log
LogSQLDBParam port 3306
LogSQLMachineID web1 
LogSQLTransferLogFormatでログ出力対象の項目を指定しています。詳細はこちらのドキュメントにあります。パフォーマンスへの影響が気になるようであれば、不要な項目は取得しない方がよいかもしれません。
また、複数のWebサーバからログを保存する場合には、LogSQLMachineIDにてマシンごとのIDを指定することができます。

この設定で作成されるaccess_logテーブルは以下のようになります。
FieldTypeNullKeyDefault
idchar(19)YESNULL
agentvarchar(255)YESNULL
bytes_sentint(10) unsignedYESNULL
child_pidsmallint(5) unsignedYESNULL
cookievarchar(255)YESNULL
machine_idvarchar(25)YESNULL
request_filevarchar(255)YESNULL
referervarchar(255)YESNULL
remote_hostvarchar(50)YESNULL
remote_lognamevarchar(50)YESNULL
remote_uservarchar(50)YESNULL
request_durationsmallint(5) unsignedYESNULL
request_linevarchar(255)YESNULL
request_methodvarchar(10)YESNULL
request_protocolvarchar(10)YESNULL
request_timechar(28)YESNULL
request_urivarchar(255)YESNULL
request_argsvarchar(255)YESNULL
server_portsmallint(5) unsignedYESNULL
ssl_ciphervarchar(25)YESNULL
ssl_keysizesmallint(5) unsignedYESNULL
ssl_maxkeysizesmallint(5) unsignedYESNULL
statussmallint(5) unsignedYESNULL
time_stampint(10) unsignedYESNULL
virtual_hostvarchar(255)YESNULL
当然ですが、、LogSQLTransferLogFormatにかかわらずテーブル構造は同じで、どの列に値が入るが変わります。

これら以外にもCookieやHTTPヘッダを記録することもできるようです。

ファイルに保存したアクセスログを取り込む手間がないはよいのですが、アクセスの都度、DBにアクセスが発生するので、パフォーマンスが求められるようなサイトで使用するのは難しいかもしれません。全くチューニングしない状態で、apache benchで簡単に測定しただけですが、実際、mod_log_sqlを使うとスループットがかなり低下しました。

mod_authn_dbd + MySQL (RDS) でBasic認証

MySQLに保存したユーザ情報を使用して、ApacheでBasic認証を行う方法です。

データベースに格納したユーザー情報を使って認証を行うためのモジュールは、Apacheの1.3系と2系でも違いますし、いろいろあってどれを使うべきなのかわかりづらいです。はじめに、Apacheクックブック 第2版に載っていたmod_authn_dbiを使おうとしたのですが、全く情報がなくmod_authn_dbdにたどり着きました。

サーバはubuntu server、DBはAmazon RDS(Relational Database Service)のMySQLで試しました。RDS上のMySQLを使うからといって特別なことはなく、mysqlコマンドでリモート接続して、データベースおよび接続するユーザーを作成し、権限を付与しておきます。

mod_authn_dbdは標準でインストールされていたのですが、MySQL用dbdドライバーがインストールされていなかったので、apt-getでインストールします。
sudo apt-get install libaprutil1-dbd-mysql
a2enmodでauthn_dbdを有効にします。
sudo a2enmod authn_dbd
Apacheの設定ファイルにて、認証の設定を行います。
DBDriver mysql
DBDParams host=<RDSエンドポイント>,user=<ユーザーID>,pass=<パスワード>,dbname=<DB名>
DBDPersist On
DBDKeep 5
DBDMax 10
DBDMin 3
DBDExptime 600
<Directory /var/www>
    AuthBasicProvider dbd
    AuthDBDUserPWQuery "SELECT encrypt(password) FROM users WHERE user = %s"
    AuthName "Please Enter Your Password"
    Authtype Basic
    require valid-user
</Directory>
DBDParamsで接続先DBを指定し、AuthDBDUserPWQueryで認証時にユーザのパスワードを取得するSQLを指定します。%sの部分にユーザIDが入ります。また、DBDPersist をOnにするとコネクションをプールします。

注意点というほどのことではありませんが、"DB***"というディレクティブは<Directory>のなかにはかけません。

Apacheを再起動して、認証が正しく行われることを確認します。Internal Server Errorが発生するなど問題がある場合にはApacheのエラーログを確認します。