|
| 1 | +import org.junit.Rule; |
| 2 | +import org.junit.Test; |
| 3 | +import org.testcontainers.containers.localstack.LocalStackContainer; |
| 4 | +import org.testcontainers.utility.DockerImageName; |
| 5 | +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; |
| 6 | +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; |
| 7 | +import software.amazon.awssdk.regions.Region; |
| 8 | +import software.amazon.awssdk.services.rds.RdsClient; |
| 9 | +import software.amazon.awssdk.services.rds.model.CreateDbInstanceRequest; |
| 10 | +import software.amazon.awssdk.services.rds.model.CreateDbInstanceResponse; |
| 11 | +import software.amazon.awssdk.services.rds.model.DescribeDbInstancesRequest; |
| 12 | +import software.amazon.awssdk.services.rds.model.DescribeDbInstancesResponse; |
| 13 | + |
| 14 | +import java.net.InetAddress; |
| 15 | +import java.net.URI; |
| 16 | +import java.net.URISyntaxException; |
| 17 | +import java.net.UnknownHostException; |
| 18 | + |
| 19 | +import static org.junit.Assert.assertEquals; |
| 20 | +import static org.junit.Assert.fail; |
| 21 | + |
| 22 | +public class TestRDS { |
| 23 | + |
| 24 | + private DockerImageName localstackImage = DockerImageName.parse("localstack/localstack:1.4.0"); |
| 25 | + private String api_key = System.getenv("LOCALSTACK_API_KEY"); |
| 26 | + |
| 27 | + /** |
| 28 | + * Start LocalStackContainer with exposed Ports. Those ports are used by services like RDS, where several databases can be started, running on different ports. |
| 29 | + * In this sample we only map 5 ports, however, depending on your use case you may need to map ports up to 4559 |
| 30 | + */ |
| 31 | + @Rule |
| 32 | + public LocalStackContainer localstack = new LocalStackContainer(localstackImage) |
| 33 | + .withExposedPorts(4510, 4511, 4512, 4513, 4514) // TODO the port can have any value between 4510-4559, but LS starts from 4510 |
| 34 | + .withEnv("LOCALSTACK_API_KEY", api_key) // TODO add your API key here |
| 35 | + .withServices(LocalStackContainer.EnabledService.named("rds")); |
| 36 | + |
| 37 | + |
| 38 | + @Test |
| 39 | + public void testRds() throws UnknownHostException, URISyntaxException { |
| 40 | + // create the rds client that will connect to the localstack testcontainer |
| 41 | + RdsClient rds = RdsClient |
| 42 | + .builder() |
| 43 | + .endpointOverride(localstack.getEndpointOverride(LocalStackContainer.EnabledService.named("rds"))) |
| 44 | + .credentialsProvider(StaticCredentialsProvider.create( |
| 45 | + AwsBasicCredentials.create(localstack.getAccessKey(), localstack.getSecretKey()) |
| 46 | + )).region(Region.of(localstack.getRegion())).build(); |
| 47 | + |
| 48 | + // create a db instance, by default it will use username "test" and password "test" |
| 49 | + CreateDbInstanceResponse response = rds.createDBInstance(CreateDbInstanceRequest.builder().dbName("hello").engine("postgres").build()); |
| 50 | + String identifier = response.dbInstance().dbInstanceIdentifier(); |
| 51 | + DescribeDbInstancesRequest request = DescribeDbInstancesRequest.builder().dbInstanceIdentifier(identifier).build(); |
| 52 | + DescribeDbInstancesResponse describedb = rds.describeDBInstances(request); |
| 53 | + |
| 54 | + // wait for db to be ready |
| 55 | + while(! describedb.dbInstances().get(0).dbInstanceStatus().equalsIgnoreCase("available")) { |
| 56 | + describedb = rds.describeDBInstances(request); |
| 57 | + } |
| 58 | + |
| 59 | + // identify the port localstack provides for the instance |
| 60 | + int localstack_port = response.dbInstance().endpoint().port(); |
| 61 | + |
| 62 | + // get the port it was mapped to, e.g. the one we can reach from host/the test |
| 63 | + int mapped_port = localstack.getMappedPort(localstack_port); |
| 64 | + try { |
| 65 | + // try to connect to database in our example we simply insert some dummy data |
| 66 | + String actual = RDS.test_connection(localstack.getHost(), mapped_port, "hello"); |
| 67 | + String expected = "ID = 1\nNAME = world"; |
| 68 | + assertEquals(actual, expected); |
| 69 | + } catch (Exception e) { |
| 70 | + fail("testing connection with database failed"); |
| 71 | + } |
| 72 | + // rds database endpoint |
| 73 | + URI rds_database_uri = getMappedAddressForPort(localstack, localstack_port); |
| 74 | + System.out.println(rds_database_uri); |
| 75 | + |
| 76 | + // TODO do whatever with RDS instance using the uri/port |
| 77 | + |
| 78 | + } |
| 79 | + |
| 80 | + |
| 81 | + /** |
| 82 | + * Helper method to get the mapped address for any port. For services with varying ports. |
| 83 | + * Similar to {@link LocalStackContainer#getEndpointOverride} for fixed mapped services. |
| 84 | + * |
| 85 | + * @param localstack LocalStackContainer |
| 86 | + * @param localstack_port the port returned by LocalStack, e.g. for DescribeDBInstances |
| 87 | + * @return URI of the endpoint, reachable from host |
| 88 | + * @throws URISyntaxException |
| 89 | + * @throws UnknownHostException |
| 90 | + */ |
| 91 | + public static URI getMappedAddressForPort(LocalStackContainer localstack, int localstack_port) throws URISyntaxException, UnknownHostException { |
| 92 | + String ipAddress = InetAddress.getByName(localstack.getHost()).getHostAddress(); |
| 93 | + int mapped_port = localstack.getMappedPort(localstack_port); |
| 94 | + return new URI("http://" + ipAddress + ":" + mapped_port); |
| 95 | + |
| 96 | + } |
| 97 | +} |
0 commit comments