2020/07/06

Jestで時刻を固定化する方法


背景


Node.jsで動作するサーバーアプリのユニットテストコードをJestで作成するため、Jestの使用方法について調査した。

記事の目的


Jestで時刻を固定する

Date関数 / moment関数


ここでは、Date関数 / moment関数について記載する。

Date関数とは

Date関数は、Javascript標準の時刻モジュールである。現在時刻の取得などが行える。

moment関数とは

moment関数は、Date関数のラッパーであり、時刻差の計算などの機能が付与されている。

時刻の固定


時刻固定の必要性

ある関数やクラスのユニットテストを実行する際、堅牢性確認のため、閏年や特定の時刻でバグが出現しないか確認する必要がある。

時刻の固定方法

MockDateモジュールで時刻を固定できる。

/test/date.test.ts
import MockDate from "mockdate";
import moment from "moment";

describe("時刻の固定化", () => {
    beforeAll(() => {
        // JSTで時刻を固定できる
        MockDate.set("2019-08-01 21:00:00");
    });

    afterAll(() => {
        // 時刻の固定を解除する
        MockDate.reset();
    });

    test("Dateは固定時刻の文字列を返す", () => {
        const time = new Date();
        expect(time.toISOString()).toBe("2019-08-01T12:00:00.000Z");
    });
    test("momentはDateのラッパーなため、固定時刻を返す", () => {
        expect(moment().toISOString()).toBe("2019-08-01T12:00:00.000Z");
    });
  });

まとめ


  • Jestで時刻を固定する方法について調査、記載した

参考文献




変更履歴


  1. 2020/07/06: 新規作成

2020/07/01

Jestで関数、クラスをMockする方法


背景


Node.jsで動作するサーバーアプリのユニットテストコードをJestで作成するため、Jestの使用方法について調査した。

記事の目的


Jestで関数やクラス全体、クラスのメソッドの一部をMockする

Jest


ここでは、Jestについて記載する。

Jestとは

Jestは、Facebookが開発を進めている、オープンソースのJavaScriptのテストフレームワークである。TypeScriptで記述したものでも利用できる。テストフレームワークであるため、テストを書くために必要な一通りの機能(メソッドのMock機能、コードカバレッジレポート機能等)が提供されている。

Mock


Mockとは

ある関数やクラスのユニットテストを実行する際、それらが依存している外部モジュールの挙動によって実行結果が変化することは不適切である。そこで、外部モジュールを、一定の実行結果がモジュールに差し替える。この差し替えたモジュールをMockと言う。

関数のMock

/src/function.ts
/**
 * 入力した数値を文字列に変換する
 * @param input 数値
 * @returns output 文字列
 **/
export async function SampleFanc(input: number): Promise<string> {
    return String<input>;
}
/**
 * 入力した数値に1を足し、文字列に変換する
 * @param input 数値
 * @returns output 文字列
 **/
export async function SampleFanc2(input: number): Promise<string> {
    const out = SampleFanc(input+1);
    return out;
}
上記の関数sampleFancをMockし、sampleFanc2をテストする場合、下記のようになる。

/test/function.test.ts
import * as sampleFanc from "../src/function.ts";

describe("SampleFancのモック化テスト", () => {
    it("モック化できているか", () => {
        // spyOnすることによって、該当関数(SampleFanc)の型がspyInplementationに変化する
        // mockReturnValueOnce()によって1度だけ設定値を返す関数にMockできる
        // jest.spyOnだけでは、実際の関数(Mockされていない関数)が実行されるので注意
        const sampleSpy = jest.spyOn(sampleFanc , "SampleFanc").mockReturnValueOnce("1");

        // SampleFanc2の実行、返り値が"2"でなければNG
        expect(sampleFanc.sampleFanc2(1)).toBe("2");
        // SampleSpyが1回以上呼ばれたかを確認、呼ばれていない場合NG
        expect(SampleSpy).toHaveBeenCalled();
    });
});
}


クラス全体のMock

/src/class.ts
/**
 * 入力した数値を文字列に変換する
 * @param input 数値
 * @returns output 文字列
 **/
export class SampleClass {
    private data: string;
    /**
     * 空文字列をセット
     */
    constructor() {
        this.data= "";
    }
    /**
     * 入力された文字列をキャッシュし、前の文字列を返す
     * @param input キャッシュする文字列
     * @returns output キャッシュされていた文字列
     */
    public Func1(input: string): string {
        const output = this.data;
        this.data = input;
        return output;
    }
    /**
     * 入力された数値を文字列に変換してキャッシュし、前の文字列を返す
     * @param input キャッシュする数値
     * @returns output キャッシュされていた文字列
     */
    public Func2(input: number): string {
        const output = this.Func1(String(input));
        return output;
    }
}
上記のクラスsampleClassをMockする場合、下記のようになる。

/test/function.test.ts
import * as sampleClass from "../src/class.ts";

// jest.mock()によってクラス全体をモック化できます
jest.mock("../src/class.ts"); // パスを指定
const SampleClassMock = sampleClass.SampleClass as jest.Mock; // TypeScriptでは型変換する必要がある

describe("SampleClass のテスト", () => {
    it("クラス全体がモックになっているか確認", () => {
        // mockImplementationOnceで実装したいクラスを設定する
        SampleClassMock.mockImplementationOnce(() => {
            return {
                data: "1",
                Func1: (): string => {
                    return "2";
                },
                Func2: (): string => {
                    return "3";
                },
            };
        });

        const sample = new sampleClass.SampleClass();
        // SampleClassMockが1度以上呼び出されたか確認
        expect(SampleClassMock).toHaveBeenCalled();
        // プライベート変数"name"が"1"であるか確認
        expect(sample["data"]).toBe("1");
        // メソッドFunc1が"2"を返すか確認
        expect(sample.Func1("1")).toBe("2");
        // メソッドFunc2が"3"を返すか確認
        expect(sample.Func2(1)).toBe("3");
    });
});

クラスの一部をMock

/src/class.ts
/**
 * 入力した数値を文字列に変換する
 * @param input 数値
 * @returns output 文字列
 **/
export class SampleClass {
    private data: string;
    /**
     * 空文字列をセット
     */
    constructor() {
        this.data= "";
    }
    /**
     * 入力された文字列をキャッシュし、前の文字列を返す
     * @param input キャッシュする文字列
     * @returns output キャッシュされていた文字列
     */
    public Func1(input: string): string {
        const output = this.data;
        this.data = input;
        return output;
    }
    /**
     * 入力された数値を文字列に変換してキャッシュし、前の文字列を返す
     * @param input キャッシュする数値
     * @returns output キャッシュされていた文字列
     */
    public Func2(input: number): string {
        const output = this.Func1(String(input));
        return output;
    }
}
上記のクラスsampleClassのFunc1のみをMockする場合、下記のようになる。

/test/function.test.ts
import * as sampleClass from "../src/class";

describe("SampleClass のテスト", () => {
    it("Func1がモックになっているか確認", () => {
        // SampleClass.prototypeのfunc1関数をspyOnすることで、func1関数のモック化ができる
        const Func1Spy = jest.spyOn(sampleClass.SampleClass.prototype, "Func1").mockReturnValue("2");

        const sample = new sampleClass.SampleClass();
        // Func2の実行結果が"2"であるか確認
        expect(sample.Func2(1)).toBe("2");
        // Func1Spy が1度以上呼び出されたか確認
        expect(Func1Spy).toHaveBeenCalled();
    });
});

まとめ


  • Jestで関数やクラス全体、クラスのメソッドの一部をMockする方法について調査、記載した

参考文献




変更履歴


  1. 2020/07/01: 新規作成

2020/06/05

node.jsでdotenvを読みだせない場合の対処法


背景


Node.jsのアプリを起動する際、「.env」ファイルが読み込めない場合があったため、対処法を含めdotenvについて調査した。

記事の目的


Node.jsでアプリ起動時に.envの環境変数を読み込む

.env


ここでは、.envの環境変数を読み込む方法について記載する。

process.env

Node.jsで環境変数を扱いたいときは、process.envオブジェクトを参照する。process モジュールはデフォルトで使用可能になっているので、requireする必要はない。
$ node
> process.env
{
  ...
  OS: 'Ubuntu'
  Path: '...',
  ...
}

dotenv

dotenvモジュールを使用すると、カレントディレクトリに置かれた.env ファイルを読み込み、そこに記述されたkeyとvalueのペアをprocess.env経由で参照できる。
  1. dotenvモジュールのインストール
  2. $ npm install dotenv
    $ npm install dotenv --save
  3. .envファイルの作成
  4. # コメント
    KEY1=VALUE1
    KEY2=VALUE2
    KEY3=VALUE3
  5. dotenvの呼び出し
    • js内でのdotenvの呼び出し
    • 下記をjsファイル内に記述(非推奨)
      require('dotenv').config();
    • 起動時にdotenvの呼び出し
    • 起動時に、-r dotenv/config オプションをつける
      $ node -r dotenv/config app.js

備考


  • .envファイルの読み込みは推奨されていないため、js内でのdotenvの呼び出しは行わない方が良い
  • 理由: 環境変数がアプリの設定ファイルのように扱われることを防ぐため


まとめ


  • Node.jsでアプリ起動時に.envの環境変数を読み込む方法について調査、記載した

