2019/08/16

APIの設計書をMarkdownで書いてみたい

なんでやろうと思ったのか

会社で基本設計書といえば、ExcelとかWordとかPPTとか、Office系のアプリを使って作成することが多い。
その場合、下記の点でいつも悩ましい状態になる。
  • バージョン管理
  • バージョン間の差分管理
    • レビュー指摘票と行数のマッピングのズレ(指摘が複数ある場合に行数や連番がずれて、どこの指摘の修正がどこに行ったのかわからなくなる)
  • レビューのクローズ状況の追跡
最近はMarkdownとPlantUMLを組み合わせて、シーケンス図やシステムコンテキスト図の概要を作ってみている。
(最終的には画像化してPPTに貼っているけど。。。)
なので、上記の悩ましい状態の解決方法として、最近慣れてきているMarkdownでの基本設計書の作成をしていきたいと考えていた。
ということで、試してみたので、その備忘録です。

で、どうだった?

記述ルールは簡単で、モックサーバをローカルに立てみて、
  • 設計と実装意図があっているか確認できる
  • 実コードが無くてもローカルでAPIを利用して、利用者側の実装ができそう
というところまで確認できたので、かなりいい感じ、という印象でした。
HTML出力したレイアウトも結構きれいで、好みでした。
ただし、レビュー指摘票の行数のマッピングのズレについては、GithubのPullRequestを利用しないと解決できないので、今後の課題ということで。。。
あれ?VSCodeに入れたExtentionを使っていない。
ま、いっか〜

実装内容の公開

今回作成したMarkdownのファイルは下記のGithubで公開します。
不備などありましたら、ご指摘いただけますと幸いです。
o310yusuke/APIBlueprint_Tutorial

何を使うのか

  • テキストエディタ:VSCode
    • 理由:使い慣れてきたし、軽いし。
  • エディタ拡張機能:vscode-apielements
    • 理由:公式サイトapiblueprintに乗っていたから
  • 設計書記述方法:API Blueprint
    • 理由:参考サイトを参考に(記述ルールがシンプルそうだったから)
  • レンダリング:Aglio
    • 理由:参考サイトを参考に(node.jsでnpmで導入できるから)
  • モックサーバ:Drakov
    • 理由:参考サイトを参考に(node.jsでnpmで導入できるから)

参考サイト

やったこと(環境構築)

実施したOSはMacです。
Node.jsは7.10.0です(古かった。。。)。

VSCodeに拡張機能をインストール

  • apielementで検索してインストール
  • workspaceとして、「apiblueprint_trial」のディレクトリ作成

npmのインストール状況を確認

$ npm ls --depth=0 -g
/usr/local/lib
├── generator-code@1.2.0
├── npm@4.2.0
└── yo@3.1.0
generator-codeとyoは、VSCodeのExtensionを作ってみたくていらたものなので、関係無し。

Aglioをインストール

参考サイトではグローバルにインストールしていたけど、今回はローカルのみにインストールを行う。
# node.jsのグローバルにインストールする場合
npm install -g aglio
# 特定ディレクトリにインストールする場合
cd 特定ディレクトリまで移動
npm install aglio
# インストール確認(直下のものだけ)
npm ls --depth=0
npm ls -g --depth=0
結果
$ npm ls --depth=0
/apiblueprint_trial
└── aglio@2.3.0
$ npm ls --depth=0 -g
/usr/local/lib
├── generator-code@1.2.0
├── npm@4.2.0
└── yo@3.1.0

Drakovをインストール

こちらもローカルのみにインストール
npm install drakov
結果
$ npm ls --depth=0
/apiblueprint_trial
├── aglio@2.3.0
└── drakov@1.0.4

$ npm ls --depth=0 -g
/usr/local/lib
├── generator-code@1.2.0
├── npm@4.2.0
└── yo@3.1.0

やったこと

API Blueprintの公式サイトにチュートリアルがあったので、そちらを参考に実施。

Markdownで書いてみる

  • tutorial.mdを作成する。
  • まず、API名とメタデータを決める。
    FORMAT: 1A ←Blueprintのバージョン
    
    # Polls ←API名
    サンプルAPIの名前を「Polls」にします。 ←APIの説明
    
  • リソースグループを「# Group」で記載する。
    • チュートリアルでは、「質問」に関する複数のAPIの章立てのイメージみたい。
    # Group 質問 ←グループ名
    「質問」に関するAPIのリソースを集約する。 ←グループの説明
    
  • リリースを定義する。
    ## 質問コレクション [/questions] ←「質問」のリソースグループ内の質問のリスト。[]内にURLテンプレートを記述可能。
    
  • アクションを定義する。
    • 1つのリソースに必ず1つのアクションを定義すること。
    ### 一覧取得 [GET] ←リソース内の1つのメソッド。[]内にHTTPメソッドを記載する。
    - Response 200 (application/json)
     [
      {
       "question": "Favourite programming language?",
       "published_at": "2014-11-11T08:40:51.620Z",
       "url": "/questions/1",
       "choices": [
        {
         "choice": "Swift",
         "url": "/questions/1/choices/1",
         "votes": 2048
        },{
         "choice": "Python",
         "url": "/questions/1/choices/2",
         "votes": 1024
        }
       ]
      }
     ]
    
    ※チュートリアルでは、2つめのアクションを記載しているが割愛
    ※チュートリアルでは、2つめのリソースを記載しているが割愛

Markdown→HTML変換してみる

  • 作成したtutorial.mdから、aglioを使ってHTMLを作成する
    • aglioをローカルインストールしたので、下記のコマンドでは実行できなかった。
      $ aglio -o tutorial.md -o tutorial.html
      
    • 下記のコマンドを実行し、npxをグローバルインストールし、npmの初期化を実施した(デフォルト値で実行した)。
      $ npm install -g npx
      # 結果
      $ npm ls --depth=0 -g
      /usr/local/lib
      ├── generator-code@1.2.0
      ├── npm@4.2.0
      ├── npx@10.2.0
      └── yo@3.1.0
      # 初期化
      $ npm init
      
    • npxを利用することで、ローカルインストールしたパッケージも利用可能にできた。
      $ npx aglio -i tutorial.md -o tutorial.html
      
    • 表記のエラーがあると、コンパイルエラーとなり、修正方法も提示してくれる。それに合わせて修正することで、コンパイルしてくれる。
  • 下記コマンドを実行しておけば、mdファイルを保存したタイミングでリアルタイムで変換してくれる。
    npx aglio -i tutorial.md --server
    # 結果
    Server started on http://127.0.0.1:3000/
    Rendering tutorial.md
    # 終了方法
    Ctrl + C
    

Mockサーバを試してみる

  • drakovでMockサーバを起動する。
    npx drakov -f tutorial.md --watch
    # 結果
    [INFO] No configuration files found
    [INFO] Loading configuration from CLI
       DRAKOV STARTED
    [LOG] Setup Route: GET /questions 一覧取得
    [LOG] Setup Route: POST /questions 新規投稿
    [LOG] Setup Route: GET /questions/:question_id 質問詳細取得
    [LOG] Setup Route: DELETE /questions/:question_id 削除
       Drakov 1.0.4      Listening on port 3000
     FILE SPY   ACTIVE
     # 終了方法
     Ctrl + C
    
  • ブラウザで、一覧を取得してみる。
    • URL: http://localhost:3000/questions
    • 結果(コンソール)
      [LOG] GET /questions
      [MATCHING] by url pattern: /questions/:question_id NOT_MATCHED
      [MATCHING] by url pattern: /questions MATCHED
      [DRAKOV] GET /questions 一覧取得
      
    • 結果(ブラウザ)
      [
          {
              "question": "好きな開発言語はなんですか?",
              "published_at": "2014-11-11T08:40:51.620Z",
              "url": "/questions/1",
              "choices": [
                  {
                      "choice": "Swift",
                      "url": "/questions/1/choices/1",
                      "votes": 2048
                  },{
                      "choice": "Python",
                      "url": "/questions/1/choices/2",
                      "votes": 1024
                  }
              ]
          }
      ]
      
  • cURLを使った確認
    • 入力画面
      # 一覧取得(HeaderとBodyを表示するため「-i」を付与)
      $ curl -i http://localhost:3000/questions
      # 新規登録
      $ curl -i -X POST -H "Content-type: application/json" -d '{"question":"好きな開発言語はなんですか?","choices":["Swift","Python"]}' http://localhost:3000/questions
      # 削除
      curl -i -X DELETE http://localhost:3000/questions/1
      
    • ウォッチ画面(Drakovを起動したコマンドプロンプト)
      # 一覧取得
      [LOG] GET /questions
      [MATCHING] by url pattern: /questions/:question_id NOT_MATCHED
      [MATCHING] by url pattern: /questions MATCHED
      [DRAKOV] GET /questions 一覧取得
      # 新規登録
      [LOG] POST /questions
      [MATCHING] by url pattern: /questions/:question_id NOT_MATCHED
      [MATCHING] by url pattern: /questions MATCHED
      [MATCHING] by request content type: application/json actual: application/json MATCHED
      [MATCHING] by request body content MATCHED
      [DRAKOV] POST /questions 新規投稿
      # 削除
      [LOG] DELETE /questions/1
      [MATCHING] by url pattern: /questions/:question_id MATCHED
      [DRAKOV] DELETE /questions/{question_id} 削除
      

