himanago

Azure・C#などのMS系技術やLINE関連技術など、好きな技術について書くブログ

Grails3.3でrest-apiプロファイルを試す(Spring Securityでの認証つき)

はじめに

長いこと業務でGrailsを使っているので、Grailsの動向が気になっています。

Grailsとは、GroovyというJavaを強力に進化させたスクリプト言語を用いたフルスタックなWebアプリケーションフレームワークです。

Ruby on Railsのように「CoC(設定より規約)」「DRY(Don’t Repeat Yourself)」を信条とし、煩わしい作業や無駄な記述を一切排除し素早くWebアプリを開発できる、高い生産性が魅力です。

そんなGrailsですが、つい最近、3.3が正式リリースになりました。

社内の認証プロキシがどうにも突破できずうまく開発できないので現在の業務では2.5を使って開発していますが、ビルドシステムがGradleになり大きく構成の変わった3.xはずっと気になっていました。今回3.3が出たのでちょっと試してみたところ、プロキシ突破できたので、3.x系に乗り換えようか悩み中。。
※プロキシ突破できた話はメモとしてQiitaに書きました

qiita.com

とりあえず、いま作ってるアプリはそのまま2.5で作って、そのあと徐々に3.x系に移行していけばいいかな、と思っています。

さて、今回はGrails 3の出番に備え、リリースしたての3.3を使って、認証機能つきのWeb APIを作ってみたいと思います。 業務で作っているシステムは複数システムを連携ありで作る想定なので、Web APIで連携しやすくすることが重要になるため、ここの検証をしておきます。今回作成したものはGithubに上げています。

github.com

以下、Grailsの簡単な説明を交えつつのやったことの流れです。

「rest-api」プロファイルでプロジェクトを作成

Grailsではコマンドを用いて開発を進めます。アプリの新規作成は「create-app」コマンドで行いますが、Grails 3になると、作りたいアプリの構成ごとに「プロファイル」が用意されており、作成時に指定することができます。プロファイルを指定せずに「create-app」コマンドでアプリを新規作成すると、デフォルトのプロファイルである「web」プロファイルが用いられ、通常のWebアプリケーションのプロジェクトが作成されます。
一方、

grails create-app api-sample --profile=rest-api

とオプションで「rest-api」プロファイルを指定すると、RESTで叩けるWeb APIを作るための雛形プロジェクトを作ってくれます。

ドメインクラスとScaffold

GrailsMVCモデルのフレームワークです。
モデル(DBのテーブルに相当し、Grailsではドメインクラスと呼ばれます)、ビュー(WebアプリではHTMLのレンダリングを司る)、コントローラー(双方の仲立ち)により構成されます。

Grailsでは「設定より規約」により、モデル、ビュー、コントローラーのファイル名を規約通りにつけることで、それぞれが連動し複雑な設定なしでWebアプリとして動いてくれます。具体的には、たとえば書籍を管理するWebアプリの場合「Book.groovy」というモデル(ドメインクラス)、「BookController.groovy」というコントローラークラスを作り、「BookController.groovy」には「index」というpublicなメソッドを作ります(このメソッドを「アクション」と呼びます)。そして、アクションと同じ名前のビュー「index.gsp」というファイルをディレクトリ名がドメイン名と同じであるディレクトリに作ります。つまり、以下のような構成です。

domain
└ Book.groovy
controllers
└ BookController.groovy
views
└ book
   └ index.gsp

この状態でWebアプリを起動し、「http://xxxx/sampleapp/book/index」というURLにアクセスすると、URLに書かれたとおりのコントローラークラスのアクションメソッドが実行され、同様にビューが表示されます。このあたりの仕組みはRuby on Railsと同じですね。

そして、このコントローラーとビューは、ドメインクラスをもとに自動生成することが可能で、それが「Scaffold」です。

ドメインクラスを

package rest.s2.sample

class Book {
    // 属性
    String name
    String author

    // 制約
    static constraints = {
        name blank: false
        author blank: false
    }
}

と定義します。そして、 ‘’‘ grails generate-all rest.s2.sample.Book ’‘’ と実行すると、ドメインクラスに定義した通りの「Book」データをDBと連携し一覧表示/登録/編集/削除ができるようなコントローラーとビューを生成してくれます。これがScaffoldです。自動生成されたコードは実際にそのまま本番で使用することは少ないと思いますが、基本的な動作の書き方の参考にしたり、カスタマイズして流用したりすることができ、開発効率向上に一役買ってくれます。

