FlywayのJavaコードによるマイグレーション

JavaのデータベースマイグレーションのライブラリであるFlywayですが、SQLファイルだけでなく、Javaのコードによるマイグレーションにも対応しています。

やり方は簡単で、SQLファイルと同じパッケージ(デフォルトだとdb.migration)配下に、SQLファイルと同じ規則でBaseJavaMigration を継承したクラスを追加して、migrateメソッドを実装するだけです。

package db.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;

public class V2__Load_data extends BaseJavaMigration {

    @Override
    public void migrate(Context context) throws Exception {

        NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(
                new SingleConnectionDataSource(context.getConnection(), true));

        jdbcTemplate.update(
                "INSERT INTO customers(first_name, last_name, address) VALUES (:firstName, :lastName, :address)",
                new MapSqlParameterSource()
                        .addValue("firstName", "Taro")
                        .addValue("lastName", "Yamada")
                        .addValue("address", "Chiba"));
    }
}

SQLで書くのが面倒なもの(ロジック自体が既にJava側にあるようなものとか)は、SQLで頑張らずにJava側での処理で行った結果をデータベースに登録する、、といったことで手間が減らせそうです。
また、データベース以外(ファイルとして保存されているようなデータとか)のマイグレーションも、これを使うと合わせて行うことができるので、いろいろ幅が広がりそうだなーと思いました。

Redmine: View customize plugin の v2.7.0 をリリースしました

View customize plugin の v2.7.0 をリリースしました。

2つの機能追加、改修を行っています。

プロジェクト識別子で対象ページを指定可能に

プロジェクト識別子(正規表現)で対象ページを絞ることができるようになりました。

今までもそういったシチュエーションがあることは認識していて、JavaScriptでViewCustomize.context.project.identifierなどを参照してハンドリングするコードを書いていましたが、プロジェクト毎の指定が多くなると管理がしずらくなる(一覧で見た際にわからない)というのをPull Requestいただいた際に認識できたので、機能として入れることにしました。
(@basyura さんからPull Requestいただきました。ありがとうございます!)

Path Pattern を任意項目に

Path Patternを必須項目ではなく任意項目に変えました。未入力の場合は、すべてのページが対象になります。
Insert Positionが入ってから、Path Patternを.*とすることが多くなったので、いつか必須は外そうと考えていました。今回新たに入力項目が増えて良いタイミング(キャプチャ撮り直すのが1度で済む...)だと思ったので、あわせて対応しています。

f:id:onozaty:20200705212001p:plain

リビングでのオンラインミーティングには Jabra Engage 50 がおススメ

リビングでのオンラインミーティングの悩み

在宅勤務で毎日オンラインミーティングがあるのですが、

  • PCデスクはリビングにおいてあるのでリビングで作業している
    (元々家にいるとき暇があればPC触っているので、家族がいるところに置きたくてリビングにしています)
  • 家族(嫁さん+娘3人)も学校やパートの休みが多くなり、平日昼間にリビングにいる時間が多い

ということで、家族が気を使ってくれていても、ミーティングに家族の声や生活音がどうしても入ってしまっていました。

ミーティングに参加しているメンバーは理解があって、まったく気にしないし、時々その音がネタになって話が盛り上がる、、みたいな感じでしたが、逆に家族に気を使ってもらうのが申し訳ないなと思う状態が続いていたため、これをどうにかすべく、マイクを調べ始めました。

元々使っていたものは、ゼンハイザーのPC 3 CHAT という3000円くらいで買ったヘッドセットです。

単一指向性でノイズキャンセリングマイクということですが、結構周りの音も拾ってしまっています。家族がリビングで話していたら、普通に聞こえる感じです。

他のものを探そうにも、なかなか家族の生活音などに関するレビューはなく、同じようなシチュエーションって考えると、コールセンターではと思い、コールセンター用のヘッドセットを探し始めました。

Jabra

コールセンター用のヘッドセットで調べていくと、Jabraというメーカーの製品がよさそうに見えました。コールセンター用のヘッドセットで高いシェアを持っているメーカーです。

www.jabra.jp

マイク性能で見ていくと、Jabra Engage 50 というのが、トリプルマイクテクノロジーとやらで、すごそうです。

とはいえ24,000円なので、これで失敗したら怖いな、、ってことで他の人のレビューを探していたところ、下記にたどり着きました。

Jabra の Engage 50 が最強だった 検証の結果、 Jabra / Engage 50 のマイク指向性が格別に強力という結論にいたりました。口元のマイク位置が数 cm ずれると装着者の声ですら拾わなくなると書けば、その指向性の強さが伝わるかと思います。

これは期待できる!!ということで、購入に踏み切りました。(この記事が無かったら、もっと悩んでいたと思います。感謝!!)

結果

1週間使ってみましたが、大満足です。まったく家族の音を拾わなくなりました。