2019/06/30

VSCode環境構築:設定変更

VSCodeをインストールしてから行っている設定変更の内容をまとめる。

随時更新予定。

テキストファイルを開くときの文字コード

設定理由

デフォルト設定では、テキストファイルの文字コードによらず、UTF-8で開こうとする。
そのため、Shift-JISのテキストファイルは、ちゃんと文字化けされて開かれる。
文字コードを指定して開き直せばよいが、毎回は面倒。

文字コードを変更して開き直す方法

  • コントロールパネルを開く
  • Change File Encodingを選択
  • Reopen with Encodingを選択
  • 文字コードを選択

設定方法

  • 設定画面を開く
    • Win: Ctrl + ,
    • Mac: Command + ,
  • 検索窓で「encoding」を検索
  • Files: Auto Guess Encoding にチェックを入れる

ターミナルからVSCodeを起動する

設定理由

GitとかをCUIで使っていて、lessコマンドとかで見るのではなく、テキストエディタでみたい。
※Winも同じように設定可能?

設定方法

  • コマンドパレットを開く
    • Win: Ctrl + Shift + P
    • Mac: Command + Shift + P
  • 検索窓で「shell」を検索
  • Shell Command: Install ‘code’ command in PATH を実行
  • ターミナルで下記を入力するとVSCodeが起動できる
    • $ code → 通常起動
    • $ code . → 現在のディレクトリをルートとして起動

2019/06/29

VSCode環境構築:いつも入れているプラグイン

2017年ごろはAtomを使っていたのだけれども、いろいろとプラグイン(拡張機能)をどんどん入れすぎたせいか、どんどん重くなってしまった。
そのころ、VSCodeが無料で使える、という情報がTwitterで流れてきた。
入れてみると、、、
  • 軽い!
  • 今となっては、Atomと負けないくらいプラグインが豊富
ということで、最初はちょこちょこ困惑はしたものの、完全に引っ越ししてしまった。
(今となっては何に困惑したのか、覚えていないけど。。。)
いつも初期導入時に入れているプラグインを備忘録として記録する。
※適宜更新はしておこうと思います。
なお、URLは「作成者」ピリオド「ツール名」で表現される。

Markdownのため

IDEなしでのソースコードレビューのため

何かと便利

VSCodeのデザイン関連

編集後記

便利な使い方とか説明する記事を別に書こうかなと思っていますが、いつになるかな。。。

2019/01/27

FusionTablesからFirebaseCloudFireStoreへ

FusionTables -> Firebase

GoogleのDriveのアプリのFusionTablesを使ったアプリを個人利用で作ってみた。
しかし、FusionTablesのサービスがクローズする事となったため、下記のTweetをしたら、Googleの「Firebase Realtime Database」というものを友人が教えてくれた。
その備忘録である。
https://twitter.com/o310yusuke/status/1078644337422913536

Firebaseとは

いろいろな方が説明されているので、割愛させていただき、私が個人的に抑えておきたい特徴は下記の通り。
  • Googleが運営しているmBaaSである
    • mBaaS(mobile backend as a service ):モバイルアプリ向けに汎用的な機能を提供するバックエンドのサービス、ってところ
  • 無料でも使える
  • データの同期を自動でやってくれる
  • Googleの認証を使える
  • Android/iOS/Webサービスのいずれでも利用できる

Firebaseのデータベースの種類

利用できるデータベースには、現時点では2種類ある。
比較の詳細については、公式サイトを参照のこと。
下記には、個人的は要約を記載する。
今回は「Cloud Firestore」を利用してみる。

Realtime Database

  • 従来からあるFirebaseのデータベース
  • リアルタイムのクライアント間の同期が必要なモバイルアプリ向け
  • 1つの大きな保存領域(CloudFirestoreのドキュメントに相当)があり、JSON型でデータを保存する(1つの大きなJSONツリーとして保存)

Cloud Firestore

  • 2019/01/26時点ではベータ版
  • Realtime Databaseより効果的らしい
  • 複数の保存領域(ドキュメント)をまとめて(コレクション)、そこにデータを保存する
    • コレクション:フォルダのようなもの
    • ドキュメント:一つのファイルのようなもの
    • データ:ドキュメントにかかれている情報

設定手順

基本的には、Cloud Firestoreのスタートガイドのサイドに従って設定を行った。
下記には、私が行った設定内容を備忘録代わりに記載する。

プロジェクトを追加

プロジェクトの追加

  • プロジェクト名
    • 自分が管理しやすい名称をつけるのが良さそう
    • firebase用のプロジェクトとわかる名前を設定
  • プロジェクトID
    • URLとして公開されるとのことなので、注意が必要そう
    • プロジェクト名を入力すると自動入力されるが、アプリの名称に変更
  • 地域/ロケーション
    • アナリティクス:日本
    • ロケーション:asia-northeast1
  • Firebase向けGoogleアナリティクスのデータ共有にデフォルトの設定を使用する:チェックOn
  • アプリでFirebaseサービスを使用することに・・・:チェックOn
上記の設定を行い「次へ」ボタンを押下すると、プロジェクトが作成される。
プロジェクトが作成されると、プロジェクトのページへ自動遷移する。
なお、作成されるプランは、「Spark」で無料$0/月である。

Databaseの設定

開発タブの中から「Database」を選択し、設定を行う。
Cloud Firestoreを作成するボタンを押下する。

Cloud Firestore セキュリティルール

  • テストモードで開始を選択
    • 本来であれば、認証必須にすべき
    • 今回はテスト開発のため、テストモード(参照権限を有するユーザは読み書き可)を選択
  • 作成が完了したら、ルールタブを選択し、ルールを変更
    • 下記のように認証必須の設定に変更し、公開ボタンを押下
    • if ~の部分を追加
      // Allow read/write access on all documents to any user signed in to the application
      service cloud.firestore {
        match /databases/{database}/documents {
          match /{document=**} {
            allow read, write: if request.auth.uid != null;
          }
        }
      }
      

開発環境の設定

Cloud Firestoreを利用するAndroidアプリを開発するための設定を記載する

必要な依存関係とクライアントのライブラリを追加する

  • AndroidStudioでFirebase用のプロジェクト(カラのActivity)を作成する
  • 作成したAndroidアプリのプロジェクトに、Android アプリに Firebase を追加するに従って、Firebase Assistantを使用して、設定を追加する
    • Firestoreを探して、「Read and write documents with Cloud Firestore」のリンクを押下
    • 表示された手順に従い、先程作成したプロジェクトを選択
    • 接続したら、Cloud Firestoreを利用するためのGradleの設定変更を取り込む
      • 下記のwarningがapp/build.gradlenに対して出たが一旦は無視(implementationになっているから)
      Configuration ‘compile’ is obsolete and has been replaced with ‘implementation’ and ‘api’.
      It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
  • Firebase Assistantで設定したGradleのバージョンが古いので変更
    • 変更前: 11.8.0
    • 変更後: 15.0.0
  • Cloud Firestore を初期化する

まだまだ先は長い・・・

文量が多くなってきたので、今回はここまで。
次回は、Cloud FirestoreをAndroidアプリで利用するための具体的な実装を行っていく。

ハマったこと

プロジェクトの再利用はしないほうが良さそう

FusionTablesを利用する際に作成したプロジェクトを利用して、Firebaseを利用しようとした。
スタートガイドのページに、下記のように記載されている通り、FusionTablesのために作成したプロジェクトは、Firestoreのプロジェクトとして利用できないそうな。
Cloud Firestore と App Engine: 同じプロジェクトで Cloud Firestore と Cloud Datastore の両方を使用することはできません。両方を使用すると、App Engine を使用するアプリが影響を受ける可能性があります。別のプロジェクトで Cloud Firestore を使用してみてください。
※Firebaseでのプロジェクトの作成のタイミングでエラーを出してくれればいいのに。。。
データベースを作成しようとしたさいに、エラーを出すなんて。。。

関連サイト

2019/01/02

2018年を振り返って

2018年を振り返って

あけましておめでとうございます。
2019年(平成31年)になりました。
2018年で、自分がどのくらい成長できたのか、振り返ってみたいと思います。
一部2017年の出来事も振り返りたいと思います。

