日曜日, 8月 20, 2017

AWS NYC Summit 2017

AWS NY Summit 2017に参加した感想 ..

  • EC2からAWS ECSへの移行はこれからのトレンド? 確かにこれをするのは色々な意味で利点があるのは間違いなさそう.このマイグレーション後、AWSのビリングがほぼ半額になったという話も聞いたし,CrowdFormationをSparkleFormationとかで管理するのは以外にしんどい. 
  • ソリューションの展示で最も多かったのはやはりモニタリング関連とセキュリティレポーティングか. DynaTrace, DataDog, NewRelic等を見て回ったが,個人的にはDynaTraceは使ってみたいと思った. 会社ではNewRelicを使っており,これも悪くはないのだが.
  • 各種AWSコンポーネントの設定を含めたシステムのPCIコンプライアンスレポートとか,会社で使えたら嬉しいなぁ,と思ったので上司に薦めてみようと画策中.
  • 当然Aurora推し.Aurora - 確かに移行はしてみたくはなる.MySQLと互換性があるのはわかったが,本当にどのくらい互換性があるのか?ベンダロッキングに陥ることがなければ使わない手はなさそう.. ?

それ以外にもおいしいデザートやサラダをいただけたり等,大満足.
また来年が楽しみである.



日曜日, 9月 11, 2016

JavaとICMP

自作の自宅用メッセンジャーを作成中,Javaでネットワーク上の他のホストを検索するのにはInetAddress.isReachable()では十分ではない、という事実を今,知りました.

http://stackoverflow.com/questions/9922543/why-does-inetaddress-isreachable-return-false-when-i-can-ping-the-ip-address

仕方がないのでpingをコマンドライン経由で打つ羽目に.かなりいい加減な実装だがまあ最初のイテレーション(だけ)ではよいとする.


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Created by neko32 on 2016/09/11.
 */
public class Ping {

    private String resultCache = null;
    private static final Logger LOG = LoggerFactory.getLogger(Ping.class);

    public boolean isReachable() {
        if(resultCache == null)
            throw new IllegalStateException("run start() first");
        LOG.debug(resultCache);
        boolean decision = false;
        decision = resultCache.contains("(0%");
        if(resultCache.contains("unreachable") ||
           resultCache.contains("到達できません") ||
           resultCache.contains("timeout") ||
           resultCache.contains("タイムアウト")) {
            decision = false;
        }
        return decision;
    }

    public void start(final String destIP) throws IOException {
        final String cmd = String.format("ping %s", destIP);
        Process p = Runtime.getRuntime().exec(cmd);
        StringBuilder sb = new StringBuilder();
        try(InputStreamReader is = new InputStreamReader(p.getInputStream(), "MS932");
             BufferedReader br = new BufferedReader(is)) {
            String line = null;
            while((line = br.readLine()) != null) {
                sb.append(line);
            }
        }
        resultCache = sb.toString();
    }

}


こちらはそのユニットテスト.
mport org.scalatest.{GivenWhenThen, FeatureSpec}
import org.tanuneko.im.net.util.Ping

/**
  * Created by neko32 on 2016/09/11.
  */
class PingSpec extends FeatureSpec with GivenWhenThen {

  info("Ping is a small utility to run ping through command line.")
  info("Because InetAddress.isReachable() doesn't rely on actual ping but ECHO(TCP 7), not reliable")

  feature("Ping") {
    scenario("Ping succeeds against known ip address(local loopback)") {
      When("Ping is executed")

      val ping = new Ping
      ping.start("127.0.0.1")

      Then("Ping should succeed")
      assert(ping.isReachable)

    }
  }

  feature("Ping") {
    scenario("Ping fails against unknown ip address") {
      When("Ping is executed")

      val ping = new Ping
      ping.start("3.99.156.254")

      Then("Ping should fail")
      assert(!ping.isReachable)

    }
  }

}

月曜日, 5月 30, 2016

Gradle - マルチプロジェクト

最近は専らmavenよりもgradleを使っている.近年はmake, ant,maven, sbtと比較的短期間で様々なビルドツールを使わざるを得なかったことに食傷気味ではあったが,gradleをいざ使ってみると,mavenやantの冗長なコンフィグからの脱却や拡張性の高さがすぐに気に入った.

