2023年9月16日土曜日

Arch Linux に MS 公式バイナリバージョンの VSCode をインストールする

前提

  • OS: Arch Linux
  • VSCode: 1.81.1-1

手順

以下の通り。

# AUR リポジトリからソースコードをクローン
git clone https://aur.archlinux.org/visual-studio-code-bin.git
cd visual-studio-code-bin
# Arch 用パッケージ作成
makepkg -s
# パッケージインストール
sudo pacman -U ./visual-studio-code-bin-1.81.1-1-x86_64.pkg.tar.zst

以上。

2023年8月20日日曜日

git submodule で管理しているサブモジュールが全部 HEAD detached になったから一括でデフォルトブランチに直す

前提

  • OS: WSL 上の Ubuntu 20.04
  • git: git version 2.25.1

やりかた

対象の git リポジトリで以下コマンドを実行。

git submodule foreach "git switch \$(git symbolic-ref refs/remotes/origin/HEAD | cut -f4 -d'/')"

解説

git symbolic-ref refs/remotes/origin/HEAD で、デフォルトブランチが取得できる。

デフォルトブランチは、 refs/remotes/origin/<DEFAULT_BRANCH_NAME> という形式で出力されるので、 cut コマンドで「‘/’ 区切りの 4 番目の値」を取ってくる。

参照資料

2023年7月26日水曜日

Java で Protocol Buffers をやる

前提

  • Windows 11 Pro 22H2 22621.1848
  • Docker Desktop version 4.20.1 (110738)
  • 使用する Docker イメージ: eclipse-temurin:17

Maven プロジェクト作成

spring initializr で、 Mavem + Java17 + Lombok のプロジェクトを作成し、展開する

開発用コンテナ起動

共通ボリュームとして maven_data を利用しているので、あらかじめボリュームを作成しておいてください。

docker volume create maven_data

そのうえで、 docker compose コマンドで開発用コンテナを立ち上げます。

docker compose up -d

開発用コンテナへ接続

以下コマンドで app コンテナへ接続し、その中で開発を行ってください。

docker compose exec app bash

Protocol Buffers に必要なパッケージのインストール

apt update
apt install -y protobuf-compiler

Protocol Buffers のコンパイルに必要なライブラリを pom.xml に追加

  • protobuf-java : 生成する Java ソースコードをコンパイルするためのライブラリ
  • protobuf-java-util : Protocol Buffers 用便利 API を使うためのライブラリ
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.23.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.23.0</version>
        </dependency>

.proto の作成

通信フォーマットを定義する .proto ファイルを作成する。

今回は、 ${PROJECT_ROOT}/proto/MemberInfo.proto に以下内容でファイルを作成。

syntax = "proto3";

option java_multiple_files = false;
option java_package="dev.mikoto2000.javastudy.protocolbuffers.firststep.model";

message CommonInfo {
  string timestamp = 1;
}

message TeacherProps {
  string teacher_id = 1;
}

message StudentProps {
  string student_id = 1;
}

message Member {
  string type = 1;
  string name = 2;
  oneof properties {
    TeacherProps teacher_props = 3;
    StudentProps student_props = 4;
  }
}

message MemberInfo {
  CommonInfo common_info = 1;
  repeated Member member = 2;
}

.proto から Java コードを生成

以下コマンドで、 Protocol Buffers のメッセージ作成に必要な Java コードを生成する。

protoc -I=./proto --java_out=./src/main/java/ ./proto/MemberInfo.proto

${PROJECT_ROOT}/src/main/dev/mikoto2000/javastudy/protocolbuffers/firststep/model/MemberInfoOuterClass.java にコードが生成される。

Protocol Buffers のエンコード・デコードを実装

簡単のために Spring Boot の CommandLineRunner を利用して処理を実装する。

package dev.mikoto2000.javastudy.protocolbuffers.firststep;

import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import com.google.protobuf.InvalidProtocolBufferException;

import dev.mikoto2000.javastudy.protocolbuffers.firststep.model.MemberInfoOuterClass.CommonInfo;
import dev.mikoto2000.javastudy.protocolbuffers.firststep.model.MemberInfoOuterClass.Member;
import dev.mikoto2000.javastudy.protocolbuffers.firststep.model.MemberInfoOuterClass.MemberInfo;
import dev.mikoto2000.javastudy.protocolbuffers.firststep.model.MemberInfoOuterClass.StudentProps;
import dev.mikoto2000.javastudy.protocolbuffers.firststep.model.MemberInfoOuterClass.TeacherProps;