あったこと

  • 2017年9月:グループ会社への出向から自社への帰任
    • 出向開始は2013年4月(岡山→東京転勤)
    • 帰任理由
      • 2014年度から特定のサービスの開発・運用を継続しており、新しいことをやりたいと思ったから
      • 2017年8月の夏休み前に、自社の部長面談でその旨を伝え、夏休み明けたら「帰任決まったから」と部長からいきなり言われた
  • 2017年12月:部署異動(東京→岡山転勤)
    • 異動理由
      • 担当案件の主幹部門が岡山拠点の部門だったから
      • 帰任の面談のときにも言われていたからOK
      • 該当案件が終了したら東京に転勤させてほしいとは伝え、聞き入れてくれたのでOK
    • 対応案件
      • 出向中に対応していたサービスのサーバ移行開発支援(あれ?w)
      • 出向中に対応していたサービスが利用するためのAPI新規開発(あれれ??ww)
      • Androidアプリ・MDM開発支援(あれ?特定サービスで使っていたタブレットと同じ??ww)
  • 2018年4月:担当案件変更(岡山勤務)
    • 終了案件
      • サーバ移行開発支援:チームから離脱
      • API新規開発:2018年3月にリリース済み
    • 対応案件
      • Androidアプリ・MDM開発支援(メンバーからリーダへ。。。)
  • 2018年8月:部署異動(岡山→東京転勤)
    • 異動理由
      • 担当案件の客先が東京部門のため
    • 対応案件
      • Androidアプリ・MDM開発支援
  • 2018年9月:担当案件変更(東京勤務)
    • 対応案件
      • Androidアプリ・MDM開発支援(リーダからメンバーへ!)
      • サーバ移行 業務要件定義支援(リーダ)

やったこと・できるようになったこと

  • サーバ移行開発支援を通して
    • 対象サービスや仕様のナレッジの共有
    • Azure SQL Databaseでのパーティション設計・実装
  • API開発を通して
    • Markdownを用いた設計書作成(atomを真面目に使った)
    • RESTfulなAPIの設計・開発
    • データストレージとしてAzure Table Storageを使用(ローカル開発環境構築が大変だった。。。)
    • SpringBootでのサーバアプリ開発(仕事で)
    • Gitを使ったソース管理(仕事で)
  • Androidアプリ・MDM開発支援を通して
    • Androidアプリのデコンパイルからの変更箇所の特定
    • PHPのソースを読み込み、設計書を作成(PHPを初めてちゃんと触った)
    • PlantUMLを使ったシーケンス図の作成(atomを入れててよかった)
    • MS Projectを使ったWBS作成・管理
    • Androidアプリの要件の実現性検証のためのサンプルアプリ実装
      • QRコードのリーダ
      • 音声レコーダ

思ったこと

  • サーバ移行開発支援を通して
    • サービスに対する関与の仕方は変わったから良かった(実開発をするチームだし)
    • 経験したことのない技術を利用した開発だったから良かった(アーキを考えたり)
  • Androidアプリ・MDM開発支援を通して
    • 良かれと思ってネゴをしたつもりが、”開発ベンダに利用される”ということがあり、がっかり。。。
  • サーバ移行 業務要件定義支援(リーダ)
    • Twitterとかでも誰かがつぶやいていたけど、「進捗どうですか?」という聞き方ではなく、「困りごとありますか?」という聞き方をすると、聞き出したい進捗が確認できる気がする
  • 全体を通して
    • これまでの経験が強みとなり、自分への仕事となることを実感
    • 一方で、これまでに技術にトンガッた仕事をしていないし、年齢も上がっているため、技術をトンガラせれるような仕事ではなく、管理や育成の仕事を求められる
    • 技術をトンガラせておくためには自分で勉強・実装する時間を設ける必要がある
    • やっぱり設計・実装は楽しい。
    • けど、スケジュールも大事。。。
    • そして、タスクの優先順位を理解することも大事。。。
    • タスクの優先順位を伝えて、スケジュールを作らせることが大事

もうひと踏ん張りなこと

  • チームのタスク管理と進捗管理(WBS作成と更新)
    • 「議論できたから良かった」となりがちだけど、「次に何をするのかをその場で明確にする」ということが大事と思ったから
  • チーム内外のコミュニケーション
    • 自分ひとりでは限界があるから、誰かにやってもらう必要があるので、やってもらうためのコミュニケーションが大事と思ったから
    • チームメンバが迷走しないために、WBSを作って理解してもらってから動いてもらうことが大事と思ったから(相手の年齢に関係なく)
  • 上長への報連相の仕方(上司の使い方)
    • コミュニケーションにも関連するけど、他の誰かに動いてもらうためには、相手に応じたコミュニケーションの仕方があると思ったから
  • Android技術者認定試験の勉強
    • やろうと思って全然できていないから。。。

2019年に向けて

2018年を振り返ってみると、普段は「何もできていない」とかって考えやすいけど、仕事として新しくできるようになったことが、思っていたよりあったな、と思えた。「反省」ではなく「振り返り」をすることで、ダメだった点もポジティブに考えられるような気がしています。
そして、2019年は下記のことをやってみたいな・頑張らないとかな、と思っています。特に自分の強みを明確にするためにもOutputとか資格取得が大事と思ったので、そのことを意識して動きたいと思います。

  • Androidアプリをちゃんと作ってみる
  • ソースコード・設計書をGithubで公開する
  • 実装時に調査したことを、Blogとかで発信する
  • k8sも勉強してみたいな
  • Android技術者認定試験の勉強をちゃんとする
  • PMBOK的な勉強もしなきゃ。。。得意じゃないけど。
  • 悩み事・困りごとをもっと周りに伝える(特に上司に)
  • 仕事でもプライベートでも相方を作る
  • チームメンバとのコミュニケーションのときは、「困りごと」「悩みごと」をまずは聞くようにしてみる
    • 進捗確認ができる
    • リスクも確認できそう
    • スケジュールを本人に決めてもらえそう
  • 自分の売り込みポイントを探す(ヒアリングする)
  • 履歴書を作る
    • 自分の強みを明確にするために(自分を好きになるために)

2018/12/02

AndroidアプリでGoogleDriceのFucionTablesをAPIで使ってみる

////////// 20181215追記ここから

12/12にGoogleさんからメールが届いていた。
Notice: Google Fusion Tables Turndown というタイトルで。
2019/12/3にサービス終了する、とのこと。

自作アプリのデータ保管先として利用していこうと思ったところだったのに、残念・・・

公式サイトはこちら。
https://support.google.com/fusiontables/answer/9185417?hl=en

////////// 20181215追記ここまで

# なんでやってみた?
GoogleDrive上のスプレッドシートに日々の体重とかを記録している。
最初は件数が少なかったから良かったけど、気づけば4年も記録していて、
比較のグラフなんて見たいと思っても、なかなか大変。

ということで、アプリでその辺をうまくカスタムして、既存のデータはそのまま流用したいと思い、うまいことできないかと調査。
そしたら、GoogleDriveにも簡単なDBを再現したFution Tablesというものがあると判明。

ということで、試してみる。

# やったこと
## Fusion Tables を有効にする
(1)のサイトを参考に、Fusion Tablesを有効にし、空のテーブルを作成。
カラムを想定した内容に変更。
また、「リンクの共有」をOnにし、「リンクを知っている全員」がアクセス
参考サイトでは、スクリプトエディタでデータの操作方法を紹介しているが、今回は割愛。

## Google Drive APIが利用できるようにする
- プロジェクトの作成
(2)のサイトを参考に、プロジェクトを作成。
具体的には下記のサイトにアクセスして作成。
https://code.google.com/apis/console/


- API登録
API登録を行おうとしたが、管理画面が更新されたようで、参考サイトの内容とは異なっていた。
「Identity-Aware Proxy」からAPIの登録ができそう。
画面遷移をすると、「IPAを使用するには、OAuth同意画面を構成する必要があります。」とのことなので、「同意画面を構成」してみる。

すると、「APIとサービス」という画面の「認証情報」の画面に遷移。
左メニューの「ダッシュボード」をクリック。
画面上部の「APIとサービスの有効化」ボタンをクリック。
検索窓に「Fusion」を入力して「Fustion Tables API」が表示されるので、
クリックして「有効にする」をクリック。
これでAPIの登録は完了。

- 認証情報の登録
APIの登録が完了すると、画面が自動遷移し、Fusion Tablesの設定画面に自動遷移。
認証情報を作成する必要がある旨のメッセージが表示されるので、作成してみる。
画面に従って、下記を設定。

1.必要な認証情報の種類を調べる
  - 使用するAPI: Fusion Tables API
  - APIを呼び出す場所: Android(今回はAndroidアプリから呼びたいので)
  - アクセスするデータの種類: ユーザーデータ(なんとなく)
2.OAuth2.0クライアントIDを作成する
  - 名前:適当に設定(Fusion Tablesで作成したTable名に合わせた)
  - フィンガープリント
  ※デバッグ用のフィンガープリントを取得したいので、下記のコマンドを実行する
  ※PW入力を求められるので、デバッグ用証明書のPW「android」を入力する
  ※実行結果のSHA-1 署名証明書フィンガープリントをコピペ
  >   keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v
  - パッケージ名:利用対象のAndroidアプリのパッケージ名
  ※Androidアプリのパッケージ名を記入
 →「OAuthクライアントIDを作成」ボタンをクリック