参考文献




変更履歴


  1. 2020/06/05: 新規作成

2020/06/02

Spinxでドキュメントを作成する方法

背景


開発ドキュメントを作成する際、Gitで差分管理ができ、HTML(Web経由でチーム内情報共有用)とPDF(チーム外向けアウトプット用)で出力ができるドキュメント作成ツールが必要となった。調査の結果、Sphinxが上記用途に最適だったてめ、使用方法をまとめた。

記事の目的


Sphinxでドキュメントを作成する

Sphinx


ここでは、Sphinxについて記載する。

Sphinxとは


Sphinxはオープンソースのドキュメント生成ツールである。reST(reStructuredText)と呼ばれる形式で記述したテキストファイルからHTMLやpdfなど様々な形式のドキュメントを生成できる。Pythonのドキュメントにも用いられている。

利点

  • reST(reStructuredText)と呼ばれるテキストファイルでき、差分管理が容易である
  • 章や節ごとに分かれた読みやすいHTMLが生成される
  • PDFやePubなど、様々なファイルに出力可能

Sphinxの導入



インストール

  1. Sphinxのインストール
    • aptを使用する場合(Pythonはインストールしない場合)
      1. Sphinxをインストール
      2. $sudo apt install python-sphinx
    • pipを使用する場合
      1. Python、pipのインストール
      2. pyenv等を利用し、Pythonをインストール
      3. Sphinxのインストール
      4. $pip install sphinx
  2. (オプション)PDF出力を可能にするため、Tex Liveをインストール
  3. $sudo apt install texlive-full
    ※容量が大きい(5Gbyte近い)ため注意

テンプレートのパッケージ構成


sphinx-quickstartコマンドで、sphinxのプロジェクトを生成できる
$ sphinx-quickstart
Welcome to the Sphinx 1.8.5 quickstart utility.

Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).

Selected root path: . # ドキュメントのルートパス(省略時は今の場所となる)

You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Separate source and build directories (y/n) [n]: y

Inside the root directory, two more directories will be created; "_templates"
for custom HTML templates and "_static" for custom stylesheets and other static
files. You can enter another prefix (such as ".") to replace the underscore.
> Name prefix for templates and static dir [_]:
# ソースと、ビルド結果のフォルダを完全に分けるかどうかを決定する。
# デフォルトはソースのフォルダ内に_buildディレクトリができる。

The project name will occur in several places in the built documentation.
> Project name: test_document # プロジェクトの名前
> Author name(s): emptyset # プロジェクトの著者
> Project release []: 1.0.0 # リリース番号

If the documents are to be written in a language other than English,
you can select a language here by its language code. Sphinx will then
translate text that it generates into that language.

For a list of supported codes, see
http://sphinx-doc.org/config.html#confval-language.
> Project language [en]: ja # 言語(en: 英語, ja: 日本語)

The file name suffix for source files. Commonly, this is either ".txt"
or ".rst".  Only files with this suffix are considered documents.
> Source file suffix [.rst]: # ソースファイルの拡張子(デフォルトはrst: Rest)

One document is special in that it is considered the top node of the
"contents tree", that is, it is the root of the hierarchical structure
of the documents. Normally, this is "index", but if your "index"
document is a custom template, you can also set this to another filename.
> Name of your master document (without suffix) [index]: # トップページのファイル名(デフォルトはindex)
Indicate which of the following Sphinx extensions should be enabled:
> autodoc: automatically insert docstrings from modules (y/n) [n]: n # docstringでドキュメントが書かれているモジュールのドキュメントを自動生成する
> doctest: automatically test code snippets in doctest blocks (y/n) [n]: y # doctestを用いて、モジュールのテストを行うか設定する
> intersphinx: link between Sphinx documentation of different projects (y/n) [n]: y # 他のプロジェクトへのリンクを自動生成する
> todo: write "todo" entries that can be shown or hidden on build (y/n) [n]: y # .. todo::などと記載すると、todo表示ができる
> coverage: checks for documentation coverage (y/n) [n]: n # ドキュメントのカバレッジ状況を自動で抽出する
> imgmath: include math, rendered as PNG or SVG images (y/n) [n]: y # LaTeX と dvipng または dvisvg を用いて数式を生成する
> mathjax: include math, rendered in the browser by MathJax (y/n) [n]: y # Mathjaxを用いて数式を生成する
> ifconfig: conditional inclusion of content based on config values (y/n) [n]: n # 設定にしたがってコンテンツ表示を切り替えられる
> viewcode: include links to the source code of documented Python objects (y/n) [n]: n # Pythonのオブジェクトを探索し、ソースコードをHTMLで出力する
> githubpages: create .nojekyll file to publish the document on GitHub pages (y/n) [n]: n # GitHub Pagesで公開するために、 .nojekyll ファイルを作成する
Note: imgmath and mathjax cannot be enabled at the same time. imgmath has been deselected.

A Makefile and a Windows command file can be generated for you so that you
only have to run e.g. 'make html' instead of invoking sphinx-build
directly.
> Create Makefile? (y/n) [y]: y # # ビルド用のバッチファイルを作るかどうかを決定する
> Create Windows command file? (y/n) [y]: y # ビルド用のバッチファイルを作るかどうかを決定する

Creating file ./source/conf.py.
Creating file ./source/index.rst.
Creating file ./Makefile.
Creating file ./make.bat.

Finished: An initial directory structure has been created.

You should now populate your master file ./source/index.rst and create other documentation
source files. Use the Makefile to build the docs, like so:
   make builder
where "builder" is one of the supported builders, e.g. html, latex or linkcheck.

Sphinxでドキュメントを作成するための最小構成
$ tree
.
├── Makefile # コンパイル用のスクリプト(Linux用)
├── build # コンパイルした結果(HTML,PDF)の出力先
|  ├── html # HTMLの出力先
|  └── latex # PDFの出力先
├── make.bat # コンパイル用のスクリプト(Windows用)
└── source # ソースコード
    ├── _static # アイコン画像などのテンプレート部品保管先
    ├── _templates # テーマのテンプレート保管先
    ├── conf.py # コンパイルの設定ファイル
    ├── index.rst # トップページ
    └── pages # ページ格納
      └── page1.rst # ページ1  

HTMLファイル出力のための設定

テンプレートのpackage.jsonファイルを記載する。
  1. テーマを変更
    1. テーマを選択
    2. Sphinxには様々なレイアウトのテーマが存在する(ここを参照)
    3. テーマをインストール
    4. $pip install stanford_theme
      ここでは、stanford_themeを使用する。
    5. テーマを設定
    6. conf.pyを編集
      import stanford_theme
      # html_themaを変更
      html_theme = "stanford_theme"
      # html_theme_pathを追加
      html_theme_path = [stanford_theme.get_html_theme_path()]
  2. html形式でbuildする
  3. $ cd 
    $ sphinx-build -b html source build/html

PDFファイル出力のための設定

テンプレートのpackage.jsonファイルを記載する。
  1. pdf形式でbuildする
  2. $ cd 
    $ make latexpdf

ページを追加


ページの作成、目次に追加する方法について記載する。
  1. ページを作成
  2. page1.rst
    ###########################
    page1
    ###########################
    
    | Test page!
  3. index.rstにページを追加
  4. .. toctree::
       :maxdepth: 2
       :caption: OverView
       :numbered:
    
       /pages/page1

まとめ


  • Sphinxでドキュメントを作成する方法を調査、記載した

参考文献



変更履歴


  1. 2020/06/02: 新規作成

2020/05/31

CPU温度を取得するスクリプトを作成(Linux)

背景


PCでのソフトウェアのヒートランを行った際、CPUの温度をモニタリングする必要があったため、スクリプトを作成した。

記事の目的


CPUの温度を取得するスクリプトを作成する

lm-sensors


ここでは、CPUの温度を取得するスクリプトの記述方法について記載する。

必要パッケージの導入

CPUの温度を取得するために必要なパッケージをインストールする
sudo apt install lm-sensors

スクリプトの作成方法

スクリプトの作成方法は以下の通りである。
  1. スクリプトcpu_temperature_monitoring.shを作成する
  2. #!/bin/bash
    echo "Start to record CPU temperature!"
    DIR_NAME=~/cpu_temperature_log/`date +%Y%m%d`
    LOG_NAME=./`date +%Y%m%d_%H%M%S`_cpu_temperature.log
    mkdir -p $DIR_NAME
    cd $DIR_NAME
    echo "Date,Temperature[C]" >> $LOG_NAME
    while :
    do
        sensors | grep "Core 0:" | grep -o [+-][0-9][0-9][.][0-9] | awk '{ "date +\"%Y/%m/%d %T\"" | getline var; print var "," $0 }' >> $LOG_NAME
        sleep 1
    done
    exit 0
  3. スクリプトに実行権限を与える
  4. $ chmod 777 ./cpu_temperature_monitoring.sh 

スクリプトの実行方法

実行方法は以下の通りである。
$ ./cpu_temperature_monitoring.sh
Start to record CPU temperature!
~/cpu_temperature_monitoring_log/日付/にCPU温度のログが作成される
$ less ./cpu_temperature_log/20190923/20190923_234227_cpu_temperature.log
Date,Temperature[C]
2019/09/23 23:42:27,+51.0
2019/09/23 23:42:28,+51.0
2019/09/23 23:42:29,+51.0
2019/09/23 23:42:30,+52.0

