Getting error while creating collection "maxTTL: Supported in enterprise edition only"

I m using official java sdk “java-client:3.9.0”

and running latest community server “Couchbase community edition 7.6.2”

while creating collection, i am getting maxTTL: supported in enterprise edition only. Even though i m not using expiry or maxTTL related setting. Same code is working in 7.2.4 server, it only fails in 7.6.x. series only

Exception:

Exception in thread "main" com.couchbase.client.core.error.InvalidArgumentException: Server error reported: {"errors":{"maxTTL":"Supported in enterprise edition only"}}
	at com.couchbase.client.core.util.CoreAsyncUtils.block(CoreAsyncUtils.java:54)
	at com.couchbase.client.java.AsyncUtils.block(AsyncUtils.java:37)
	at com.couchbase.client.java.manager.collection.CollectionManager.createCollection(CollectionManager.java:98)
	at com.couchbase.client.java.manager.collection.CollectionManager.createCollection(CollectionManager.java:78)

This is sample code:


import java.time.Duration;
import java.util.concurrent.TimeUnit;
import com.couchbase.client.core.env.CompressionConfig;
import com.couchbase.client.core.retry.BestEffortRetryStrategy;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.env.ClusterEnvironment;
import com.couchbase.client.java.manager.bucket.BucketManager;
import com.couchbase.client.java.manager.bucket.BucketSettings;
import com.couchbase.client.java.manager.collection.CollectionManager;
import com.couchbase.client.java.manager.collection.CollectionSpec;
import com.couchbase.client.java.manager.collection.ScopeSpec;

public class CbTest
{
  // Couchbase community edition 7.6.2
  // Java SDK for couchbase com.couchbase.client:java-client:3.9.0

  private static Cluster cluster;

  private static ClusterEnvironment env;

  // Change these placeholders
  private static final String CONNECTION_STRING = "couchbase://127.0.0.1";

  private static final String USERNAME = "Administrator";

  private static final String PASSWORD = "password";

  // Test resource names
  private static final String BUCKET_NAME = "TestBucket";

  private static final String SCOPE_NAME = "testScope";

  private static final String COLLECTION_NAME = "testCollection";

  public static void main(String[] args) throws InterruptedException
  {
    setUp();
    createBucketScopeAndCollection();
  }

  static void setUp()
  {
    env = ClusterEnvironment
      .builder()
      .compressionConfig(CompressionConfig.builder().enable(true))
      .retryStrategy(BestEffortRetryStrategy.INSTANCE)
      .build();

    cluster = Cluster.connect(CONNECTION_STRING, USERNAME, PASSWORD);
    cluster.waitUntilReady(Duration.ofSeconds(30));
  }

  static void createBucketScopeAndCollection() throws InterruptedException
  {
    // 1) Bucket
    BucketManager bucketManager = cluster.buckets();
    if(!bucketExists(bucketManager, BUCKET_NAME))
    {
      bucketManager.createBucket(
        BucketSettings.create(BUCKET_NAME)
          .ramQuotaMB(100)
          .flushEnabled(true)
      );
      // Small wait to let the bucket register in the cluster manager
      TimeUnit.SECONDS.sleep(2);
    }

    Bucket bucket = cluster.bucket(BUCKET_NAME);
    bucket.waitUntilReady(Duration.ofSeconds(30));

    // 2) Scope
    CollectionManager cm = bucket.collections();
    if(!scopeExists(cm, SCOPE_NAME))
    {
      cm.createScope(SCOPE_NAME);
      // Allow propagation
      TimeUnit.SECONDS.sleep(1);
    }

    // 3) Collection
    if(!collectionExists(cm, SCOPE_NAME, COLLECTION_NAME))
    {
      cm.createCollection(CollectionSpec.create(COLLECTION_NAME, SCOPE_NAME));
      // Allow propagation
      TimeUnit.SECONDS.sleep(1);
    }
  }

  private static boolean bucketExists(BucketManager manager, String name)
  {
    try
    {
      return manager.getAllBuckets().containsKey(name);
    }
    catch(Exception e)
    {
      return false;
    }
  }

  private static boolean scopeExists(CollectionManager manager, String scopeName)
  {
    try
    {
      return manager.getAllScopes().stream().anyMatch(s -> s.name().equals(scopeName));
    }
    catch(Exception e)
    {
      return false;
    }
  }

  private static boolean collectionExists(CollectionManager manager, String scopeName, String collectionName)
  {
    try
    {
      for(ScopeSpec scope : manager.getAllScopes())
      {
        if(scope.name().equals(scopeName))
        {
          return scope.collections().stream().anyMatch(c -> c.name().equals(collectionName));
        }
      }
      return false;
    }
    catch(Exception e)
    {
      return false;
    }
  }
}

2 Likes

Hi @hiren.rojasara !

The method CollectionManager.createCollection(CollectionSpec) is deprecated because of the problem you encountered. Can you try using the suggested replacement, the overload that takes a scope name, collection name, and optionally a CreateCollectionSettings?

For example, instead of:

cm.createCollection(CollectionSpec.create(COLLECTION_NAME, SCOPE_NAME));

please use:

cm.createCollection(SCOPE_NAME, COLLECTION_NAME);

Thanks,

David

P.S. Thank you for the sample code which made it easy to reproduce the problem!

2 Likes

Thanks for your answer David. It works.

1 Like