以下はgradleでmavenのようなマルチモジュールのプロジェクトを定義した例.
以下の例では親プロジェクトが"tanu-im",子モジュールとして"desktop-ui"と"core"を想定している.

1. settings.gradleにはプロジェクトの定義を書く

rootProject.name = 'tanu-im'

include 'core'
include 'desktop-ui'

2. ルートプロジェクト直下のbuild.gradle. dependencyManagementを使いたいので,spring-gradleのdependency-managementプラグインを追加.
group 'org.tanuneko.im'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'io.spring.gradle:dependency-management-plugin:0.5.6.RELEASE'
    }
}

3. common.gradleとdependencies.gradleの作成 共通の処理をcommon.gradle,プロジェクトの依存ライブラリをdependencies.gradleに定義.

common.gradle
// apply plugin here
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
apply from: "${rootProject.projectDir}/gradle/dependencies.gradle"

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies.gradle

repositories {
    mavenCentral()
}

project.ext {
    // spring
    springVersion = '4.2.6.RELEASE'
    // JSON
    jacksonVersion = '2.7.1'
    // unit test
    junitVersion = '4.11'
    hamcrestVersion = '1.3'
    // util
    commonsLang3Version = '3.4'
    commonsIOVersion = '2.4'
    // logging
    slf4jVersion = '1.7.21'
    logbackVersion = '1.1.5'
}

dependencyManagement {

    dependencies {
        // spring
        dependency "org.springframework:spring-core:${springVersion}"
        dependency "org.springframework:spring-test:${springVersion}"

        // JSON
        dependency "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
        dependency "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}"

        // unit test
        dependency "junit:junit:${junitVersion}"
        dependency "org.hamcrest:hamcrest-all:${hamcrestVersion}"

        // util
        dependency "org.apache.commons:commons-lang3:${commonsLang3Version}"
        dependency "commons-io:commons-io:${commonsIOVersion}"

        // logging
        dependency "ch.qos.logback:logback-classic:${logbackVersion}"
        dependency "org.slf4j:slf4j-api:${slf4jVersion}"
    }
}

dependencies {
    compile 'org.slf4j:slf4j-api'
    testCompile 'junit:junit'
    testCompile 'ch.qos.logback:logback-classic'
}