備考

  • grepで特定の文字列だけを抽出するオプションは、-o

まとめ


  • CPUの温度を取得するスクリプトを作成した

参考文献



変更履歴


  1. 2020/05/31: 新規作成

2020/05/24

内部仕様書のテンプレート

背景


仕事の中でシステムやソフトウェアの開発を行う際、内部仕様書を書く機会が増えてきたので、外部仕様書に必要な項目をまとめた。


記事の目的


内部仕様書を効率的に作成するため、内部仕様書のテンプレートを作成する


内部仕様書とは


内部仕様書は、詳細設計とも呼ばれている。外部仕様書の目的は、複数名で開発を行う場合、外部設計の結果を受けて効率的に実装作業を行えるように実装内容を整理することである。


内部仕様書の全体構成



外部仕様書の船体構成は、下記の通りである。
  • クラス図
  • システムを構成するクラスとクラス間の関係を表す。
  • 内部データ
  • システム内部で使用するデータ一覧(データ名、データ型、データ長、その他制約)について記載する。
  • 機能
  • 下記の項目を機能毎に作成する。
    1. 機能名
    2. 機能名を記載する。
    3. 入出力値
    4. 入出力値のデータ名、データ型、データ長、その他制約について記載する。
    5. 他の機能モジュールとの関係性
    6. 他の機能モジュールとの関連性(データの流れ、データ名)について記載する。
    7. アクティビティ図
    8. 処理内容をアクティビティ図で記載する。
    9. シーケンス図
    10. 処理詳細をシーケンス図で記載する。


まとめ


  • 内部仕様書のテンプレートに関して記述した


参考文献




変更履歴


  1. 2020/05/24: 新規作成



2020/05/23

ROSでcatkin_makeする際にundefined referenceが出る原因まとめ

背景


ROS melodicでOSSパッケージを利用した開発を行う中で、make時にundefined reference to...(に対する定義されていない参照です)のエラーが発生する場合があったため、原因をまとめておく。

記事の目的


ROSのOSSパッケージを利用する際、make時にundefined reference to...のエラーが出る原因をまとめる

undefined reference


現象

GitHubでOSSのパッケージをcloneしてcatkin_makeする際、下記のようなエラーが出る場合がある
$ catkin_make ...
...
/opt/ros/melodic/lib/libtf.so: undefined reference to tf2_ros::TransformListener::TransformListener(tf2::BufferCore&, ros::NodeHandle const&, bool)'
collect2: error: ld returned 1 exit status
...

原因

原因として、下記が考えられる。
  • OSSパッケージのバージョン違い
  • rosには、ディストリビューション毎にバージョンが変更され、tfなどの標準パッケージの仕様が変更される場合がある。 よって、git cloneしたパッケージのバージョンが異なると、make時にエラーとなる場合がある。

対処方法

  • OSSパッケージのバージョン違い
  • OSSパッケージのgitブランチを確認し、バージョンを合わせる
    1. ブランチを確認する
    2. $ cd < OSSパッケージののルートディレクトリ >
      $ git branch
      noetic-devel # ros noetic用のブランチ
    3. ブランチを変更する
    4. $ git checkout <現在のROSのブランチ>
      <現在のROSのブランチ>

まとめ


  • ROSのOSSパッケージを利用する際、make時にundefined reference to...のエラーが出る原因をまとめた


参考文献




変更履歴


  1. 2020/05/23: 新規作成

2020/05/21

外部仕様書のテンプレート

背景


仕事の中でシステムやソフトウェアの開発を行う際、外部仕様書を書く機会が増えてきたので、外部仕様書に必要な項目をまとめた。

記事の目的


外部仕様書を効率的に作成するため、外部仕様書のテンプレートを作成する

外部仕様書とは


外部仕様書は、基本設計書もとも呼ばれている。外部仕様書の目的は、要件定義の結果を受けて、具体的なシステム構成や機能に記載した文書である。

外部仕様書の全体構成


外部仕様書の全体構成は、下記の通りである。
  1. 処理設計
    1. システム化の背景・目的
    2. システム化が必要な背景(理由)と目的を簡潔に記載する。
    3. (オプション)システム化の対象範囲
    4. 対象処理のシステム化範囲を明確に記載する。新規の場合は不要。
    5. システム機能要件一覧
    6. システムの機能要件について、一覧で記載する。
      • 分類
      • 機能名
      • 利用者
      • 機能概要
      • 重要度
      • 優先度
    7. 処理フロー
    8. システム全体の処理の流れについて記載する。
      UML図のアクティビティ図を使用すると良い。
    9. ユースケースシナリオ
    10. システム全体の処理をユースケースごとに分解し、そのシナリオについて記載する。
      UML図のユースケース図シーケンス図を使用すると良い。
  2. システム方式設計
    1. ハードウェア構成図
    2. システムを実現するためのハードウェア構成について記載する。
      UML図の配置図を使用すると良い。
    3. ソフトウェア構成図
    4. システムを実現するためのソフトウェア構成について記載する。
      • OS
      • Windows、Mac-OS、Unix、Linux、iOS、AndroidなどのOSについて記載する。
      • ミドルウェア
      • DB(Oracle、DB2、SQL Server、MySQL、PostgreSQL)、Webサーバ(Apache、nginx、IIS)、APサーバ(WAS、Tomcat、WebLogic、JBoss、Interstage)などのミドルウェアについて記載する。
    5. ネットワーク構成図
    6. システムを実現するためのネットワーク構成について記載する。
      UML図の配置図を使用すると良い。
    7. アプリケーション機能構成
    8. 開発するシステム機能が階層的に分かる資料を作成する。
      機能要件とアプリケーション機能の関係性を明示するとともに、機能の分類、整理を行い記載する。
      • 分類
      • 機能名
      • 利用者
      • 処理タイミング
      • 処理内容
  3. アプリケーション機能設計
    1. 画面設計
      1. 画面一覧
      2. 開発する画面の一覧について記載する。
        • 分類
        • 画面名
        • 説明
        • 関連機能名
      3. 画面遷移図
      4. 画面がどの順番で遷移するか記載する。
      5. 画面レイアウト
      6. 各画面の詳細なレイアウトについて記載する。
      7. 画面入出力項目一覧
      8. 各画面で表示する内容と、入力する内容について記載する。
      9. 画面アクション定義
      10. 画面操作が行われた時の処理内容について記載する。
    2. バッチ設計
      1. バッチ処理一覧
      2. バッチ処理の一覧について記載する。
        • バッチ処理名
        • 処理概要
        • 処理周期
        • 処理タイミング
        • 関連機能名
      3. バッチ処理定義
      4. バッチ処理の具体的な入出力と処理内容について記載する。
        • 入力データ
        • 処理内容
        • 出力データ
      5. バッチ処理フロー
      6. バッチ処理の流れについて記載する。 UMLのシーケンス図を使用すると良い。
    3. DBテーブル・ファイル設計
      1. テーブル・ファイル一覧
      2. システムで用いるDBのテーブル一覧について記載する。
      3. テーブル関連図
      4. システムで用いるDBのテーブルの関係性について記載する。 UMLのER図を使用すると良い。
      5. テーブル定義
      6. テーブル内の項目名、データ型、データ長、その他制約について記載する。
      7. ファイル定義
      8. ファイル内の項目名、データ型、データ長、その他制約について記載する。
      9. CRUD図
      10. 各テーブルについて、どの機能で作成、参照、更新、削除がされるかについて記載する。
        C: 作成(Create)、R: 参照(Read)、U: 更新(Update)、D: 削除(Delete)
    4. 外部インターフェース設計
      1. 外部インターフェース一覧
      2. 外部システムとの界面(インターフェース)の一覧を記載する。
        • インターフェース名
        • 入出力の種別
        • 相手先システム名
        • 接続方式
        • 通信タイミング
      3. 外部システム関連図
      4. 外部システムとのデータ連携について記載する。
        UML図の配置図を使用すると良い。
      5. 外部インターフェース項目定義
      6. 外部システムと連携するデータについて記載する。(データ型、データ長、その他制約)
      7. 外部インターフェース処理概要
      8. システム間のデータ連携方式(リソース共有(データベース共有、ディスク共有)、アプリケーション連携(RPC、Webサービスなど)、ファイル連携、メッセージング)について記載する。
  4. 非機能要件設計
    1. 性能設計
    2. 要件定義の性能要件に対して、対応方針や評価方法について記載する。
      • 基準値
      • 画面応答時間、バッチ実行時間など、基準となる定量的な値を記載する。
      • 対策
      • 上記基準を満たすための、アプリケーション機能やプラットフォーム設計等への対策について記載する。
      • 評価方法
      • テスト段階において、上記基準を満たしているか判定する方法について記載する。
    3. 信頼性設計
    4. 要件定義の可用性と完全性の要件に対しての対応方針について記載する。
      • 可用性
        • 可用性基準値
        • 要件定義で定めた基準値を記載する。(例: 稼働率99.999%)
        • 可用性対策
        • アプリケーション機能(例: 障害発生時の復旧方法)やプラットフォーム設計等(例:システム多重化、縮退運用)への対策について記載する。
        • 可用性評価方法
        • テスト段階において、上記基準を満たしているか判定する方法について記載する。
      • 完全性
        • 完全性基準値
        • 要件定義で定めた基準値を記載する。
        • 完全性対策
        • 上記基準を満たすための、アプリケーション機能(例: データバックアップや更新ログの取得)やプラットフォーム設計(例: ディスクバックアップ、アクセスログ取得)等への対策について記載する。
        • 完全性評価方法
        • テスト段階において、上記基準を満たしているか判定する方法について記載する。
    5. 拡張性設計
      • 規模の拡張性
      • 要件定義で定めた性能拡張の実現方法について記載する。。
      • 機能の拡張
      • 要件定義で定めた機能拡張の実現方法について記載する。。
    6. 情報セキュリティ設計
    7. 要件定義のセキュリティ要件に対しての対応方針について記載する。
      • 利用者等の認証
      • 利用者認証(利用者自身、利用者の知っているもの、利用者が持っているものを用いた認証)の方式について記載する。
      • 権限管理
      • アカウント管理(登録、更新、停止、削除)の方法について記載する。
      • アクセス管理
      • 利用者の職務に応じて利用機能を制限する方法について記載する。
      • ログ管理
      • システムの利用記録・検索方法について記載する。
      • 暗号化機能
      • 保存したデータや通信するデータの暗号化方式について記載する。
      • 不正プログラム対策
      • コンピュータウィルス感染防止の対策方式について記載する。
      • 通信の制御
      • 不正通信の遮断方式について記載する。
    8. テスト方針
    9. 各テストについて、システムの品質を担保するために必要なテストの種類や目的、方法、開始条件、実施内容、テスト環境、テストデータの準備方針、実施タイミング、役割分担、報告書等の方針について記載する。
      • 単体テスト(MT, UT)
      • プログラムを構成する比較的小さな単位(ユニット)が個々の機能を正しく果たしているかどうかを検証するテストのことである。
      • 結合テスト(IT)
      • システム開発におけるプログラムの検証作業の中でも、手続きや関数といった個々の機能を結合させて、うまく連携・動作しているかを確認するテストのことである。
      • システムテスト(ST)
      • システム開発におけるプログラムの検証作業の中でも、構築したシステムが全体として予定通りの機能を満たしているかどうかを確認するテストのことである。
      • 運用テスト(OT)
      • システム開発においていくつかあるテスト工程の中で、本番稼働直前、テスト工程の一番最後に行う確認テストのことである。
    10. 移行方針
    11. 要件定義に基づき、システム移行に関する下記のような方針について記載する。
      • 移行スケジュール
      • 全体の開発、導入スケジュールについて記載する。
      • プログラム移行
      • プログラムの移行手順について記載する。
      • 初期データ登録
      • 新たなデータの登録方法について記載する。
      • 既存システムからのデータ移行
      • 既存システムからのデータの移行方法について記載する。
      • 役割分担
      • 担当者について記載する。
    12. 運用保守設計
    13. 要件定義に基づき、各要件を実現するに当たっての運用保守業務設計、および必要な環境や機能の設計について記載する。
      • 運用保守業務内容
      • 運用保守で対応する内容一覧を記載する。
      • 役割分担と対象範囲
      • 担当者と担当範囲について記載する。
      • 管理項目
      • 運用保守で対応する機能項目について記載する。
      • 必要なシステムやドキュメント
      • 運用保守を行うために必要なドキュメント一覧を記載する。
      • システム監視方法
      • システムの監視方法(定期的なログ確認、アラート機能)について記載する。
      • データ管理方法(ログなど)
      • データの保存場所や運用方法について記載する。
      • バックアップ方法
      • バックアップ先やタイミング、手法について記載する。
      • 障害対応方法
      • 障害発生時の対応手順について記載する。