3.OAuth2.0同意画面を設定する
  - メールアドレス:プロジェクトの管理者のアドレスを選択する
  - ユーザーに表示するサービス名:[ProjectName]-Fusion
  ※どのプロジェクトのどのサービスかがわかるようにしたら良さそう
  →「次へ」ボタンをクリック
4.認証情報をダウンロードする
 ※必要に応じてダウンロード
→「完了」ボタンをクリック

完了すると、APIとサービスの画面の認証情報が選択された画面に戻る
作成した認証情報が表示されていればOK。

## APIを利用するAndroidアプリを作っていく
AndroidStudioを起動し、プロジェクトを作成する
特に注意するのはパッケージ名だけで、他は通常のAndroidアプリを作るときと同じ

- Create Android Project
 - Application name
 OAuth2.0クライアントIDを作成した際に設定した「名前」を入力する
 - Company domain
 OAuth2.0クライアントIDを作成した際に設定したパッケージ名を入力する(アプリ名を除いた部分)
 - Project location
 適宜
 - Package name
 OAuth2.0クライアントIDを作成した際に設定したパッケージ名になっていることを確認する
 - Inclode XXXX
 適宜
- Target Android Devices
 今回はスマホでの利用を想定するので、「Phone and Tablet」を選択する
 対象APIバージョンは、自分のスマホに合わせて選択する
- Add an Activity to Mobile
 自分で画面を頑張って作るので「Empty Activity」を選択する
- Configure Activity
 デフォルトの内容のまま

## 作成したプロジェクトの設定を変更していく
- ライブラリ追加
API利用のためにGoogleアカウント認証を利用できるようにする

ファイル: app/build.gradle
内容:
dependencies {
    ...
    compile 'com.google.android.gms:play-services-auth:16.0.1'
    compile 'com.google.android.gms:play-services-drive:16.0.0'
}

- パーミッション追加
インターネット接続のパーミッションを追加する

ファイル: AndroidManifest.xml
内容:
<uses-permission android:name="android.permission.INTERNET" />

- 認証処理の実装
(5)のサイトの「認証処理」の内容を実装する

- データ取得の実装
 (5)のサイトの「テーブル情報の取得」に記載の内容を実装する。
 selectの結果は、JSON形式だが、InputStreamに格納される。
 そのため、InputStreamからString、そしてJSONオブジェクトに変換が必要。
 なお、FusionTablesのレコードは、"rows"に配列で格納されているので、JSONArrayで取得する。
 詳細は(9)のサイトを参照。

 なお、Androidの場合、APIを呼び出すときには非同期で処理する必要がある。
 そして、非同期処理にてUIの変更は禁止されている。
 なので、AsyncTaskクラスを使って非同期で呼び出し&呼び出し後にUI更新を行う。
 具体的には、下記の通り。

  - AsyncTask#doInBackgroundで非同期(別スレッド)でAPIを呼び出す。
    取得した結果をメインスレッドに返却するために、AsyncTaskの第三引数をVoidではなく、返却するオブジェクトの型(例:ListやString)を指定する。
  - AsyncTask#onPostExecuteでdoInBackgroundの処理結果を受け取り、UIを更新する(メインスレッド)

 これでハマって取得したデータを表示できなかった。。。
 また、非同期処理の結果を返却するためのAsyncTaskクラスの宣言にハマった。
 取得したデータは、TableLayoutとTableRowを利用して、表形式で表示した。

- データ登録の実装
 (5)のサイトの「テーブル行追加処理」に記載の内容を実装する。
 取得時と同様に、例外処理は割愛されている。
 Insertの結果もInputStreamで取得可能。内容は、登録した際のrowIDが得られる。

# 感想
FusionTablesを利用したSelectとInsertをAndroidアプリとして実行できるようになった。
また、Androidアプリで表形式でのデータ表示もできるようになった。
ただ、(5)のサイトに紹介されている方法は、SQLを直接実行するようになっている。
FusionTablesはAPI化されているのに、SQL直接実装は格好が悪いように感じた。
なので、もう少し格好良い実装ができないか、追加調査をしてみる。
また、Select/Insertの他にUpdate/Deleteも実装してみたいと思う。
それは別の記事として投稿させていただく。

※なお、作成したソースはGithubで公開したいけど、パスワードとか入っているので、キレイにしてから公開したいと思う。


# 参考サイト
1)GoogleDriveでデータベースを使ったみた
  https://sitest.jp/blog/?p=8701
2)Google APIからGoogle Fusion Tablesに触れる
  http://schima.hatenablog.com/entry/2013/11/28/005648
3)AndroidアプリでGoogle Drive APIを使う
  http://vividcode.hatenablog.com/entry/20130908/1378613811
4)Google Drive APIの有効化とクライアントID、クライアントシークレットの取得方法
  https://www.virment.com/google-drive-api-activate/
5)AndroidからFution Tablesを操作する
 https://qiita.com/kassy_kz/items/4c0ca6571fa3f5004ec1
6)Google Play Serviceのバージョン確認
 https://developers.google.com/android/guides/setup
7)AndroidからAPIを叩いてJSON取って中身を表示させるまで
 https://qiita.com/minme31/items/a9636cb0453524c64e67
8)Google Table Fusions リファレンス(英語)
 https://developers.google.com/fusiontables/docs/v2/reference/
9)Fusion Tables REST API : Query
 https://developers.google.com/fusiontables/docs/v2/reference/query/sql


2018/01/19

XXPayでできるスマホ決済とは

久々の投稿です。
自分向けのメモとして。

モバイルSuicaが登場してから、Suicaと楽天Edyの電子マネーを使っていました。
ここ最近はnanacoも使うようになりました。
一方で、ここ数年でXXPayが出てきました。試しにAndroidPayを入れてみましたが、何だか分からず、特に勉強せずに利用しないでいました。

今日、ふと、何のことか、知りたくなりいくつかのサイトを調べてみました。
お店で支払いをする方法で比較したら分かりやすかったです。

・電子マネー
これまでは、お財布に入れていたお金から支払いをしていた。
それに代わり、スマホに入金しておいたお金で支払いをする。
電子マネーは現金での支払いを電子化(スマホでできるように)した。

・XXPay
これまでは、お財布に入れていたクレジットカードを店員に渡してスキャンして支払いをしていた。
それに代わり、スマホに登録したクレジットカードをスキャナにかざすなどして、支払いをする。
XXPayはクレジットカードでの支払いを電子化(スマホでできるように)した。

と、こんな理解で良さそうな気がします。
クレジットカードを店員に渡してスキャナに通す訳ではないので、より安全だ、ということなんだろうな。

2012/12/03

GAE/Jのアノテーション@Modelでの注意点

実際に経験して、しばらく解決ができなかった事象について共有します。 

業務でGAE/JでSlim3をフレームワークとしてWebアプリを作っています。
以下のようなルールを設定して使用するEntityを作成していました。


  • Javaのクラスは末尾に「Model」をつける
  • Kind名には「Model」を付けない
    →アノテーションでKind名を設定する
     例)@Model(kind="カインド名")


新規でEntityを作ってアノテーションを設定していました。
そしたら、以下のような状況が発生しました。


  • ローカルの開発環境ではデータがうまく取得できる
  • GAE環境にデプロイしたらデータがうまく取得できない
  • GAE管理画面では該当のKINDにデータが投入されていることは確認できた


ん〜ってソースを見なおしていたら・・・

@Model(kind=" カインド名")

こんな感じになっていました。
??
一見間違いはない。問題はない。

よーく見ると・・・

@Model(kind=" カインド名")

そう、カインド名の前に半角スペースが!!
ローカルの開発環境ではうまく動くっていうのが非常に辛い><

皆様ご注意下さい。。。

MacのEclipse Juno(4.2)にstepcounterをインストール

とある事情があってMacにインストールしたEclipse Juno(4.2)にstepcounterをインストールしました。
stepcounterは、以前ProjectAmaterasのページで公開されていました(Version2.0まで)。現在は、Githubで開発・公開が進められているそうな。




無事に使えましたw

2012/10/07

GAE/Jでメール送信機能を実装してみた

GAE/Jでメールを送信する機能が必要となったので、調べて実装してみました。
参考にしたGoogle App Engineの日本語サイトは こちら(※1)
⇒https://developers.google.com/appengine/docs/java/mail/overview?hl=ja

このページによると、Mail Service Java API は、メール メッセージの送信用に JavaMail(javax.mail)インターフェースをサポートしているそうです。基本的なメール送信の実装方法はこちらのサイトをご参考ください。

ちなみにローカルで実行した場合には、メールは送信されません。 その代わりに、コンソールに送信しようとしたメールの内容が出力されます。 ここで困ったことは、メール本文は出力されなかったこと。 現在も表示方法がわからないので、もしご存知の方がいたら教えていただけると幸いです^^

GAE/Jにデプロイしてケータイにメール送信をして動作確認してみました。 そしたら、英語の件名、本文はきちんと送信されました。

