2017年7月26日水曜日

【Java】【Spring Integration】Service Activatorで例外送出

Service Activatorで例外送出するとどうなるのか?
下記のsaServiceで例外を発生させる。

◆integration-graph

◆ファイル構成

ソースコードのvalはlombokを使用。
◆Main.java
public class Main {
  public static void main(String[] args) {
    try (val ctx = new ClassPathXmlApplicationContext("SpringIntegration.xml")) {
      val inCh = ctx.getBean("inCh", MessageChannel.class);
      val outCh = ctx.getBean("outCh", PollableChannel.class);

      inCh.send(MessageBuilder.withPayload("test").build());
      System.out.println(outCh.receive());

      System.in.read();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

◆SampleService
@Component
public class SampleService {
  @ServiceActivator
  public String Exec(String msg) throws IllegalArgumentException {
    throw new IllegalArgumentException("err");
  }
}

◆SpringIntegration.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xmlns:int="http://www.springframework.org/schema/integration"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.1.xsd">

  <context:component-scan base-package="sample.springint.exception" />
  <int:channel id="inCh" />
  <int:channel id="outCh">
    <int:queue capacity="10" />
  </int:channel>

  <int:service-activator id="saService"
    input-channel="inCh" output-channel="outCh" ref="sampleService" />
</beans>

◆log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
  xmlns:log4j='http://jakarta.apache.org/log4j/'>
  <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%p] %m%n" />
    </layout>
  </appender>
  <root>
    <priority value="info" />
    <appender-ref ref="STDOUT" />
  </root>
</log4j:configuration>


◆実行結果
2017-07-26 01:43:34 [INFO] Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2e18f2: startup date [Wed Jul 26 01:43:34 JST 2017]; root of context hierarchy
2017-07-26 01:43:34 [INFO] Loading XML bean definitions from class path resource [SpringIntegration.xml]
2017-07-26 01:43:35 [INFO] Loading properties file from URL [jar:file:/C:/Users/root/.m2/repository/org/springframework/integration/spring-integration-core/4.1.4.RELEASE/spring-integration-core-4.1.4.RELEASE.jar!/META-INF/spring.integration.default.properties]
2017-07-26 01:43:35 [INFO] No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2017-07-26 01:43:35 [INFO] No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2017-07-26 01:43:35 [INFO] No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
2017-07-26 01:43:35 [INFO] JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2017-07-26 01:43:35 [INFO] Loading properties file from URL [jar:file:/C:/Users/root/.m2/repository/org/springframework/integration/spring-integration-core/4.1.4.RELEASE/spring-integration-core-4.1.4.RELEASE.jar!/META-INF/spring.integration.default.properties]
2017-07-26 01:43:35 [INFO] Initializing ExecutorService  'defaultSockJsTaskScheduler'
2017-07-26 01:43:35 [INFO] Initializing ExecutorService  'taskScheduler'
2017-07-26 01:43:36 [WARN] Neither 'urlMap' nor 'mappings' set on SimpleUrlHandlerMapping
2017-07-26 01:43:36 [INFO] Starting beans in phase -2147483648
2017-07-26 01:43:36 [INFO] Starting beans in phase 0
2017-07-26 01:43:36 [INFO] Adding {service-activator:saService} as a subscriber to the 'inCh' channel
2017-07-26 01:43:36 [INFO] Channel 'org.springframework.context.support.ClassPathXmlApplicationContext@2e18f2.inCh' has 1 subscriber(s).
2017-07-26 01:43:36 [INFO] started saService
2017-07-26 01:43:36 [INFO] Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2017-07-26 01:43:36 [INFO] Channel 'org.springframework.context.support.ClassPathXmlApplicationContext@2e18f2.errorChannel' has 1 subscriber(s).
2017-07-26 01:43:36 [INFO] started _org.springframework.integration.errorLogger

2017年7月21日金曜日

【SQL Server】【Visual Studio】【C#】DBからC#コード更新(上書き)

◆メニュー
 【SQL Server】開発環境構築(ER図作成にSSMSを使用)

◆手順

1.edmxファイルをダブルクリック。

2.モデルブラウザの空白部分を右クリックし、[データベースからモデルを更新]

3.「完了」ボタンを押下。

4. 変更されたことを確認(下図では生年月日が増えた)し、Ctrl+Sで保存。

5.以下が表示された場合は、「すべてに適用」ボタン押下。

6.生成されたコードも生年月日が増えている。

2017年7月15日土曜日

【SQL Server】【Visaul Studio】DBからC#コード生成

◆メニュー
【SQL Server】開発環境構築(ER図作成にSSMSを使用)

◆概要
SSMSで作成したDBインスタンスからC#のエンティティクラスを生成する手順

◆環境
Visual Studio Pro以上(Community版は未調査。)

1. Winキー押下し、visを入力し、Enterキー押下。(環境によってはVisだけでは足りないので、入力文字を増やすこと)

2. [ファイル]-[新規作成]-[プロジェクト]を選択。

3. 適切なテンプレートを選択し、適切なプロジェクト名を設定し、OKボタン押下。

4. Ctrl+Shift+Bでビルドし、F5キーで実行まで確認しておく。

5. プロジェクトを右クリックし、[追加]-[新しい項目]を選択。

6. 「ADO.NET Entity Data Model」を選択、適切な名前を入力し、「追加」ボタン押下。

7. 「データベースからEF Designer」を選択し、「次へ」ボタン押下。

8. サーバ名・データベース名を入力し、「テスト接続」ボタン押下。サーバ名・DBインスタンス名は読み替えること。

9. 「OK」ボタン押下。

10. 「接続設定に名前を付けて App.Config」に保存をチェックし、「次へ」ボタン押下。

11. 「Entity Framework 6.x」を選択し、「次へ」ボタン押下。

12. データベースオブジェクトは全選択し、「完了」ボタン押下。下記ではビューが存在しないため、チェックしていないが、基本的には全てにチェックを入れる。(モデル名前空間はDbEmployeesModelのようにしたほうがいいかも。)

13. 「OK」ボタン押下。

14. ソリューションエクスプローラーにedmxが作成され、配下にテーブル名.csが生成ていることを確認。

15. MainWindows.xamlをダブルクリックし、ツールボックスからButtonをD&D。

16. フォーム上に配置したbuttonを選択し、プロパティパネルの⚡ボタンを押下し、Clickテキストボックスをダブルクリック。
17. コードが生成されることを確認。

18. 下記のようにDBアクセスのコードを入力し、ビルド&実行。


namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            using (var ctx = new DB_EMPLOYEESEntities())
            {
                using (var tran = ctx.Database.BeginTransaction())
                {
                    ctx.T_部署.Add(new T_部署() { 部署ID = 1, 部署名 = "開発1" });
                    ctx.T_社員.Add(new T_社員() { 社員ID = 1, 姓 = "名無し", 名 = "太郎", 所属部署ID = 1 });

                    ctx.SaveChanges();
                    tran.Commit();
                }

                var ret = (from shain in ctx.T_社員
                           join bu in ctx.T_部署
                             on shain.所属部署ID equals bu.部署ID
                         select new { shain, bu }).First();

                // Namespace==Systemは、外部参照などを表示しないようにプリミティブとstringのみにフィルタ
                // しっくりこないが…。
                Func<object, List<string>> trans = o =>
                    (  from ps in o.GetType().GetProperties()
                      where ps.PropertyType.Namespace == "System"
                     select ps.Name + ":" + ps.GetValue(o, null)).ToList();

                MessageBox.Show(
                    string.Join(",", trans(ret.bu   )) + Environment.NewLine +
                    string.Join(",", trans(ret.shain)));
            }
        }
    }
}