まとめ


  • 外部仕様書のテンプレートに関して記述した

参考文献



変更履歴


  1. 2020/05/21: 新規作成



2020/05/18

要件定義書のテンプレート

背景


仕事の中でシステムやソフトウェアの開発を行う際、要件定義書を書く機会が増えてきたので、要件定義書に必要な項目をまとめた。

記事の目的


要件定義書を効率的に作成するため、要件定義書のテンプレートを作成する

要件定義書とは


要件定義書は、開発仕様書とも呼ばれている。要件定義書の目的は、開発にかかわるすべての技術者に開発する製品(新規の開発およびバージョンアップ)が備えるべき要件を決定事項として周知することである。

要件定義書の全体構成


要件定義書の全体構成は、下記の通りである。
  1. 処理要件の定義
    1. 処理概要
      1. 背景と目的
      2. システム化が必要な背景(理由)と目的を簡潔に記載する。
      3. 用語・略語の定義
      4. システム化対象処理にて使用する専門的な用語・略語の説明を記載する。
      5. 処理の概要
      6. システム化対象の処理の概要を記載する。
        UMLのアクティビティ図を利用すると良い。
      7. (オプション)現行システム概要
      8. 現行システムの概要を記載する。新規の場合は不要。
        • ハードウェア構成
        • 現行システムのハードウェア一覧について記載する。
        • ネットワーク構成
        • 現行システムのネットワーク構成について記載する。
          UMLの配置図を利用すると良い。
        • システム機能一覧(UI、UX)
        • 現行システムの機能一覧について記載する。
        • ミドルウェア構成
        • 現行システムで使用しているミドルウェア(Web、AP、DB)について記載する。
        • データ一覧(テーブルやファイル)
        • 現行システムで使用しているデータ形式一覧について記載する。
        • 外部インターフェース一覧
        • 現行システムの外部との界面(インターフェース)について記載する。
    2. 規模
    3. システム化対象処理の利用者数など、処理の規模を記載する。
    4. 時期・時間
    5. システム化対象処理の稼働時間を記載する。
    6. 場所
    7. システム化対象処理が関係する場所や組織について概要を記載する。
    8. 管理すべき指標
    9. システム化対象処理にて、管理すべき指標(KPI)を記載する。
    10. (オプション)システム化範囲
    11. 対象処理のシステム化範囲を明確に記載する。新規の場合は不要。
  2. 機能要件の定義
    1. システム機能要件
    2. システム機能一覧について記載する。
      • 機能名
      • 機能の名称について記載する。
      • 機能種別(表示(出力)、入力、処理、保存、削除)
      • 機能の種別について記載する。
      • 処理概要
      • 処理の概要について記載する。
      • 利用者
      • 機能を利用する対象者について記載する。
    3. UI、UX要件
    4. システムの表示(大きさや位置)や入力(入力方法など)に関する要件を記載する。
    5. データ要件
    6. 保管するデータ項目の一覧やデータ量の想定件数を記載する。
      UMLのER図を利用すると良い。
    7. 外部インターフェース要件
    8. 処理連携やデータの授受を行う他システムについて記載する。
      • 外部インターフェース名
      • 外部インターフェースの名称を記載する。
      • 外部インターフェース概要
      • 外部インターフェースの概略を記載する。
      • 連携方式(バッチorオンライン)
      • 連携する方法を記載する。
      • 送受信区分
      • データの流れを記載する。
      • 相手先システム
      • 外部インターフェースで接続されるシステムについて記載する。
      • 送受信タイミング
      • データの送受信タイミングについて記載する。
      • 送受信方式
      • データの送受信の方式(リソース共有(データベース共有、ディスク共有)、アプリケーション連携(RPC、Webサービスなど)、ファイル連携、メッセージング)について記載する。
  3. 非機能要件の定義
    1. ユーザビリティ要件
    2. システムの利用者について、ITリテラシーの水準を記載する。
    3. アクセシビリティ要件
    4. システム利用者の特性を受けて、今回開発システムに求める使いやすさを記載する。
      • 画面構成
      • 操作のしやすさ、分かりやすさ
      • 指示や状態の分かりやすさ
      • エラーの防止と処理
      • ヘルプ(ヘルプ情報やマニュアルなどの参照)
    5. システム方式要件
    6. システム構成の方針、全体構成図、開発方式や手法などについて記載する。
      1. システム構成の方針
        • システムアーキテクチャ
        • Webサーバなどの使用するアーキテクチャについて記載する。
        • アプリケーションプログラムの設計方式
        • 設計時の機能分割やコンポーネントの再利用の方針について記載する。
        • ソフトウェア製品の活用方式
        • OSSなどの外部ソフトウェアの利用方針について記載する。
        • システム基盤の方針
        • 処理や保存するデータ量や利用者の増加(拡張性)について記載する。
      2. システム全体構成
      3. プラットフォーム(ネットワーク、ハードウェア、OS ・ミドルウェア)の構成について記載する。
        UMLの配置図を利用すると良い。
      4. 開発方式や開発手法
        1. 開発方式
        2. スクラッチ開発、パッケージを使った開発などの開発方式について記載する。
        3. 開発手法
        4. ウォーターフォール、プロトタイピング、スパイラル、アジャイルなどの開発手法について記載する。
    7. 規模要件
    8. システム化において必要な機器数やデータ量、処理件数などを記載する。
      • 機器数
      • サーバー、クライアント端末などの機器の数について記載する。
      • データ量
      • テーブル毎のデータ量について記載する。 「データ要件」に記載の場合は、そちらを参照する旨を記載する。
      • 処理件数
      • システム機能毎にピーク時の処理件数について記載する。
    9. 性能要件
    10. システムの応答時間について記載する。
    11. 信頼性要件
      • 可用性
      • システムの稼働率について記載する。(例: 稼働率99.999%)
      • 完全性
      • 機器の破損やデータ欠損、不整合への対策、ログの取得について記載する。
    12. 拡張性要件
      • 性能の拡張性
      • 扱える利用者やデータ量の増加などの性能拡張の可否について記載する。
      • システム機能の拡張性
      • システムに新たな機能を追加可能かなどの機能拡張の可否について記載する。
    13. 上位互換性要件
    14. OSやソフトウェアのバージョンアップにおける要件について記載する。
    15. 継続性要件
    16. 大規模災害時における復旧目標時間やデータバックアップについて記載する。
    17. 情報セキュリティ要件
    18. 開発するシステムが満たすべきセキュリティの要件を記載する。
      • 利用者等の認証
      • 利用者認証(利用者自身、利用者の知っているもの、利用者が持っているものを用いた認証)の方式について記載する。
      • 権限管理
      • アカウント管理(登録、更新、停止、削除)の方法について記載する。
      • アクセス管理
      • 利用者の職務に応じて利用機能を制限する方法について記載する。
      • ログ管理
      • システムの利用記録・検索方法について記載する。
      • 暗号化機能
      • 保存したデータや通信するデータの暗号化方式について記載する。
      • 不正プログラム対策
      • コンピュータウィルス感染防止の対策方式について記載する。
      • 通信の制御
      • 不正通信の遮断方式について記載する。
    19. 情報システム稼働環境要件
    20. システム稼働可能な環境要件について記載する。
      • ハードウェア構成図
      • 最低限必要なハードウェア構成について記載する。
      • ソフトウェア構成図
      • 最低限必要なソフトウェア構成について記載する。
      • ネットワーク構成図
      • 最低限必要なネットワーク構成について記載する。 UMLの配置図を利用すると良い。
    21. テスト要件
    22. 各テストについて、システムの品質を担保するために必要なテストの種類や目的、方法、実施内容、範囲、報告書等の要件について記載する。
      • 単体テスト(MT, UT)
      • プログラムを構成する比較的小さな単位(ユニット)が個々の機能を正しく果たしているかどうかを検証するテストのことである。
      • 結合テスト(IT)
      • システム開発におけるプログラムの検証作業の中でも、手続きや関数といった個々の機能を結合させて、うまく連携・動作しているかを確認するテストのことである。
      • システムテスト(ST)
      • システム開発におけるプログラムの検証作業の中でも、構築したシステムが全体として予定通りの機能を満たしているかどうかを確認するテストのことである。
      • 運用テスト(OT)
      • システム開発においていくつかあるテスト工程の中で、本番稼働直前、テスト工程の一番最後に行う確認テストのことである。
    23. 移行要件
    24. システム移行に関する下記のような要件について記載する。
      • 移行スケジュール
      • 全体の開発、導入スケジュールについて記載する。
      • プログラム移行
      • プログラムの移行手順について記載する。
      • 初期データ登録
      • 新たなデータの登録方法について記載する。
      • 既存システムからのデータ移行
      • 既存システムからのデータの移行方法について記載する。
      • 役割分担
      • 担当者について記載する。
    25. 引継ぎ要件
    26. システム開発企業と、システム運用企業が異なる場合は、運用企業への引継ぎ要件について記載する。 具体的には、ドキュメントやトレーニング(対象者、スケジュール、実施場所、内容)について記載する。
    27. 教育要件
    28. システム利用者への操作教育について、下記のような観点で記載する。
      • 教育対象者
      • 教育の内容
      • 教育の実施時期
      • 教育の方法
      • 教材
      • 教育対象者数
    29. 運用要件
    30. システム運用(定常運用、随時運用、障害時運用のそれぞれ)における要件について記載する。
      • 運転管理及び監視
      • システム稼働監視、障害時の対応、報告内容や報告頻度について記載する。
      • 運用実績の評価と改善
      • 運用業務の内容や工数、報告内容や報告頻度について記載する。
      • システム操作
      • バックアップやアカウントの管理、ウィルスチェックの方法について記載する。
      • 運用サポート
      • 操作研修や問い合わせ対応について記載する。
      • 業務運用支援
      • データ作成支援や問い合わせ対応について記載する。
      • システムの現況確認
      • 各種管理台帳の提出方式について記載する。
    31. 保守要件
    32. システムの保守における要件について記載する。
      • プログラム
      • 保守の受付時間、対応時間について記載する。
      • ハードウェア
      • 保守の受付時間、対応時間について記載する。
      • ソフトウェア製品
      • 保守の受付時間、対応時間について記載する。
      • データ保守実績の評価と改善
      • 保守業務の内容や工数、報告内容や報告頻度について記載する。

