JBossでのパスワード設定

基本的にはTomcatと同じ仕組みのようですが触るファイルが異なるのでメモしておきます。
まずはJboss全体レベルとして触るのが以下のファイルです。ここで、このファイルにuserやroleを指定します。
….jboss-epp-5.2/jboss-as/server/default/conf/login-config.xml
私が追加した例はこんな感じ、
  <application-policy name=”MyJbossWebService”>
    <authentication>
      <login-module code=”org.jboss.security.auth.spi.UsersRolesLoginModule”
        flag=”required”>
        <module-option name=”usersProperties”>props/ws-users.properties</module-option>
        <module-option name=”rolesProperties”>props/ws-roles.properties</module-option>
      </login-module>
    </authentication>
  </application-policy>
ここで実際のuser名やrole名は実はprop配下の対応ファイルにこんな感じで設定

# cat ws-users.properties
# A sample users.properties file for use with the UsersRolesLoginModule
admin=testpassword
# cat ws-roles.properties
# A sample roles.properties file for use with the UsersRolesLoginModule
admin=client

次にそれぞれのアプリケーションに付属するファイルは以下の二つです。
WEB-INF/jboss-web.xml
WEB-INF/web.xml

jboss-web.xmlはTomcatにはありませんが、セキュリティ部分を宣言するだけのようです。

<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<!DOCTYPE jboss-web
    PUBLIC “-//JBoss//DTD Web Application 2.3V2//EN”
    “http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd“>
<jboss-web>
  <!– A security domain that restricts access –>
  <security-domain>java:/jaas/MyJbossWebServiceClient</security-domain>
</jboss-web>

web.xmlに関してはTomcatと同じような設定が必要です。

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>
        MyJbossWebServcieClient
      </web-resource-name>
      <url-pattern>/RemoteHourly</url-pattern>
      <url-pattern>/RemoteTemp</url-pattern>
      <url-pattern>/RemoteYear</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>client</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>UserDatabaseRealm</realm-name>
  </login-config>
  <security-role>
   <role-name>client</role-name>
  </security-role>

MySQL テーブルコピーの方法

ネットで調べたテーブルのコピー方法。

結構使えるのでメモ。特にDBを超えてコピーもできるので試験環境用のデータベースを作ったりするのにも便利。

こんな感じ。

Could not parse configuration: /hibernate.cfg.xml

昨日から本日にかけてはまってしまったエラー。
自分のPCで作成したhibernateを使用したプロジェクトをSolaris上のJbossに展開したときに発生したエラー。これだけみればxmlとしてのフォーマットが何か間違っているケースが考えられます。但し、同一のファイルが私のPCの環境では動作していますので、何か変です。また、別プロジェクトですが同様の内容のファイルがLinux上で動作していますのでDosとUnixのテキストファイルの差分によって発生している可能性も少ないです。(dos2unixでの確認もしましたが状況変わりませんでした。)
Web Service経由の動作なのでClient側、Server側にもあまり深いエラーメッセージが無く、困ってしまいました。仕方がないのでサーバ側に直接DBにアクセスするサーブレットを作成してログを確認してみました。こんなのが出ました。

Caused by: org.dom4j.DocumentException: www.hibernate.org Nested exception: www.
hibernate.org

ネットで調べてみました。なるほど、hibernate.cfg.xmlの先頭ではDTDのVersionに関してのヘッダーがあります。私の使用していたものの内容はこんな感じ。

<!DOCTYPE hibernate-configuration
    PUBLIC “-//Hibernate/Hibernate Configuration DTD//EN”
    “http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd“>

実はネットでサンプルコードを調べて使用していたときはこれとは異なる以下の設定をしようしていました。

<!DOCTYPE hibernate-configuration
    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
 
この設定をTomcat7.0上で使っていた際にobsoleteとのWarningが出たので上記の設定に変更していました。しかし、私のSolaris Jboss環境ではこのVersionではどこかのライブラリなどで競合状態になってしまっていたようです。古いスタイルに変更してとりあえず問題は解消しました。
勉強にはなりましたが、かなり時間を無駄にしてしまいました。
カテゴリー: AWS

「コメントは受け付けていません」を消す

個人的メモ、ネットには色々な方法が出ていますが、私の場合はこれでOKでした。

[root@ip-10-162-38-78 twentyeleven]# pwd
/var/www/html/wordpress/wp-content/themes/twentyeleven
[root@ip-10-162-38-78 twentyeleven]# diff comments.php  comments.php.old
71a72
>               <p><?php _e( ‘Comments are closed.’, ‘twentyeleven’ ); ?></p>

カテゴリー: AWS

IMAPが動かない…..dovecotの起動

