deveopers-memo

27

CSVファイル分割プログラム

def split_text_file(input_file, lines_per_file):
    with open(input_file, 'r') as file:
        lines = file.readlines()

    # ファイル名と拡張子を分離
    if '.' in input_file:
        base_name, ext = input_file.rsplit('.', 1)
        ext = '.' + ext
    else:
        base_name = input_file
        ext = ''

    file_count = 1

    for i in range(0, len(lines), lines_per_file):
        output_file_name = f'{base_name}_part{file_count}{ext}'
        with open(output_file_name, 'w') as output_file:
            output_file.writelines(lines[i:i + lines_per_file])
        file_count += 1

if __name__ == '__main__':
    input_file = 'example'  # 入力テキストファイルの名前(拡張子がなくても良い)
    lines_per_file = 10     # 各ファイルに含まれる行数

    split_text_file(input_file, lines_per_file)

txtファイル分割プログラム

import csv

def split_csv_file(input_file, lines_per_file):
    with open(input_file, 'r') as file:
        reader = csv.reader(file)
        header = next(reader)  # ヘッダー行を読み取る

        # ファイル名と拡張子を分離
        if '.' in input_file:
            base_name, ext = input_file.rsplit('.', 1)
            ext = '.' + ext
        else:
            base_name = input_file
            ext = ''

        file_count = 1
        rows = []

        for i, row in enumerate(reader, start=1):
            rows.append(row)
            if i % lines_per_file == 0:
                output_file_name = f'{base_name}_part{file_count}{ext}'
                with open(output_file_name, 'w', newline='') as out_file:
                    writer = csv.writer(out_file)
                    writer.writerow(header)
                    writer.writerows(rows)
                rows = []
                file_count += 1

        if rows:  # 残りの行がある場合、最後のファイルに書き込む
            output_file_name = f'{base_name}_part{file_count}{ext}'
            with open(output_file_name, 'w', newline='') as out_file:
                writer = csv.writer(out_file)
                writer.writerow(header)
                writer.writerows(rows)

if __name__ == '__main__':
    input_file = 'example.csv'  # 入力CSVファイルの名前(拡張子がなくても良い)
    lines_per_file = 10         # 各ファイルに含まれる行数

    split_csv_file(input_file, lines_per_file)

26

# test_file_writer.py
import unittest
import os
from file_writer import write_to_file

class TestFileWriter(unittest.TestCase):

    def setUp(self):
        # テスト用のファイルパスと期待する内容を初期化
        self.test_file_path = 'test_output.txt'
        self.expected_content = 'Hello, World!\nThis is a test.\n'

    def tearDown(self):
        # テストが終わった後にテスト用ファイルを削除
        if os.path.exists(self.test_file_path):
            os.remove(self.test_file_path)

    def test_write_to_file(self):
        # ファイルに書き込みを実行
        write_to_file(self.test_file_path, self.expected_content)

        # ファイルの内容を読み取り、期待する内容と比較
        with open(self.test_file_path, 'r') as f:
            file_content = f.read()

        self.assertEqual(file_content, self.expected_content)

if __name__ == '__main__':
    unittest.main()

25

# test_my_module.py
import unittest
from my_module import add, subtract

class TestMyModule(unittest.TestCase):

    def test_add(self):
        self.assertEqual(add(1, 2), 3)
        self.assertEqual(add(-1, 1), 0)
        self.assertEqual(add(-1, -1), -2)

    def test_subtract(self):
        self.assertEqual(subtract(2, 1), 1)
        self.assertEqual(subtract(-1, 1), -2)
        self.assertEqual(subtract(-1, -1), 0)

if __name__ == '__main__':
    unittest.main()

24

public class UtcToJstConverter {
    public static void main(String[] args) {
        // 例: 現在のUTC時間を取得
        Instant utcInstant = Instant.now();
        System.out.println("UTC時間: " + utcInstant);

        // UTC時間をJST時間に変換
        ZonedDateTime jstZonedDateTime = utcInstant.atZone(ZoneId.of("Asia/Tokyo"));
        System.out.println("JST時間: " + jstZonedDateTime);

        // JST時間をTimestamp型に変換
        Timestamp jstTimestamp = Timestamp.valueOf(jstZonedDateTime.toLocalDateTime());
        System.out.println("JST Timestamp: " + jstTimestamp);
    }
}

23

import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // 現在のミリ秒を取得
        long currentTimeMillis = System.currentTimeMillis();

        // Timestampオブジェクトを生成(UTC)
        Timestamp currentTimestampUTC = new Timestamp(currentTimeMillis);

        // UTCのTimestampをJSTのLocalDateTimeに変換
        LocalDateTime localDateTimeJST = currentTimestampUTC.toInstant()
                .atZone(ZoneId.of("Asia/Tokyo")).toLocalDateTime();

        // JSTのLocalDateTimeをエポックミリ秒に変換してTimestampを作成
        long jstEpochMillis = localDateTimeJST.atZone(ZoneId.of("Asia/Tokyo")).toInstant().toEpochMilli();
        Timestamp currentTimestampJST = new Timestamp(jstEpochMillis);

        // フォーマット設定
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

        // 結果を出力
        System.out.println("Current Timestamp (UTC): " + currentTimestampUTC);
        System.out.println("Current LocalDateTime (JST, formatted): " + localDateTimeJST.format(formatter));
        System.out.println("Current Timestamp (JST): " + currentTimestampJST);
    }
}

22

// 現在のミリ秒を取得
        long currentTimeMillis = System.currentTimeMillis();

        // Timestampオブジェクトを生成
        Timestamp currentTimestamp = new Timestamp(currentTimeMillis);

        // TimestampをInstantに変換
        Instant instant = currentTimestamp.toInstant();

        // InstantをZonedDateTimeに変換(JST)
        ZonedDateTime zonedDateTimeJST = instant.atZone(ZoneId.of("Asia/Tokyo"));

        // フォーマット設定
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

        // 結果を出力
        System.out.println("Current Timestamp (UTC): " + currentTimestamp);
        System.out.println("Current ZonedDateTime (JST): " + zonedDateTimeJST.format(formatter));

21

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // 現在のミリ秒を取得
        long currentTimeMillis = System.currentTimeMillis();

        // 現在のミリ秒をTimestampに変換
        Timestamp currentTimestamp = new Timestamp(currentTimeMillis);

        // Timestampを日本標準時 (JST) に変換
        LocalDateTime nowJST = currentTimestamp.toLocalDateTime().atZone(ZoneId.of("Asia/Tokyo")).toLocalDateTime();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

        // 結果を出力
        System.out.println("Current Timestamp (JST): " + nowJST.format(formatter));
    }
}

20

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // 日本標準時 (JST)で現在の日時を取得
        LocalDateTime nowJST = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        System.out.println("Current LocalDateTime (JST): " + nowJST.format(formatter));
    }
}