まとめ


  • 要件定義書のテンプレートに関して記述した

参考文献



変更履歴


  1. 2020/05/18: 新規作成



2020/05/16

NECルータの設定方法

背景


Windows環境からコンソール経由でNEC社製ルータをセットアップする必要があったため、調査した。

記事の目的


NECルータを設定できるようにする

NECルータ


国内では、業界3位のシェアを誇るルータである。(1位:cisco、2位:Yamaha)
ギガビット回線とワイヤレス回線に対応したルータ(IX2000シリーズIX3000シリーズ)、有線とモバイルを1台で収容可能なルータ(WA2600-APシリーズWA1500 シリーズ)などがある。

ルータへの接続方法


  1. コンソールケーブルを使用し、PCとルータのCOMポートを接続する
  2. 接続方法詳細は、RLoginでシリアルコンソール接続を参照

ルータの設定方法


ここでは、ルータの基本的な設定方法について記載する。ターミナルには、RLoginを使用した。
  1. ルーターにログインする
  2. login admin
    Password: admin
    NEC Portable Internetwork Core Operating System Software
    Copyright Notices:
    Copyright (c) NEC Corporation 2001-2014. All rights reserved.
    Copyright (c) 1985-1998 OpenROUTE Networks, Inc.
    Copyright (c) 1984-1987, 1989 J. Noel Chiappa
    Router#
    loginユーザー名、パスワードを入力する。
  3. 現在の設定を確認する
  4. Router# show running-config
    ...
    interface GigaEthernet0.0
     ip address 192.168.2.100/24
     ipv6 address 2001:db8:200::1/64
     no shutdown
    interface GigaEthernet1.0 
    ...
    show running-configで現在の設定を確認できる。
  5. コンフィグモードに変更する
  6. Router# enable-config
    Router(config)#
    機種によってはenableを使用する。
    Router# enable
    Router(config)#
    コンフィグモードになると、設定の変更ができるようになる。
  7. インターフェースにIPアドレスを設定する
    1. 設定したいインターフェースを指定する
    2. Router(config)# interface GigaEthernet0.0
      Router(config-GigaEthernet0.0)#
      ここでは、GigaEthernet0.0を選択した。
    3. インターフェースのIPアドレスを設定する
    4. Router(config-GigaEthernet0.0)# ip address 192.168.1.1/24
      ここでは、192.168.1.1を選択した。
    5. インターフェースを有効化する
    6. Router(config-GigaEthernet0.0)# no shutdown
      無効化時は、shutdownと入力する。
    7. 設定を確認する
    8. Router(config-GigaEthernet0.0)# show ip address
      Interface GigaEthernet0.0 is up, line protocol is up
       Internet address is 192.168.1.1/24
       Broadcast address is 255.255.255.255
      Address determined by config
    9. インターフェースの指定を解除する
    10. Router(config-GigaEthernet0.0)# exit
      Router(config)#
  8. モバイルインターフェース(LTEなど)にIPアドレスを設定する
    1. 設定したいインターフェースを指定する
    2. Router(config)# interface MobileEthernet0.0
      Router(config-MobileEthernet0.0)#
      ここでは、MobileEthernet0.0を選択した。
    3. インターフェースに各種設定をする
      • IPアドレスをDHCPとする(SIMに依存する)
      • Router(config-MobileEthernet0.0)# ip address dhcp
      • NAPT(ネットワークアドレス変換)を有効にする
      • Router(config-MobileEthernet0.0)# ip napt enable
        これを有効にすることで、内部ネットワーク(例では、192.168.1.XX)の端末がモバイルネットワークと通信できる。

      • SIMの情報に基づいて、モバイルの設定を行う
      • Router(config-MobileEthernet0.0)# mobile id "SIMに記載のモバイル会社のID"
        Router(config-MobileEthernet0.0)# mobile username "SIMに記載の接続用username"
        Router(config-MobileEthernet0.0)# mobile password encrypted "SIMに記載の接続用パスワード"
        
      • 自動で接続するように設定する
      • Router(config-MobileEthernet0.0)# auto-connect
      • (オプション)セキュリティ対策のため、送信するポートをポート番号100(TCP)に制限する
      • Router(config-MobileEthernet0.0)# ip filter all_out 100
    4. インターフェースを有効化する
    5. Router(config-MobileEthernet0.0)# no shutdown
      無効化時は、shutdownと入力する。
    6. インターフェースの指定を解除する
    7. Router(config-MobileEthernet0.0)# exit
      Router(config)#
  9. ネットワーク経由でログインできるようにする
  10. sshでネットワーク上のPCからルータにログインできるように設定する
    1. sshサーバーの有効化
    2. Router(config)# ssh-server ip enable
    3. 接続元を制限する
    4. Router(config)# ssh-server ip permit 192.168.1.0/24
      セキュリティ対策のため、接続できるIPアドレスを制限する。(例では、192.168.1.XXからのみ接続可能)
  11. 設定を保存する
  12. Router(config)# write memory
    機種によっては、saveを使用する。
    Router(config)# save
    設定を保存しないと、再起動時に現在の設定は失われる。
  13. オペレーションモードに戻る(コンフィグモードを終了する)
  14. Router(config)# exit
    Router#