が、しかし!!

日本語の件名が文字化けしていました;;
本文の日本語はきちんと表示されていたんですけど、件名だけが・・・
画面から入力した日本語を含む件名をGAE管理画面でログ出力するように実装して確認したら、きちんと表示されていました。。。

色々と調べてみたら、分かりやすいサイト(※2)を発見しました。
件名はきちんと文字コードを設定しないと文字化けしてしまうようです。 しかも、"ISO-2022-JP"にしないといけない、という事でした。
ということで、以下のように変更してみました。

変更前:msg.setSubject("日本語の件名");

変更前:msg.setSubject("日本語の件名", "ISO-2022-JP");

が、コンパイルが通らない。。。
よくよくサイトを見ると、もう一箇所修正が必要でした。

変更前:Message msg = new MimeMessage(session);

変更後:MimeMessage msg = new MimeMessage(session);

これでコンパイルが通り、日本語の件名も使えるようになりました!!
本文についても、文字コードを指定してあげる方が安全かもしれません。私はやっておきました。

以上!!

参考サイト

2012/08/04

GAE/Jアプリのローカル・データストアのアップ・ダウンロード

Google App Engine SDK for Java を利用したアプリを開発している。
ユーザ認証をするときにGoogleアカウントを利用せず、データストアにユーザマスタを作成して行っている。

データのアップロード・ダウンロードにはGoogle App Engine SDK for Pythonで公開されているappcfg.pyとbulkloader.yamlを使った一括ローダーが一般的だろう。
データのアップロードとダウンロード

しかし、「開発用サーバーへのデータのロード」にローカル環境へのコマンドが記載されているが、同じようにやってもうまく行かず、結局イマイチよく分からなかった。これってpythonで作ったアプリに対してだけなのかな、って判断した。なので、マスタ登録用のロジックを組んで・・・って感じで登録を行っていた。

これが相当面倒・・・
できれば、ユーザマスタとか他のマスタデータをエクセルやCSVファイルとかで用意して、ローカル環境で動作確認をしたかった。

色々調べたり、試してみたりしていたところ、
httplib.BadStatusLine
という例外が発生していた。

これを調べてみるとProxy設定の記事にたどり着いた。

おや?

会社からGAE環境にアップするときには、会社のProxy設定をしている。
ということは??ローカルURLでProxy設定を行うのか?????

やってみよう!!

ということで、やってみた。

・・・

・・・・・・

でけたーーーーーーーーー!


という事で、データアップロードの手順とかまとめる。
諸々のインストールとかEclipseからGAE/JでWebApplicationとして実行できるとか、yamlファイルを作成と編集とか、そこらへんは割愛!

  • 設定内容
    • OS:Windows
    • ポート番号:8888
    • リモートAPIのパス:http://localhost:8888/remote_api
    • アップするデータファイル:CSVファイル

  1. Google App Engine for Pythonにパスを通す
    set PATH=%PATH%;appEnginePython¥bin
  2. Proxy設定を行う
    set HTTP_PROXY=http://localhost:8888
    set HTTPS_PROXY=http://localhost:8888
  3. Eclipseで該当のアプリを起動
  4. アップロードコマンドの実行!
    appcfg.py upload_data
    --filename=xxxxx.csv
    --config_file=bulkloader.yaml
    --url=http://localhost:8888/remote_api
    --kind=xxxx
    -v --no_cookies --email=test@example.com --passin
  5. メールアドレスのパスワードの入力が求められるので、入力

上記手順でローカル環境へのアップロードが完了する!(はず・・・)

ちなみに、プロキシはEclipseの起動オプションで設定したものを、メールアドレスとパスワードは何でもOKです。
ポイントはアップロードコマンドにアプリケーションIDを指定するオプションを使用しないこと。

理由は分からないけど、アプリケーションIDを指定してしまうと、データが行方不明になりましたw

ダウンロードも同様の設定でできた〜

2012/05/15

良いソースとは?-Javaの参照型変数と引数- 私の結論

先日5月7日に記事を一つ書かせていただいた。
良いソースとは?-Javaの参照型変数と引数

簡単におさらいを。


最近の悩み。「良い設計・ソースとは」
【要件】
あるクラスの中で、0から9までの整数を格納しているリストが必要である。
今回はこのリスト取得のために、1つメソッドを作成したい。
メソッドは以下の要件を満たすこと。
  • アクセス修飾子:private
  • メソッド名:createList
と、上記のように2人のコーダーに伝えたとする。 すると、下記のようなメソッドが納品された。

【納品物1】
private void createList(List <Integer> list) {
    for(int i = 0; i < 10; i++) {
        list.add(new Integer(i));
    }
}

【納品物2】
private List<Integer> createList() {
    List<Integer> result = new ArrayList<Integer>();
    for(int i = 0; i < 10; i++) {
        result.add(new Integer(i));
    }
    return result;
}


「1と2でどちらが良いか」についてコメントをいただいた。
コメントを頂戴いただいた方々、この場を持って御礼申し上げます。
ありがとうございました。

頂いたコメントをまとめるとこんな感じ。
  • 2が良い。
  • 1はNullチェックや引数のリストに対して追加をする場合には良い。(条件付)

私も2が良いと考える。その理由は以下の通り。
  • 要件から「作成したメソッドを呼び出すことで、必要なリストが作成される」と読み取れ、満足するのは2である。
  • 1を使用する場合、呼び出し元で予期せぬデータ操作が行われてしまう可能性がある。
  • 1を使用する場合、予期しない例外が発生する可能性がある。
つまり、コメント頂いた方々と同じ理由だ。

もし、1のように実装する場合は、呼び出し側で明示的に入れ替える処理を記載するようにListをreturnするのが良いと思う。
そうすれば、呼び出し元で予期しないデータ操作を幾らか回避することができると考える。

コメントでも頂いたのだが、
結局はそのメソッドの責務を明確にすることが重要で、その責務に見合った引数と戻り値を設定することが大切ではないか
ということだと思う。
後輩に説明する際には、コメント頂いた内容を参考にさせていただきます。

2012/05/07

良いソースとは?-Javaの参照型変数と引数

仕事で詳細設計と実装をやっていたり、後輩のソースコードレビューをしたり。 そこで最近の悩み。

「良い設計・ソースとは」

私自身、”何が良い”という好みはある。けど、後輩に指導するときの根拠として弱いと思う。 そこで、皆さんのご意見をお聞かせ頂けたら、と思って今回のブログを書かせていただきたい。 今回は実際に私が困った事と類似の例を紹介させていただく。


【要件】
あるクラスの中で、0から9までの整数を格納しているリストが必要である。
今回はこのリスト取得のために、1つメソッドを作成したい。
メソッドは以下の要件を満たすこと。

  • アクセス修飾子:private
  • メソッド名:createList
と、上記のように2人のコーダーに伝えたとする。 すると、下記のようなメソッドが納品された。

【納品物1】

private void createList(List<Integer> list) {
 for(int i = 0; i < 10; i++) {
  list.add(new Integer(i));
 }
}

【納品物2】

private List<Integer> createList() {
 List<Integer> result = new ArrayList<Integer>();
 for(int i = 0; i < 10; i++) {
  result.add(new Integer(i));
 }
 return result;
}


どちらも要件を満たしているが・・・

  • どちらが”良い”ソースだと思いますか?
  • それはなぜですか?
コメントに皆様のご意見をお書き頂けたら幸いです。

2012/05/06

JavaOne Tokyo 2012に参加して~4月5日~

遅くなってしまいましたが、4月4日と5日に開催された JavaOne の二日目の5日の参加報告です。

【参加したセッション】

  1. 9:00-11:00 [JK2-01] Technology Keynote
  2. 11:15-12:15 [JS2-01] Chuck Munn Lee 「The Java EE 6 Programming Model Explained」
  3. 12:30-13:30 ランチセッション-エンジニアに直接質問してみよう!
  4. 13:15-14:15 休憩
  5. 14:30-15:30 [JS2-24] 輪島 裕之 「ビジネスの継続的改善に貢献するJava EEアーキテクチャとアジャイル開発」
  6. 15:45-16:45 [JS2-33] 山本 裕介 「JSR 353: Java API for JSON Processing」
  7. 17:00-18:00 [JS2-41] Douglas Clarkeis 「Java Persistence API on the Grid」
  8. 18:15-19:15 [BoF2-04] 木村 貴由、寺田 佳央 「The New JSR-107 Caching Standard 」
  9. 19:30-20:30 スペシャルセッション


1. 9:00-11:00 [JK2-01] Technology Keynote

■SE 7での主な変更点

  1. MapやらListの宣言時の型宣言を行うジェネリックス
     -> 左辺だけ記述して、右辺については省略可能
  2. Switch文の条件にStringが使用可能に
  3. try-catchのcatch句で条件をor表記可能に
     -> 例) catch(NullPointerException | NumberFormatException)
  4. FileStreamのclose()が不要になる
     -> try-with-resourceを使って自動close