19

@startuml
<style>
activityDiagram {
  BackgroundColor #33668E
  BorderColor #33668E
  FontColor #888
  FontName arial

  diamond {
    BackgroundColor #ccf
    LineColor #00FF00
    FontColor green
    FontName arial
    FontSize 15
  }
  arrow {
    FontColor gold
    FontName arial
    FontSize 15
  }
  partition {
    LineColor red
    FontColor green
    RoundCorner 10
    BackgroundColor PeachPuff
  }
  note {
    FontColor Blue
    LineColor Navy
    BackgroundColor #ccf
  }
}
document {
   BackgroundColor transparent
}
</style>
start
:init;
-> test of color;
if (color?) is (<color:red>red) then
:print red;
else 
:print not red;
note right: no color
endif
partition End {
:end;
}
-> this is the end;
end
@enduml

18

provider "aws" {
  region = "us-west-2"  # 適切なAWSリージョンに変更してください
}

# Lambda用IAMロールの作成
resource "aws_iam_role" "lambda_exec_role" {
  name = "lambda_exec_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      }
    ]
  })
}

# Lambda用IAMロールのポリシーアタッチ
resource "aws_iam_role_policy_attachment" "lambda_policy" {
  role       = aws_iam_role.lambda_exec_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

# API Gateway用IAMロールの作成
resource "aws_iam_role" "api_gateway_role" {
  name = "api_gateway_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "apigateway.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      }
    ]
  })
}

# API Gateway用IAMロールのポリシーアタッチ(Lambdaを呼び出すためのポリシー)
resource "aws_iam_role_policy" "api_gateway_policy" {
  name = "api_gateway_policy"
  role = aws_iam_role.api_gateway_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = "lambda:InvokeFunction"
        Resource = "*"
      }
    ]
  })
}

# Lambda関数の作成
resource "aws_lambda_function" "my_lambda" {
  function_name = "my_lambda"
  handler       = "index.handler"
  runtime       = "nodejs14.x"

  role = aws_iam_role.lambda_exec_role.arn

  filename = "path/to/your/lambda/deployment/package.zip"  # Lambdaのデプロイバンドルのパス

  source_code_hash = filebase64sha256("path/to/your/lambda/deployment/package.zip")
}

# API Gatewayの作成
resource "aws_api_gateway_rest_api" "my_api" {
  name        = "MyAPIGateway"
  description = "API Gateway Example"
}

resource "aws_api_gateway_resource" "my_resource" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  parent_id   = aws_api_gateway_rest_api.my_api.root_resource_id
  path_part   = "myresource"
}

resource "aws_api_gateway_method" "my_method" {
  rest_api_id   = aws_api_gateway_rest_api.my_api.id
  resource_id   = aws_api_gateway_resource.my_resource.id
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_integration" {
  rest_api_id             = aws_api_gateway_rest_api.my_api.id
  resource_id             = aws_api_gateway_resource.my_resource.id
  http_method             = aws_api_gateway_method.my_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.my_lambda.invoke_arn

  credentials = aws_iam_role.api_gateway_role.arn  # API Gateway用IAMロール
}