rest-api の場合の Scaffold

さて、こんなScaffoldですが、「rest-api」プロファイルで作成されたプロジェクトで行うと、ちゃんとRESTで呼べるものが自動生成されます。 特に重要なのはビューで、通常は拡張子が「.gsp」であるGSPファイル(Groovy Server Pages。HTMLをレンダリングするためのファイル)が生成されますが、rest-apiの場合に生成されるのが「.gson」のGSONファイルです。これは、その名の通りGSPのJSON版で、リクエストに対しJSONのレスポンスを返すための情報を記載するファイルです。

起動と動作確認

Scaffoldまでできたら、「run-app」コマンドでアプリを起動します。 APサーバー、DBがあらかじめ含まれているのですぐ動作確認できます(DRYな特徴のひとつ)。 今回はrest-apiなのでブラウザではなくコマンドから確認します。Windows環境なので、PowerShellInvoke-RestMethodを使ってみます。この方法だと、送信するデータをスクリプトで組み立てられるため、RESTの動作確認におすすめです。

RESTということなので、今回、URLにアクションは含めません。UrlMappingsという設定ファイルで、HTTPメソッドとアクションメソッドの対応が定義されており、Grailsのデフォルトの規約を上書きしています。rest-apiでは、規約より設定、ということでしょうか。

package grails3.rest.api.s2.sample

class UrlMappings {

    static mappings = {
        delete "/$controller/$id(.$format)?"(action:"delete")
        get "/$controller(.$format)?"(action:"index")
        get "/$controller/$id(.$format)?"(action:"show")
        post "/$controller(.$format)?"(action:"save")
        put "/$controller/$id(.$format)?"(action:"update")
        patch "/$controller/$id(.$format)?"(action:"patch")

        "/"(controller: 'application', action:'index')
        "500"(view: '/error')
        "404"(view: '/notFound')
    }[f:id:himanago:20170803094920p:plain]
}

実行結果は以下のようになりました。まず登録。

PS C:\> Invoke-RestMethod -Uri "http://localhost:8080/book" -Method POST -Body @{name="Sample Book";author="Sample Author"}

id name        author
-- ----        ------
 1 Sample Book Sample Author

そして一覧表示です。

PS C:\> Invoke-RestMethod -Uri "http://localhost:8080/book" -Method GET

id name        author
-- ----        ------
 1 Sample Book Sample Author

たったこれだけで、RESTなWeb APIを作成することができました。

認証機能をつけるプラグイン

では、次にこのAPIに認証機能を付けてみたいと思います。Grailsには、認証機能をつけるための「Spring Security」がプラグインとして用意されています。プラグインは、Grailsの大きな利点のひとつで、さまざまな機能を追加したり、またよく使う機能を自前のプラグインとして外部化することもできます。

それでは、Spring Securityプラグインを使って認証機能を追加します。 rest-apiの場合、使うのはSpring Security CoreSpring Security RESTの2つ。

プラグインは、build.gradle内のdependenciesに以下の行を追加するだけで導入できます。

    compile 'org.grails.plugins:spring-security-core:3.2.0.M1'
    compile "org.grails.plugins:spring-security-rest:2.0.0.M2"

ちなみに認証の流れはSpring Security RESTのUser guideに載っているこの図がわかりやすいです。 rest

s2-quickstart

Spring Security Coreには、コマンド一発で認証に必要なユーザーとロールのドメインを作ってくれる「s2-quickstart」コマンドが用意されています。

grails s2-quickstart rest.s2.sample.auth User Role

次に、できあがったクラス(User、Roleとその関連を管理するUserRole)に対してgenerate-allでコントローラー/ビューを生成しておきます。

grails generate-all rest.s2.sample.auth.User
grails generate-all rest.s2.sample.auth.Role
grails generate-all rest.s2.sample.auth.UserRole

権限設定

Spring Securityでは、コントローラーのクラス単位/アクション単位でSecuredアノテーションを付けることできめ細かく権限制御をすることができます。ログイン有無や、Userに紐付くRoleごとの制御ができます。今回は、BookControllerのアクションを「ROLE_ADMIN」というRoleを持つUserでログインしていないと実行できないようにしてみます。