(1)については非常に嬉しい!
MapのMapを作ったときには1行が200文字程度になったりするから・・・ ま、そんなMapを作るくらいならBeanをうまく作った方が現実的なような気がしますが(汗)

(2)これについても嬉しい!
Stringの比較をする際にはIf文が大変なことになるから。 それがSwitch文で書ければ、分岐が分かりやすくなる。

(3)今まで予期したExceptionのCatch句が複数になる場合、 ログ出力とかはそのクラス内でprivateメソッドを作って共通処理化して、 そのメソッドを呼び出すようにしていた。 結局テストのし易さとかで判断するようになると思うけど、 今はまだ旨みが分からんな。。。

(4)これってDBのトランザクションもだっけ?
それだったらかなり嬉しい!ちょっと調査が必要だな。

2.11:15-12:15 [JS2-01] Chuck Munn Lee 「The Java EE 6 Programming Model Explained」

正直なところ、英語も早かったし、通訳も早かった。。。 途中まで、というか最初しか付いていけなかった。

分かった範囲では、次の感じ。

  • これまでWeb.xmlに書いていたサーブレットの設定がアノテーションでできる
  • 同じくフィルターの設定もアノテーションでできる

これでweb.xmlの記載量が減ることは確か。
でも、一方のサーブレットから他方のサーブレットを呼びたい時はどうすんだ? サーブレットクラス自身には自分のマッピングルールだけ書けば、 他のサーブレットからでも、そのマッピングルールが参照できるってこと? 1ユースケース内であればイイと思うけど、ユースケースの入り口のような 複数箇所から呼ばれそうなサーブレットはweb.xmlに記載して共通化した方が チーム開発では便利なような気がする。。。

フィルタに関してはSaStrutsでも同じようにできるようになるのか? それならweb.xmlが太ることなく設定できるからいいかも。 けど、どのクラスに設定したかは探すのが大変になりそうだ。 でも、パッケージ構成とかクラス名とかを工夫すれば解決できるか。 ん~どうなんだろ??

3.12:30-13:30 ランチセッション-エンジニアに直接質問してみよう!

正直なところ、ご飯を食べてるだけで、ほとんど英語でディスカッションされていたので、 内容が分からなかった。。。 本来はネイティブな方が通訳になってくれて、日本語での質問がOKだったのに、10回中3回くらいしか日本語なかった。

4.13:15-14:15 休憩

ノートPCとケータイの充電が(私の体力も)切れてしまったので、カフェで1時間休憩した。
この間にGmailに来てたメールを処理したり、ブログ書くようにまとめ作業を行ったりした。 カフェは窓際に面していて、東京タワーやスカイツリーが見えた。風景写真を撮影している人も居た。 とても明るく開放的な雰囲気で、電源タップが用意されていたので、PCを触ったり食事をしながら雑談をしたり、って感じ。 あとは、各協賛会社のブースもあって、かなりにぎわっていた。

5.14:30-15:30 [JS2-24] 輪島 裕之 「ビジネスの継続的改善に貢献するJava EEアーキテクチャとアジャイル開発」

アジャイル開発の事例紹介が聞けると思って参加。確かに事例は聞くことができた。
他の会社がどのように開発スケジュールをひいているのか、を聞くことができた。 また、要員確保の方法と契約方法について、どのような契約方法があってどのような特徴があるのかを知ることができた。

6.15:45-16:45 [JS2-33] 山本 裕介 「JSR 353: Java API for JSON Processing」

TwitterだけでなGoogle、Yahoo!でも使用されているJSON(JavaScript Object Notation)。 現在最もポピュラーなWebAPIであるJSONについて標準化を行っていること、その内容についてお話いただいた。 XMLと比較して、JSONは設定が簡単で人間でも読みやすいのが特徴。

■Javaの標準化に関する略称

  • JCP:Java Community Process Java標準化機構
  • JSR:Java Specification Request Java新機能提案
  • TCK:Technology Compability Kit 準拠判断テストツール

JSONについては、JSR353で標準化作業が行われている。 標準として策定されるためにはTCKも作成する必要がある。

このセッションの中で一番驚いたのが、 JSONのモデリングにVisitorパターンが採用されていること。 Visitorパターンをちゃんと把握しているわけではないけど、ちょっと違和感を感じた。 Template Methodの方がしっくりくるような気もするけど。。。

このJSR353が策定・承認されて、Javaの標準APIとして搭載されるようになれば、 独自でAPIを突っ込む必要がなくなるので、楽になるだろうなぁ。

6.17:00-18:00 [JS2-41] Douglas Clarkeis 「Java Persistence API on the Grid」

このセッションではJavaとDatabaseとの関連について話があったみたい。 正直私の頭では、ついていくことがかなり難しかった。。。

ついていけたのは
「Java Persistence API(JPA)は、POJOとDBのEntityをマッピングしてくれる」
ということ。
このマッピングルールはアノテーションまたはXMLで設定する。 実際のマッピング処理は、Entity Manager Factoryが行う。 JPAはキャッシュを行うので、パフォーマンス向上も図れる。 けど、キャッシュ上にあるデータとDB上にあるデータでの不整合発生が問題点だったからコントロールできるようにした。 それがData Gridらしい。

ここら辺から「コヒーエンス」とか知らない単語がバンバン出てきて付いていけなくなってしまった。。。 とりあえず、アノテーションとかXMLを利用することで、DBのエンティティとのマッピングを自動化できることが分かった。 具体的な使い方については、分からないので、調べて試してみる必要があるな。

7.18:15-19:15 [BoF2-04] 木村 貴由、寺田 佳央 「The New JSR-107 Caching Standard」

Java EE 7で本格導入されるJavaのキャッシュについてのお話。 寺田さんと木村さんの絶妙なやり取りが面白く、飽きないプレゼンだった。

JCache(JSR107)がJava Objectのキャッシュ。 使い方はConcurrentMapに類似していて、Java SE/EE 6以降で使用可能。 mavenを使用することでAPIをインポートすることができる。

Google App Engineではmemcahceが該当する。

キャッシュの対象にすべきデータは下記の4種。

  • DBから取得した値(参照回数の多いデータ)
  • ネットワーク越しの処理結果
  • オブジェクト生成に時間のかかる処理結果
  • 大規模Session情報(Sessionに大きな情報を格納すると読み書きバッファが多くかかるから)

GAEではレスポンス時間とデータ量がポイントになってくるから、 Sessionとキャッシュとリクエストとをうまく使い分けていく必要があると感じた。 どのタイミングで確定させるのがいいのかな?やっぱり詳細設計の段階かな~

8.19:30-20:30 スペシャルセッション

スペシャルセッションでは、各勉強会の主催者によるパネルディスカッション。 社内の勉強も大切だがそれだけでは不十分なんだな、って感じました。 私個人では自分で勉強会を立ち上げるのは、ちょっと厳しいので既存の勉強会から参加して勉強をしていこうと思った。

2012/04/09

JavaOne Tokyo 2012に参加して~4月4日~

7年ぶりに日本でJavaOneが開催されました。

私が4月4日に参加したセッションについて、技術的な内容については他の方々のBlogを参考にしてください。 ここでは私の感想を主に書いて、他には備忘録を書きたいと思います。

【 参加したセッション】

  1. 9:00-11:00 [JK1-01] Strategy Keynote
  2. 11:15-12:15 [JS1-04] 櫻庭 祐一 「NIO.2を使って、簡単ファイル操作」
  3. 12:30-13:30 ランチセッション-GlassFish
  4. 13:15-14:15 [JS1-14] 斉藤 賢哉 「Java EE 6時代におけるエンタープライズシステムのあり方」
  5. 14:30-15:30 [JS1-21] John Clingan 「Pragmatic Cloud and PaaS with Java EE 7 (and GlassFish)」
  6. 15:45-16:45 [JS1-33] 寺田 佳央 「What's coming in Java Message Service 2.0」
  7. 17:00-18:00 [BoF1-02] 佐藤 直生 「Windows AzureでのスケーラブルなJavaアプリケーション構築」
  8. 18:15-19:15 [BoF1-04] 谷本 心 江里口 温 「トラブルシューターの頭の中身 ~7年間のJavaトラブルシュートサービスから」
  9. 19:30-20:30 スペシャルセッションLT

1. 9:00-11:00 [JK1-01] Strategy Keynote

 このセッションでは、主に下記の2点についての報告があった(と思う)

  • これまでの標準化の進捗状況や今後のスケジュールについて
  • Java 7に搭載される各Editionの機能紹介
     (Java SE 7/Java EE 7/Java FX 2.0/GlassFish など)
あとはJavaがここまで発展したのは、コミュニティの存在が大きかったらしい。
各講演の中でスピーカーは常々、使ってみて不便なところがあったらメーリングリストにメールを投げて欲しい、コミュニティで発言して欲しい、と仰っていたのが印象的。Javaを一緒に作っていきましょう!という強いメッセージを感じた。

 続いて、Education分野であるOracle資格についての講演があった。