resource "aws_lambda_permission" "apigw_lambda" {
  statement_id  = "AllowAPIGatewayInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.my_lambda.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "${aws_api_gateway_rest_api.my_api.execution_arn}/*/*"
}

resource "aws_api_gateway_deployment" "my_deployment" {
  depends_on = [aws_api_gateway_integration.lambda_integration]

  rest_api_id = aws_api_gateway_rest_api.my_api.id
  stage_name  = "prod"
}

17

aws codeartifact get-authorization-token --domain <domain-name> --domain-owner <AWS-account-id> --query authorizationToken --output text

16

aws codeartifact login --tool pip --repository <リポジトリ名> --domain <ドメイン名> --domain-owner <AWSアカウントID>

15

# 認証トークンの取得
aws codeartifact login --tool nuget --repository my-repo --domain my-domain

# 注: Mavenの場合は以下のようにします
aws codeartifact login --tool maven --repository my-repo --domain my-domain

14

@FunctionalInterface
public interface FunctionWithException<T, R> {
    R apply(T t) throws Exception;
}
public class FunctionWithExceptionExample {

    public static void main(String[] args) {
        try {
            String result = transform("Hello, World!", s -> {
                if (s.isEmpty()) {
                    throw new IllegalArgumentException("Input string is empty");
                }
                return s.toUpperCase();
            });
            System.out.println(result);  // 出力: HELLO, WORLD!
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            // 空文字列を渡して例外を発生させる
            String result = transform("", s -> {
                if (s.isEmpty()) {
                    throw new IllegalArgumentException("Input string is empty");
                }
                return s.toUpperCase();
            });
        } catch (Exception e) {
            e.printStackTrace();  // 出力: IllegalArgumentException: Input string is empty
        }
    }

    // カスタムインターフェースを使用したメソッド
    public static <T, R> R transform(T input, FunctionWithException<T, R> transformer) throws Exception {
        return transformer.apply(input);
    }
}

13

^(SM|SN)\d*$

12

@Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", message = "Invalid date format. Required format: yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")

11

@FunctionalInterface
interface ThrowingFunction<T, R> {
    R apply(T t) throws Exception;
}
import java.sql.SQLException;

@FunctionalInterface
interface ThrowingFunction<T, R> {
    R apply(T t) throws Exception;
}

public class LambdaExceptionExample {
    public static <T, R> R applyFunction(T input, ThrowingFunction<T, R> function) throws Exception {
        return function.apply(input);
    }

    public static void main(String[] args) {
        ThrowingFunction<String, String> function = s -> {
            if (s == null) {
                throw new SQLException("Input cannot be null");
            }
            return s.toUpperCase();
        };

        try {
            String result = applyFunction(null, function);
        } catch (Exception e) {
            // SQLExceptionはラップされずにそのままスローされる
            System.out.println(e.getClass().getName() + ": " + e.getMessage());
        }
    }
}

10

import java.util.*;
import java.util.function.*;

public class LambdaExample {
    public static void main(String[] args) {
        // リストを定義
        List<String> list = Arrays.asList("apple", "orange", "banana", "lemon");

        // 匿名クラスを使ってリストをソート
        list.sort(new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s1.compareTo(s2);
            }
        });

        // ラムダ式を使ってリストをソート
        list.sort((s1, s2) -> s1.compareTo(s2));

        // ソートされたリストを出力
        list.forEach(System.out::println);
    }
}

9

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class JDBCSample {
    // JDBC URL, ユーザー名、パスワード
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/your_database";
    private static final String JDBC_USER = "your_username";
    private static final String JDBC_PASSWORD = "your_password";

    public static void main(String[] args) {
        // データベース接続、ステートメント、結果セット
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // データベース接続の確立
            connection = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);

            // SQLクエリの準備
            String sql = "SELECT * FROM your_table";
            preparedStatement = connection.prepareStatement(sql);

            // クエリの実行
            resultSet = preparedStatement.executeQuery();

            // 結果セットのメタデータを取得
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();

            // データを保持するリスト
            List<HashMap<String, Object>> records = new ArrayList<>();

            // 結果セットの処理
            while (resultSet.next()) {
                HashMap<String, Object> record = new HashMap<>();

                // カラムごとにループして値を取得
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    Object value = resultSet.getObject(i);
                    record.put(columnName, value);
                }

                // リストに追加
                records.add(record);
            }

            // データの出力
            for (HashMap<String, Object> record : records) {
                System.out.println(record);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // リソースのクローズ
            try {
                if (resultSet != null) resultSet.close();
                if (preparedStatement != null) preparedStatement.close();
                if (connection != null) connection.close();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
    }
}

8

短期間の有効期限付き認証トークンが発行されます。

aws codeartifact login --tool npm --domain my-domain --repository my-repo

jarファイルのアップロード

mvn deploy:deploy-file -DgroupId=com.mycompany.app -DartifactId=my-library -Dversion=1.0 -Dpackaging=jar -Dfile=path/to/my-library-1.0.jar -DrepositoryId=aws-codeartifact -Durl=https://my-domain-123456789012.d.codeartifact.us-west-2.amazonaws.com/maven/my-repo/

7

import static org.mockito.Mockito.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.mockito.InOrder;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class EventHandlerTest {

    private MockOracleClient mockClient;
    private EventHandler eventHandler;

    @BeforeEach
    public void setUp() {
        // MockOracleClient のモックを作成
        mockClient = mock(MockOracleClient.class);

        // EventHandler インスタンスを初期化してMockOracleClientを注入
        eventHandler = new EventHandler(mockClient);
    }

    @Test
    public void testBMethodCalledTwiceThrowsException() {
        // Bメソッドの呼び出し回数をカウントする変数
        AtomicInteger bCallCount = new AtomicInteger(0);

        // Aメソッドを呼び出すとBメソッドが呼ばれるように設定
        doAnswer(invocation -> {
            for (int i = 0; i < 20; i++) {
                // Bメソッドが2回呼び出されたら例外を投げる
                if (bCallCount.incrementAndGet() == 2) {
                    throw new RuntimeException("B method called for the second time");
                }
                mockClient.B();
            }
            return null;
        }).when(mockClient).A();

        // 例外が投げられることを確認
        Assertions.assertThrows(RuntimeException.class, () -> eventHandler.invokeAMethod());

        // Bメソッドが2回呼ばれていることを確認
        verify(mockClient, times(2)).B();
    }

    // Mockのためのクラス
    class MockOracleClient {
        public void A() {
            // 実際には何もしない
        }

        public void B() {
            // 実際には何もしない
        }
    }

    // EventHandlerクラスの仮実装
    class EventHandler {
        private final MockOracleClient client;

        public EventHandler(MockOracleClient client) {
            this.client = client;
        }

        public void invokeAMethod() {
            client.A();
        }
    }
}

6

import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import static org.mockito.Mockito.*;
import static org.junit.Assert.*;

public class MyServiceTest {

    @Test
    public void testPerformOperation_withExceptionOnSecondCall() throws Exception {
        // モックを作成
        OracleClient mockOracleClient = mock(OracleClient.class);

        // カウンター変数を定義
        final int[] counter = {0};

        // モックのメソッドに対してカスタムAnswerを設定
        when(mockOracleClient.メソッド(any())).thenAnswer(new Answer<String>() {
            @Override
            public String answer(InvocationOnMock invocation) throws Throwable {
                if (counter[0]++ == 1) {  // 2回目の呼び出しで例外を投げる
                    throw new Exception("Exception on second call");
                }
                return "Success";
            }
        });

        // テスト対象のサービスを作成
        MyService myService = new MyService(mockOracleClient);

        // 1回目の呼び出し(例外は発生しない)
        String result1 = myService.performOperation();
        assertEquals("Success", result1);

        // 2回目の呼び出し(例外が発生することを期待)
        String result2 = myService.performOperation();
        assertEquals("Error occurred", result2);
    }
}

5

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.Column;
import org.dbunit.dataset.DefaultTable;
import org.dbunit.dataset.DefaultTableMetaData;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.ITableMetaData;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;

import java.io.File;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortTableExample {
    public static void main(String[] args) throws Exception {
        // データベースの接続を取得 (例としてH2データベースを使用)
        IDatabaseConnection connection = new DatabaseConnection(DriverManager.getConnection("jdbc:h2:~/test", "sa", ""));

        // IDataSetを読み込み
        IDataSet dataSet = new FlatXmlDataSetBuilder().build(new File("dataset.xml"));

        // ITableを取得
        ITable table = dataSet.getTable("テーブルA");

        // ITableのメタデータとカラム情報を取得
        ITableMetaData metaData = table.getTableMetaData();
        Column[] columns = metaData.getColumns();

        // ソート対象の項目名
        String sortColumnName = "name";  // ソートする列名を指定

        // カラムインデックスを見つける
        int sortColumnIndex = -1;
        for (int i = 0; i < columns.length; i++) {
            if (columns[i].getColumnName().equalsIgnoreCase(sortColumnName)) {
                sortColumnIndex = i;
                break;
            }
        }

        // もしカラムインデックスが見つからなければ処理を中止
        if (sortColumnIndex == -1) {
            throw new IllegalArgumentException("指定された項目名がテーブルに存在しません: " + sortColumnName);
        }

        // ITableの内容をリストに変換
        List<List<Object>> rows = new ArrayList<>();
        for (int i = 0; i < table.getRowCount(); i++) {
            List<Object> row = new ArrayList<>();
            for (Column column : columns) {
                row.add(table.getValue(i, column.getColumnName()));
            }
            rows.add(row);
        }

        // ソート (指定された列名に基づくソート)
        Collections.sort(rows, new Comparator<List<Object>>() {
            @Override
            public int compare(List<Object> row1, List<Object> row2) {
                Comparable value1 = (Comparable) row1.get(sortColumnIndex);
                Comparable value2 = (Comparable) row2.get(sortColumnIndex);
                return value1.compareTo(value2);
            }
        });

        // 新しいソートされたITableを作成
        DefaultTable sortedTable = new DefaultTable(new DefaultTableMetaData(metaData.getTableName(), columns), rows.size());
        for (int i = 0; i < rows.size(); i++) {
            sortedTable.addRow(rows.get(i).toArray());
        }

        // 結果の表示
        for (int i = 0; i < sortedTable.getRowCount(); i++) {
            for (Column column : columns) {
                System.out.print(sortedTable.getValue(i, column.getColumnName()) + " ");
            }
            System.out.println();
        }
    }
}

4

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.ITableMetaData;
import org.dbunit.dataset.Column;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.DefaultTable;
import org.dbunit.dataset.DefaultTableMetaData;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;

import java.io.File;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortTableExample {
    public static void main(String[] args) throws Exception {
        // データベースの接続を取得 (例としてH2データベースを使用)
        IDatabaseConnection connection = new DatabaseConnection(DriverManager.getConnection("jdbc:h2:~/test", "sa", ""));

        // IDataSetを読み込み
        IDataSet dataSet = new FlatXmlDataSetBuilder().build(new File("dataset.xml"));

        // ITableを取得
        ITable table = dataSet.getTable("テーブルA");

        // ITableのメタデータとカラム情報を取得
        ITableMetaData metaData = table.getTableMetaData();
        Column[] columns = metaData.getColumns();

        // ITableの内容をリストに変換
        List<List<Object>> rows = new ArrayList<>();
        for (int i = 0; i < table.getRowCount(); i++) {
            List<Object> row = new ArrayList<>();
            for (Column column : columns) {
                row.add(table.getValue(i, column.getColumnName()));
            }
            rows.add(row);
        }

        // ソート (例として最初の列を基準にソート)
        Collections.sort(rows, new Comparator<List<Object>>() {
            @Override
            public int compare(List<Object> row1, List<Object> row2) {
                Comparable value1 = (Comparable) row1.get(0); // 最初の列を基準にソート
                Comparable value2 = (Comparable) row2.get(0);
                return value1.compareTo(value2);
            }
        });

        // 新しいソートされたITableを作成
        DefaultTable sortedTable = new DefaultTable(new DefaultTableMetaData(metaData.getTableName(), columns), rows.size());
        for (int i = 0; i < rows.size(); i++) {
            sortedTable.addRow(rows.get(i).toArray());
        }

        // 結果の表示
        for (int i = 0; i < sortedTable.getRowCount(); i++) {
            for (Column column : columns) {
                System.out.print(sortedTable.getValue(i, column.getColumnName()) + " ");
            }
            System.out.println();
        }
    }
}

3

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.DefaultTable;
import org.dbunit.dataset.DefaultTableMetaData;
import org.dbunit.dataset.RowOutOfBoundsException;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortTableExample {
    public static void main(String[] args) throws Exception {
        // データベースの接続を取得 (例としてH2データベースを使用)
        IDatabaseConnection connection = new DatabaseConnection(DriverManager.getConnection("jdbc:h2:~/test", "sa", ""));

        // IDataSetを読み込み
        IDataSet dataSet = new FlatXmlDataSetBuilder().build(new File("dataset.xml"));

        // ITableを取得
        ITable table = dataSet.getTable("テーブルA");

        // ITableの内容をリストに変換
        List<Object[]> rows = new ArrayList<>();
        for (int i = 0; i < table.getRowCount(); i++) {
            rows.add(table.getValues(i));
        }

        // ソート (例として最初の列を基準にソート)
        Collections.sort(rows, new Comparator<Object[]>() {
            @Override
            public int compare(Object[] row1, Object[] row2) {
                Comparable value1 = (Comparable) row1[0]; // 最初の列を基準にソート
                Comparable value2 = (Comparable) row2[0];
                return value1.compareTo(value2);
            }
        });

        // 新しいソートされたITableを作成
        DefaultTable sortedTable = new DefaultTable(new DefaultTableMetaData(table.getTableMetaData().getTableName(), table.getTableMetaData().getColumns()), rows.size());
        for (int i = 0; i < rows.size(); i++) {
            sortedTable.addRow(rows.get(i));
        }

        // 結果の表示
        for (int i = 0; i < sortedTable.getRowCount(); i++) {
            System.out.println(Arrays.toString(sortedTable.getValues(i)));
        }
    }
}

2

^(?!00000000FFFFFF$).*

1

SELECT
    SID,
    SERIAL#,
    USERNAME,
    STATUS,
    MACHINE,
    PROGRAM
FROM
    V$SESSION;

a

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DatabaseAccess {

    private static HikariDataSource dataSource;

    public static void main(String[] args) {
        try {
            // HikariCPの初期化
            HikariConfig config = new HikariConfig("db.properties");
            dataSource = new HikariDataSource(config);

            // PKを使ってデータを検索して取得件数を確認
            int searchId = 1;
            int count = getCountById(searchId);
            System.out.println("Count of records with ID " + searchId + ": " + count);

        } finally {
            if (dataSource != null) {
                dataSource.close();
            }
        }
    }

    /**
     * 特定のIDでレコードを検索して件数を取得
     *
     * @param id 検索するレコードのID
     * @return 件数
     */
    public static int getCountById(int id) {
        String query = "SELECT COUNT(*) FROM user WHERE id = ?";

        try (Connection connection = dataSource.getConnection();
             PreparedStatement statement = connection.prepareStatement(query)) {

            statement.setInt(1, id);

            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    return resultSet.getInt(1);
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return 0;
    }
}

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;

@Constraint(validatedBy = UserValidator.class)
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidUser {
    String message() default "Invalid user data";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class UserValidator implements ConstraintValidator<ValidUser, User> {

    @Override
    public void initialize(ValidUser constraintAnnotation) {
        // 初期化が必要ならここに書きます
    }

    @Override
    public boolean isValid(User user, ConstraintValidatorContext context) {
        if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("Password must not be blank")
                   .addPropertyNode("password")
                   .addConstraintViolation();
            return false;
        }
        if (user.getPassword().length() < 6) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("Password must be at least 6 characters long")
                   .addPropertyNode("password")
                   .addConstraintViolation();
            return false;
        }
        if (user.getEmail() == null || !user.getEmail().contains("@")) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("Email must be a valid email address")
                   .addPropertyNode("email")
                   .addConstraintViolation();
            return false;
        }
        return true;
    }
}

