Screaming Loud

日々是精進

AWScalaでIamRoleのクレデンシャルでクライアントに繋ぎたかった

本題の通りAWScalaを使っていて、IAMRoleを適用したかったんですが、InstanceProfileCredentialsProviderを埋めたS3Clientが作れず、困っていました。

やりたかったこと

local環境ではcredentialKeyを使い、prd環境ではIAMroleを使う ただし、複数のアカウントのS3を見ているため、一部credentialKeyを利用する必要がある。

問題点

単純に空でS3インスタンスを作成すれば、DefaultAwsCredentialsProviderChainから作成できる(以下参照)んですが、 Default empty constructor for AmazonS3Client (and others) · Issue #11 · seratch/AWScala · GitHub
lastUsedのクレデンシャルを使うので、IAMroleとクレデンシャルファイルを混ぜて使うことが出来ない。

対応

以下のように単純に親のSDKを型として指定してあげれば、うまくいきました。

  val credentailName = "hoge"
  protected implicit lazy val s3: AmazonS3 = {
    if (env == "local") {
      val credential = new ProfileCredentialsProvider(credentialName).getCredentials
      // AWScalaでクライアント作成
      S3(credential.getAWSAccessKeyId, credential.getAWSSecretKey)(Region.AP_NORTHEAST_1)
    } else {
      val credential: AWSCredentialsProvider = new InstanceProfileCredentialsProvider()
      val clientConfiguration = new ClientConfiguration
      clientConfiguration.setConnectionTimeout(30000)
      // AWSSDKの生のclientを作成
      new AmazonS3Client(credential, clientConfiguration)
    }
  }

AWScalaのS3はAWSSDKのAmazonS3を継承しているので、こうやって指定することができます。

まとめ

なんか単純なことですが、思考を柔軟にしないとだめですね。。

参考

マーケティングという内容で社内で話した

ついにGravityDaze2をクリアしたmoc_yutoです。 ストーリー的にはフラグ立てるところまでは良かったんですが、回収部分がちょっと物足りなかったです。 ただ、フィールドの自由度はすごかったです。

ということで本題ですが、本日エンジニアによるマーケティングというタイトルで社内LTで発表しました。

www.slideshare.net

エンジニアという職種は技術が優れるのはもちろんなのですが、 ちゃんとマーケティングしていくことも重要だなと感じることが多く、LTで発表しました。

その中でも今回伝えたかったこととしては、 「認知率×配荷率×好意度」 です。

どんなに技術的に優れていても、どんなに機能がたくさんあっても、 そもそも認知されていなければそのプロダクトは利用されないということです。

逆に認知されているなら、配荷率と好意度を上げていく必要があるということ。

当たり前なんですが、以下の本を読んでその認識を強めたのでオススメでした。

play2.4向けにi18n(国際化)をアップデートした話

概要

以前GlobalSettingの撲滅に関してブログを書きましたが、言語対応に関して書いていなかったので、続編ということでブログにまとめました。 yuutookun.hatenablog.com

前提

Play2.4移行の対応を以下スライドを参考に実施。 http://sssslide.com/speakerdeck.com/tsuyoshizawa/play-2-dot-3-kara-2-dot-4-heatupudetositahua

import play.api.play.current
import play.api.i18n.Messages.Implicits._

言語対応に関しては、上記のようにimportを追加して一旦対応していました。

コンパイルは通っていましたが、このままではCookieに対応される言語に変換 これでは翻訳が実行されていませんでした。

根本対応

以下の5ステップで対応を進めました。

1.コントローラーをInjectionの形に移行

変更前

object Account extends Controller

変更後

import javax.inject.Inject
class Account @Inject() () extends Controller 

このようにInjectionの形に修正

同時にroutesの設定を以下に変更

GET /accounts controllers.Accounts.index
GET /accounts @controllers.Accounts.index

2.DefaultMessageApiを継承した自前のmessageApiを作成

MeMessageApiを作ります。

