

# Java ランタイムを使用した Canary スクリプトの記述
<a name="Synthetics_WritingCanary_Java"></a>

**Topics**
+ [Canary の Java プロジェクトの構造](#Synthetics_canary_Java_package)
+ [Canary プロジェクトのパッケージ化](#Synthetics_canary_Java_package_canary)
+ [ハンドラー名](#Synthetics_canary_Java_handler)
+ [CloudWatch Synthetics の設定](#Synthetics_canary_Java_config)
+ [CloudWatch Synthetics 環境変数](#Synthetics_canary_Java_variables)

## Canary の Java プロジェクトの構造
<a name="Synthetics_canary_Java_package"></a>

Java で Canary を作成するには、記述したコードをコンパイルし、コンパイル後のアーティファクトを Synthetics にデプロイする必要があります。Java Lambda プロジェクトはさまざまな方法で初期化できます。例えば、IntelliJ IDEA や Visual Studio Code といった任意の IDE での標準 Java プロジェクト設定などを使用できます。または、必要なファイル構造を手動で作成することもできます。

Synthetics Java プロジェクトの一般的な構造は、次のとおりです。

```
/project-root
    └ src
        └ main
            └ java
                └ canarypackage // name of package
                |    └ ExampleCanary.java // Canary code file
                |    └ other_supporting_classes
                - resources
                     └ synthetics.json // Synthetics configuration file    
     └ build.gradle OR pom.xml
```

Maven または Gradle を使用してプロジェクトを構築し、依存関係を管理できます。

上記の構造の `ExampleCanary` クラスは、Canary のエントリポイントまたはハンドラーです。

 **Java Canary クラスの例** 

この例では、Canary が Lambda 環境変数 *TESTING\$1URL* に格納されている URL に対して、get リクエストを実行しています。Canary は Synthetics ランタイムのメソッドは使用しません。

```
package canarypackage;

import java.net.HttpURLConnection;
import java.net.URL;

// Handler value: canary.ExampleCanary::canaryCode
public class ExampleCanary { 
  public void canaryCode() throws Exception{ 
      URL url = new URL(System.getenv("TESTING_URL"));
      HttpURLConnection con=(HttpURLConnection)url.openConnection();
      con.setRequestMethod("GET");
      con.setConnectTimeout(5000);
      con.setReadTimeout(5000);
      int status=con.getResponseCode();
      if(status!=200){
        throw new Exception("Failed to load " + url + ", status code: " + status);
      }
  }
}
```

Synthetics のライブラリ関数 `executeStep` を使用して、Canary をモジュール化することを強くお勧めします。Canary は環境変数 URL1 および URL2 から取得した 2 つの URL に対して `get` 呼び出しを実行します。

**注記**  
`executeStep` の機能を使用するには、Canary のハンドラーメソッドで、次に示すようにタイプ Synthetics のパラメータを使用する必要があります。

```
package canarypackage;

import com.amazonaws.synthetics.Synthetics;
import java.net.HttpURLConnection;
import java.net.URL;

// Handler value: canary.ExampleCanary::canaryCode
public class ExampleCanary {
  public void canaryCode(Synthetics synthetics) throws Exception {
    createStep("Step1", synthetics, System.getenv("URL1"));
    createStep("Step2", synthetics, System.getenv("URL2"));
    return;
  }
  
  private void createStep(String stepName, Synthetics synthetics, String url) throws Exception{
    synthetics.executeStep(stepName,()->{
      URL obj=new URL(url);
      HttpURLConnection con=(HttpURLConnection)obj.openConnection();
      con.setRequestMethod("GET");
      con.setConnectTimeout(5000);
      con.setReadTimeout(5000);
      int status=con.getResponseCode();
      if(status!=200){
        throw new Exception("Failed to load" + url + "status code:" + status);
      }
      return null;
    }).get();
  }
}
```

## Canary プロジェクトのパッケージ化
<a name="Synthetics_canary_Java_package_canary"></a>

Synthetics は Java Canary のコードを *zip* 形式で受け入れます。Canary コードの zip は、Canary コード用のクラスファイル、サードパーティーの依存関係用の jar ファイル、Synthetics の設定ファイルで構成されます。

Synthetics Java の zip ファイルの一般的な構造は、次のとおりです。

```
example-canary
    └ lib
    |  └ //third party dependency jars
       └ java-canary.jar
    └ synthetics.json
```

上記のプロジェクト構造からこの zip をビルドするには、gradle (build.gradle) または maven (pom.xml) を使用します。以下はその例です。

Synthetics ライブラリのコンパイル時の依存関係やインターフェイスについては、[aws-cloudwatch-synthetics-sdk-java](https://github.com/aws/aws-cloudwatch-synthetics-sdk-java/tree/main) の README を参照してください。

```
plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    // Third party dependencies 
    // example: implementation 'software.amazon.awssdk:s3:2.31.9'
    
    // Declares dependency on Synthetics interfaces for compiling only
    // Refer https://github.com/aws/aws-cloudwatch-synthetics-sdk-java for building from source.
    compileOnly 'software.amazon.synthetics:aws-cloudwatch-synthetics-sdk-java:1.0.0'}

test {
    useJUnitPlatform()
}

// Build the zip to be used as Canary code.
task buildZip(type: Zip) {

    archiveFileName.set("example-canary.zip")
    destinationDirectory.set(file("$buildDir"))
    
    from processResources
    into('lib') {
        from configurations.runtimeClasspath
        from(tasks.named("jar"))
    }
    from "src/main/java/resources/synthetics.json"
    
    doLast {
        println "Artifact written to: ${archiveFile.get().asFile.absolutePath}"
    }
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

tasks.named("build") {
    dependsOn "buildZip"
}
```

## ハンドラー名
<a name="Synthetics_canary_Java_handler"></a>

ハンドラー名は Canary のエントリポイントです。Java ランタイムの場合、ハンドラーは次の形式になります。

```
<<full qualified name for canary class>>::<<name of the method to start the execution from>>
// for above code: canarypackage.ExampleCanary::canaryCode
```

## CloudWatch Synthetics の設定
<a name="Synthetics_canary_Java_config"></a>

Synthetics Java ランタイムの動作を設定するには、`synthetics.json` という名前のオプション JSON 設定ファイルを指定します。このファイルは、パッケージ化して zip パッケージのルートディレクトリに配置する必要があります。設定ファイルはオプションですが、設定ファイルを指定しない場合、または設定キーがない場合、CloudWatch はデフォルトを使用します。

サポートされている設定値とそのデフォルト値を次に示します。

```
{
    "step": {
        "stepSuccessMetric": true,
        "stepDurationMetric": true,
        "continueOnStepFailure": false,
        "stepsReport": true
    },
    "logging": {
        "logRequest": false,
        "logResponse": false
    },
    "httpMetrics": {
        "metric_2xx": true,
        "metric_4xx": true,
        "metric_5xx": true,
        "aggregated2xxMetric": true,
        "aggregated4xxMetric": true,
        "aggregated5xxMetric": true
    },
    "canaryMetrics": {
        "failedCanaryMetric": true,
        "aggregatedFailedCanaryMetric": true
    }
}
```

 **ステップ設定** 
+ *continueOnStepFailure* – ステップが失敗した後もスクリプトを続行するかどうかを決定します。デフォルトは False です。
+ *stepSuccessMetric* – ステップの ` SuccessPercent` メトリクスが出力されるかどうかを決定します。ステップの `SuccessPercent` メトリクスは、ステップが成功した場合は Canary 実行の値が *100* になり、ステップが失敗した場合は *0* になります。デフォルトは *True* です。
+ *stepDurationMetric* – ステップの *Duration* メトリクスが出力されるかどうかを決定します。出力される *Duration* メトリクスは、ミリ秒単位でステップの経過時間を表します。デフォルトは *true* です。

 **ロギング設定** 

CloudWatch Synthetics によって生成されたログに適用されます。リクエストログとレスポンスログの詳細度を制御します。
+ *logRequest* - すべてのリクエストを Canary ログに記録するかどうかを指定します。デフォルトは False です。
+ *logResponse* - すべてのレスポンスを Canary ログに記録するかどうかを指定します。デフォルトは False です。

 **HTTP メトリクス設定** 

この Canary の CloudWatch Synthetics によって出力される、異なる HTTP ステータスコードを持つネットワークリクエストの数に関連するメトリクスの設定。
+ *metric\$12xx* – この Canary の *2xx* メトリクスを (canaryName ディメンションと一緒に) 出力するかどうかを指定します。デフォルトは *True* です。
+ *metric\$14xx* – この Canary の *4xx* メトリクスを (canaryName ディメンションと一緒に) 出力するかどうかを指定します。デフォルトは *True* です。
+ *metric\$15xx* – この Canary の *5xx* メトリクスを (canaryName ディメンションと一緒に) 出力するかどうかを指定します。デフォルトは *True* です。
+ *aggregated2xxMetric* – この Canary の *2xx* メトリクスを (canaryName ディメンションは出力せずに) 出力するかどうかを指定します。デフォルトは *True* です。
+ *aggregated4xxMetric* – この Canary の *4xx* メトリクスを (canaryName ディメンションは出力せずに) 出力するかどうかを指定します。デフォルトは *True* です。
+ *aggregated5xxMetric* – この Canary の *5xx* メトリクスを (canaryName ディメンションは出力せずに) 出力するかどうかを指定します。デフォルトは *True* です。

 **Canary メトリクス設定** 

CloudWatch Synthetics によって出力される他のメトリクスの設定。
+ *failedCanaryMetric* Network Access Analyzer でこの Canary の *Failed* メトリクスを (canaryName ディメンションと一緒に) 出力するかどうかを指定します。デフォルトは *True* です。
+ *aggregatedFailedCanaryMetric* – この Canary の *Failed* メトリクスを (CanaryName ディメンションは出力せずに) 出力するかどうかを指定します。デフォルトは *True* です。

## CloudWatch Synthetics 環境変数
<a name="Synthetics_canary_Java_variables"></a>

環境変数を使用してログ記録レベルと形式を設定できます。

 **ログ形式** 

CloudWatch Synthetics Java ランタイムは、Canary の実行ごとに CloudWatch ログを作成します。ログは、クエリしやすいように JSON 形式で書き込まれます。必要に応じて、ログ形式を *TEXT* に変更できます。
+ *環境変数名* – CW\$1SYNTHETICS\$1LOG\$1FORMAT
+ *サポートされる値* – JSON、TEXT
+ *デフォルト* – JSON

 **ログレベル** 
+ *環境変数名* – CW\$1SYNTHETICS\$1LOG\$1LEVEL
+ *サポートされる値* – TRACE、DEBUG、INFO、WARN、ERROR、FATAL
+ *デフォルト* – INFO

上記の環境変数以外に、Java ランタイム用のデフォルトの環境変数、`AWS_LAMBDA-EXEC_WRAPPER` 環境変数が関数に追加され、その値が `/opt/synthetics-otel-instrument` に設定されます。この環境変数によりテレメトリの関数の起動時動作が変更されます。この環境変数が既に存在する場合は、必要な値に設定されていることを確認してください。