###

// インポートする必要のあるパッケージ
import java.sql.*;
import oracle.sql.CLOB;
import java.io.Reader;
import java.io.BufferedReader;

public class ClobExample {

    // データベース接続情報
    private static final String URL = "jdbc:oracle:thin:@<HOST>:<PORT>:<SID>"; // 例: jdbc:oracle:thin:@localhost:1521:XE
    private static final String USER = "myuser";
    private static final String PASSWORD = "mypassword";

    public static void main(String[] args) {
        Connection conn = null;

        try {
            // データベース接続
            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            conn = DriverManager.getConnection(URL, USER, PASSWORD);

            // SQLJ定型文の宣言
            #sql context DBContext;
            DBContext ctx = new DBContext(conn);

            // CLOB型のデータを格納する変数の宣言
            CLOB clobData;
            String columnName = "test_column"; // 取得するカラム名
            String tableName = "test_table"; // 取得するテーブル名
            int rowId = 1; // 特定の行を示すID

            // SQLJを使用してCLOB型のデータを取得する
            #sql [ctx] { SELECT CLOB_COLUMN INTO :clobData FROM :tableName WHERE ID = :rowId };

            // CLOBデータの読み取り
            Reader clobReader = clobData.getCharacterStream();
            BufferedReader br = new BufferedReader(clobReader);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

            // 取得したCLOBデータの表示
            System.out.println("CLOB Data: " + sb.toString());

            // リソースの解放
            br.close();
            clobReader.close();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement;
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder;
import com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest;
import com.amazonaws.services.simplesystemsmanagement.model.GetParameterResult;

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class SSMClientWithProxy {

    public static void main(String[] args) {
        // プロキシサーバの設定
        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;
        final String proxyUser = "yourProxyUsername";
        final String proxyPassword = "yourProxyPassword";

        // AWSアクセスキーとシークレットキーを指定
        String accessKeyId = "YOUR_ACCESS_KEY_ID";
        String secretAccessKey = "YOUR_SECRET_ACCESS_KEY";
        BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKeyId, secretAccessKey);

        // 認証情報を設定
        Authenticator.setDefault(new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());
            }
        });