記述はクラス名の上に「@Secured(‘ROLE_ADMIN’)」をつけるだけです。もちろん、importは必要になります(この参照がうまくいかない場合はGradleプロジェクトのリフレッシュを行います)。

package rest.s2.sample

import grails.plugin.springsecurity.annotation.Secured
...

@Secured('ROLE_ADMIN')
class BookController {

}

各種設定

初期ユーザー登録

init/Bootstrap.groovyに、起動時処理として初期ユーザーの登録処理を書いておきます。今回は、このユーザーで認証を行います。

package grails3.rest.api.s2.sample

import rest.s2.sample.auth.Role
import rest.s2.sample.auth.User
import rest.s2.sample.auth.UserRole

class BootStrap {

    def init = { servletContext ->
        def user = new User(username: 'admin', password: 'admin')
        user.save(flush: true)
        def role = new Role(authority: 'ROLE_ADMIN')
        role.save(flush: true)
        new UserRole(user: user, role: role).save(flush: true)
    }
    def destroy = {
    }
}

設定ファイルの変更

今回はconf/application.ymlに設定を書きます。

grails:
    ....

    plugin.springsecurity:
        userLookup.userDomainClassName: 'rest.s2.sample.auth.User'
        userLookup.authorityJoinClassName: 'rest.s2.sample.auth.UserRole'
        authority.className: 'rest.s2.sample.auth.Role'
        filterChain.chainMap:
            #Stateless chain
            - {pattern: '/**', filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'}
        rest.token:
                validation:
                    useBearerToken: false
                    headerName: 'X-Auth-Token'

application.groovyにあるSpring Security関連の設定はすべてコメントアウトします。

実行結果を確認

では、実行確認です。run-appして、Invoke-RestMethodコマンドを実行していきます。

認証情報のない状態で、先ほどと同じようにbookの登録を行おうとすると、403エラーになります。

PS C:\> Invoke-RestMethod -Uri "http://localhost:8080/book" -Method POST -Body @{name="Sample Book";author="Sample Author"}
Invoke-RestMethod : リモート サーバーがエラーを返しました: (403) 使用不可能
発生場所 行:1 文字:1
+ Invoke-RestMethod -Uri "http://localhost:8080/book" -Method POST -Bod ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod]、WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

なのでまずは認証をし、アクセストークンを得ます。実行したスクリプト

$user = @{
    username='admin'
    password='admin'
}
$json = $user | ConvertTo-Json
$response = Invoke-RestMethod 'http://localhost:8080/api/login' -Method POST -Body $json -ContentType 'application/json'
echo $response.access_token

<実行結果>

PS C:\> $user = @{
>>     username='admin'
>>     password='admin'
>> }
PS C:\> $json = $user | ConvertTo-Json
PS C:\> $response = Invoke-RestMethod 'http://localhost:8080/api/login' -Method POST -Body $json -ContentType 'application/json'
PS C:\> echo $response.access_token
eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTdlVcL2JRQlJcL1RoTlJnVlNnRWtnZFlBRTI1RWgwek1SbjFjb05xR2tXa0VBWCsrRWVu
5cGFKRXFkZTNJZjlJdVwvUU5RTzNSbDd0cDNodURBZ25xVFwvZTduMzlmenhSVlVqSWJuc1daY0dEOFZXY3lsYjFMTlpXd3d6RFMzSFQ4enFDTzBPZUpGRG16U0JLNlBW
4cXdvbTQrcG02d0JEVzJ0cldGSTZ2bUhjMXl6QkU2VVBcL1Z2dVVHbThJMUJRZTk5S01MSU5reXdNVlNadFhjbjFkc28xUnRzd1Vjd0NGUjY2MFZSSU55Z3RaOElNUTBk
sUTVHZ3ZqMTJZenkwVzFnYllXd09PVUdVUHU3aVZwV0dmZDNUdWJraEljd1hzb3QxT1BEblczNEtDKzRcL0ZYbFJDVW1pdHA1cHN5VVJIZjUwNmMrTHN6WnpcLzdYN3ZO
wMHYrXC8rbmMyTDlrSUwwMFBXQzFpdG5aS2J5WUw1clVhbmZQbGw2OVA1MVllZFI2VHNFQnZcL3Y0XC81NVp2bU9xc3FTWmxtVmczdGlHaFB5dTZaeUZjZUpoOXNvZU0z
waWlsdldTZ3o2dGpENlpqTlkzMXRlZVwvMnk3bDRyTEVxNEpOVW5lV2kzTFQ5UXRLdmVuNDhcLytuT1wvaU9FVlZJNlp5SkE2bnloQTlTeHBvVDY5T0o4WitcL3k3bHlj
SQXdBQSIsInN1YiI6ImFkbWluIiwicm9sZXMiOlsiUk9MRV9BRE1JTiJdLCJleHAiOjE1MDE2NTI5ODcsImlhdCI6MTUwMTY0OTM4N30.P2n42_q6WSNY9weZad23aRSP