この中で話題になったのは、以下の2点。
・Javaの資格がOracleDBと同様にBronze、Silver、Goldという3形態になること
・現在のJava資格の合格者は日本だと合格点ぎりぎりだが、インドではほぼ満点。
日本人、頑張らないと仕事がなくなりそうって感じた。

資格については興味があったので、資格のレベルをまとめる。
【Gold】単独で開発が可能なレベル
【Silver】上級者のサポートの元で、開発が可能なレベル
【Bronze】Javaに関する基本知識レベル
そいや今はJavaSEに対してはOJC-Pが、JavaEEにはOJC-WCが、対応している認識だけど、これからはどうなるんだろう??


2.11:15-12:15 [JS1-04] 櫻庭 祐一 「NIO.2を使って、簡単ファイル操作」
■NIO2でできるようになったこと
・ファイルのコピーが簡単になった
・ファイルのメタデータの操作が可能になった
・ディレクトリツリーに対する操作も簡単になった
・ファイルを使用する際に冗長だった記述が非常にシンプルになった

これまで私個人の見解としては「Javaはファイル操作が苦手だ、」というイメージを持っていたけど、NIO2の登場によって、そんなイメージも完全になくなりそうな予感。
Java FXと組み合わせることで、Javaでかなり使い勝手の良いファイル操作アプリが作れそうな予感もする!


3.12:30-13:30 ランチセッション - GlassFish
GlassFishとはOracleが提供しているアプリケーションサーバーの開発プロジェクトのこと。
他に有名なJavaのアプリケーションサーバーにはTomcatがある。
GlassFishのライセンスはオープンソースになっているものもある。

GlassFish3はJava EE 6に、GlassFish4はJava EE 7に対応。

セッション開始時には、GlassFishのTシャツを投げる。
また、終了時にはGlassFishのシールを配布する、というイベントがあった。


4.13:15-14:15 [JS1-14] 斉藤 賢哉 「Java EE 6時代におけるエンタープライズシステムのあり方」
■Java EE5からの特徴
・開発容易性を実現
→POJO:シンプルなクラス
→アノテーション:XML地獄からの開放・テスト容易性の確保

■Java EE 6の特徴
・JSF2.0(Java Server Faces)
 Webアプリケーション標準フレームワーク
 【特徴】
 1.HTMLにJSFタグを埋め込むだけ(モックアップが不要)
 2.JSF拡張フレームワーク
 3.JS + JAX-RSパターン(ネットワークの切れ目=担当者の切れ目)
・EJB(Enterprise Java Beans)
 トランザクション管理、インターフェースが省略可
 シングルトンSessionBean

■デザインパターン
・EE 5:プレゼンテーション層+ビジネスロジック層+DAO層
 ※各層を疎結合にすることが目的。
 ※ただし、各層をつなぐための”グレーコード”(DTO)が必要。
  詰め替えを行うための不要な処理が必要となり、コード量が増大
・EE 6:フルスタックなフレームワーク
 ※CDIによって各コンポーネントの結合が楽になる
 ※”グレーコード”(DTO)が不要

■CDIを使用することで、
保守性・生産性がアップするらしい。
アプリ実装範囲の軽減することができるらしい。
モデリングが容易になるらしい(オブジェクト指向、モデリングスキルが必要だけど)
設定ファイルが不要になるらしい


5.14:30-15:30 [JS1-21] John Clingan 「Pragmatic Cloud and PaaS with Java EE 7 (and GlassFish)」

このセッションに関しては途中までしか把握できなかった。
把握できた内容は以下の通り。

Java EE 7は「PaaS」でクラウドに対応するよう作られている。
そのために、WebサーバとしてGlassFishが提供されている。

・SaaS:Software as a Service → PaaSに加えてWebアプリまでを提供。Webメールなど
・PaaS:Platform as a Service → IaaSに加えてWebサーバまでを提供(Webアプリとデータは自分で用意)
・IaaS:Infrastructure as a Service → サーバそのものを提供(Webアプリサーバなどは自分でインストール)

SaaSは業務でも開発しているものなので把握していたが、他の二つについてはきちんと把握できなかったから、復習になった。


6.15:45-16:45 [JS1-33] 寺田 佳央 「What's coming in Java Message Service 2.0」
大きな変更点
・アプリケーションサーバを利用
 →JDBCと同じように、コネクションプーリングの利用が可能
・EJBコンテナを利用して
 →コネクション接続の記述不要(コード削減)
・例外の実装方法が変更
 →7のtry-with-resourceに対応(コネクションのクローズ処理を書かなくてOK)
・ある例外を非チェック例外にした
 →try-catch不要(rollbackの記載が不要)
・Messageスケジューリングもできる(非同期通信として処理可能)

今まで使ったことはないが、かなり使いやすそう、というイメージを持った。
GAEだとTaskQueueがあるけど、そんな感じで使えるんだと思う。
AjaxでTaskQueueを動かしておいて、完了時にMessageを返して、って感じで使うといいのかなぁ~って思った。


7.17:00-18:00 [BoF1-02] 佐藤 直生 「Windows AzureでのスケーラブルなJavaアプリケーション構築」

サーバは世界に6台(日本にはない)。アプリデプロイ時にメインサーバを選択できる。
(ただし、すべてのサーバに自動バックアップされる)

■Azureで使えるもの
・テーブル:Key-Valueストア
・キュー
・BLOB:ファイル形式
・Drive:マウントしてローカルドライブのように使える

・データについては、SQL Azure DB(SQL Server)を利用
→論理サーバを提供
・Trafic Manager
→データセンター毎にクラッシュした場合、他方のセンターへ割り振り
・staticなデータはキャッシュしておく
(キャッシュサーバは日本にもある)

GAEとは異なり、デプロイ時にメインサーバを選べたり、サーバの設定ができるらしい。
GAEと同様にJavaアプリが動くので、状況によって使い分けることが大切になりそう。
あとは互いの特徴を調べて比較しないと何とも言えんな。


8.18:15-19:15 [BoF1-04] 谷本 心 江里口 温 「トラブルシューターの頭の中身 ~7年間のJavaトラブルシュートサービスから」
事例の紹介と、それに対し「どのように原因を究明するのか」の実演が行われた。
キーワードはこちら。
java -XX:+HeapDumpOnOutOfMemoryError
jvisualvm
jstack
Jメーターで負荷テスト

私自身、作成したロジックのパフォーマンスを実際に検証することはなかった。
特にWebアプリを作っていると、ApachやTomcatの設定、SQLパフォーマンスに目が行き、Javaそのもののパフォーマンスを考えることが少ないように思う。
だけど、今回この話を聞いてパフォーマンス検証の重要性を感じた。
ヒープダンプを取ったりスレッドの状態をチェックしたりやってみよう。
Eclipseのプラグインでも見れるのかな?


9.19:30-20:30 スペシャルセッションLT

ここでは何人だったかな?5分で思いのたけを話すLTでした。
LTだけあってかなりユニークなプレゼンもありました。
一番びっくりしたのは「;」なしで色々実装した、というプレゼン。
そんな発想が私にはなかったので。。。ただただ「すげー」だった。。。

スペシャルセッションではご飯も出ました。
おにぎり2個とから揚げとたくあんと出し巻き卵と・・・
そんなくらいだったかな?
おにぎりの1個はJavaマスコットのDukeになってましたww



初日はこんな感じでした。
かなり刺激的な一日で途中からパンクしていました。。。

あとは、業務の中で、JavaでWebアプリ開発をしているけど、Javaについて知っていることは、ほんの一部でしかないことを実感しました。
全部を全部、自分だけで勉強することは難しいから、業務で知りえた範囲から一歩外側も勉強して知識を少しずつでもいいから増やしていきたい、と感じました。

2日目の5日の分については、また後日アップしたいと思います。

2011/12/14

GAEのことでやってみたい事のメモ

GAEを使ってやってみたい事を忘れないようにメモメモ。
  1. 簡単なアプリを作って公開する
  2. RDB→Bigtable(Key-Value)のDB設計方法の変換
  3. Slim3プロジェクトのディレクトリ構成の変更方法をまとめる
  4. ログのフォーマット変換とローカル環境でのログファイル保存方法

1は自分の勉強のため。
まずログイン処理をする。 そのあと、簡単な掲示板を作ってみる。 これで、一連の処理の流れを押さえられる、と思うから。

2は、RDBとは異なり敢えて非正規化をすることが必要とあるけど、 実際にはどのように設計すればいいのか、という具体例を見つけることができなかった。 (私の検索能力の問題だな・・・) だから、RDBでの簡単なテーブル2,3個をBigtable用にデザイン変更にしてみようかと。

3は、Slim3のデフォルトのディレクトリ構成が個人的に好きでないからww

4は、仕事上、ログのフォーマットを記録する必要があったから調べたので。 それを忘れないようにまとめておこうかと思います。