        // プロキシ設定を含むClientConfigurationを作成
        ClientConfiguration clientConfig = new ClientConfiguration()
                .withProxyHost(proxyHost)
                .withProxyPort(proxyPort)
                .withProxyUsername(proxyUser)
                .withProxyPassword(proxyPassword);

        // SSMクライアントを作成
        AWSSimpleSystemsManagement ssmClient = AWSSimpleSystemsManagementClientBuilder.standard()
                .withRegion(Regions.US_EAST_1) // 適切なリージョンを指定
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .withClientConfiguration(clientConfig)
                .build();

        // パラメータ名を指定してパラメータを取得
        String parameterName = "/test/test";
        GetParameterRequest getParameterRequest = new GetParameterRequest()
                .withName(parameterName)
                .withWithDecryption(true);

        try {
            GetParameterResult getParameterResult = ssmClient.getParameter(getParameterRequest);
            String parameterValue = getParameterResult.getParameter().getValue();
            System.out.println("Parameter value: " + parameterValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>ssm</artifactId>
    <version>2.17.106</version> <!-- 最新のバージョンに置き換えます -->
</dependency>
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>apache-client</artifactId>
    <version>2.17.106</version> <!-- 最新のバージョンに置き換えます -->
</dependency>
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.http.apache.ProxyConfiguration;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ssm.SsmClient;
import software.amazon.awssdk.services.ssm.model.GetParameterRequest;
import software.amazon.awssdk.services.ssm.model.GetParameterResponse;

public class SSMClientWithProxy {

    public static void main(String[] args) {
        // プロキシサーバの設定
        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;
        final String proxyUser = "yourProxyUsername";
        final String proxyPassword = "yourProxyPassword";

        // AWSアクセスキーとシークレットキーを指定
        String accessKeyId = "YOUR_ACCESS_KEY_ID";
        String secretAccessKey = "YOUR_SECRET_ACCESS_KEY";
        AwsBasicCredentials awsCreds = AwsBasicCredentials.create(accessKeyId, secretAccessKey);

        // プロキシ設定を含むApacheHttpClientを構成
        ProxyConfiguration proxyConfig = ProxyConfiguration.builder()
                .endpoint(URI.create("http://" + proxyHost + ":" + proxyPort))
                .username(proxyUser)
                .password(proxyPassword)
                .build();

        ApacheHttpClient httpClient = ApacheHttpClient.builder()
                .proxyConfiguration(proxyConfig)
                .build();

        // SSMクライアントを作成
        SsmClient ssmClient = SsmClient.builder()
                .region(Region.US_EAST_1)  // 適切なリージョンに変更
                .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                .httpClient(httpClient)
                .build();

        // パラメータ名を指定してパラメータを取得
        String parameterName = "/test/test";
        GetParameterRequest getParameterRequest = GetParameterRequest.builder()
                .name(parameterName)
                .withDecryption(true)
                .build();

        try {
            GetParameterResponse getParameterResponse = ssmClient.getParameter(getParameterRequest);
            String parameterValue = getParameterResponse.parameter().value();
            System.out.println("Parameter value: " + parameterValue);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ssmClient.close();
        }
    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class InternetConnectionTest {

    public static void main(String[] args) {
        String targetUrl = "http://www.example.com"; // 確認したいURLを指定

        try {
            // URLオブジェクトを作成
            URL url = new URL(targetUrl);

            // HttpURLConnectionオブジェクトを作成
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // GETリクエストの設定
            connection.setRequestMethod("GET");

            // 接続タイムアウト(ミリ秒)
            connection.setConnectTimeout(5000);
            // 読み取りタイムアウト(ミリ秒)
            connection.setReadTimeout(5000);

            // リクエストを送信
            int responseCode = connection.getResponseCode();

            // レスポンスコードの表示
            System.out.println("Response Code: " + responseCode);

            // レスポンスボディの読み取り
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // レスポンスボディの表示
            System.out.println("Response Body: ");
            System.out.println(response.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public static void main(String[] args) {
    System.setProperty("http.proxyHost", "proxy.example.com");
    System.setProperty("http.proxyPort", "8080");
    System.setProperty("https.proxyHost", "proxy.example.com");
    System.setProperty("https.proxyPort", "8080");

    String targetUrl = "http://www.example.com"; // 確認したいURLを指定

    try {
        // URLオブジェクトを作成
        URL url = new URL(targetUrl);

        // HttpURLConnectionオブジェクトを作成
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // GETリクエストの設定
        connection.setRequestMethod("GET");

        // 接続タイムアウト(ミリ秒)
        connection.setConnectTimeout(5000);
        // 読み取りタイムアウト(ミリ秒)
        connection.setReadTimeout(5000);

        // リクエストを送信
        int responseCode = connection.getResponseCode();

        // レスポンスコードの表示
        System.out.println("Response Code: " + responseCode);

        // レスポンスボディの読み取り
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        // レスポンスボディの表示
        System.out.println("Response Body: ");
        System.out.println(response.toString());

    } catch (Exception e) {
        e.printStackTrace();
    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;

public class InternetConnectionTestWithProxy {

    public static void main(String[] args) {
        // プロキシサーバのアドレスとポート
        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;

        // プロキシ認証情報
        final String proxyUser = "yourProxyUsername";
        final String proxyPassword = "yourProxyPassword";

        // 認証情報を提供するためにAuthenticatorを設定
        Authenticator.setDefault(new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());
            }
        });

        // テスト対象のURL
        String targetUrl = "http://www.example.com";

        try {
            // プロキシサーバの設定
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));

            // URLオブジェクトを作成
            URL url = new URL(targetUrl);

            // HttpURLConnectionオブジェクトを作成
            HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);

            // GETリクエストの設定
            connection.setRequestMethod("GET");

            // 接続タイムアウト(ミリ秒)
            connection.setConnectTimeout(5000);
            // 読み取りタイムアウト(ミリ秒)
            connection.setReadTimeout(5000);

            // リクエストを送信
            int responseCode = connection.getResponseCode();

            // レスポンスコードの表示
            System.out.println("Response Code: " + responseCode);

            // レスポンスボディの読み取り
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // レスポンスボディの表示
            System.out.println("Response Body: ");
            System.out.println(response.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

カスタムバリデータ

カスタムアノテーション

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Constraint(validatedBy = ValueRangeValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidNumberRange {
    String message() default "Invalid number";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    long min() default Long.MIN_VALUE;
    long max() default Long.MAX_VALUE;
}

カスタムバリデータ

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class ValueRangeValidator implements ConstraintValidator<ValidNumberRange, String> {

    private long min;
    private long max;

    @Override
    public void initialize(ValidNumberRange constraintAnnotation) {
        this.min = constraintAnnotation.min();
        this.max = constraintAnnotation.max();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || value.isEmpty()) {
            return true; // 空の値は別のアノテーションでチェックする
        }
        try {
            long longValue = Long.parseLong(value);
            return longValue >= min && longValue <= max;
        } catch (NumberFormatException e) {
            return false; // 数値ではない文字列は無効
        }
    }
}

JavaBeanへの適用

public class Product {

    @ValidNumberRange(min = 0, max = 100, message = "The price must be between 0 and 100")
    private String price;

    // コンストラクタ
    public Product(String price) {
        this.price = price;
    }

    // ゲッターとセッター
    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }
}

正規表現

@Pattern(regexp = "^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-3])[0-5][0-9][0-5][0-9]$",
             message = "The field must be in yyyyMMddHHmmss format")

terraformリクエストヘッダーの追加2

CORS(Cross-Origin Resource Sharing)の設定を追加するには、以下のようにTerraformコードを更新します。CORS設定では、HTTPメソッドやヘッダーの許可設定を行う必要があります。この例では、GETメソッドのリソースに対してCORSを設定します。

以下の追加および変更を行います:

1. オプション(OPTIONS)メソッドを追加します。
2. OPTIONSメソッドに対して、CORS設定を追加します。

以下は、既存のコードに対して追加と変更を加えた完全な例です。

```hcl
provider "aws" {
  region = "us-west-2"  # 必要に応じて変更してください
}

# Lambda実行ロール
resource "aws_iam_role" "lambda_exec_role" {
  name = "lambda_exec_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy" "lambda_exec_policy" {
  name   = "lambda_exec_policy"
  role   = aws_iam_role.lambda_exec_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Effect   = "Allow"
        Resource = "*"
      }
    ]
  })
}

# Lambda関数のデプロイ
resource "aws_lambda_function" "my_lambda" {
  function_name = "my_lambda"
  runtime       = "nodejs14.x"  # 必要に応じて変更
  role          = aws_iam_role.lambda_exec_role.arn
  handler       = "index.handler"
  source_code_hash = filebase64sha256("lambda_function_payload.zip")  # Lambda関数のコードが含まれたZipファイル

  # Lambda関数のコード(例)
  // index.js ファイルには基本的に以下のようなコードが必要です
  //    exports.handler = async (event) => {
  //      console.log(JSON.stringify(event));
  //      return "Success";
  //    }

  filename = "lambda_function_payload.zip"  # Lambda関数のコードが含まれたZipファイル
}

# API Gateway作成
resource "aws_api_gateway_rest_api" "my_api" {
  name = "MyAPI"
}

# ルートリソース作成
resource "aws_api_gateway_resource" "my_resource" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  parent_id   = aws_api_gateway_rest_api.my_api.root_resource_id
  path_part   = "myresource"
}

# GETメソッドの作成
resource "aws_api_gateway_method" "my_get_method" {
  rest_api_id   = aws_api_gateway_rest_api.my_api.id
  resource_id   = aws_api_gateway_resource.my_resource.id
  http_method   = "GET"
  authorization = "NONE"
}

# GETメソッド用のIntegration設定
resource "aws_api_gateway_integration" "lambda_get_integration" {
  rest_api_id             = aws_api_gateway_rest_api.my_api.id
  resource_id             = aws_api_gateway_resource.my_resource.id
  http_method             = aws_api_gateway_method.my_get_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.my_lambda.invoke_arn
}

# GETメソッドに対するMethod Response設定
resource "aws_api_gateway_method_response" "default_get_method_response" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  resource_id = aws_api_gateway_resource.my_resource.id
  http_method = aws_api_gateway_method.my_get_method.http_method
  status_code = "200"

  response_parameters = {
    "method.response.header.Access-Control-Allow-Origin" = true
  }
}

# GETメソッドに対するIntegration Response設定
resource "aws_api_gateway_integration_response" "default_get_integration_response" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  resource_id = aws_api_gateway_resource.my_resource.id
  http_method = aws_api_gateway_method.my_get_method.http_method
  status_code = "200"

  response_parameters = {
    "method.response.header.Access-Control-Allow-Origin" = "'*'"
  }
}

# OPTIONSメソッドの作成
resource "aws_api_gateway_method" "options_method" {
  rest_api_id   = aws_api_gateway_rest_api.my_api.id
  resource_id   = aws_api_gateway_resource.my_resource.id
  http_method   = "OPTIONS"
  authorization = "NONE"

  request_parameters = {
    "method.request.header.Origin"                         = false
    "method.request.header.Access-Control-Request-Method"  = false
    "method.request.header.Access-Control-Request-Headers" = false
  }
}

# OPTIONSメソッドに対するIntegration設定
resource "aws_api_gateway_integration" "options_integration" {
  rest_api_id             = aws_api_gateway_rest_api.my_api.id
  resource_id             = aws_api_gateway_resource.my_resource.id
  http_method             = aws_api_gateway_method.options_method.http_method
  type                    = "MOCK"

  request_templates = {
    "application/json" = <<EOF
{
  "statusCode": 200
}
EOF
  }

  integration_response {
    status_code = "200"
    response_parameters = {
      "method.response.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
      "method.response.header.Access-Control-Allow-Methods" = "'GET,OPTIONS'",
      "method.response.header.Access-Control-Allow-Origin"  = "'*'"
    }

    response_templates = {
      "application/json" = ""
    }
  }
}

# OPTIONSメソッドに対するMethod Response設定
resource "aws_api_gateway_method_response" "options_method_response" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  resource_id = aws_api_gateway_resource.my_resource.id
  http_method = aws_api_gateway_method.options_method.http_method
  status_code = "200"

  response_parameters = {
    "method.response.header.Access-Control-Allow-Headers" = true
    "method.response.header.Access-Control-Allow-Methods" = true
    "method.response.header.Access-Control-Allow-Origin"  = true
  }
}

# デプロイの設定
resource "aws_api_gateway_deployment" "api_deployment" {
  depends_on = [aws_api_gateway_integration.lambda_get_integration, aws_api_gateway_integration.options_integration]
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  stage_name  = "dev"
}

output "invoke_url" {
  value = aws_api_gateway_deployment.api_deployment.invoke_url
}
```

この追加および変更を行うことで、API GatewayのGETメソッドとOPTIONSメソッドに対してCORS設定を行います。これにより、ブラウザからのクロスオリジンリクエストが許可されるようになります。

### 内容の変更点:
1. OPTIONSメソッドを作成し、そのリクエストパラメータを設定。
2. OPTIONSメソッドに対するMOCK統合を作成し、レスポンスヘッダーにCORS設定を追加。
3. GETメソッドのレスポンスヘッダーにCORS設定を追加。

これらの変更を行うことで、クライアントはAPI Gatewayを介してLambda関数にリクエストを送信する際に、CORSポリシーに従ったリクエストを送ることができます。

terraform リクエストヘッダーの追加

以下に、Terraformを使用してAPI Gatewayの設定を行い、HTTPリクエストヘッダーをLambdaに渡す方法を示します。具体的には、`X-Amz-Date`と`x-amz-date`の両方のヘッダーをLambdaに渡す設定です。

まず、以下のリポジトリが必要です。
- `aws_api_gateway_rest_api` : API Gateway
- `aws_api_gateway_resource` : API Gateway リソース
- `aws_api_gateway_method` : HTTP メソッド
- `aws_api_gateway_integration` : リソースとLambdaとの統合設定
- `aws_lambda_function` : Lambda関数
- `aws_iam_role` : Lambda実行ロール
- `aws_iam_role_policy` : Lambda実行ロール用ポリシー

以下は必要なTerraformコードの例です。

```hcl
provider "aws" {
  region = "us-west-2"  # 必要に応じて変更してください
}

# Lambda実行ロール
resource "aws_iam_role" "lambda_exec_role" {
  name = "lambda_exec_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy" "lambda_exec_policy" {
  name   = "lambda_exec_policy"
  role   = aws_iam_role.lambda_exec_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Effect   = "Allow"
        Resource = "*"
      }
    ]
  })
}

# Lambda関数のデプロイ
resource "aws_lambda_function" "my_lambda" {
  function_name = "my_lambda"
  runtime       = "nodejs14.x"  # 必要に応じて変更
  role          = aws_iam_role.lambda_exec_role.arn
  handler       = "index.handler"
  source_code_hash = filebase64sha256("lambda_function_payload.zip")  # Lambda関数のコードが含まれたZipファイル

  # Lambda関数のコード(例)
  // index.js ファイルには基本的に以下のようなコードが必要です
  //    exports.handler = async (event) => {
  //      console.log(JSON.stringify(event));
  //      return "Success";
  //    }

  filename = "lambda_function_payload.zip"  # Lambda関数のコードが含まれたZipファイル
}

# API Gateway作成
resource "aws_api_gateway_rest_api" "my_api" {
  name = "MyAPI"
}

# ルートリソース作成
resource "aws_api_gateway_resource" "my_resource" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  parent_id   = aws_api_gateway_rest_api.my_api.root_resource_id
  path_part   = "myresource"
}

# メソッドの作成 (GETメソッドを使用した例)
resource "aws_api_gateway_method" "my_method" {
  rest_api_id   = aws_api_gateway_rest_api.my_api.id
  resource_id   = aws_api_gateway_resource.my_resource.id
  http_method   = "GET"
  authorization = "NONE"
}

# API GatewayとLambdaの統合
resource "aws_api_gateway_integration" "lambda_integration" {
  rest_api_id             = aws_api_gateway_rest_api.my_api.id
  resource_id             = aws_api_gateway_resource.my_resource.id
  http_method             = aws_api_gateway_method.my_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.my_lambda.invoke_arn
}

# デプロイの設定
resource "aws_api_gateway_deployment" "api_deployment" {
  depends_on = [aws_api_gateway_integration.lambda_integration]
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  stage_name  = "dev"
}

# API Gatewayのリクエストヘッダー設定
resource "aws_api_gateway_integration_response" "default_integration_response" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  resource_id = aws_api_gateway_resource.my_resource.id
  http_method = aws_api_gateway_method.my_method.http_method
  status_code = "200"

  response_parameters = {
    "method.request.header.X-Amz-Date" = "integration.request.header.X-Amz-Date",
    "method.request.header.x-amz-date" = "integration.request.header.x-amz-date"
  }
}

resource "aws_api_gateway_method_response" "default_method_response" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  resource_id = aws_api_gateway_resource.my_resource.id
  http_method = aws_api_gateway_method.my_method.http_method
  status_code = "200"
}

output "invoke_url" {
  value = aws_api_gateway_deployment.api_deployment.invoke_url
}
```

このTerraformコードを適用することで、以下のステップが実行されます:
1. 必要なIAMロールとポリシーを作成します。
2. Lambda関数をデプロイします。
3. API Gatewayリソースとメソッドを作成します。
4. LambdaとAPI Gatewayの統合設定を行います。
5. `X-Amz-Date`および`x-amz-date`ヘッダーをLambda関数に渡す設定を行います。

これで、API Gatewayを通じてHTTPリクエストを送信する際に、指定したヘッダーをLambda関数に渡すことができます。

Javaコード

String isoDate = "20240825T030211Z";
        
        // ISO 8601形式の文字列を解析
        DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
        TemporalAccessor temporalAccessor = formatter.parse(isoDate);
        Instant instant = Instant.from(temporalAccessor);
        
        // InstantをTimestampに変換
        Timestamp timestamp = Timestamp.from(instant);
-H "X-Amz-Date: 20240825T030211Z"cur

API Gatewayから日時をラムダに受け渡すJSON

{
  "method": "$context.httpMethod",
  "body": $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))"
    #if($foreach.hasNext),#end
    #end
  }
}
Map<String, Object> requestContext = (Map<String, Object>) event.get("requestContext");
        String requestTime = (String) requestContext.get("requestTime");

        // タイムスタンプをフォーマットするためのSimpleDateFormatを作成
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

        // TimestampをStringに変換
        String formattedDate = dateFormat.format(timestamp);

DBUnit

pom.xml

<dependency>
    <groupId>org.dbunit</groupId>
    <artifactId>dbunit</artifactId>
    <version>2.7.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
    <scope>test</scope>
</dependency>

テストコード

import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.dbunit.dataset.excel.XlsDataSet;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class SelectTest extends DBTestCase {

    public SelectTest(String name) {
        super(name);
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "oracle.jdbc.driver.OracleDriver");
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:oracle:thin:@localhost:1521:yourdb");
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "username");
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "password");
    }

@Override
protected IDataSet getDataSet() throws Exception {
    // Excelファイルからテストデータセットをロード
    return new XlsDataSet(new FileInputStream("path/to/your/dataset.xls"));
}

    @Override
    protected DatabaseOperation getSetUpOperation() throws Exception {
        // テスト前にデータセットをデータベースにインサート
        return DatabaseOperation.CLEAN_INSERT;
    }

    @Override
    protected DatabaseOperation getTearDownOperation() throws Exception {
        // テスト後にデータベースをクリーンアップ
        return DatabaseOperation.NONE;
    }

    public void testSelect() throws Exception {
        // データベース接続を取得
        Connection connection = getConnection().getConnection();

        try {
            // SELECT文を実行
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table WHERE id = 1");

            // 結果を検証
            assertTrue("Result set is empty", resultSet.next());
            assertEquals("Test Name 1", resultSet.getString("name"));
            assertEquals(123, resultSet.getInt("value"));

            // 結果セットに次の行がないことを確認
            assertFalse("Result set contains more than one row", resultSet.next());
        } finally {
            // リソースをクリーンアップ
            connection.close();
        }
    }
}

このテストケースでは、getDataSet()メソッドでテストデータセットをロードし、getSetUpOperation()でテスト実行前にデータベースにデータをインサートしています。testSelect()メソッドでは、実際にSELECT文を実行し、結果が期待通りであるかを検証しています。

テストを実行するには、Mavenのmvn testコマンドを使用します。このコマンドはプロジェクトのルートディレクトリで実行してください。

注意: 実際のテストケースでは、データベースの接続情報(URL、ユーザー名、パスワード)を直接コードに記述するのではなく、環境変数や設定ファイルから読み込むようにすることが一般的です。また、データベースのクリーンアップはDatabaseOperation.DELETE_ALLなどを使用して行うことができます。

org.apache.poi:poiorg.apache.poi:poi-ooxmlはApache POIライブラリで、Excelファイルの読み書きに使用されます。バージョンはプロジェクトの要件に応じて適宜調整してください。

Excelファイルを使用することで、テストデータをより直感的に管理しやすくなりますが、大量のデータや複雑なデータ構造を扱う場合は、XML形式の方が適している場合もあります。使用するフォーマットは、プロジェクトのニーズに応じて選択してください。

その他

import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunit.operation.DatabaseOperation;

public class LambdaProgramTest extends DBTestCase {

    public LambdaProgramTest(String name) {
        super(name);
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "org.h2.Driver");
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "sa");
        System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "");
    }

    @Override
    protected IDataSet getDataSet() throws Exception {
        // テスト用のExcelデータセットをロード
        return new XlsDataSet(new FileInputStream("src/test/resources/dataset.xls"));
    }

    @Override
    protected DatabaseOperation getSetUpOperation() throws Exception {
        // テスト前にデータベースをクリーンインサート状態にする
        return DatabaseOperation.CLEAN_INSERT;
    }

    @Override
    protected DatabaseOperation getTearDownOperation() throws Exception {
        // テスト後にデータベースを元の状態に戻す
        return DatabaseOperation.NONE;
    }

    public void testLambdaProgram() {
        // Lambdaプログラムのインスタンスを作成
        LambdaProgram lambdaProgram = new LambdaProgram();

        // Lambdaプログラムを実行
        lambdaProgram.run();

        // データベースの状態を検証
        IDataSet databaseDataSet = getConnection().createDataSet();
        ITable actualTable = databaseDataSet.getTable("YOUR_TABLE");

        // 期待されるExcelデータセットをロード
        IDataSet expectedDataSet = new XlsDataSet(new FileInputStream("src/test/resources/expected_dataset.xls"));
        ITable expectedTable = expectedDataSet.getTable("YOUR_TABLE");

        // 実際のテーブルと期待されるテーブルを比較
        Assertion.assertEquals(expectedTable, actualTable);
    }
}