備考

  • 何も入力がない状態でのタブ補完で、コマンド一覧が表示できる
  • タブ補完で、コマンドやヘルプが表示できる

まとめ


  • NECルータの設定方法ついて調査、記載した

参考文献



変更履歴


  1. 2020/05/16: 新規作成

2020/05/13

RLoginでデータ転送

背景


Windows環境からSSHでログインしたLinuxに、データを転送する方法を調査した。

記事の目的


RLoginでSSHログインLinuxとデータ転送をできるようにする

RLoginとは


RLoginは、Culti (kmiya@culti) が開発しているWindows用のターミナルソフトである。
タブ単位で操作でき、様々なショートカットキーを登録できることが特色である。


RLoginの導入方法


RLoginの設定方法を参照

RLoginでデータ転送する方法


ここでは、RLoginでデータ転送する方法について記載する。
  1. SSHでログインし、転送ボタンを押す
    • ログイン方法は、RLoginの設定方法を参照
    • 転送ボタンは、画面上にあるバー内の、左から6つめのアイコン
  2. 転送するファイルの存在するディレクトリと転送先のディレクトリに移動する
    • 画面内、左半分
    • 接続元(Windows)PCのエクスプローラー画面
    • 画面内、右半分
    • 接続先(Linux)PCのエクスプローラー画面
  3. 接続先にアップロード
  4. アップロードしたいファイルを右クリックし、ファイルのアップロード(U)を選択する。接続先(Linux)PCの、現在表示しているディレクトリに転送される。
  5. 接続先からダウンロード
  6. ダウンロードしたいファイルを右クリックし、ファイルのダウンロード(D)を選択する。接続元(Windows)PCの、現在表示しているディレクトリに転送される。

まとめ


  • RLoginでファイル転送する方法ついて調査、記載した

参考文献



変更履歴


  1. 2020/05/13: 新規作成

2020/05/10

python-socketioでAttributeError: 'module' object has no attribute 'main_thread'が出る場合の対処法

背景


Python2.7でpython-socketioを使用したとき時、下記のエラーが発生した。
$ python ./test_socketio_client.py 
Traceback (most recent call last):
  File "./test_socketio_client.py", line 123, in 
    sio_client = SocketIOClient('127.0.0.1', 10000, 'test', 'secret')
  File "./test_socketio_client.py", line 76, in __init__
    self.sio_        = socketio.Client()
  File "/home/emptyset/.local/lib/python2.7/site-packages/socketio/client.py", line 88, in __init__
    threading.current_thread() == threading.main_thread():
AttributeError: 'module' object has no attribute 'main_thread'

記事の目的


python-socketioのAttributeErrorを解決する

原因と対策


エラー原因

threadingモジュールのバージョン問題である。threadingの説明によると、main_thread関数は、バージョン 3.4以降で追加されたメソッドであるため、Python2系では使用できない。

対策

該当モジュールのmain_thread関数を修正する。
  1. python-socketioの該当モジュール(例/home/emptyset/.local/lib/python2.7/site-packages/socketio/client.py)を修正する
  2. 修正前
            global original_signal_handler
            if original_signal_handler is None and \
                    threading.current_thread() == threading.main_thread():
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    修正後
            global original_signal_handler
            if original_signal_handler is None and\
                    threading.current_thread().isDaemon() is False:
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    Clientのインスタンス生成がmainスレッドでのみ可能になってるが、この部分を削除した。代わりに、スレッドがデーモンかの判定を追加した。(mainスレッド以外がデーモンであると仮定)
  3. python-engineioの該当モジュール(例/home/emptyset/.local/lib/python2.7/site-packages/engineio/client.py)を修正する
  4. 修正前
            global original_signal_handler
            if original_signal_handler is None and \
                    threading.current_thread() == threading.main_thread():
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    修正後
            global original_signal_handler
            if original_signal_handler is None and \
                    threading.current_thread().isDaemon() is False:
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    Clientのインスタンス生成がmainスレッドでのみ可能になってるが、この部分を削除した。代わりに、スレッドがデーモンかの判定を追加した。(mainスレッド以外がデーモンであると仮定)
  5. 動作確認を行う
  6. $ python ./test_socketio_client.py 
    Try to connect to server(localhost:10000, namespace="/test", query="secret")
    Namespace may be invalid.(namespace="/test")
    Connected to server (localhost:10000, namespace="/test", query="secret")
    Send message {'test_data': 'send_from_client'} (namespace="/test")
    Emit message {'test_data': 'emit_from_client'} (namespace="/test")
    Received message {u'test_ack': u'send_from_server'}
    Received message {u'test_ack': u'emit_from_server'}
    ...

まとめ


  • python-socketioでAttributeError: 'module' object has no attribute 'main_thread'が出る場合の対処法について調査、記載した

参考文献



変更履歴


  1. 2020/05/10: 新規作成

RLoginで多段ssh

背景


Windows環境から別ネットワーク内のLinuxにSSHでログインするための方法を調査した。

記事の目的


RLoginでWindowsから多段SSHできるようにする

多段SSHとは


多段SSHは、別ネットワークと自分のPCがあるネットワークの両方に接続されたPC(踏み台サーバー)を経由して、別ネットワーク内のPCにSSHログインする方法である。
踏み台サーバーにポートフォワード設定を行ってプロキシサーバーとし、自分のPCから踏み台サーバー経由で接続する。

RLoginの導入方法


RLoginの設定方法を参照

RLoginの設定方法


ここでは、RLoginで多段SSHを行うための設定方法について記載する。

1. 踏み台サーバーの設定方法

  1. Server Selectウインドウの新規(N)をクリック(Server Selectウインドウは、RLoginウインドウ右上の黄色いプラグマークで表示できる)
  2. 接続設定を行う
    1. エントリー名
    2. この接続設定の名前を記入する
    3. コメント
    4. この接続設定の説明を記入する
    5. タブ
    6. 接続先のタグを記載する(Server Selectウインドウ内で、タブ毎に整理されて表示されるようになる)
    7. 前接続先
    8. 記載しない
    9. ホスト名(サーバーIPアドレス)
    10. 踏み台サーバーのホスト名、又はIPアドレスを記入する
    11. TCPポート
    12. SSHの場合は、sshとする
    13. ログインユーザー名
    14. 踏み台サーバーのログインするユーザー名を記入する
    15. ユーザー認証の方式によりパスワードorパスフレーズ
    16. パスワード認証の場合、踏み台サーバーのパスワードを入力する
    17. SSH認証鍵
    18. RSA認証の場合、ここをクリックして踏み台サーバーの認証鍵を指定する
    19. プロキシ設定
    20. 社内ネットワークなど、プロキシ経由でアクセスする場合はここを設定する
  3. ポートフォワード設定
    1. プロトコル内のポートフォワードを選択
    2. 新規(N)を選択
    3. ポートフォワード設定
      1. Listened
      2. Local Socksを選択する
      3. Hostname
      4. localhostと記載する
      5. Port
      6. ポートフォワードで使用するポート番号を記載する(ここでは、9000とした)
      7. OKボタンを押す
  4. 全てのウインドウをOKで閉じる

2. 接続先の設定方法

  1. Server Selectウインドウの新規(N)をクリック(Server Selectウインドウは、RLoginウインドウ右上の黄色いプラグマークで表示できる)
  2. 接続設定を行う
    1. エントリー名
    2. この接続設定の名前を記入する
    3. コメント
    4. この接続設定の説明を記入する
    5. タブ
    6. 接続先のタグを記載する(Server Selectウインドウ内で、タブ毎に整理されて表示されるようになる)
    7. 前接続先
    8. 踏み台サーバー(例では、Linux PC 1)を記載する
    9. ホスト名(サーバーIPアドレス)
    10. 接続先のホスト名、又はIPアドレスを記入する
    11. TCPポート
    12. SSHの場合は、sshとする
    13. ログインユーザー名
    14. 接続先のログインするユーザー名を記入する
    15. ユーザー認証の方式によりパスワードorパスフレーズ
    16. パスワード認証の場合、接続先のパスワードを入力する
    17. SSH認証鍵
    18. RSA認証の場合、ここをクリックして接続先の認証鍵を指定する
  3. プロキシ設定
    1. Server Edit Entryウインドウ内におけるサーバーのプロキシ設定(P)を選択する
    2. Select Proxy Protocol
    3. SOCKS5を選択
    4. Over SSL
    5. 使用しないを選択
    6. Proxy Server Address
    7. localhostと記載
    8. Socket Port
    9. 踏み台サーバーのポートフォワードで使用しているポート番号を記載する(例では9000)
  4. 全てのウインドウをOKで閉じる