次にBookの登録です。

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("X-Auth-Token", $response.access_token)
Invoke-RestMethod -Uri "http://localhost:8080/book" -Method POST -Body @{name="Sample Book";author="Sample Author"} -Headers $headers

<実行結果>

PS C:\> $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
PS C:\> $headers.Add("X-Auth-Token", $response.access_token)
PS C:\> Invoke-RestMethod -Uri "http://localhost:8080/book" -Method POST -Body @{name="Sample Book";author="Sample Author"} -Headers $headers

id name        author
-- ----        ------
 1 Sample Book Sample Author

ちなみに、アクセストークンが誤っていた場合は、401エラーになります。

ということで無事、認証つきでRESTのAPIをたたくことができました。
これだけ手軽に認証機能つきのWeb APIが作れるようになり、Grailsはとても便利に進化していると思います。

画面ロックのショートカットをタスクバーにピン留めする(Windows 10)

はじめに

こんにちは。
今回は画面ロックをタスクバーからかんたんに行えるようにする小技を紹介します。

経緯

(本題とは関係ないので読み飛ばして結構です) 最近会社のメインPCが変わりました。念願のWindows10です。
会社では長らく開発用(Win8.1)とメイン(Win7)の2台体制で仕事していましたが、今回メイン機が7→10と入れ替わったかたち。

この2台はInput Directorというツールでマウス・キーボードを共有しています。

Input Directorは、PCを同一ネットワーク上にある別のPCから操作するためのツールです。
マスター(操作する側のPC)のマウスとキーボードで、スレーブ側(操作される側のPC)を操作できる優れものです。

なのですが、1点、不便なのが画面ロックです。
画面ロックは通常、Winキー+Lやファンクションキーの組み合わせなどで行えますが、マウス・キーボード共有している状態でスレーブ側を画面ロックしようとしても、マスター側がロックされるだけで、スレーブ側はとロックされません。
つまり、キーボード共有した状態で画面ロックのショートカットキーを入力すると、スレーブ側ではなくマスター側がロックされてしまうので、スレーブ側をロックするには別の手段を用いる必要が出てきます。
そこで使ったのが、今回の「タスクバーに画面ロックショートカットをピン留めする」という方法です。

画面ロックをコマンドで行う

画面ロックをタスクバーから実行するために、まず考えたのはバッチ化する、ということでした。
バッチ化するために、コマンドから画面ロックを実行する方法を調べたところ、下記の記事がヒットしたので、使わせていただきました。

www.projectgroup.info

ここに書かれている通り、「rundll32.exe user32.dll,LockWorkStation」と書いたファイルを作成し、拡張子を「bat」すればOKです。
このファイルをダブルクリックなどで実行すると、しっかり画面ロックされます。 (今回は「ロック.bat」というファイルにしました)

ショートカット化する

バッチファイルは、そのままではタスクバーにピン留めできません。 f:id:himanago:20170729230928p:plain

そこで、作ったバッチファイルをショートカット化します。
バッチファイルを右クリック→ショートカットの作成、とするとショートカットができます(ショートカットの名前は「ロック」にしておきます)。
これだけではまだタスクバーにピン留めできないので、これをコマンドプロンプト経由で呼ぶよう、変更します。 今回はバッチファイルは「C:\bat」のフォルダに保存しているので、作成したショートカットのリンク先は「C:\bat\ロック.bat」となっています。
これを、「C:\bat\ロック.bat」→「C:\Windows\System32\cmd.exe /C C:\bat\ロック.bat」と変更することで、コマンドプロンプト経由で呼ばれるようになります。
f:id:himanago:20170729231714p:plain:w300

こうすると、バッチファイルはタスクバーにピン留めできるようになります。

f:id:himanago:20170729234003p:plain:w400

