virtualBox上(ゲストOS)のValKeyへ(ホストOSの)Eclipseからデータの登録､取得を試みる

# 1,目的
virtualBox上(ゲストOS)のValKeyへ(ホストOSの)Eclipseからデータの登録､取得(CRUD)を試みる｡

# 2､環境概要

◯ホストOS
- Windos11
- Eclipse
- virtualBox:7.0

◯ゲストOS(virtualBox内の仮想環境)
- Ubuntu:22.04
- Docker:27.2.1
- ValKey:7.2.6

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/48933519-d8e8-5635-9485-2c7d2d160039.png)

# 3､概要
①EclipseからValKeyへCRUDできるよう､｢spring-data-redis ｣環境を作成
②EclipseからValKeyへ接続できるよう､virtualBoxのポートフォワーディングとValKeyのポート設定を行う｡

# 4､作業
## 1､virtualBoxのネットワーク設定
### 1､設定したい仮想環境にフォーカス後設定押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/6564d80d-e03d-1fa1-9071-40d54fc38cf0.png)

### 2､アダプター2タブを押下
アダプター2タブでホストオンリーアダプターを設定｡
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/3331304e-a93a-e392-414d-bafbb1d0d1d4.png)

### 3､ホストオンリーネットワークのDHCPが有効になっていることを確認
ツール押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/de5a4b45-0642-8d01-2ad6-b457ac745e5c.png)

### 4､Ubuntuターミナルで仮想OSのIPアドレスを確認
ターミナルで
```
ip addr show
```
enp0s8がホストオンリーアダプターで設定されたIPアドレス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/60f9be39-1625-494d-f291-ffa2c291fa1d.png)

※ホストオンリーアダプター
ホストOSとゲストOSの通信を可能とする設定

### 5､NATのポートフォワーディングを設定して､Docker内のValKeyとの通信を可能とする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/6564d80d-e03d-1fa1-9071-40d54fc38cf0.png)



アダプター1タブ→高度→ポートフォワーディング押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/0d5ce4c6-7b6d-b5aa-3bb7-7c25fa6a640f.png)

+ボタン押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/31ef47d9-187f-364e-beb0-43eb6ac1827a.png)

ゲストIPへ先程のIPを記入
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/95e6d106-afe4-e911-607e-f6349f58290c.png)

ホストOSのIPを確認
Windows PowerShell で
```
ipconfig
```

いろいろ出てくるが､自分の場合はWi-Fi
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/55d54c3c-2e67-5ec5-6a08-705107308a39.png)

ホストポート番号はEclipseのApplication.propertiesで設定する番号
ゲストポートはValKeyに接続する際に必要となる番号

valkeyコンテナのport番号を調べる
valkeyコンテナ起動→ps
```
docker run --name valkey --rm -d valkey/valkey:7.2.6
docker ps
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/419dcea0-9788-d5e4-c95a-12cadaae814b.png)

ポートフォワーディングへ入力｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/c0ea0903-5127-ada6-26da-e5a2b2fc125c.png)

※valkeyコンテナを止めたい場合
```
docker stop valkey
```

### 6､Ok押下

virtualBoxの設定は一旦終了｡


## 2､Eclipse(Gradleプロジェクト)にspring-data-redis を導入
### 1. Gradleビルドファイルへの依存関係追加
build.gradeleへ下記を追記

```XML
dependencies {
    // ... (既存の依存関係)
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}
```
この依存関係を追加することで、Spring Data Redisに必要なライブラリが自動的にダウンロードされ、プロジェクトに追加されます。

### 2. Redisの設定
※Redisの設定と書いてありますが､ValKeyがRedisをフォークして作成されたものであるため､まだまだRedisの機能が残っているからです｡

application.properties (または application.yml) ファイルに、Redisへの接続情報を設定します。

```XML
// virtualBoxで設定したゲストOSのIPを設定
spring.data.redis.host=192.168.56.102
// virtualBoxで設定したホストOSのポート番号を設定
spring.data.redis.port=6379 
```

Geminiで調べると
```
spring.redis.host=localhost
spring.redis.port=6379
```
という古い書き方を教えてくれるので注意が必要｡ここに気づかず､半日ほどハマりました｡｡｡


### 3. Redis Repositoryの作成
Spring Data Redisでは、Redis(ValKey)とやり取りするためのRepositoryインターフェースを作成します。

※RedisTemplateを使用した方法は[別記事](https://qiita.com/tanaka_taro_JP_KYUSYU/items/886cd9cf6d64d21f7aab)で記載します｡RedisTemplateの方が要なオーバーヘッドが少なく､動作が早いようです｡

```java
package com.example.demo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends CrudRepository<UserEntity, String> {
}
```
CrudRepository: CRUD操作（Create, Read, Update, Delete）を定義するインターフェース
UserEntity: Redisに保存するエンティティクラス 
~~

### 4. Entityクラスの作成
Redis(ValKEy)に保存するデータの構造を定義するエンティティクラスを作成します。

```java
package com.example.demo;