多段SSHの使用方法


ここでは、RLoginで多段SSHの方法について記載する。
  1. Server Selectウインドウで接続先を選択し、OKボタンを押す
  2. 踏み台サーバーと接続先の両方へSSHでログインされる

備考

  • 踏み台サーバーとの接続を切断すると、接続先も切断される


まとめ


  • RLoginで多段SSHする方法ついて調査、記載した

参考文献



変更履歴


  1. 2020/05/10: 新規作成

2020/05/07

Dockerコンテナ内でnpm installをした場合のエラー(EAI_AGAIN)に対する対処法(Linux編)

背景


プロキシ下のPC上でDockerを使用し、コンテナ上でnpm installを行った時、下記のエラーが発生した。
$ npm install
npm ERR! code EAI_AGAIN
npm ERR! errno  EAI_AGAIN

記事の目的


DockerにDNSアドレスを設定し、コンテナ内でホスト名を解決できるようにする

原因と対策


エラー原因

DockerがDNSを見つけられないため、コンテナ内でホスト名をIPアドレスに変換できない。
社内プロキシ内などプロキシ下のPCである場合、プロキシサーバーのホスト名を解決できない。

対策

DockerにDNSのアドレスを登録する。
  1. /etc/docker/daemon.jsonを作成する
  2. {
        "dns": ["DNSアドレス1","DNSアドレス2"]
    }
    DNSアドレスは、8.8.8.8(GoogleのDNS)や社内ネットワーク内のDNSアドレスを設定する。
  3. dockerを再起動する
  4. $ sudo ststemctl docker restart

まとめ


  • Dockerコンテナ内でnpm installを行った際、EAI_AGAINと表示されインストールできない問題を修正する方法について調査、記載した

参考文献



変更履歴


  1. 2020/05/07: 新規作成

RLoginでシリアルコンソール接続

背景


Windows10環境からルーターなどのネットワーク機器にコンソールでログインする必要があったため、調査した。

記事の目的


RLoginでシリアルコンソールに接続できるようにする

RLoginとは


RLoginは、Culti (kmiya@culti) が開発しているWindows用のターミナルソフトである。
タブ単位で操作でき、様々なショートカットキーを登録できることが特色である。

RLoginの導入方法


RLoginの設定方法を参照

シリアルコンソールへの接続


ここでは、シリアルコンソールに接続するための方法について記載する。
  1. 機器との接続
  2. コンソールケーブルを使用し、機器と接続する
  3. デバイスマネージャーを開く
  4. 画面左下のWindowsマークを右クリックし、デバイスマネージャーを選択する
  5. COMポート番号を確認
  6. ポート番号を確認する(複数ある場合、機器を抜き差しして確認(操作(A)→ハードウェア変更のスキャン(A)で表示の更新も行う))

RLoginの設定方法


ここでは、RLoginでシリアルコンソールに接続するための設定方法について記載する。
  1. Server Selectウインドウの新規(N)をクリック(Server Selectウインドウは、RLoginウインドウ右上の黄色いプラグマークで表示できる)
  2. 接続設定を行う
    1. エントリー名
    2. この接続設定の名前を記入する
    3. コメント
    4. この接続設定の説明を記入する
    5. プロトコル
    6. comを選択する
    7. タブ
    8. 接続先のタグを記載する(Server Selectウインドウ内で、タブ毎に整理されて表示されるようになる)
    9. ホスト名(サーバーIPアドレス)
    10. ビットレート;データビット;パリティ(NOP,ODD,EDEN,MARK,SPC);ストップビット;フロー制御(NOC,CTS,XON);を記入する(例: 9600;8;NOP;1;NOC;)
    11. TCPポート
    12. シリアルコンソールの場合は、COMポートを指定する(自分のPCの場合、COM1が全面にあるUSB3.0ポートだった)
    13. OKボタンを押す
  3. Server Selectウインドウで接続先の設定を選択(クリック)し、OKボタンを押す

備考

  • 上記設定(9600;8;NOP;1;NOC;)でNECのルータに接続できることは確認済み

まとめ


  • RLoginでシリアルコンソール接続する方法ついて調査、記載した

参考文献



変更履歴


  1. 2020/05/07: 新規作成

2020/05/06

PlantUMLでユースケース図作成

背景


システムの要件定義でユースケース図を作成する必要があり、Gitで差分管理が可能なユースケース図作成ツールを調査した。

記事の目的


PlantUMLでユースケース図を作成する

ユースケース図


ユースケース図について記載する。

ユースケース図とは

ユースケース図は、ユーザ(外部システムも含む)の要求に対するシステムの振る舞いを記述したものである。

ユースケース図の描き方

  • 利用者(Actor)
  • @startuml
    actor :Actor:
    @enduml
    システムの利用者を表す。
  • ユースケース(Usecase)
  • @startuml
    usecase Usecase
    @enduml
    システムの利用シーン(ユースケース)を表す。
  • サブジェクト(Subject)
  • @startuml
    rectangle Subject {
        usecase Usecase1
        usecase Usecase2
    }
    @enduml
    システムの境界線を表す。
  • パッケージ(Package)
  • @startuml
    rectangle Subject {
        package Package1 {
            usecase Usecase1
            usecase Usecase2
        }
        package Package2 {
            usecase Usecase3
            usecase Usecase4
        }
    }
    @enduml
    サブジェクト内で複数のユースケースをまとめて表現する。
  • オブジェクト間の関係
  • @startuml
    actor :Member:
    actor :Customer:
    actor :Employee:
    
    rectangle "Shopping system" {
        package "Customer registration" {
            usecase "ID registration" as id
            usecase "Name registration" as name
            usecase "Shopping list registration" as asmt
            usecase "Password registration" as pw
            /'Include: <., .>, <.., or ..>'/
            id <.. name : <<include>>
            /'Extend: <., .>, <.., or ..>'/
            id ..> asmt : <<extend>>
        }
        package "Customer  search" {
            usecase "Search customer  by name" as se
            usecase "Show list of all customer " as sh
        }
    }
    /'Generalization: <|-, -|>, <|--, or --|>'/
    Member --|>  Employee
    
    /'Relationship: --, or -'/
    Customer  -- id
    Customer  -- pw
    
    se -- Employee
    sh -- Employee
    @enduml
    • 関連(Relationship)
    • アクターとユースケースをつなげるときに使用する。
    • 汎化(Generalization)
    • オブジェクト間で「汎化関係」が成り立つときに使用する。汎化関係とは、「担当社員」と「XX社社員」のように要素と要素の所属の関係である。
    • 包含(Include)
    • オブジェクト間で「包含関係」が成り立つときに使用する。包含関係とは、「個人情報登録」と「住所登録」のように全体と構成要素の関係である。
    • 拡張(Extend)
    • 拡張するユースケース(機能)を表現する際に使用する。包含の逆である。

作成時の注意点

ユースケース図作成時の注意点について記載する。
  • 網羅的に書く
  • 利用者やユースケースは省略せずにすべて書く。
  • 利用者視点で書く
  • ユースケース図は、開発者ではなく、システム利用者視点で書く。
  • シンプルに書く
  • 分岐条件やシステム内部のロジックなどは書かない。
  • 機能分割しない
  • ユースケースを詳細な機能に分割しない。
  • ユースケースの粒度を統一する
  • ユースケースの粒度(抽象度)を均一にする。
  • 表現を統一する
  • 同じ意味の内容は、同じ表現で記載する。
  • ユースケース記述も一緒に作成する
  • ユースケース名、概要、利用者、事前条件、トリガー、処理フローについての資料も別途作成しておく。

まとめ


  • PlantUMLでユースケース図を作成する方法を調査、記載した


参考文献



変更履歴


  1. 2020/05/06: 新規作成

PlantUMLで配置図作成

背景


システムの全体設計で配置図を作成する必要があり、Gitで差分管理が可能な配置図作成ツールを調査した。

記事の目的


PlantUMLで配置図を作成する

配置図


配置図について記載する。

配置図とは

配置図は、システムの物理的側面(ハードウェア構成や通信経路等)を記述したものである。