コマンドプロンプトのアイコンだと味気ないので、アイコンも変更します。
アイコンはフラットデザインでよさげなものを選択。今回はこちらの「PNG」「背景なし」を使わせていただきました。

flat-icon-design.com

これをicoに変換すると、ショートカットアイコンとして使えるようになります。
今回はオンラインで変換できる下記のサイトを使用。

app.tree-web.net

アイコンの準備ができたら、再びショートカットのプロパティを開き、アイコンを変更し、タスクバーにピン留めしなおします。
これで、ちょっとおしゃれな画面ロックショートカットをタスクバーにピン留めすることができました。

f:id:himanago:20170730011353p:plain:w200

もう一工夫

これだけでもいいのですが、この状態でピン留めしたショートカットから画面ロックをしようとすると、コマンドプロンプトの画面が一瞬出てしまいます。
そこで、コマンドプロンプトが出ない方法を調べると、VBScriptで記述すればよい、ということがわかりました。

d.hatena.ne.jp

拡張子を変更し、「ロック.vbs」というファイル名にします。 中身は以下のコードに変更します。

Dim oShell
Set oShell = WScript.CreateObject ("WSCript.shell")
oShell.run "rundll32.exe user32.dll,LockWorkStation",0
Set oShell = Nothing

ショートカットのプロパティのリンク先も、VBScriptになったので以下のように実行するexeを変更します。

C:\Windows\System32\wscript.exe //B C:\bat\ロック.vbs

最後に、ショートカットをタスクバーにピン留めしなおします。
これで、ワンクリックできれいにロックがかかるようになりました!
快適な2PC生活が送れそうです。

Oracle Database XE を Linux 32bit環境にインストールする

はじめに

どうにも最近業務が忙しく、なかなかブログが書けません。 下書きばかりがたまっていきます…。

さて、ここ数日久しぶりにOracleをいじっていたのですが、社内の研修用環境として、32bitのLinuxVM(CentOS 6.9)にOracleデータベースの無償版であるExpress Edition(以下XE)を入れようとしたら見事にハマりました。

11g以降のバージョンで、OracleデータベースのXEではLinuxは64bit版のみの提供で、32bit版は提供されなくなってしまっていたのです(Windows向けは両方あり)。
かといって、10gの32bit用XEも公開が停止されており、公式ではどうにもならない模様。
今回は要件的に32bitのLinux+XEという組み合わせがMUSTだったので、なんとか粘って解決策を見つけました。

この組み合わせが必要になった場面、実は今回で2度目なので(1度目はあきらめた)、需要あるかも?ということで備忘も兼ねて書いておきます。

基本的に32bitのLinux向けXEは入手不可

11g以降はXEについて32bitのLinux向けが提供されていないということで、検索してみるとやはりそれを求める人の質問が結構ヒットします。
しかし、それらの結論はXEはあきらめて上位エディション入れましょう、など「不可能」という回答ばかり。
海外の質問サイトで、ここにリンクが残っていますよ、というような回答をみつけたりもしたのですが、すでにリンク切れ。
あきらめずに根気よく探すと、以下の記述を発見…!

「この中にあるよ」

unix.stackexchange.com ここには、 http://oss.oracle.com/debian/ に10gXEが含まれていると書かれていました。

探ってみると、こちらから10gXE(32bit)のパッケージがダウンロードができました! https://oss.oracle.com/debian/dists/unstable/non-free/binary-i386/ (この中の「oracle-xe-universal_10.2.0.1-1.1_i386.deb」というやつです)

しかし、形式がdebなので、今回使うCentOSではインストールできません。
そこで、こちらの記事を参考に、rpmに変換してインストールしました。

dotnsf.blog.jp

ということで、無事Linux32bitの環境にOracleXEを入れることができました。

MCP試験(70-483:C#によるプログラミング)を受けてきました

はじめに

先月末、Microsoftの認定資格であるMCPの、「C#によるプログラミング(70-483)」を受けてきました。 今回は受けるにあたっての準備と実際の試験についてなどを書き残しておこうと思います。

動機

この試験をなぜ受けたか、というと理由は3つです。

1. スキルの証明

かれこれ7年半くらい前から業務でも頻繁に使っているC#について、スキルを持っているということを対外的に証明したかったというのがひとつ。

同じく継続的に使っているJavaについてもOracleの認定資格をとったりしているので、C#でもそれをやっておきたいと思ったため、時間があれば前から受けたいと思ってました。

2. 講師登壇の説得力

上記と少しかぶるのですが、今年度会社でC#関連の講座を担当するので、講師として説得力をもてるようにしたかったことです。
講師プロフィールに関連資格が書いてあると、とりあえず「この人ちゃんと知ってるのかな」って思いますよね。
もちろん、資格だけあればいいかというとそういうわけでないのはもちろんですが。

3. de:code MCP割引

これがいちばん大きかったです。 f:id:himanago:20170521210618p:plainde:code 2017 リーフレットより)

