2626import com .couchbase .client .java .env .DefaultCouchbaseEnvironment ;
2727import com .couchbase .client .java .query .Index ;
2828import lombok .AllArgsConstructor ;
29+ import lombok .Cleanup ;
2930import lombok .Getter ;
31+ import lombok .SneakyThrows ;
3032import lombok .experimental .Wither ;
33+ import org .jetbrains .annotations .NotNull ;
3134import org .testcontainers .containers .GenericContainer ;
3235import org .testcontainers .containers .wait .HttpWaitStrategy ;
3336
@@ -60,6 +63,7 @@ public class CouchbaseContainer<SELF extends CouchbaseContainer<SELF>> extends G
6063 private static final int ANALYTICS_PORT = 8095 ;
6164 private static final int ANALYTICS_SSL_PORT = 18095 ;
6265 //</editor-fold>
66+ public static final String DELIMITER = "," ;
6367
6468 @ Getter
6569 @ Wither
@@ -115,6 +119,9 @@ public class CouchbaseContainer<SELF extends CouchbaseContainer<SELF>> extends G
115119 @ Getter (lazy = true )
116120 private final CouchbaseCluster couchbaseCluster = createCouchbaseCluster ();
117121
122+ @ Getter (lazy = true )
123+ private final CouchbaseNodeWaitStrategy couchbaseNodeWaitStrategy = createCouchbaseWaitStrategy ();
124+
118125 @ Getter
119126 private static final Collection <CouchbaseContainer > containers = new HashSet <>();
120127
@@ -123,7 +130,8 @@ public class CouchbaseContainer<SELF extends CouchbaseContainer<SELF>> extends G
123130
124131 private List <BucketSettings > newBuckets = new ArrayList <>();
125132
126- private String urlBase ;
133+ @ Getter (lazy = true )
134+ private final String urlBase = createUrlBase ();
127135
128136 public CouchbaseContainer () {
129137 this ("couchbase/server:latest" );
@@ -136,7 +144,7 @@ public CouchbaseContainer(String containerName) {
136144
137145 @ Override
138146 protected Integer getLivenessCheckPort () {
139- return getMappedPort (CONFIG_PORT );
147+ return isSsl () ? getMappedPort ( CONFIG_SSL_PORT ) : getMappedPort (CONFIG_PORT );
140148 }
141149
142150 @ Override
@@ -165,76 +173,101 @@ protected void configure() {
165173 addExposedPort (ANALYTICS_SSL_PORT );
166174 }
167175 }
168- setWaitStrategy (new HttpWaitStrategy ().forPath ("/ui/index.html#/" ));
176+ HttpWaitStrategy waitStrategy = new HttpWaitStrategy ().forPath ("/ui/index.html#/" );
177+ setWaitStrategy (ssl ? waitStrategy .usingTls () : waitStrategy );
169178 }
170179
171180 public SELF withNewBucket (BucketSettings bucketSettings ) {
172181 newBuckets .add (bucketSettings );
173182 return self ();
174183 }
175184
176- public void initCluster () {
177- urlBase = String .format ("http://%s:%s" , getContainerIpAddress (), getMappedPort (CONFIG_PORT ));
178- try {
179- String poolURL = "/pools/default" ;
180- String poolPayload = "memoryQuota=" + URLEncoder .encode (memoryQuota , "UTF-8" ) + "&indexMemoryQuota=" + URLEncoder .encode (indexMemoryQuota , "UTF-8" );
185+ @ SneakyThrows
186+ public void init () {
187+ initCluster ();
188+ initServices ();
189+ initAdminUser ();
190+ initSampleBuckets ();
191+ this .getCouchbaseNodeWaitStrategy ().waitUntilReady (this );
192+ initIndexes ();
193+ this .getCouchbaseNodeWaitStrategy ().waitUntilReady (this );
194+ }
181195
182- String setupServicesURL = "/node/controller/setupServices" ;
183- StringBuilder servicePayloadBuilder = new StringBuilder ();
184- if (keyValue ) {
185- servicePayloadBuilder .append ("kv," );
186- }
187- if (query ) {
188- servicePayloadBuilder .append ("n1ql," );
189- }
190- if (index ) {
191- servicePayloadBuilder .append ("index," );
192- }
193- if (fts ) {
194- servicePayloadBuilder .append ("fts," );
195- }
196- if (analytics ) {
197- servicePayloadBuilder .append ("cbas," );
198- }
199- String setupServiceContent = "services=" + URLEncoder .encode (servicePayloadBuilder .toString (), "UTF-8" );
196+ private void initCluster () throws IOException {
197+ logger ().debug ("Initializing couchbase cluster" );
198+ String poolURL = "/pools/default" ;
199+ String poolPayload = "memoryQuota=" + URLEncoder .encode (memoryQuota , "UTF-8" ) + "&indexMemoryQuota=" + URLEncoder .encode (indexMemoryQuota , "UTF-8" );
200+ callCouchbaseRestAPI (poolURL , poolPayload );
201+ }
202+
203+ private void initServices () throws IOException {
204+ StringJoiner services = new StringJoiner (DELIMITER );
205+ if (keyValue ) {
206+ services .add ("kv" );
207+ }
208+ if (query ) {
209+ services .add ("n1ql" );
210+ }
211+ if (index ) {
212+ services .add ("index" );
213+ }
214+ if (fts ) {
215+ services .add ("fts" );
216+ }
217+ if (analytics ) {
218+ services .add ("cbas" );
219+ }
220+ logger ().debug ("Initializing services : {}" , services .toString ());
221+ callCouchbaseRestAPI ("/node/controller/setupServices" , "services=" + URLEncoder .encode (services .toString (), "UTF-8" ));
222+ }
200223
201- String webSettingsURL = "/settings/web" ;
202- String webSettingsContent = "username=" + URLEncoder .encode (clusterUsername , "UTF-8" ) + "&password=" + URLEncoder .encode (clusterPassword , "UTF-8" ) + "&port=8091" ;
224+ private void initAdminUser () throws IOException {
225+ logger ().debug ("Creating cluster admin user '{}'" , clusterUsername );
226+ callCouchbaseRestAPI ("/settings/web" ,
227+ "username=" + URLEncoder .encode (clusterUsername , "UTF-8" ) + "&password=" + URLEncoder .encode (clusterPassword , "UTF-8" ) + "&port=8091" );
228+ }
203229
204- String bucketURL = "/sampleBuckets/install" ;
230+ private void initSampleBuckets () throws IOException {
231+ StringJoiner sampleBucketPayload = new StringJoiner (DELIMITER );
232+ if (travelSample ) {
233+ sampleBucketPayload .add ("\" travel-sample\" " );
234+ }
235+ if (beerSample ) {
236+ sampleBucketPayload .add ("\" beer-sample\" " );
237+ }
238+ if (gamesIMSample ) {
239+ sampleBucketPayload .add ("\" gamesim-sample\" " );
240+ }
241+ if (sampleBucketPayload .length () != 0 ) {
242+ logger ().debug ("Initialize sample buckets {}" , sampleBucketPayload .toString ());
243+ callCouchbaseRestAPI ("/sampleBuckets/install" , "[" + sampleBucketPayload .toString () + "]" );
244+ }
245+ }
205246
206- StringBuilder sampleBucketPayloadBuilder = new StringBuilder ();
207- sampleBucketPayloadBuilder .append ('[' );
208- if (travelSample ) {
209- sampleBucketPayloadBuilder .append ("\" travel-sample\" ," );
210- }
211- if (beerSample ) {
212- sampleBucketPayloadBuilder .append ("\" beer-sample\" ," );
213- }
214- if (gamesIMSample ) {
215- sampleBucketPayloadBuilder .append ("\" gamesim-sample\" ," );
216- }
217- sampleBucketPayloadBuilder .append (']' );
247+ private void initIndexes () throws IOException {
248+ logger ().debug ("Activate memory optimized index" );
249+ callCouchbaseRestAPI ("/settings/indexes" , "indexerThreads=0&logLevel=info&maxRollbackPoints=5&storageMode=memory_optimized" );
250+ }
218251
219- callCouchbaseRestAPI (poolURL , poolPayload );
220- callCouchbaseRestAPI (setupServicesURL , setupServiceContent );
221- callCouchbaseRestAPI (webSettingsURL , webSettingsContent );
222- callCouchbaseRestAPI (bucketURL , sampleBucketPayloadBuilder .toString ());
252+ private String createUrlBase () {
253+ return String .format ((ssl ? "https" : "http" ) + "://%s:%s" , getContainerIpAddress (), getMappedPort (CONFIG_PORT ));
254+ }
223255
224- CouchbaseWaitStrategy s = new CouchbaseWaitStrategy ();
225- s .withBasicCredentials (clusterUsername , clusterPassword );
226- s .waitUntilReady (this );
227- callCouchbaseRestAPI ("/settings/indexes" , "indexerThreads=0&logLevel=info&maxRollbackPoints=5&storageMode=memory_optimized" );
228- } catch (Exception e ) {
229- throw new RuntimeException (e );
230- }
256+ @ NotNull
257+ private CouchbaseNodeWaitStrategy createCouchbaseWaitStrategy () {
258+ return new CouchbaseNodeWaitStrategy ()
259+ .withUsername (clusterUsername )
260+ .withPassword (clusterPassword )
261+ .withSsl (ssl );
231262 }
232263
233264 public void createBucket (BucketSettings bucketSetting , boolean primaryIndex ) {
265+ logger ().debug ("Creating bucket {}" , bucketSetting .name ());
234266 ClusterManager clusterManager = getCouchbaseCluster ().clusterManager (clusterUsername , clusterPassword );
235267 // Insert Bucket
236268 BucketSettings bucketSettings = clusterManager .insertBucket (bucketSetting );
237269 // Insert Bucket admin user
270+ logger ().debug ("Creating bucket admin user '{}'" , bucketSetting .name ());
238271 UserSettings userSettings = UserSettings .build ()
239272 .password (bucketSetting .password ())
240273 .roles (Collections .singletonList (new UserRole ("bucket_admin" , bucketSetting .name ())));
@@ -243,35 +276,38 @@ public void createBucket(BucketSettings bucketSetting, boolean primaryIndex) {
243276 } catch (Exception e ) {
244277 logger ().warn ("Unable to insert user '" + bucketSetting .name () + "', maybe you are using older version" );
245278 }
279+ this .getCouchbaseNodeWaitStrategy ().waitUntilReady (this );
246280 if (index ) {
247281 Bucket bucket = getCouchbaseCluster ().openBucket (bucketSettings .name (), bucketSettings .password ());
248282 new CouchbaseQueryServiceWaitStrategy (bucket ).waitUntilReady (this );
249283 if (primaryIndex ) {
284+ logger ().debug ("Creating primary index" );
250285 bucket .query (Index .createPrimaryIndex ().on (bucketSetting .name ()));
251286 }
252287 }
253288 }
254289
255290 public void callCouchbaseRestAPI (String url , String payload ) throws IOException {
256- String fullUrl = urlBase + url ;
291+ String fullUrl = getUrlBase () + url ;
292+ @ Cleanup (value = "disconnect" )
257293 HttpURLConnection httpConnection = (HttpURLConnection ) ((new URL (fullUrl ).openConnection ()));
258294 httpConnection .setDoOutput (true );
259295 httpConnection .setRequestMethod ("POST" );
260296 httpConnection .setRequestProperty ("Content-Type" ,
261297 "application/x-www-form-urlencoded" );
262298 String encoded = Base64 .encode ((clusterUsername + ":" + clusterPassword ).getBytes ("UTF-8" ));
263299 httpConnection .setRequestProperty ("Authorization" , "Basic " + encoded );
300+ @ Cleanup
264301 DataOutputStream out = new DataOutputStream (httpConnection .getOutputStream ());
265302 out .writeBytes (payload );
266303 out .flush ();
267- out .close ();
268304 httpConnection .getResponseCode ();
269- httpConnection .disconnect ();
270305 }
271306
272307 @ Override
273308 public void start () {
274309 super .start ();
310+ init ();
275311 if (!newBuckets .isEmpty ()) {
276312 for (BucketSettings bucketSetting : newBuckets ) {
277313 createBucket (bucketSetting , primaryIndex );
@@ -284,7 +320,6 @@ private CouchbaseCluster createCouchbaseCluster() {
284320 }
285321
286322 private DefaultCouchbaseEnvironment createCouchbaseEnvironment () {
287- initCluster ();
288323 DefaultCouchbaseEnvironment .Builder builder = DefaultCouchbaseEnvironment .builder ()
289324 .sslEnabled (ssl );
290325 if (isSsl ()) {
0 commit comments