参考までに、リビングで子供がいる状態で録音した音声を2つあげておきます。 最初がゼンハイザーのPC 3 CHAT、2つ目がJabra Engage 50です。

  • ゼンハイザー PC 3 CHAT
  • Jabra Engage 50

ゼンハイザーでは子供の声が入り込んでいますが、Jabra Engage 50 ではまったく入り込んでいません。また、マイクが拾う声もとてもクリアです。

同じ悩みを抱えた方は多いと思いますので、参考になったらうれしいです。値段以上の価値があると個人的には感じています。

attendance-recorder という出退勤を記録、参照するアプリケーションを作りました

在宅勤務中の出退勤がもう少し見える化できないかなぁと思って、attendance-recorder という出退勤を記録、参照できるアプリケーションを作りました。

github.com

Spring Bootで作ってます。

APIを叩いて出勤、退勤を記録して、それをWeb上で見れるような形になっています。

https://raw.githubusercontent.com/onozaty/attendance-recorder/master/screen.png

Rocket.Chat上でボットに話しかけて記録したかったので、Rocket.ChatのOutgoing WebHookを使って連携できるようにしています。(Slackと同じフォーマットだったと思うので、Slackでも使えるかも)

https://raw.githubusercontent.com/onozaty/attendance-recorder/master/rocket-chat.png

最低限の機能しかないのですが、公開したら他にも使う人がいるかもしれないということで、、

詳しくはREADMEをご参照ください。

第18回 redmine.tokyo勉強会で発表してきました

第18回 redmine.tokyo にて、『「伝わるチケット」の書き方』というタイトルでLTさせていただきました。

資料はこちら。

www.slideshare.net

一番重要なのは「チームの他のメンバのことを考えること」としましたが、実際この気持ちが無いと、なかなか今回書いたようなことをやろうという気持ちになれないと思います。
逆に「チームの他のメンバのことを考える」という気持ちがあれば、これ以外にもいろいろできることがあると思います。

そういう気持ちのメンバが一人だったとしても、それをチケットに表していけば、他の人もそのチケットを見ることによって、どんどんチーム内に伝播していくと思います。そして気が付いたら、それがチーム内の文化になっていると思います。
もしも自分のチームにはそういった気持ちが足りないな、、って感じたら、まずは自分が一人目としてチケットに表現していくのはいかがでしょうか。

最後に、、
お誘いいただいたスタッフの皆様ありがとうございました。 オンラインでの開催でしたが、スムーズに開催できたのは、スタッフのみなさまのおかげだと思います。
他の方々の発表は、急遽はいった家の用事もあって全部は聞けなかったのですが、気になる話ばかりだったので、後から資料などで見返そうと思っています。

次の開催も楽しみにしています。ありがとうございました!

redmine-issue-loader のバージョン2.3.0をリリースしました

CSVを読み込んでRedmineのチケットを新規作成、更新するツール、redmine-issue-loaderのバージョン2.3.0をリリースしました。

変更点は下記の2つです。

  1. HTTPタイムアウトの設定を変更可能に
    • デフォルト10秒だったのですが、親子関係が激しい状態だとタイムアウトしかねないと思ったので、タイムアウトを変更可能にしました。
  2. 文字置換を設定可能に
    • Redmineに登録時に問題となる文字を除外したいために、正規表現による文字置換を行えるようにしました。古いMySQLでutf8だったりすると、サロゲートペアがエラーになるので、それを除外したい場合に使えると思います。(というか、そのために入れました)

自分で作ったライブラリをJCenterとMaven Centralで公開する

下記自作ライブラリをJCenterとMaven Centralに公開した際の手順を残しておきます。
(後から記憶をたどって書いているので、抜けがあったらすいません...)

公開の流れとしては、下記のようになります。

  1. Bintrayにアップロード
  2. JCenterに公開
  3. JCenterからMaven Centralへ公開

Bintrayのアカウント+Mavenリポジトリ作成

JCenterへ公開するためには、BintrayのMavenリポジトリにライブラリを公開する必要があります。

下記にアクセスし、Bintrayのアカウントを作成します。

ログインしたら、Add New Repositoryで、Mavenリポジトリを追加します。Nameは適当で、TypeにMavenを選びます。

Gradleの設定

Bintrayへのアップロードを行うためのGradleプラグイン(com.jfrog.bintray)があるので、そちらを利用します。

plugins {
    id 'java-library'
    id 'maven-publish'
    id 'com.jfrog.bintray' version "1.8.4"
}

JCenterとMaven Centralの両方で公開するためには、満たさなければならない条件がいくつかあります。それを満たしていないとアップロード時にエラーとなります。

  • POMの各種項目
  • ソースコードとJavadoc

以下はそれを満たした設定例です。

task sourcesJar(type: Jar, dependsOn: classes) {
    classifier = 'sources'
    from sourceSets.main.allSource
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}