de:codeのMCP割引は税抜\56,000で、早期割引(税抜\68,000)よりも安いんです。
なので、まずはこのタイミングで試験を受けてしまって、だめだったら早期割引の値段で申し込むことにしました。
早期割引が4/28までだったので、駆け込みで4/24に受けました。

試験の概要

試験で出題されるC#のバージョンは、試験の概要に「Visual Studio 2012」と記載されているので、C# 5.0」となります。
async/awaitあたりまでが試験範囲に含まれることになります。

準備

この試験には日本語の対策書籍(MCP教科書 Windows 10(試験番号:70-697)などのいわゆる赤本)がないので、英語の書籍ですが、Exam Refというものを使いました。
MCP対策書籍としては定番もののようです。

https://www.amazon.co.jp/dp/0735676828/www.amazon.co.jp

すべてを読み込むことはできませんでしたが、練習問題が各パートごとに数問載っているので、どんな問題が出るのか知る上で重宝しました。

章立ては試験に沿っていて、

  • Manage Program Flow(プログラムフローの管理)
  • Create and Use Types(型の作成と使用)
  • Debug Applications and Implement Security(アプリケーションのデバッグとセキュリティの実装)
  • Implement Data Access(データ アクセスの実装)

と、試験範囲と同じ構成になっています(全384ページ)。
全部をじっくり読み込むのは相当骨が折れそうですし、ある程度C#経験があれば文法的な部分はおおよそ問題ないので、ほとんどは流し読みで、気になったところはじっくり読む、という使い方をしました。

個人的には、セキュリティの実装あたりは普段そこまで意識していなかったところなので、ちゃんと勉強する必要があるなと思いました。

しかし結局、4月は業務が忙しく、ろくに対策をする時間もとれず、「もう落ちてもいいや!」と当たって砕けろな覚悟で申し込みました。
すべてはde:codeのため。受験を先延ばしにして万が一そこで落ちて早期割引でも申し込めなかったり、さらにはチケット完売なんてなったりしてしまったら目も当てられませんから。

試験当日

夕方18:30からの予約だったので定時ダッシュして秋葉原の試験センターへ。

ひととおり手続きを終え、予約時間になったらPCの前へ。
案内には試験時間が150分と書いてあったのに実際には120分だったり、試験開始前に、「試験はどうでしたか?」的なアンケート答えさせられたりと、若干混乱させられましたが、試験が始まりました。

形式はほとんどが多肢選択式。
プログラムの虫食い部分に当てはまるコードや、正しい実行結果を選択します。

なかには、複数の選択肢から複数の虫食い部分にドラッグ&ドロップして解答するものも。
この形式でswitchのcase, default, breakの穴埋めが出たときは「ばかにしてるのか!」とも思いましたが、LINQのクエリ形式やasync/awaitまわりのキーワードを埋める問題も出たので、そこは楽しく解いていくことができました。

案の定、対策の不十分だった「アプリケーションのデバッグとセキュリティの実装」まわりの問題には苦戦しました。

またなかには、翻訳が微妙な問題(ひとつだけ「あれ?」と思ったものがあった)や、解答の選択肢のソースコードから単語間のスペースが消えて詰まってしまっているものなどがありました。

こういうときは、試験問題の表示を英語に切り替えることをおすすめします(試験問題の機能でできる)。
英語に切り替えると、ソースコードの空白がちゃんと表示され、読みやすくなりました。

また、自分の知識と照らし合わせて問題と選択肢が「何か変だな」と思ったら、英語の方を読んでみると、誤訳とまではいかなくても、ニュアンスの微妙な違いから英語のほうが本来の意味を理解できることがあります(そんなに英語が得意でなくても)。

こういう対応ができたのも、Exam Refを見ておいたことで英語の問題文への抵抗感がそこまでなくなっていたからかな、と思います。

結果