/**
 * CliEntrypoint
 */
@Component
@Profile("!test")
public class CliEntrypoint implements CommandLineRunner {
    @Override
    public void run(String... args) throws InvalidProtocolBufferException {
        // MemberInfo の組み立て
        MemberInfo.Builder builder = MemberInfo.newBuilder();
        MemberInfo memberInfo = builder
            .setCommonInfo(CommonInfo.newBuilder().setTimestamp("1234567890").build())
            .addMember(Member.newBuilder()
                    .setType("student")
                    .setStudentProps(StudentProps.newBuilder()
                        .setStudentId("mikoto2000")
                        .build())
                    .build())
            .addMember(Member.newBuilder()
                    .setType("teacher")
                    .setTeacherProps(TeacherProps.newBuilder()
                        .setTeacherId("makoto2000")
                        .build())
                    .build())
            .build();

        System.out.printf("memberInfo: %s\n", memberInfo);

        // エンコード
        byte[] memberInfoBytes = memberInfo.toByteArray();

        // デコード
        MemberInfo memberInfoFromByteArray = MemberInfo.parseFrom(memberInfoBytes);

        System.out.printf("memberInfoFromByteArray: %s\n", memberInfoFromByteArray);

        // エンコード前後の結果比較
        System.out.printf("memberInfo.toString().equals(memberInfoFromByteArray.toString()): %s\n", memberInfo.toString().equals(memberInfoFromByteArray.toString()));
    }
}

動作確認

./mvnw spring-boot:run

以下のような出力になる。(Maven の出力や、 Spring Boot のロゴは省略)

memberInfo: common_info {
  timestamp: "1234567890"
}
member {
  type: "student"
  student_props {
    student_id: "mikoto2000"
  }
}
member {
  type: "teacher"
  teacher_props {
    teacher_id: "makoto2000"
  }
}

memberInfoFromByteArray: common_info {
  timestamp: "1234567890"
}
member {
  type: "student"
  student_props {
    student_id: "mikoto2000"
  }
}
member {
  type: "teacher"
  teacher_props {
    teacher_id: "makoto2000"
  }
}

memberInfo.toString().equals(memberInfoFromByteArray.toString()): true

うん、できている気がする。

以上。

参考資料

2023年5月4日木曜日

Arch Linux に mlterm をインストールする

前提

  • base-devel パッケージインストール済みであればこれで行けるはず…

AUR リポジトリのクローン

git clone https://aur.archlinux.org/mlterm.git
cd mlterm

パッケージのビルド

makepkg -s
  • -s: ビルド依存関係をインストール

ビルドしたパッケージのインストール

sudo pacman -U ./mlterm-3.9.2-1-x86_64.pkg.tar.zst

参考資料

2023年2月2日木曜日

Docker Hub の公式 RabbitMQ イメージで、 MQTT over WebSocket を試す

前提

  • OS: Windows 11 Pro 22H2 ビルド 22621.963
  • Docker Desktop: version 4.15.0 (93002)
  • 使用イメージ: rabbitmq:3.11

イメージの pull

docker pull rabbitmq:3.11

プラグインの一覧確認

docker run -it --rm --name rabbitmq rabbitmq:3.11 rabbitmq-plugins list

プラグイン有効化設定ファイルの作成

プラグイン有効化設定のためのファイルを作成し、 rabbitmq_mqttrabbitmq_web_mqtt を有効にする設定を記述。

echo "[rabbitmq_mqtt,rabbitmq_web_mqtt]." > enabled_plugins

MQTT over WebSocket の設定

今回は、エンドポイントのパスと、待ち受けポート番号を変更する。

echo "web_mqtt.ws_path = /mqtt" > rabbitmq.conf
echo "web_mqtt.tcp.port = 9090" >> rabbitmq.conf

RabbitMQ コンテナ起動

作成した設定ファイルを渡しつつ rabbitmq を実行。

docker run -it --rm --name rabbitmq -v "$(pwd)/enabled_plugins:/etc/rabbitmq/enabled_plugins" -v "$(pwd)/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf" -p "9090:9090" rabbitmq:3.11

動作確認

HiveMQ の MQTT WebSocket クライアント を使って、先ほど起動したコンテナへ接続する。

今回は、シークレットモードの FireFox, Google Chrome を使って、 testtopic/1 をサブスクライブしたりパブリッシュしたりしてみた。

はい、上手くできていそう。

以上。

参考資料