artifacts {
    archives sourcesJar, javadocJar
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
            artifact sourcesJar
            artifact javadocJar

            pom {
                name = 'your_project'
                description = 'Your project dscription.'
                url = 'https://example.com/your_name/your_project/'
                licenses {
                    license {
                        name = 'The Apache License, Version 2.0' // 適用するライセンスを適宜記載
                        url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                scm {
                    connection = 'scm:git:https://example.com/your_name/your_project.git'
                    url = 'https://example.com/your_name/your_project/'
                }
                developers {
                    developer {
                        id = "your_id"
                        name = "your_name"
                        email = "your_name@example.com"
                    }
                }
            }
        }
    }
    repositories {
        maven {
            url "file://$buildDir/maven"
        }
    }
}

Bintray用の設定ですが、アップロードするためにBintrayのユーザ名のAPI Keyを指定する必要があります。
どちらもそのままGradle上で記載するわけにはいかないので、gradle.propertiesに記載する方法を取ります。

自分のホームディレクトリの .gradle/gradle.properties に下記のように記載します。

bintray_user=<BintrayでのID>
bintray_api_key=<API Key>

API KeyはBintray上で Edit Profile → API Key で確認できます。

build.gradle上は下記のようにgradle.propertiesから取得するように書きます。

bintray {
    user = project.hasProperty('bintray_user') ? bintray_user : ''
    key = project.hasProperty('bintray_api_key') ? bintray_api_key : ''

    publications = ['mavenJava'] // publishing/publications で指定したのと同じ名前

    pkg {
        repo = 'maven' // Bintrayで作成したMavenリポジトリ名
        name = group + ':' + project.name
        licenses = ['Apache-2.0']
        vcsUrl = 'https://example.com/your_name/your_project/'
   }
}

build.gralde 全体は下記を参考にしてみてください。

Bintrayへのアップロード、公開

GradleタスクのbintrayUploadで、Bintray上にアップロードされます。この時点ではまだ非公開です。
Bintray上でアップロードしたリポジトリを確認し、問題なければPublishを押下します。これでBintray上で公開されます。

JCenterへの公開

BintrayのGeneralタブのLitnked toのところに「Add to JCenter」というボタンがあるので押下します。
そうすると、Compose Messageという画面になり、JCenterへ公開するためのリクエストがタイトルに書かれた状態になるので、そのままSendでメッセージを送信します。
1、2時間で承認されました的なメッセージが来て、JCenterに公開されました。

Sonatype JIRA のアカウント+Project作成の申請

続いてMaven Centralへの公開です。

Sonatype JIRA上でProject作成のIssueを作成する必要があります。

まずはSonatype JIRAのアカウントを作成します。

ログインしたら、CreateボタンでIssueの作成フォームを開きます。
Projectは「Community Support - Open Source Project Repository Hosting (OSSRH)」、Issue Typeは「New Project」となっているはずなので、そのままで、必要な情報を記入して作成します。

とりあえず必須項目の下記を埋めます。

  • Summary : Create new repository for xxxxxx みたいな感じでOK
  • Group Id : プロジェクトのGroup IDです。Gradleで指定しているのと同じものにします。自分がドメインの所有者であることを後から証明する必要があるので、自由な形にすることはできません。GitHubで公開しているものならば、com.github.onozaty みたいな自分のGitHubのページ指定すればOKです。
  • Project URL : プロジェクトのURLです。
  • SCM url : ソースコード管理のURLです。Gitならばcloneする際のURLです。

自分が書いたIssueを参考までに。

この後すぐにGroup Idの所有者の確認のためのコメントが来ます。
GitHubの場合は、Issueの番号と同じプロジェクトを作ってくれとくるので、プロジェクトを作って、作ったよとコメントします。(コメント来る前に作ったよといってしまってもOKです)

確認が終わると、プロジェクトの準備できたよーとコメントが返ってきます。
これで準備はOKです。

JCenterからMaven Centralへの同期

直接Maven Centralへアップロードする方法もありますが、JCenterにせっかくあげているのでJCenter経由でMaven Centralにアップロードします。
JCenter経由とすると良い点もあって、JCenterの鍵を使ってGPG署名を行うことができます。Maven Centralに公開するものは、GPG署名が必須ですが、個人でやるのはちょいと面倒に感じたので、この方法を取ることにしました。

まず、JCenterにアップロードした際にJCenterの鍵で署名をするように設定します。 Edit RepositoryのGeneral Settingsに「GPG sign uploaded files using Bintray's public/private key pair.」という項目があるので、これをチェックします。
こうすると、アップロードされたタイミングで、Bintrayの鍵を使ってGPG署名が行われるようになります。

PackageのMaven Centralのタブから、Maven Centralへアップロードできます。
Sonatype OSSのUser token keyとUser token passwordの入力を行い「Sync」ボタンを押下してアップロードします。

右側にあるSync Statusでエラー無く完了するとアップロードされたことになります。

下記からアップロードされていることを確認することができます。

Maven Centralとの同期がとられるまでは時間がかかるようです。通常は10分程度とのことですが、最大で2時間かかるとのことです。

参考にしたサイト

下記のサイトが参考になりました。ありがとうございました。