そんなこんなで試験を終え、結果は無事合格でした。合格点は700点とのことだったので、7割合格でしょうか。
点数はぎりぎりで、やはりというか、「アプリケーションのデバッグとセキュリティの実装」のところがやたら低かったです。
そこ以外でなんとか点数をとれていたのと、(全部でなくとも)Exam Refを見ておいたことが今回の勝因かと思います。

まとめ

Exam Refの確認はしておいたほうがいいなと思いました。
試験本番で英語に切り替えることも戦略として一つの手なので、その対策の意味でも必須だと感じました。

とはいえ、基本的なことがしっかりわかっているかが結果に大きく関わってくるので、やはり普段からの経験がものをいうのは事実でしょう。
実際、今回は試験対策が功を奏したというよりは地力で踏みとどまった感じですし。

このあとの認定パスとしては70-357:Developing Mobile Appsを受けてMCSA: Universal Windows Platformを目指すか、
70-486:Developing ASP.NET MVC Web Applicationsを受けてMCSA: Web Applicationsを目指すかの2択になりそうです。
UWPもASP.NETもきちんと勉強したいなと思っていた技術なので、どちらに挑戦しようかまだ悩み中です。今年度中には、ぜひ挑戦したいと思います。

そして明後日からはついにde:code 2017!
前夜祭のDay0と今回初となる「Hack Days」のDay3,4も含めて5日連続参加します。最新テクノロジに触れられる貴重な機会、楽しんできたいと思います。

以上です。

PCレスでXamarin ~ Xamarin入門者の集い #2 でLTやってきました

初投稿になります。

ひらりんと申します。

先日、「初心者歓迎XamarinのLT会!Xamarin入門者の集い #2」というイベントでLTをさせていただいてきたので、その報告と内容紹介をしたいと思います。 jxug.connpass.com

いま話題の「Xamarin」というクロスプラットフォームのモバイルアプリ開発ツールの入門者イベントでした。

MicrosoftによるXamarin社買収以降、無償化やVisual Studio 2017の登場などでかなり手を出しやすくなった印象です。

会社で技術系の社内講座などを開催している身としては、この流れには乗っておかねばと思い、今回入門者LTにも申し込んだ次第であります。

概要

テーマは「最近Xamarinを触った話」。

LTをやろうと決めてから、そのネタ探しもかねてXamarinをやろう!と環境作成やらいろいろ意気込んでやっていたら、なんとPCがブルースクリーンから復帰しなくなり、初期化すらままならない状況となってしまったのです。
f:id:himanago:20170420104217p:plain

手元に残ったコンピューターはiPhoneだけ…。
(実はちょっと前にMacも壊してしまったばかり)

これじゃあXamarinが触れない…

そこで思いついたのが Microsoft Azureです。

Microsoft AzureはMicrosoftクラウドサービスです。

そのAzureにVMを立てて、iPhoneからリモートでつなげばiPhoneだけでもXamarinできるはず!という発表でした。

XamarinとAzureの相性が抜群という話はよく聞くし、きっとAzure上での開発もわけないでしょう。
※本当はAzureをモバイルアプリのバックエンドとして使う際に便利、ということです

全体像

f:id:himanago:20170420105746p:plain

ということで実際にやってみたので、その流れをスクリーンショット交えて話しました。

LTでは時間の関係上端折った部分も補いつつ、以下書いていきたいと思います。

Azure VM作成

まずは、Azure VMWindows Server 2016の仮想マシンを作成します。
スマホに最適化されていないため、リージョン選択などやりにくい部分もありましたが、なんとかiPhoneSafariからAzureのVMを作ることができました。 f:id:himanago:20170420105804p:plain

リモートデスクトップアプリ

次に作ったVMへのリモート接続です。

Microsoft製のリモートデスクトップiOSアプリがあったので、それを使いました。

iPhone6sの小さな画面でWindows Serverをいじるのはどうなのかな…と思いましたが、ちゃんとズーム機能が備わっていて、慣れるとすいすい操作することができました。
f:id:himanago:20170420110211p:plain

Windows Server 2016自体がタッチ操作しやすいUIというところも手伝って、iPhoneからの操作はなかなか快適でした。

これは普通にサーバー管理するときにも使えそうな印象です。

Visual Studio 2017のインストール

最初につっかかったのがインストーラーのダウロードでした。

Windows Serverでは、デフォルトの設定のままではインターネットからファイルをダウンロードしたりできません。