19. Buttonを押下。

20. selectの結果も正しい。


21. SSMSで確認しても、レコードが挿入されていることが確認できる。


【SQL Server】開発用DBインスタンス作成&インポート

◆メニュー
 【SQL Server】開発環境構築(ER図作成にSSMSを使用)

◆前書き
 DB設計とアプリ開発を平行作業するなら、ER図作成用とアプリ開発用のDBインスタンスは分けておくと良い。管理が面倒だが、テーブル設計中にアプリの変更が発生なんて時に便利。(むぅ、アプリ開発者とDB設計者って普通のプロジェクトでは別々の人がやるんじゃねーの?)
 開発の終盤ではだんだん面倒になってきて、メンテナンスしなくなる。終盤では一本に絞っていいかも。
 DBインスタンスではなく、インスタンス内のDBを複数作る手もあるが、DB名はそこら中に出てくるため※、DBを複数作り、DB名を変えるというのも結構面倒になる。
 【SQL Server】新規インスタンス作成(ER図作成用)を参照してDBインスタンスを作成する。ただし、インスタンス名はDevelopにしておく。(大文字だけは見ずらい。Developのほうが見やすい。いや、長いのでDevで良い。)

※ 下記のように、DDLのエクスポートファイル等にDB名である「DB_EMPLOYEES」が出てきてしまっている。

◆インポート手順
1. インポート先のDBインスタンスへ接続

2. エクスポートしたファイル(script.sql)をSSMSへD&D。

3. インスタンス名を変更。下記ではERDIAGRAMをDevelopに変更している。ファイル内に2か所存在している。


4. 「!実行(X)」ボタンを押下。「コマンドは正常に完了しました。」となることを確認。


2017年7月14日金曜日

【SQL Server】DDL文をエクスポート Management Studio

◆メニュー
 【SQL Server】開発環境構築(ER図作成にSSMSを使用)

◆DDL文をエクスポート(SQL Server Management Studio)手順

1. Winボタン押下&「SSMS」と入力し、Enter。

2. 認証方法を選択し、接続。

3. 「スクリプトの生成」を選択。

4.  「次へ」ボタン押下

5. 必要なものを選択。以下では「データベース全体~」を選択。

6. オプションを選択して、次へ。(詳細設定ボタンで、より細かくオプションを選べる)

※ここで悩ましい問題がある。
 単一ファイルの場合、DDLが巨大(数千行?)だと、エクスポートは成功しても、インポートに失敗することがある(SQL Server2008の頃なので、今は大丈夫かも)。逆に「オブジェクトごとに1つのファイル」としてしまうと、インポートの際に、外部キー制約を意識して順番にファイルを投入する必要がある。

 両方出しておけばいいか。svnで扱う際はファイル単位のほうが過去ファイルと比較しやすいし、初回登録は、単一ファイルのほうが楽だし。巨大すぎて失敗したら、その時にファイル分割するかな。


7. 内容を確認し、「次へ」ボタン押下

8.「完了」ボタン押下。

9. ファイル出力を確認

10. ファイル内容を確認

以上