package models

import javax.inject.{ Inject, Singleton }
import consts.AppConfig
import play.api.i18n.{ DefaultMessagesApi, Lang, Langs, Messages }
import play.api.mvc.RequestHeader
import play.api.{ Configuration, Environment }

@Singleton
class MyMessageApi @Inject() (
    environment: Environment,
    configuration: Configuration,
    langs: Langs) extends DefaultMessagesApi(environment, configuration, langs) {
  private lazy val cookieName = AppConfig.play.modules.i18n.langCookieName.toString

  override def preferred(request: RequestHeader) = {
    val langOp = request.cookies.get(cookieName).map(_.value)
    langOp.fold(super.preferred(request))(lang => new Messages(Lang(lang), this))
  }
}

3.MessageModuleを作成

作成したMyMessageApiをbindします。

package modules

import models.MyMessageApi
import play.api.i18n.{ DefaultLangs, Langs, MessagesApi }
import play.api.{ Configuration, Environment }
import play.api.inject.Module

class MyMessageModule extends Module {
  def bindings(environment: Environment, configuration: Configuration) = {
    Seq(
      bind[Langs].to[DefaultLangs],
      bind[MessagesApi].to[MyMessageApi] // instead of DefaultMyMessagesApi
    )
  }
}

4,confにそのmoduleを使う旨を記述

application.confなどに書きます。

play.modules.enabled += "modules.MyMessageModule"
play.modules.disabled += “play.api.i18n.I18nModule"

5,各controllerが継承している親クラスに対してI18nSupportを継承させ、messageApiをInjectさせる

import play.api.i18n.{ I18nSupport, Lang, Messages }
trait BaseController extends I18nSupport { }
class Account @Inject() (val messageApi: MessageApi) extends Controller extends BaseController

元々BaseControllerを継承させていたので、そのControllerにI18nSupportを継承させれば、全部動くので、この方式を取りました。 MessageApiを使うControllerが少ないのであれば、個別に継承させたほうがいいですね。

ここのMessageApiは型を変えなくてもconfでmodule指定をしているので、 自動でMyMessageModuleがDIされてきます。

以上が、i18nの対応です。

まとめ

Controllerが多いと改修範囲が大きいですが、 moduleの形で実装すればロジック的な改修範囲は最低限に抑えられるので、ぜひ挑戦してみてください。

参考URL

play2-i18n-patterns

5月の読書メーター

 

5月の読書メーター
読んだ本の数:2
読んだページ数:647
ナイス数:6

確率思考の戦略論  USJでも実証された数学マーケティングの力確率思考の戦略論 USJでも実証された数学マーケティングの力感想
非常に面白かった。苦悩を書いた物語としての側面、ブランドの構築、実際に利用していた分析のリアルな話、そして組織論へと。 とくにプロダクトの戦略として「好意度・認知・配荷」が最も重要な軸という話には気付かされた。 巻末に確率論がまとまっているので、ストーリーと数式が別々になっており、すごい読みやすかった。 マーケ担当だけでなく、ビジネスを思考する上で役に立つ本。
読了日:05月24日 著者:森岡 毅,今西 聖貴

 


HIGH OUTPUT MANAGEMENT(ハイアウトプット マネジメント) 人を育て、成果を最大にするマネジメントHIGH OUTPUT MANAGEMENT(ハイアウトプット マネジメント) 人を育て、成果を最大にするマネジメント感想
マネージャーとしてどのように振る舞うべきかとチームの構成をどうしていくかをインテルのCEOが書いた本。 「ワンオンワンによるメンバーとの対話」と「効率性を上げるためのハイブリッド組織とそれを運営するための二重所属」の部分に関してちょうど考えていた部分でもあり、参考になった。 実際工場のマネジメントなど製造業の話が強いので、情報通信系の場合だと少し期待した内容と違ってしまうかも。
読了日:05月04日 著者:アンドリュー・S・グローブ

読書メーター