Server ManagerのLocal Serverから、「IE Enhanced Security Configuration」をOffにしてあげる必要があります。 f:id:himanago:20170420122215j:plain

設定を変えると、ちゃんとVS2017のインストーラー(のインストーラー)がダウンロードできるようになります。
※ちゃんとサーバー運用する場合は、用が済んだら設定を戻す必要があります

さて、ダウンロードができたらいよいよVisual Studio 2017インストールです。

2017から、イントーラーが劇的な進化を遂げました。 必要なものを選んでインストールするのですが、このUIがとてもわかりやすくなっています。

今回はXamarinのみをインストールします。 f:id:himanago:20170420155655p:plain

Xamarin開発開始

いよいよ開発開始です。
通常通り、Xamarin.Formsのプロジェクトを作成します。 f:id:himanago:20170420155724p:plain

ちなみにWindows ServerではUWPの開発はできないようで、UWPのプロジェクトは作成されませんでした。

エミュレーターでの動作確認

PCが壊れる前、ローカルで試してたときはエミュレーターとしてXamarin Android Player使っていました。他のものと比べてかなり快適だったのでそれを入れたかったのですが、VM上でVirtualBoxが動かなかったので断念しました。

さらにVS EmulaterやHAXMも使用不可だったので、結局使えそうなのはARMエミュレーターのみに。

ARMエミュレーターを立ち上げてみました。 iPhoneの中のWindowsの中のAndroid…!なかなかに衝撃的な画です。
(ここがたぶんいちばんウケました) f:id:himanago:20170420161522p:plain

エミュレーターが立ち上がったのはいいのですが、肝心のXamarinでビルドしたアプリのデプロイに失敗してしまいました。

ARMのエミュレーターはものすごく重いので、おそらくタイムアウトしてしまったのだと思います。

VMのスペックを上げる

でもそこはAzure。

VMの性能をもっと上げてしまえばいいのです。

最初はケチってHDDで作っていたのをSSDにしたら無事動きました。 f:id:himanago:20170420161648p:plain

まとめ

ということで、PCレスでもXamarinはできる!ということが証明されました。

もちろん、実際にはこんな形で開発することはないとは思いますが、今回のようなある意味縛りプレイをやってみると、意外な気づきがあるのだな、と感じました。

f:id:himanago:20170420155940p:plain

この気づきがいつか何かに活きてくるといいなと思います。

追加:懇親会にていただいたアドバイス

LTを聞いていただいた方に、懇親会で「AzureにVM立ててやるなら、はじめからVisual Studioが入っているのを使うといいよ」という話をしていただきました。

なるほど、そういうものがあるんですね。

さっそくAzureを見てみました。

f:id:himanago:20170421181959p:plainf:id:himanago:20170421182311p:plain

いろいろな組み合わせが用意されています。
今回は「Visual Studio Community 2017 on Windows Server 2016」の組み合わせで試してみました。

作ってつないでみると、ちゃんとVisual Studio 2017が最初からインストールされてます!

f:id:himanago:20170421185742p:plain

なにやら他にもいろいろ入っているようだし、これならXamarinがすぐ使える!と思ったのですが、どうやらエミュレーターが用意されていないようです。

f:id:himanago:20170421213313p:plain

なので、Xamarinをやる場合はここに手間が余計にかかってしまうみたいですが、Unityなどもインストール済みのようなので、用途によってはこちらのほうが楽なのかもしれません。

LTを終えて

LT会の終了後、イベントのアンケート結果の中からLTの感想を共有いただいたのですが、その中に「ひらりんさんの面白かったです。」という感想がありました。

すっごくうれしいですね。当日もLT中みなさんにたくさん笑っていただけたので、とても楽しく話せました。

ほかにも「Xamarin+Azureに大きな未来を感じました」というコメントもありましたが、これ私のLTを聞いて…??

でも確かに、可能性は無限大ですね。

面白いことがたくさんできそうな組み合わせなのは事実。

いろいろな可能性を試していきたいです。

今回は初LTということであんまり余裕がなかったので登壇を楽しみきれなかったところがあるので、今度また何かしらで登壇できたらと思います。

そして、社内でも今年Xamarinセミナーをやるので、がんばります!

資料

資料はDocs.comにあげてみました。

そこまで需要ないと思いますが…ネタとしてお楽しみいただければと思います。

doc.co