[SORACOM SDK for Ruby]SIMの設定を行う内部DSLを書いてみた

2015.12.14

はじめに

以前の記事に引き続き、SORACOM SDK for Rubyを触ってみました。今回はSIMの設定を行う内部DSLを書いてみました。

作成したサンプルプログラム

設定ファイル

まずは今回作成した内部DSLによる設定ファイルです。ここにSIMの設定を記述し、rubyコマンドで実行します。

test_settings.rb
require_relative "subscriber_dsl_helper"

subscriber "Sample SIM" do
  imsi "440xxxxxxxxxxxx"              # 設定対象のSIMのimsi
  group_name "sample_group"           # グループ名
  speed_class "s1.minimum"            # 速度クラス
  activate false                      # 開始/休止(true/false)
  expiry_time "2016/12/31 23:59:59"   # 有効期限
end

設定対象のSIM毎にブロックを作成し、SIMのIMSIや設定項目を記述しています。SORACOM SDK for Rubyを直接使用すると、SIMの開始や休止は異なるメソッドを呼び出す必要があることや、有効期限をUTCのミリ秒で指定する必要があるのですが、それらが隠蔽化してみました。設定ファイルとして見ると、多少は分かり易くなったかと思います。

ヘルパーファイル

先の設定ファイルの一行目でrequireしている「subscriber_dsl_helper」になります。このファイルに記述している内容を設定ファイルに直接記述してもいいのですが、設定ファイルに記述する量を少なくするため、敢えてヘルパーファイルとして切り出しました。

subscriber_dsl_helper.rb
require_relative "subscriber_dsl"
include SubscriberDsl

実行ファイル

「実行ファイル」という呼び名が正しいかは疑問ですが、上記の設定ファイルを解釈し、実際に設定を行う処理についてです。スコープを限定するためmoduleを宣言し、先のヘルパーファイル内でincludeして使用するようにしています。

subscriber_dsl.rb
require 'soracom'
require 'time'

module SubscriberDsl
  def subscriber(block_name)
    puts block_name + " setting start."
    yield
    puts block_name + " setting success."
  end

  def imsi(imsi)
    @imsi = imsi
  end

  def group_name(group_name)
    validate
    group_id = get_group_id(group_name)
    client.set_group(@imsi, group_id)
  end

  def speed_class(speed_class_name)
    validate
    client.update_subscriber_speed_class(@imsi, speed_class_name)
  end

  def activate(is_activate)
    validate

    if is_activate
      client.activate_subscriber(@imsi)
    else
      client.deactivate_subscriber(@imsi)
    end
  end

  def expiry_time(yyyy_mm_dd_hh_mm_ss)
    t = Time.parse(yyyy_mm_dd_hh_mm_ss).instance_eval { self.to_i * 1000 + (usec/1000) }
    client.set_expiry_time(@imsi, t.to_i)
  end

  private

  def validate
    fail "you have to set imsi." if !@imsi

    subscribers = client.subscribers
    fail "imsi is wrong." if subscribers.select{|subscriber| subscriber['imsi'] == @imsi}.count == 0
  end

  def get_group_id(group_name)
    groups = client.list_groups(nil)

    groups.each do |group|
      return group['groupId'] if groups.select{|group| group['tags']['name'] == group_name}.count == 1
    end

    fail "group_name undefined."
  end

  def client
    @client ||= Soracom::Client.new
  end
end

先頭のsubscriber()メソッドでyieldを呼び出し、設定ファイルより渡されるブロックを実行しています。実際の設定処理はメソッドとして記述してあり、それぞれがSORACOM SDK for RubyのSoracom::Clientのメソッド呼び出し、各種の設定を行っています。

先にも書いたように、SIMの開始・休止には異なるメソッドを呼び出す必要があります。これを隠蔽化しているのがactivate()メソッドで、単純に引数のtrue/falseで呼び出すメソッドを切り替えています。

また有効期限を設定するexpiry_time()メソッドでは、設定ファイルで指定した日時よりUTCのミリ秒を取得してSDKのメソッドに渡しています。

validate()に関しては・・・、IMSIの指定チェック・存在チェックしか行っていません。実運用ではもっと細かいチェックが必要だと思われます。

Gemfile

最後にGemfileです。とはいっても今回はSORACOM SDK for Rubyを指定しているだけです。

Gemfile
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
gem 'soracom'

まとめ

以上、簡単ですがSORACOM SDK for Rubyを使用した内部DSLの例でした。Rubyという言語のDSLの作成のし易さ、SORACOM SDK for RubyでSIM(だけではないが)の設定が自在にできることを組み合わせると、色々なことができそうです。

参考サイト

以下のサイトを参考にさせて頂きました。ありがとうございました。
API Reference
Time.nowにミリ秒単位を追加する [Ruby]
スタック・オーバーフロー