import org.springframework.data.redis.core.RedisHash;

import lombok.Data;

@Data
@RedisHash("users") 
public class UserEntity {
    private String id;
    private String name;
    // 他のプロパティ (年齢、メールアドレスなど)
}
```
@RedisHash: Redisのハッシュにマッピングするアノテーション

>@RedisHash("users") は、一般的にJavaのSpring Frameworkなどのアプリケーションにおいて、RedisというNoSQLデータベースのHash型のデータ構造をアノテーションによって定義していることを示します。
>@RedisHash: このアノテーションは、Spring Data Redisの機能であり、Javaのクラスに付与することで、そのクラスをRedisのHashにマッピングします。
"users": この文字列は、Redis内のHashのキー名です。つまり、"users"という名前のHashがRedisに作成され、このクラスのインスタンスがそのHashに格納されます。

### 5. サービス層での利用
本来はサービスを作成すべきですが､EclipseとValKeyのデータのやり取りを確認したいため､今回はControllerへ直接記載しました｡

```java
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class DemoController {
    @Autowired
    private UserRepository userRepository;

    @GetMapping("/save")
    public String saveUser() {
        UserEntity user = new UserEntity();
        user.setId("1");
        user.setName("Taro");
        userRepository.save(user);
        return "redirect:/check"; // 保存後にリダイレクトし､/checkメソッドへ飛ぶ
    }
    
    @GetMapping("/check") // saveメソッドで登録された後こちらへ移動
    public String checkUser() {
        UserEntity user = userRepository.findById("1").orElse(null);
        if (user != null) {
            // userの情報を表示したり、他の処理を行う
            System.out.println("User: " + user);
        } else {
            // ユーザーが見つからない場合の処理
        }
        return "redirect:https://www.google.com/";
    }

    @GetMapping("/findUser")
    public String findUser(@RequestParam("id") String id, Model model) {
        UserEntity user = userRepository.findById(id).orElse(null);
        model.addAttribute("user", user);
        return "user"; // user.htmlにフォワードする例
    }
}
```

### 6. Gradleプロジェクトの再ビルド
Gradleプロジェクトを再ビルドし、変更を反映させます。

### 7. アプリケーションの実行
Spring Bootアプリケーションを実行します。

## 3､ValKey起動(ポート番号設定)
### 1､ValKey起動
Ubuntuターミナルで
```
docker run --name valkey --rm -d valkey/valkey
```
docker run: Dockerコンテナを起動するコマンド
--name valkey: コンテナに付ける名前です。後から停止や削除を行う際に便利です。
--rm: コンテナが停止した際に、自動的にコンテナを削除します。
-d: デタッチモードでコンテナを起動します。フォアグラウンドで実行せずにバックグラウンドで実行されます。
valkey/valkey: 使用するDockerイメージの名前です。Valkeyの公式イメージであることを想定しています。

### 2.ValKeyのポート番号を確認

```
docker ps
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/241385a4-f115-c2e2-24f9-e84f3d16551e.png)
valkeyのポート番号はデフォルトで6379らしい｡

### ゲストOSからのポート接続
一旦起動させたvalkeyを止める
```
docker stop valkey
```

valkey : 先ほどつけた名前

ポート番号指定でvalkey起動
```
docker run --name valkey --rm -d -p 6379:6379 valkey/valkey

```
-p 6379:6379: コンテナ内のポート6379をUbuntuのポート6379にマッピングします。これにより、Ubuntuマシンからvalkeyへアクセスできるようになります。

## 4､動作確認
### Webブラウザーのアドレスへ
```
localhost:8080/save
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/d79a0103-f3f5-1cad-e919-ba72499fc6bc.png)

設定がうまく行っていればGoogleへリダイレクト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/f8fc11d2-cc19-48d7-dd1e-8c4669e2263d.png)

コンソールへ登録したデータが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877686/d820c02b-f6e1-2df5-6b68-e300e82685ea.png)


# 5､まとめ
以上でホストOS上のEclipseからゲストOSのDockerで稼働させたvalkeyへのCRUD(登録等)の動作確認が終わりました｡

Redisが大人の事情で使用できなくなったため､valkeyを導入することになったのですが､まだまだ日が浅いということで､ネット上の記事が少なかったため執筆しました｡

どなたかの役に少しでも立てれば幸いです｡

※都度都度docker run コマンドを入力する手間を省くため､[次の記事](https://qiita.com/tanaka_taro_JP_KYUSYU/items/a67eef5265d041834f29)でdocker-compose.ymlを使用してみました｡