|
| 1 | +package org.testcontainers.azure; |
| 2 | + |
| 3 | +import org.testcontainers.containers.GenericContainer; |
| 4 | +import org.testcontainers.utility.DockerImageName; |
| 5 | +import org.testcontainers.utility.MountableFile; |
| 6 | + |
| 7 | +/** |
| 8 | + * Testcontainers implementation for Azurite Emulator. |
| 9 | + * <p> |
| 10 | + * Supported image: {@code mcr.microsoft.com/azure-storage/azurite} |
| 11 | + * <p> |
| 12 | + * Exposed ports: |
| 13 | + * <ul> |
| 14 | + * <li>Blob: 10000</li> |
| 15 | + * <li>Queue: 10001</li> |
| 16 | + * <li>Table: 10002</li> |
| 17 | + * </ul> |
| 18 | + */ |
| 19 | +public class AzuriteContainer extends GenericContainer<AzuriteContainer> { |
| 20 | + |
| 21 | + private static final String ALLOW_ALL_CONNECTIONS = "0.0.0.0"; |
| 22 | + |
| 23 | + private static final int DEFAULT_BLOB_PORT = 10000; |
| 24 | + |
| 25 | + private static final int DEFAULT_QUEUE_PORT = 10001; |
| 26 | + |
| 27 | + private static final int DEFAULT_TABLE_PORT = 10002; |
| 28 | + |
| 29 | + private static final String CONNECTION_STRING_FORMAT = |
| 30 | + "DefaultEndpointsProtocol=%s;AccountName=%s;AccountKey=%s;BlobEndpoint=%s://%s:%d/%s;QueueEndpoint=%s://%s:%d/%s;TableEndpoint=%s://%s:%d/%s;"; |
| 31 | + |
| 32 | + /** |
| 33 | + * The account name of the default credentials. |
| 34 | + */ |
| 35 | + private static final String WELL_KNOWN_ACCOUNT_NAME = "devstoreaccount1"; |
| 36 | + |
| 37 | + /** |
| 38 | + * The account key of the default credentials. |
| 39 | + */ |
| 40 | + private static final String WELL_KNOWN_ACCOUNT_KEY = |
| 41 | + "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="; |
| 42 | + |
| 43 | + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse( |
| 44 | + "mcr.microsoft.com/azure-storage/azurite" |
| 45 | + ); |
| 46 | + |
| 47 | + private MountableFile cert = null; |
| 48 | + |
| 49 | + private String certExtension = null; |
| 50 | + |
| 51 | + private MountableFile key = null; |
| 52 | + |
| 53 | + private String pwd = null; |
| 54 | + |
| 55 | + /** |
| 56 | + * @param dockerImageName specified docker image name to run |
| 57 | + */ |
| 58 | + public AzuriteContainer(String dockerImageName) { |
| 59 | + this(DockerImageName.parse(dockerImageName)); |
| 60 | + } |
| 61 | + |
| 62 | + /** |
| 63 | + * @param dockerImageName specified docker image name to run |
| 64 | + */ |
| 65 | + public AzuriteContainer(DockerImageName dockerImageName) { |
| 66 | + super(dockerImageName); |
| 67 | + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); |
| 68 | + withExposedPorts(DEFAULT_BLOB_PORT, DEFAULT_QUEUE_PORT, DEFAULT_TABLE_PORT); |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * Configure SSL with a custom certificate and password. |
| 73 | + * |
| 74 | + * @param pfxCert The PFX certificate file |
| 75 | + * @param password The password securing the certificate |
| 76 | + * @return this |
| 77 | + */ |
| 78 | + public AzuriteContainer withSsl(final MountableFile pfxCert, final String password) { |
| 79 | + this.cert = pfxCert; |
| 80 | + this.pwd = password; |
| 81 | + this.certExtension = ".pfx"; |
| 82 | + return this; |
| 83 | + } |
| 84 | + |
| 85 | + /** |
| 86 | + * Configure SSL with a custom certificate and private key. |
| 87 | + * |
| 88 | + * @param pemCert The PEM certificate file |
| 89 | + * @param pemKey The PEM key file |
| 90 | + * @return this |
| 91 | + */ |
| 92 | + public AzuriteContainer withSsl(final MountableFile pemCert, final MountableFile pemKey) { |
| 93 | + this.cert = pemCert; |
| 94 | + this.key = pemKey; |
| 95 | + this.certExtension = ".pem"; |
| 96 | + return this; |
| 97 | + } |
| 98 | + |
| 99 | + @Override |
| 100 | + protected void configure() { |
| 101 | + withCommand(getCommandLine()); |
| 102 | + if (this.cert != null) { |
| 103 | + logger().info("Using path for cert file: '{}'", this.cert); |
| 104 | + withCopyFileToContainer(this.cert, "/cert" + this.certExtension); |
| 105 | + if (this.key != null) { |
| 106 | + logger().info("Using path for key file: '{}'", this.key); |
| 107 | + withCopyFileToContainer(this.key, "/key.pem"); |
| 108 | + } |
| 109 | + } |
| 110 | + } |
| 111 | + |
| 112 | + /** |
| 113 | + * Returns the connection string for the default credentials. |
| 114 | + * |
| 115 | + * @return connection string |
| 116 | + */ |
| 117 | + public String getConnectionString() { |
| 118 | + return getConnectionString(WELL_KNOWN_ACCOUNT_NAME, WELL_KNOWN_ACCOUNT_KEY); |
| 119 | + } |
| 120 | + |
| 121 | + /** |
| 122 | + * Returns the connection string for the account name and key specified. |
| 123 | + * |
| 124 | + * @param accountName The name of the account |
| 125 | + * @param accountKey The account key |
| 126 | + * @return connection string |
| 127 | + */ |
| 128 | + public String getConnectionString(final String accountName, final String accountKey) { |
| 129 | + final String protocol = cert != null ? "https" : "http"; |
| 130 | + return String.format( |
| 131 | + CONNECTION_STRING_FORMAT, |
| 132 | + protocol, |
| 133 | + accountName, |
| 134 | + accountKey, |
| 135 | + protocol, |
| 136 | + getHost(), |
| 137 | + getMappedPort(DEFAULT_BLOB_PORT), |
| 138 | + accountName, |
| 139 | + protocol, |
| 140 | + getHost(), |
| 141 | + getMappedPort(DEFAULT_QUEUE_PORT), |
| 142 | + accountName, |
| 143 | + protocol, |
| 144 | + getHost(), |
| 145 | + getMappedPort(DEFAULT_TABLE_PORT), |
| 146 | + accountName |
| 147 | + ); |
| 148 | + } |
| 149 | + |
| 150 | + String getCommandLine() { |
| 151 | + final StringBuilder args = new StringBuilder("azurite"); |
| 152 | + args.append(" --blobHost ").append(ALLOW_ALL_CONNECTIONS); |
| 153 | + args.append(" --queueHost ").append(ALLOW_ALL_CONNECTIONS); |
| 154 | + args.append(" --tableHost ").append(ALLOW_ALL_CONNECTIONS); |
| 155 | + if (this.cert != null) { |
| 156 | + args.append(" --cert ").append("/cert").append(this.certExtension); |
| 157 | + if (this.pwd != null) { |
| 158 | + args.append(" --pwd ").append(this.pwd); |
| 159 | + } else { |
| 160 | + args.append(" --key ").append("/key.pem"); |
| 161 | + } |
| 162 | + } |
| 163 | + final String cmd = args.toString(); |
| 164 | + logger().debug("Using command line: '{}'", cmd); |
| 165 | + return cmd; |
| 166 | + } |
| 167 | +} |
0 commit comments