久しぶりに簡単なことではまってしまいました。
サーバ上のメールアカウントの作業を簡単にするためにWindows Live Mailを使ってIMAPでサーバと通信しています。ところが、本日Live Mailを起動するとサーバ側の状態を取得できないとのエラーが発生。ネットワークの問題かと考えてtcpdumpで調べてみてもパケットは到達しているみたい…..
分かってみれば理由は簡単、IMAPサーバとしてdovecotを使っているのですが、これがサーバの再起動後に自動起動していなかっただけでした。(自分で再起動にしていないだけなのですが….)

[root@ip-10-162-38-78 log]# /etc/init.d/dovecot status
dovecot is stopped
[root@ip-10-162-38-78 log]# /etc/init.d/dovecot start
Starting Dovecot Imap:                                     [  OK  ]
[root@ip-10-162-38-78 log]# ps -ef|grep dovecot
root     30414     1  0 12:32 ?        00:00:00 /usr/sbin/dovecot
dovecot  30416 30414  0 12:32 ?        00:00:00 dovecot/anvil
root     30417 30414  0 12:32 ?        00:00:00 dovecot/log
root     30419 30414  0 12:32 ?        00:00:00 dovecot/config
root     30421 29120  0 12:32 pts/0    00:00:00 grep dovecot

AWSのパッチのスケジュールにあわせて大体一ヶ月に1回くらいサーバの再起動を実施していますが、dovecotを導入したのがちょうど先月の末ごろで2日前のサーバの再起動が導入後初の再起動でした。自動起動にすれば忘れないのですが、それではどんなソフトが動いているかも忘れてしまいますので、この後、再起動の際にはdovecotも再起動するようにしたいと思います。

Web Serviceへのパスワード認証追加