AndroidやGAEの事を考えると、 Googleさんは”JavaVM”という仮想OSを新しいOSとして利用することで、 マルチプラットホームを実現して、より簡単にアプリとかのサービスを 展開していこうとしているんだろうな~
となると、今のOSの未来も変わってくるのかな??

さて、今日はメモだけで寝ようかな~

2011/12/11

【GAE】Eclipseローカルで起動時に出るエラーメッセージ

会社のようなプロキシ経由で外部ネットワークに接続する場合、 Google App Engine(以降、GAE)をローカルで実行する際に 以下のようなエラーメッセージが表示されることがある。 (バージョン情報は伏せ時にしてます。)
Unable to access https://appengine.google.com/api/updatecheck?runtime=java&release=x.x.x×tamp=xxxxx1&api_versions=['x.x']
どうやら実行時にアプリのGAE SDKのバージョンと 公開されている最新のGAE SDKのバージョンの比較をするらしい。 その時、プロキシのせいで問い合わせができずにエラーが出ているみたい。 そこで、下図の画面で実行時のプロキシ設定を追加。

【画面表示】
プロジェクトを右クリック > Run As > Run Configrations > Argmentsタブをクリック

【追加内容】
proxy hostやproxy postは適宜変更で。

-Dhttp.proxyHost=<proxy host>
-Dhttp.proxyPort=<proxy port>

-Dhttps.proxyHost=<proxy host>
-Dhttps.proxyPort=<proxy post>

【実行環境】

Eclipse EE3.7
Java SDK1.0.27

【参考サイト】
Eclipse(Galileo)のGAEでプロキシ

2011/06/23

FlexPMDのEclipseプラグイン

仕事でFlash作成を行った。

開発環境:Flash Builder(Eclipseプラグイン)
開発言語:ActionScript3
コンパイラ:Flex4

結合テストの際に、ActionScriptのステップ数のカウントを行うためのプラグインを
探していたら、FlexPMDを発見した。
そのインストール手順の備忘録。
Eclipseのバージョンとかは以下のサイトを参考に。

参考URL:http://opensource.adobe.com/wiki/display/flexpmd/FlexPMD+Eclipse+plugin

◆インストール
1.Eclipseのメニュー Help > Install new software
2.Addボタンをクリックして、新規リポジトリの登録を行う。
 名前:FlexPMD
 場所:http://opensource.adobe.com/svn/opensource/flexpmd/plugin/trunk/flex-pmd-eclipse-plugin-site
3.FlexPMDをインストール
4.Eclipse再起動


◆設定
設定のためには、いくつかダウンロードが必要。
1.FlexPMDのコマンドライン.jarをダウンロード
 zipファイル
2.ダウンロードしたファイルを適当なディレクトリに展開。
 ただし、ディレクトリ名に半角スペースがあると、うまく動かない様子。
 (http://www.kei3.jp/diary.php?id=7561より)
 ちなみに、私はFlexSDKを以下のディレクトリに入れていたので、同じディレクトリに展開。
 <C:\tools\Flex\flex-pmd-all-in-one-bundle-1.1>
3.EclipseのFlexPMDアドインにコマンドライン.jarを登録する
 Eclipseメニュー > Window > Preferences > FlexPMD と設定画面を表示。
 ・FlexPMD command line installation:(2)のディレクトリ\flex-pmd-command-line.jar
 ・FlexPMD custom ruleset:今はブランクで
 ・FlexCPD command line installation:(2)のディレクトリ\flex-pmd-cpd-command-line.jar
 ※ファイル名にはダウンロードしたバージョンが入っている場合有
4.Apply > OK

以上で設定終了。


◆動作確認
検証したいファイル/ディレクトリを右クリック > FlexPMD > Run FlexPMD

これで検証結果が表示されれば、インストール&設定が完了!!
ただし、ワークスペース名に半角スペースがあると、うまく動かない様子。
 (http://www.kei3.jp/diary.php?id=7561より)


◆監査ルールの取得
1.監査ルールの設定ファイル(xml)のダウンロード
 URL:http://opensource.adobe.com/svn/opensource/flexpmd/bin/flex-pmd-ruleset-creator.html

2.上記サイトにアクセスし、画面下部の「Export」ボタンをクリック。
もし、ルールを変更したい場合は、画面内を操作してカスタマイズ可能。

3.ダウンロードしたファイルの格納場所は適当な場所へ。
 私の場合、以下のディレクトリに格納。
 ルールファイルはxmlなので、テキストエディタで編集可能。
  ・C:\tools\Flex\FlexPMD_Ruleset

4.ダウンロードしたルールファイルの設定
 Eclipseメニュー > Window > Preferences > FlexPMD と設定画面を表示。
 ・FlexPMD custom ruleset:(3)でダウンロードしたファイル


以上で、一通り動くはず!

2011/05/09

Flash(AS3)で外部XMLファイルを参照する方法



Flash(ActionScript3)でXMLファイルを読み込む手順について
解説されているサイトは沢山あったけど、今回自分がやりたかったのは、
<Flexプロジェクト>でのやり方。

これについては、なかなか紹介されているサイトがなく、
悩んだので、実現できた方法を忘れないようにまとめます。

ちなみに作成環境は以下の通り。
・Windows Vista
・Flash Develop(フリーのFlash開発環境統合ソフト)

【手順】
1)Flash Developにて<Flex3プロジェクト>を新規作成
 パッケージ:test
 テンプレートのコピーをする

2)src/test/Main.mxml の編集
~~~~~ Main.mxml ここから ~~~~~
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Script>
    <![CDATA[
      import test.asFile.ShowMessage;
    ]]>
  </mx:Script>
  
  <!-- レイアウト -->
  <mx:Text id="messe" text="以下に表示するファイル名を入力"/>
  <mx:TextInput id="textBox" text="test.xml" />
  <mx:Button id="button" label="Click!!"
    click="new ShowMessage(textBox, textArea)" />
  <mx:TextArea id="textArea"
    width="500" height="200"
    text="ここに指定したXMLファイルの内容が表示されます。" />
</mx:Application>
~~~~~ Main.mxml ここまで ~~~~~

3)asファイルの作成
~~~~~ ShowMessage.as ここから ~~~~~
package test.asFile {
  import flash.events.Event;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import mx.controls.TextArea;
  import mx.controls.TextInput;

  /** XMLファイルの内容を表示するためのクラス */
  public class ShowMessage {
    /** XMLファイルを設置するディレクトリ */
    private const XML_HOME_DIR:String = "test/xml/";

    /** コンストラクタ */
    public function ShowMessage(
      textInput:TextInput, textArea:TextArea) {
      var fileName:String = textInput.text;
      ReadXMLFile(fileName, textArea);
    }
    
    /** ファイル内容の取得 */
    private function ReadXMLFile(
      fileName:String, textArea:TextArea):void {
      
      var xml:XML = new XML();
      var urlRequest:URLRequest =
        new URLRequest(XML_HOME_DIR + fileName);
      var urlLoader:URLLoader = new URLLoader(urlRequest);
      
      urlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
      
      function xmlLoaded(event:Event):void {
        xml = XML(urlLoader.data);
        trace(xml.toString());
        textArea.text = xml.toString();
      }
    }
  }
}
~~~~~ ShowMessage.as ここまで ~~~~~

4)xmlファイル作成
~~~~~ test.xml ここから ~~~~~
<?xml version="1.0" encoding="utf-8" ?>
<data>
 <member>
  <name>first</name>
 </member>
 <member>
  <name>second</name>
 </member>
</data>
~~~~~ test.xml ここまで ~~~~~

5)最終的なディレクトリ構成

XMLファイルを設置する場所がポイント!
swfファイルが設置されているディレクトリが
ホーム扱いになるので、
そこから相対パスで参照できるようにする
必要がある点に注意。

これに関しては、EclipseにFlash Developerのプラグインを入れてコンパイルすると
自動でディレクトリが作成されるからsrcディレクトリに入れると行ける。

2011/04/19

便利なEclipseのプラグイン~JStyle~

Eclipseを使ってJavaの開発を行ってます。

その時にいつも困っているのが、インデント。
半角4つだったり、タブだったり・・・
その区別もソースを見ただけだと判断できません。。。

そこで、Eclipseの設定を変更していました。
Window→Preferences→General→Editors→Text Editors
ここの「Show whitespace characters」にチェックを入れます。
そうすると、タブと改行の部分が明示的に表示されるようになります。

しかし、個人的にはタブは表示してほしいけど、改行は不要でした。
んで、見つけたのがJStyleというプラグイン!!
こいつがかなりナイスな働きをしてくれます!

JStyleでは以下の項目の表示/非表示が選択できます。
・改行
・タブ
・全角スペース
・半角スペース

私は、これの「タブ」と「全角スペース」にチェックを入れました。
「全角スペース」にもチェックを入れたのは、
以前ソースコード中に全角スペースを入れてしまいコンパイルエラーになったことがあるから・・・

参考サイトは検索してみてください。
ダウンロード、インストールなど色々な情報がありますので。

以上です。