配置図の描き方

  • 要素
  • @startuml
    actor Actor
    card Card
    cloud Cloud
    component Component
    database Database
    file File
    folder Folder
    frame Frame
    interface Interface
    node Node
    package Package
    storage Strage
    @enduml
    システムの構成要素を表す。
    • 利用者(Actor)
      利用者を表す。
    • カード(Card)
      認証カードや社員証などのカードを表す。
    • クラウド(Cloud)
      AWSやAzureなどのクラウドサービスを表す。
    • コンポーネント(Component)
      クラスやオブジェクトなどのソフトウェアの最小単位
    • データベース(Database)
      SQLやMongoなどのデータベースを表す。
    • ファイル(File)
      データの最小単位。
    • フォルダ(Folder)
      ファイルをまとめた構造体を表す。
    • フレーム(Frame)
      特定の構造、規則に基づいて作成されたソフトウェア群を表す。
    • インターフェース(Interface)
      ネットワークインターフェースなど、複数要素の接続点を表す。
    • ノード(Node)
      PCなどのハードウェアの最小単位
    • パッケージ(Package)
      特定の目的のために作成されたソフトウェア群を表す。
    • ストレージ(Strage)
      NAS、blob-strageなどの記憶媒体を表す。
  • 入れ子表現
  • @startuml
    node "Controle PC" {
        frame "ROS" {
            component "Controle node"
        }
    }
    @enduml
    システムの親子関係を表すことができる。
  • 接続
  • @startuml
    node "Control PC" as p{
        frame "ROS" {
            component "Control node" as c
            component "Communication node" as com
            component "rviz" as r
        }
        interface "/dev/usb_ctr" as i1
        interface "Full size HDMI" as i2
        interface "LTE dongle" as i3
    }
    node "Robot arm" as a
    node "Monitor" as m
    cloud "Cloud vpn network" {
        interface "10.0.0.2" as n1
    }
    /'ROS network'/
    com --> c
    c   --> r
    
    /'Control network'/
    c  ->  i1
    i1 --> a: USB
    
    /'Monitor network'/
    r  -left-> i2
    i2 -down-> m: HDMI
    
    /'Communication network'/
    com <-left-> i3
    i3  <-up->   n1: LTE
    @enduml
    システムの接続関係を表すことができる。矢印はデータの流れる向きを表す。ノードの中身を抽象化し、省略する場合もある。

まとめ


  • PlantUMLでコンポーネント図を作成する方法を調査、記載した

参考文献


変更履歴


  1. 2020/05/06: 新規作成

PlantUMLでシーケンス図作成

背景


システムの詳細設計でシーケンス図を作成する必要があり、Gitで差分管理が可能なクラス図作成ツールを調査した。

記事の目的


PlantUMLでシーケンス図を作成する

シーケンス図


シーケンス図について記載する。

シーケンス図とは

シーケンス図は、クラスやオブジェクト間のやりとりを時間軸に沿って表現したものである。

シーケンス図の描き方

  • ライフライン(Lifeline)
  • @startuml
    participant Participant
    actor Actor
    database Database
    collections Collections
    @enduml
    使用するオブジェクトやクラスを表す。利用者(Actor)、オブジェクトやクラス(Participant)、データベース(Database)、集合(Collections)がある。
  • 実行仕様(ExecutionSpecification)
  • @startuml
    participant Participant
    Participant -> Participant: Activate
    activate Participant
    Participant -> Participant: Deactivate
    deactivate Participant
    @enduml
    生成されているライフラインが実行状態であることを表す。
  • 停止(Stop)
  • @startuml
    participant Participant
    activate Participant
    Participant -> Participant: Destroy
    destroy Participant
    @enduml
    生成されたライフライン自体の消滅を表す。
  • メッセージ(Message)
  • @startuml
    participant Client as c
    participant Server as s
    activate c
    c -> s : Synchronous message
    activate s
    s --> c: Reply message
    c ->> s: Asynchronous message
    [o->  s: Found message
    c ->o] : Lost message
    @enduml
    データやトリガーの通信を表す。
    • 同期(Synchronous)メッセージ
    • 送り先のライフラインの実行に同期されるメッセージを表す。
    • 非同期(Asynchronous)メッセージ
    • 送り先のライフラインの実行に同期されないメッセージを表す。
    • 応答(Reply)メッセージ
    • 送り先のライフラインから送り手への戻り値を表す。
    • ファウンド(Found)メッセージ
    • 図解上にない送り手から送られた、もしくは送り手がダイアグラム上にないことを表す。
    • ロスト(Lost)メッセージ
    • 意図された受け手に送られていない、もしくは受け手がダイアグラム上にないことを表す。
  • 参照(Reference)
  • @startuml
    participant Client as c
    participant Server as s
    activate c
    c -> s : Connect
    activate s
    c -> s : Login
    ref over s
        Check id and password
        sequence
    end ref
    s --> c: Result
    @enduml
    別で定義されてるシーケンス図を参照することを表す。
  • 条件分岐(Alternative)
  • @startuml
    participant Client as c
    participant Server as s
    activate c
    c -> s : Connect
    activate s
    c -> s : Login
    s -> s : Check ID and password
    alt ID and password are matched
        s --> c: Send token
    else not matched
        s --> c: Disconnect
    else ID is not exist
        s --> c: Disconnect
    end
    @enduml
    条件による処理の分岐を表す。
  • 条件判断(Option)
  • @startuml
    participant Client as c
    participant Server as s
    activate c
    c -> s : Connect
    activate s
    c -> s : Login
    s -> s : Check ID and password
    opt ID and password are matched
        s --> c: Send an authorized token
    end
    @enduml
    条件を満たす場合に処理を実行することを表す。
  • 並列処理(Parallel)
  • @startuml
    participant Client as c
    participant Server as s
    database    "Login record DB" as db
    activate c
    c -> s : Connect
    activate s
    c -> s : Login
    s -> s : Check ID and password
    opt ID and password are matched
        par
            s -> s : Create an authorized token
            s --> c: Send an authorized token
        else
            s -> db: Send login time
            activate db
            db -> db: Record login time
            deactivate db
        end
    end
    @enduml
    複数の処理を並列で実行することを表す。
  • 反復処理(Loop)
  • @startuml
    collections Client as c
    participant Server as s
    activate c
    activate s
    opt Time is 00:00
        loop Number of connected clients
            s -> c : Check client status
            c --> s: Send status
        end
    end
    @enduml
    処理を反復実行することを表す。
  • 中断(Break)
  • @startuml
    collections Client as c
    participant Server as s
    activate c
    activate s
    opt Time is 00:00
        loop Number of connected clients
            s -> c : Check client status
            c --> s: Send status
            break Client status is illegal
                loop Number of connected clients
                    s -> c : Disconnect
                end
            end
        end
    end
    @enduml
    反復処理中に特定の条件を満たした場合、(決められた処理を行い)反復処理を中止することを表す。
  • クリティカルセッション(Critical)
  • @startuml
    participant Client as c
    participant Server as s
    database    "Login record DB" as db
    activate c
    c -> s : Connect
    activate s
    c -> s : Login
    s -> s : Check ID and password
    opt ID and password are matched
        par
            s -> s : Create an authorized token
            s --> c: Send an authorized token
            s -> db: Send an authorized token
            critical
                activate db
                db -> db: Record an authorized token
                deactivate db
            end
        else
            s -> db: Send login time
            critical
                activate db
                db -> db: Record login time
                deactivate db
            end
        end
    end
    @enduml
    並列処理中に、排他制御された処理を表す。
  • アサート(Assert)
  • @startuml
    participant Client as c
    participant Server as s
    database    "Deposit record DB" as db
    activate c
    activate s
    c -> s : Send transfer information
    group assert 
    s -> db: Update deposit amount
    note right : Deposit amount = Transfer amount + Previous deposit amount
    activate db
    db -> db: Record deposit amount
    deactivate db
    end
    @enduml
    処理結果の妥当性を保証しなければならないことを表す。
  • 不正なシーケンス(Negative)
  • @startuml
    participant Client as c
    participant Server as s
    database    "Deposit record DB" as db
    activate c
    activate s
    c -> s : Send transfer information
    alt Deposit amount = Transfer amount + Previous deposit amount 
        s -> db: Update deposit amount
        activate db
        db ->db: Record deposit amount
        s --> c: Send accept msg
        deactivate db
    else Deposit amount != Transfer amount + Previous deposit amount 
        group neg
            s -->c : Send error msg
        end
    end
    @enduml
    処理が通常起こりえない処理である(異常系である)ことを表す。
  • 無効(Ignore)
  • @startuml
    participant Client as c
    participant Server as s
    activate c
    c -> s : Connect
    activate s
    group ignore {Send client status}
    c -> s : Login(Send id, password)
    c -> s : Send client status
    end
    s -> s : Check ID and password
    alt ID and password are matched
        s --> c: Send token
    else not matched
        s --> c: Disconnect
    end
    @enduml
    必須ではない処理を{}内に記載する。
  • 有効(Consider)
  • @startuml
    participant Client as c
    participant Server as s
    activate c
    c -> s : Connect
    activate s
    group consider {Login(Send id, password)}
    c -> s : Login(Send id, password)
    c -> s : Send client status
    end
    s -> s : Check ID and password
    alt ID and password are matched
        s --> c: Send token
    else not matched
        s --> c: Disconnect
    end
    @enduml
    必須な処理を{}内に記載する。
  • セクション(Section)
  • @startuml
    participant Client as c
    participant Server as s
    activate c
    == Make connection ==
    c -> s : Connect
    activate s
    == Login ==
    c -> s : Login
    ref over s
        Check id and password
        sequence
    end ref
    s --> c: Result
    @enduml
    セクションで区切ると、処理をまとめて整理できる。
  • オブジェクト生成(Create)
  • @startuml
    participant parent as p
    activate p
    p -> p: Initial process
    create participant child as c
    p -> c: New
    @enduml
    オブジェクト(インスタンス)を生成していることを表す。

まとめ


  • PlantUMLでシーケンス図を作成する方法を調査、記載した

参考文献



変更履歴


  1. 2020/05/06: 新規作成

MQTTの導入

背景 IoTデバイスの接続環境構築のため、MQTT(mosquitto)の導入を行った。 記事の目的 MQTT(mosquitto)をUbuntuに導入する mosquitto ここではmosquittoについて記載する。 MQTT MQTT(Message Qu...