memo

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.sql.Timestamp;

public class TimestampConverter {
    public static Timestamp convertStringToTimestamp(String strDate) {
        try {
            // API GatewayからのDateヘッダーは通常RFC 7231に従った形式であるため、
            // 以下のようなフォーマットを使用します。
            SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
            Date parsedDate = dateFormat.parse(strDate);
            return new Timestamp(parsedDate.getTime());
        } catch (ParseException e) {
            // 日時のパースに失敗した場合は、適切な例外処理を行います。
            // ここでは単純にnullを返していますが、実際のアプリケーションでは
            // エラーログを出力したり、カスタム例外を投げたりすることを検討してください。
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        // テスト用の日時文字列
        String requestTime = "Wed, 21 Oct 2015 07:28:00 GMT";

        // String型からTimestamp型への変換
        Timestamp timestamp = convertStringToTimestamp(requestTime);

        // 結果の出力
        System.out.println("Timestamp: " + timestamp);
    }
}

メモ

public static void setPreparedStatementParameters(PreparedStatement preparedStatement, Object... parameters) throws SQLException {
    for (int i = 0; i < parameters.length; i++) {
        Object parameter = parameters[i];
        int parameterIndex = i + 1;
        if (parameter instanceof String) {
            preparedStatement.setString(parameterIndex, (String) parameter);
        } else if (parameter instanceof Integer) {
            preparedStatement.setInt(parameterIndex, (Integer) parameter);
        } else if (parameter instanceof Long) {
            preparedStatement.setLong(parameterIndex, (Long) parameter);
        } else if (parameter instanceof Double) {
            preparedStatement.setDouble(parameterIndex, (Double) parameter);
        } else if (parameter instanceof java.sql.Date) {
            preparedStatement.setDate(parameterIndex, (java.sql.Date) parameter);
        } else if (parameter instanceof java.sql.Timestamp) {
            preparedStatement.setTimestamp(parameterIndex, (java.sql.Timestamp) parameter);
        } else if (parameter == null) {
            preparedStatement.setNull(parameterIndex, Types.NULL);
        } else {
            // 他のデータ型に対する処理を追加することができます
            throw new SQLException("Unhandled parameter type: " + parameter.getClass().getSimpleName());
        }
    }
}
CREATE TABLE your_table_name (
    date TIMESTAMP PRIMARY KEY,
    data CLOB,
    status NUMBER
);
CREATE TABLE your_table_name (
    AAA NUMBER PRIMARY KEY,
    BBB TIMESTAMP,
    CCC CHAR
);

CREATE SEQUENCE your_sequence_name
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;

CREATE OR REPLACE TRIGGER your_trigger_name
BEFORE INSERT ON your_table_name
FOR EACH ROW
BEGIN
    SELECT your_sequence_name.NEXTVAL
    INTO :new.AAA
    FROM dual;
END;
/

CREATE INDEX KEYAAA ON your_table_name (AAA);

コメント

タイトルとURLをコピーしました