4. 子モジュールの作成.ルートプロジェクト直下に"core", "desktop-ui"のディレクトリを作ったのち,mavenスタンダードアーキタイプの構成を作る(e.g. src/[main|test]/[java|resources].
5. build.gradleを子モジュールのルートに作成.ここには子モジュール独自の依存関係や処理を定義.

日曜日, 3月 06, 2016

Java - Retrofit RESTクライアント

Javaにはいまいち使い勝手の良いRESTクライアントは無かった。。と思うが,最近話題になっているRetrofit2は非常に使い勝手が良いように思える.
以下の例は統合テストにおいてlocalhost:9099/beanmgrに対してGETのリクエストを投げる例.

サービスインターフェース定義
package org.tanuneko;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;

/**
 * Created by neko32 on 2016/03/06.
 */
public interface WebInterfaceIF {

    @GET("tanubean/{id}")
    public Call<TanuBean> getNeko(@Path("id") int id);

    @POST("tanubean")
    public Call<TanuResponse> createNeko(@Body TanuBean bean);

}

統合テストからサービスインタフェース経由でGETリクエストを出す
    @Test
    public void testTanuAppWithRetroFit() throws IOException {

        Retrofit retro = new Retrofit.Builder()
                .baseUrl("http://localhost:9099/beanmgr/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        WebInterfaceIF service = retro.create(WebInterfaceIF.class);
        Call<TanuBean> tanu = service.getNeko(1);
        TanuBean t = tanu.execute().body();
        System.out.println("Retrived - id:" + t.getId() + ",name:" + t.getName());
        assertThat(t.getId(), is(1));
        assertThat(t.getName(), is("Tanuchan"));
    }


日曜日, 2月 07, 2016

Scala - 初めてのAkka - アクター

最近の流行りはどうやらreactive programming..らしく.. というか別に新しいものじゃない..old wine in a new bottleの典型例ではないか...
憤る気分を抑えながらもakkaを試してみた.
以下の例は単純なアクターをつくった例.私が読んだ本でakkaが紹介されているが,そのサンプルはakkaの非同期的性質を無視した代物であり,ランダムに失敗する.というわけで,以下の例は汚く危ない例ではあるがフェイルはしないようフラグを付けたもの.フラグを外すと,メッセージが到着する前にActorSystemが閉じることもある為,ランダムにdead letter のエラーが出るだろう.
import akka.actor.{Actor, ActorSystem, Props}
import akka.event.Logging

/**
  * Created by neko32 on 2016/02/07.
  */

object HelloActor {
  var flag = false
}

class HelloActor(processId:Int, processName:String) extends Actor {

  val log = Logging(context.system, this)
  def receive = {
    case "hello" => { log.info(s"[HELLO@${processName}:${processId}]"); println("Konnitiwa!");HelloActor.flag = true }
    case _ => { log.info(s"[UNKNOWN@${processName}:${processId}]"); println("..."); }
  }
}

object Runner extends App {

  val sys = ActorSystem("HelloSystem")
  val helloActor = sys.actorOf(Props(new HelloActor(1, "Tanuki")), name = "helloActor")
  helloActor ! "muimui!"
  helloActor ! "RUirui!"
  helloActor ! "hello"
  while(!HelloActor.flag) {
    Thread.sleep(1000)
  }
  sys.shutdown

}

月曜日, 1月 18, 2016

Spark - StatsCounter

StatsCounterを使えば簡単に統計用の基本的な値を計算できる.

import org.apache.spark.{SparkContext, SparkConf}

/**
  * Created by neko32 on 2016/01/18.
  */
object Stats {

  def main(args:Array[String]) = {
    val conf = new SparkConf().setMaster("local").setAppName("stats")
    val sc = new SparkContext(conf)
    val rdd = sc.textFile("/user/neko32/spark/study7/nums.txt")
    val stats = rdd.flatMap(l => l.split(":")(1).split(" ").map(_.toInt)).stats
    println(s"mean:${stats.mean}, max:${stats.max}, min:${stats.min}, var:${stats.variance}")
  }
}

Spark - パーティション単位でのマップ

PairRDDのpartitionBy()を使ってパーティション毎の要素の合計を計算をする例.
入力ファイルは以下のようなキーバリューの対とする.また,バリューはスペース区切りの整数の列とする.

lineA:73 44 58 62
lineAB:88 21 20
lineABC:50 21 99 82 25 62

import org.apache.spark.{Partitioner, SparkConf, SparkContext}

/**
  * Created by neko32 on 2016/01/17.
  */
object CalcPart {

  def main(args:Array[String]) = {
    val conf = new SparkConf().setMaster("local").setAppName("Takoran")
    val sc = new SparkContext(conf)
    val data =  sc.textFile("/user/neko32/spark/study7/nums.txt")
          .map(l => {
            val splitted = l.split(":")
            (splitted(0), splitted(1).split(" "))
          })
    data.partitionBy(new OddEvenPartitioner(2)).persist

    data.foreach(elem => {
      val buf = new StringBuilder
      buf ++= "key[" + elem._1 + "]:"
      elem._2.foreach(n => buf ++= (n + " "))
      println(buf.toString)
    })

    val x = data.mapPartitions(iter => {
        val nums = iter.map(x => (x._1, x._2.foldLeft(0)(_ + _.toInt)))
        nums
      }
    )

    x foreach println
    for(x <- x collect) {
      println(s"${x._1}:${x._2}")
    }
  }
}

class OddEvenPartitioner(nums:Int) extends Partitioner {
  override def numPartitions: Int = nums

  override def getPartition(key: Any): Int = {
    val n = key.asInstanceOf[String].length
    n % 2
  }

  override def equals(others: Any) = others match {
    case o:OddEvenPartitioner => o.numPartitions == this.numPartitions
    case _ => false
  }
}

金曜日, 1月 15, 2016

Scala - JSONの作成

以下の例はPlay frameworkのJSONライブラリを使ってJSONを作った例.
Scalaの型から作られたJSONをJson.parse()を使ってまたJSON化もしている.

import play.api.libs.json._
/**
  * Created by neko32 on 2016/01/15.
  */
object JsonSample {

  def main(args:Array[String]) = {
    val mine = Json.obj("name" -> "tanuchan", "age" -> 5, "Nekoz" -> Json.arr("Chatora", "Mikeneko", "Snowball"))
    println(mine.toString)
  }

}

SBTには以下を追加.
libraryDependencies ++= Seq("com.typesafe.play" %% "play-json" % "2.4.6")