パスワード関連の続き。
Web Serviceに関してもBasic認証を設定し、Client側での設定方法を模索。
こんな感じで実現しました。
ポイント部分だけですが,

   URL url = new URL(“http://localhost:8080/MyTomWebService/services/SimpleWebService“);
   SimpleWebServiceSoapBindingStub stub = new SimpleWebServiceSoapBindingStub(url,null);
   stub.setUsername(“username”);
   stub.setPassword(“password”);
   System.out.println(stub.add(123, 345));

stubを作成して、そこにuser名とpasswordを設定するかだけでOKでした。
まあ、このままではクリアテキストで送信されますのでSSLでのラップは必要になると思います。個人的なSSLのcertificateを使用するとBrowserではWarningが出ますが、多分Web Sericeの場合はその部分は気にしなくてもいいのではと思いますが、このあたりも次に試験を実施したいところです。

 

カテゴリー: AWS

パスワード設定

wordpressやwebアプリケーションに関してパスワードでのロックを調査。
Tomcatにはbuild inのパスワード設定があるが、その外側wordpressにパスワードを掛ける方法を探す。
wordpressの場合にはpluginを使えば実現できることを発見。さらにこのパスワード入力画面の画像をカスタマイズするpluginもあわせて発見。以下の二つで期待の動作を実現できました。
password-protected
login-logo

Tomcatのパスワード設定に関してはいくつか関連するファイルがあるようですが、実際に設定する必要があったのは以下の二つのファイルでした。
/usr/share/tomcat7/conf/tomat-users.xml
/usr/share/tomcat7/webapps/MyProject/WEB-INF/web.xml
具体的な内容はこんな感じ
web.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:web=”http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd” id=”WebApp_ID” version=”3.0″>
  <display-name>MyProject</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>QuartzInitializer</servlet-name>
    <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
    <init-param>
      <param-name>shutdown-on-unload</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
    <security-constraint>
    <web-resource-collection>
      <web-resource-name>
        Authentication of MyWebProject
      </web-resource-name>
      <url-pattern>/input.jsp</url-pattern>
      <url-pattern>/inputHist.jsp</url-pattern>
      <url-pattern>/Schedule</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>client</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>UserDatabaseRealm</realm-name>
  </login-config>
        <security-role>
                <role-name>client</role-name>
        </security-role>
</web-app>

tomat-users.xml: (コメントなどはは省略して実際にEnableした部分だけ)
<tomcat-users>
<role rolename=”client”/>
  <user username=”user” password=”password” roles=”client”/>
</tomcat-users>

同じ仕組みでWeb Applicationのパスワードも設定できるのかを確認予定。

カテゴリー: AWS

Hibernateとデータのキャッシュ

さらに経験したのでメモって置く。
Web Serviceのクライアントからデータを取得。
そこには現れないデータをサーバ側にMySQLにてInsert
投入したデータをクライアント側からサーチ….それでもサーチ結果はNull

考えてみれば当然でHibernateはDBのデータをキャッシュしているので、Hibernateの
外側でデータが投入されてもそれはHibernateのキャッシュには反映されない。
おそらく、このようにHibernate経由以外のデータ更新の可能性があるシステムの
場合にはHibernateに対してDBへのRecasheをする仕組みが必要になると思われる。

できたら嬉しい仕組みとしては変更のあったテーブルに対して情報がDBからHibernate
に伝えられる。さらに、その情報からHibernateが該当テーブルのリキャッシュを行う….

アプリがHibernateに対して強制的にリキャッシュさせる仕組み、APIはきっとあると
思う。でもDBからHibernate以外の変更を確実に取得する方法は難しそう。
適当な時間間隔で自動リキャッシュが現実的な解決策かな….

カテゴリー: AWS

HIbernate関連メモ

今回Hibernateを導入した際に経験したトラブルなど…
まずはxmlファイルについて、この内容に関してフォーマットやデータの整合に関して問題があるとTomcat起動時のロード自体が失敗して関連機能が全く動作しなくなります。
とりあえず、以下が私が作成したhibernate.cfg.xmlとWeatehr.hbm.xmlの例です。

<!DOCTYPE hibernate-configuration
    PUBLIC “-//Hibernate/Hibernate Configuration DTD//EN”
    “http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd“>
 
<hibernate-configuration>
 
  <session-factory>
    <property name=”hibernate.connection.driver_class”>
      com.mysql.jdbc.Driver</property>
    <property name=”hibernate.connection.url”>
      jdbc:mysql://localhost/weather</property>
    <property name=”hibernate.connection.username”>nozomu</property>
    <property name=”hibernate.connection.password”>hasegawa</property>
    <property name=”hibernate.connection.pool_size”>3</property>
    <property name=”hibernate.dialect”> 
      org.hibernate.dialect.MySQLDialect</property>
    <property name=”hibernate.show_sql”>true</property>
    <!– Mapping files –>
    <mapping resource=”com/nozomu/hibernate/Social.hbm.xml”/>
    <mapping resource=”com/nozomu/hibernate/Weather.hbm.xml”/>
  </session-factory>
 
</hibernate-configuration>

<?xml version=”1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD//EN”
http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd“>
  <hibernate-mapping>
  <class name=”com.nozomu.hibernate.Hour” table=”hourly” lazy=”false”>
    <composite-id name=”id” >
      <key-property name=”date” />
      <key-property name=”hour” />
      </composite-id>
    <property name=”temperature” />
  </class>
  <class name=”com.nozomu.hibernate.Temperature” table=”temperature” lazy=”false”>
    <id name=”date” unsaved-value=”null” >
      <column name=”date” sql-type=”varchar(8)” not-null=”true”/>
      <generator/>
      </id>
    <property name=”average” />
    <property name=”high” />
    <property name=”low” />
  </class>
  <query name=”hourByDate”><![CDATA[from com.nozomu.hibernate.Hour as hour where hour.id.date = :date]]></query>
  <query name=”hourByFromAndTo”><![CDATA[from com.nozomu.hibernate.Hour as hour where hour.id.date >= :from and hour.id.date <= :to]]></query>
  <query name=”tempByDate”><![CDATA[from com.nozomu.hibernate.Temperature as temp where temp.date = :date]]></query>
  <query name=”tempByFromAndTo”><![CDATA[from com.nozomu.hibernate.Temperature as temp where temp.date >= :from and temp.date <= :to]]></query>
</hibernate-mapping>

higebernate-configに関してはサンプルのようにmappingタグは複数設定できますが、この先のxmlの内容に問題があるとhibernateは動きません。ここでmapping されていないファイルに関してはhibernateは使用しませんし、その内容のチェックは実行されません。動作環境で一部の機能に関して問題があったりした場合、ここでマッピングファイルを切り離すのもトラブルシュートのテクニックかも知れません。
mappingファイルの方はここではcomposite-idの使用例となります。composite-idの自体として別にid というpropertyをここではHourというクラスに設定しています。そしてそのclassはcom.nozomu.hibernate.CompositeIDというクラスで指定される構造であることを指定します。当然、CompositeIDというクラスが定義されること、また、Hourクラスに関して、
CompositeID id
という形でのデータが定義されていなければなりません。実際に作成してみると構造が分かってきましたが、ネットの情報を読んだだけではなかなか理解できませんでした。クラス名はすべて階層構造を含めて記載する必要があります。同じディレクトリとか関係無さそうです。
queryフィールドに関しても、このcomposite_idの設定が効いてきますので、
hour.date
では無く
hour.id.date
となります。おそらく、さらに階層化するケースもあるかも知れません。
階層化クラス名、query構造の正常性などもパッケージがロードされる段階でチェックされ問題があればエラーが出て機能しません。

動かす前にこのあたりのチェック、デバッグがかなり必要でした。まあ、分かっていないので当然ですが…..

少し、脱線しますが、サーバ側でHibernate経由のデータ検索、クライアント側でのHibernate経由のデータセーブのWeb Serviceを作りました。目論みとしてはHibernate関連のファイル(データ形式やDaoファイル)は共通で使用できると考えていました。しかし、Web Serviceの構築を行って、Client側にStabが作られる際に同時にデータ形式のファイルに変更が入っているようです。変更ではなく、サーバ側のクラスから自動再構成されているのかも知れません。
明らかに実装が変わっているのはequals()やhashCode()など本来Overloadしているもの、さらに、本来のコードでは特に記載の無かった、getSerializer()とかgetDeserializer()などが追加されています。確かにこのデータに関してはデータ構造が前述のCompositeID idがあることによってserializeに関して手当てが必要なのは想像できるのですが、どのタイミングでファイルが再構成されているのか気になります。おそらくWeb Serviceの作成のタイミングとは想像しています。

カテゴリー: AWS

Hibernateで学ぶサーバプログラミング…..Factoryとは工場のこと

DBの走っているサーバにWeb Serviceを構築し、他のサーバのWeb Service Client(これもTom Cat上でのサーブレット)でリモートDBのデータを取得してローカルのDBに格納しようというプロジェクト。実際に試験してみると思うように動作せず、その問題の解決で学べることが多いです。

リソースプールとsession Factory
ワンショットのコマンドやツールのコーディングと違い、サーバのプログラムを作る場合、リソースの再利用に関して注意が必要。javaにはgarbageコレクターがあるとはいえ不必要にリソースの割り当てを行えばプラットフォームへの負荷も掛かるし、メモリーリークの問題にもなる。基本的に、メモリやコネクション、セッションなどのリソースはできるだけ、アプリケーション内部で再利用するのがとても重要….と分かっていてもどこで実現するかは結構知識が必要だったり
今回学んだのがHibernateのsession処理に関する部分。以下はネットで参考にしたセッションの取得方法のサンプルコード。

public abstract class DaoSupport {
  protected Session getSession() {
        Configuration config = new Configuration().configure();
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        return session;
    }

このコードを呼んでsessionを取得する。私が考えたのはこの取得したsessionを呼び出し側のクラスのstaticデータとして記録してしまう方式。Sudoコードはこんな感じ。

sampleClass(
     static Session session = null;
    init(){
             if(session == null) session = getSession();
     }
     insert(){
           init();
           session.insert()
     }
}

こんな感じでsessionを使いまわしていると、正常にinsertしている限りはうまく動作したのですが、たとえば既にデータがあってHibernateConstraintViolationが出てしまうとその後の処理が同一sessionではできません。なにかtransactionがnestになれないといったエラーが出てしまいます。同一sessionを維持しながらその内容をクリアする方法を探したのですが、結局見つかりませんでした。しかし、もし、このsessionのローカルコピーをキープせずに一つのinsertやupdateなどのアクションごとにgetSession()を実行するとあっという間にtoo many connectionというエラーでDBへのアクセスができなくなります。困ってしまって、再度getSession()を眺めて見ました。
sessionFactoryのFactoryが怪しい…..これはここでsessionの再利用を管理しているのではないか….でも、それではなぜ、getSession()が呼ばる度に実際のコネクションが消費されてしまうのだろう….

気がついてしまえば簡単でした、sessionFactory自体の動作には問題が無くてもその前のbuildSessionFactory()でgetSession()が呼ばれるたびに新たにsessionFactoryを作成していることが原因でした。これではgetSession()が呼ばれるたびに新規のsessionFactoryが作成されそこからsessionが取得されてしまいます。明示的に毎回新規のDBコネクションを要求していたわけです。getSession()に関しては以下のように変更しました。

  static Configuration config = null;
 static ServiceRegistryBuilder serviceRegistryBuilder = null;
 static ServiceRegistry serviceRegistry = null;
 static SessionFactory sessionFactory = null;
 static boolean initF = false;
 private void init(){
        config = new Configuration().configure();
        serviceRegistryBuilder = new ServiceRegistryBuilder();
        serviceRegistryBuilder.applySettings(config.getProperties());
        serviceRegistry = serviceRegistryBuilder.buildServiceRegistry();
        sessionFactory = config.buildSessionFactory(serviceRegistry);        
  initF = true;
 }
 protected Session getSession() {
  if (!initF)init();
        Session session = sessionFactory.openSession();
        return session;
    }

古いコードがdeplicateされたメソッドを使用していたので少し変更されていますが、ポイントはgetSession()が呼ばれてもいつも同一のsessionFactoryが使われる点となります。このような配慮はワンショットの独立コマンドでは意味ありませんが、サービスや継続的に動作するアプリケーションの場合は重要な実装になると思います。

確かにFactory「工場」とは良いネーミングかも知れませんね。1台の自動車を作るために毎回工場を建設していたら採算合いませんね。工場は一箇所で十分ということでしょうか…..

 

カテゴリー: AWS