Skip to content

DATACOUCH-963 - Scope and collection api. #1071

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

mikereiche
Copy link
Collaborator

@mikereiche mikereiche commented Feb 3, 2021

Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963
Original pull request: #1071.

  • You have read the Spring Data contribution guidelines.
  • There is a ticket in the bug tracker for the project in our JIRA.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

@mikereiche mikereiche requested a review from daschl February 3, 2021 06:20
@mikereiche mikereiche marked this pull request as draft February 3, 2021 06:20
Copy link
Member

@mp911de mp911de left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All repository-related changes violate the core ideas of Spring Data repositories to keep these as pure as possible. Introducing another 50 method overloads clutters the API and pulls in a level of abstraction that duplicates the Template API.

Specifying store-specific options can be done on the Template API.

import java.util.LinkedList;
import java.util.List;

public class MapList<K,V> extends HashMap<K, List<V>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need for this one as Spring Framework ships with MultiValueMap.

@@ -0,0 +1,14 @@
package org.springframework.data.couchbase.core.support;

public class ScopeName {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where possible, use immutable value objects.


public class CollectionName {
String name;
public CollectionName(String name){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where possible, use immutable value objects.


@Override
Optional<T> findById(ID id);
Optional<T> findById(ID id, QueryOptions... options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is exactly what we want to avoid. The repository must not accept store-specific types as we do not want the calling code to interact with store specifics.

Store specifics at the Template API level are fine.

List<T> findAll(CollectionName collectionName, ScopeName... scopeNames);


List<T> findAll(org.springframework.data.couchbase.core.query.Query query);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introducing Query makes the Repository somewhat pointless as this method duplicates what's possible on the Template API level.

@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch 2 times, most recently from 81b6bb6 to ce42488 Compare February 26, 2021 22:05
…name.

Queries on field annotated properties have original name.

They should use getFieldName() which will use the annotated if it exists.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch 2 times, most recently from 9f6b2c7 to 5050cf0 Compare March 5, 2021 01:39
mikereiche added a commit that referenced this pull request Mar 9, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from 5050cf0 to afe0bd2 Compare March 9, 2021 01:20
*
* @author Michael Nitschinger
* @author Michael Reiche
*/
@Repository
public interface AirportRepository extends PagingAndSortingRepository<Airport, String> {
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
public interface AirportRepository extends CouchbaseRepository<Airport, String>, DynamicProxyable<AirportRepository> {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PagingAndSortingRepository is from spring-data-common
CouchbaseRepository extends PagingAndSortingRepository. AirportRepository needs to extend DynamicProxyable to have the AirportRepository type.

@Override
public RemoveByQueryInCollection<T> inScope(String scope) {
return null;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed to return new ExecutableRemoveByQuerySupport<>()

mikereiche added a commit that referenced this pull request Mar 9, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from afe0bd2 to e974a8c Compare March 9, 2021 23:50
@@ -74,7 +74,7 @@ private SimpleCouchbaseClientFactory(final Supplier<Cluster> cluster, final Stri

@Override
public CouchbaseClientFactory withScope(final String scopeName) {
return new SimpleCouchbaseClientFactory(cluster, bucket.name(), scopeName);
return new SimpleCouchbaseClientFactory(cluster, bucket.name(), scopeName != null ? scopeName : getScope().name());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is that change needed? Wouldn't this return the exact same instance?

Copy link
Collaborator Author

@mikereiche mikereiche Mar 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: This is getting handled by the caller, so I've reverted this change.

If scopeName is null,
the old behavior would return a clientFactory with scope = _default
the new behavior returns a clientFactory with the same scope as the "this". (yes, it could actually return "this" instead of a new object - that is a better implementation).
This is to allow just using withScope(scopeName) without checking if scopeName is null.

/**
* @param pseudoArgs - the metaArgs to set on the ThreadLocal field of the CouchbaseOperations
*/
void setThrdLocalArgs(PseudoArgs<?> pseudoArgs);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we name this setThreadLocalArgs ? The two chars seem like a typo :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely.

@@ -59,7 +59,7 @@ ClusterType type() {

@Override
TestClusterConfig _start() throws Exception {
bucketname = UUID.randomUUID().toString();
bucketname = "my_bucket"; // UUID.randomUUID().toString();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this hardcoded now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the creation of multiple scopes and collections and the indexing, the initialization is getting long. This now reuses the bucket, scopes, collections etc. if they already exist.

if (postResponse.code() != 202) {
throw new Exception("Could not create bucket: " + postResponse + ", Reason: " + postResponse.body().string());
String reason = postResponse.body().string();
if (postResponse.code() != 202 && !(reason.contains("Bucket with given name already exists"))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't exist with the uuid change above, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When reusing "my_bucket", 202(created) and "already exists" is acceptable, don't throw an exception.

@@ -107,6 +107,7 @@ public static void beforeAll() {
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
reactiveCouchbaseTemplate = (ReactiveCouchbaseTemplate) ac.getBean(REACTIVE_COUCHBASE_TEMPLATE);
System.err.println("JavaIntegrationTests.beforeAll() couchbaseTemplate: " + couchbaseTemplate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should these be logged instead? because then you can turn it on off with the logger config, vs these will show up all the time

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I'll look for other System.out and change to log.debug

* @author Michael Reiche
* @param <T> - the entity class
*/
public interface WithScope<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the naming difference is odd - with vs. in

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - it should match - InScope. Changing these an all the FindByQueryWithScope etc. interfaces to FindByQueryInScope etc.

import org.springframework.data.couchbase.core.query.Query;

public class PseudoArgs<OPTS> {
OPTS options;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be private final?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still outstanding?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in local, needs push.

if (getParameters() != null) {
if (getParameters() instanceof JsonArray) {
options.parameters((JsonArray) getParameters());
} else {
options.parameters((JsonObject) getParameters());
}
}
if (scanConsistency == null) {
if (getScanConsistency() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be combined with &&

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still outstanding?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed locally. Need to push.

@@ -48,16 +52,18 @@

}

interface ExistsByIdWithCollection extends TerminatingExistsById, WithCollection {
interface ExistsByIdWithOptions<T> extends TerminatingExistsById, WithGetOptions<T> {
TerminatingExistsById withOptions(GetOptions options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't that be ExistsOptions?

}

static class ExecutableExistsByIdSupport implements ExecutableExistsById {

private final CouchbaseTemplate template;
private final String scope;
private final String collection;
private final GetOptions options;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ExistsOptions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Similar issue with RemoveByQuery - it had RemoveOptions instead of QueryOptions - and in both cases the options were not passed in execution. Going through all the Reactive*OperationSupport classes to check for usage of options.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added "options" tests that pass an options with timeout of 10 nanoseconds, resulting in a timeout.

mikereiche added a commit that referenced this pull request Mar 11, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from e974a8c to d0da3a1 Compare March 11, 2021 02:20
mikereiche added a commit that referenced this pull request Mar 11, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from d0da3a1 to d045e5e Compare March 11, 2021 02:41
mikereiche added a commit that referenced this pull request Mar 11, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from d045e5e to 7a9d533 Compare March 11, 2021 03:09
mikereiche added a commit that referenced this pull request Mar 22, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from 7a9d533 to 71af4c7 Compare March 22, 2021 15:56
mikereiche added a commit that referenced this pull request Mar 29, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from 71af4c7 to cf60490 Compare March 29, 2021 21:56
@mikereiche mikereiche force-pushed the master branch 4 times, most recently from 9af0782 to 3f1cea1 Compare April 6, 2021 15:59
Copy link
Contributor

@daschl daschl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found a couple things - also I noticed many of my questions did not have comments/answers, would be good to get clarifications on those as well (just look through the change they will pop up)

/**
* Insert Operations
*
* @author Christoph Strobl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy/paste?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No - I tried to fill in some of the missing javadoc. From looking at javadoc on other classes that would have been created at the same time, I assumed the same author.

Assert.hasText(collection, "Collection must not be null nor empty.");
return new ExecutableExistsByIdSupport(template, collection);
public ExistsByIdWithOptions inCollection(final String collection) {
return new ExecutableExistsByIdSupport(template, scope, collection, options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was the assertion removed by accident? I wonder if it makes sense to validate those as well (also inScope)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At one point I removed the assertion to allow just calling without checking if the caller was using collections or not. That said - I put the assertion back in and all the tests pass - so it seems I'm not doing that anymore. I'll put it back for scope and collection.

/**
* FindByAnalytics Operations
*
* @author Christoph Strobl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like some copy paste, you can put your name there if we want that at all

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to "back-date" the javadoc with the correct author.

/**
* Get Operations
*
* @author Christoph Strobl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, I'll stop pointing them out below

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

if (getParameters() != null) {
if (getParameters() instanceof JsonArray) {
options.parameters((JsonArray) getParameters());
} else {
options.parameters((JsonObject) getParameters());
}
}
if (scanConsistency == null) {
if (getScanConsistency() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still outstanding?

import org.springframework.data.couchbase.core.query.Query;

public class PseudoArgs<OPTS> {
OPTS options;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still outstanding?

/**
* @@return the options from the ThreadLocal field of the template
*/
private OPTS getTlOptions(ReactiveCouchbaseTemplate template) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can those be also renamed to getThreadLocalOptions so it's not as confusing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed local, needs push.

@@ -47,7 +47,7 @@ public N1qlRepositoryQueryExecutor(final CouchbaseOperations operations, final C
this.queryMethod = queryMethod;
this.namedQueries = namedQueries;
this.evaluationContextProvider = evaluationContextProvider;
throw new RuntimeException("Deprecated");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

this.evaluationContextProvider = evaluationContextProvider;
throw new RuntimeException("Deprecated");
this.evaluationContextProvider = QueryMethodEvaluationContextProvider.DEFAULT;
//throw new RuntimeException("Deprecated");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@@ -40,7 +40,7 @@ public ReactiveN1qlRepositoryQueryExecutor(final ReactiveCouchbaseOperations ope
this.queryMethod = queryMethod;
this.namedQueries = namedQueries;
this.evaluationContextProvider = evaluationContextProvider;
throw new RuntimeException("Deprecated");
//throw new RuntimeException("Deprecated");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@gregturn gregturn changed the base branch from master to main April 15, 2021 17:47
mikereiche added a commit that referenced this pull request Apr 23, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from cf60490 to 5c88c3c Compare April 23, 2021 14:36
Draft of changes for scope and collection API to share with Michael Nitschinger.

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche force-pushed the datacouch_963_scope_and_collection_api branch from 5c88c3c to d2b0b92 Compare April 23, 2021 14:37
}

static class ExecutableFindByAnalyticsSupport<T> implements ExecutableFindByAnalytics<T> {

private final CouchbaseTemplate template;
private final Class<T> domainType;
private final Class<?> domainType;
private final Class<T> returnType;
private final ReactiveFindByAnalyticsSupport<T> reactiveSupport;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if returnType (for producing an object other than domainType) makes sense here, but it is in Query apis.

/**
* Insert Operations
*
* @author Christoph Strobl
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No - I tried to fill in some of the missing javadoc. From looking at javadoc on other classes that would have been created at the same time, I assumed the same author.

Assert.hasText(collection, "Collection must not be null nor empty.");
return new ExecutableExistsByIdSupport(template, collection);
public ExistsByIdWithOptions inCollection(final String collection) {
return new ExecutableExistsByIdSupport(template, scope, collection, options);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At one point I removed the assertion to allow just calling without checking if the caller was using collections or not. That said - I put the assertion back in and all the tests pass - so it seems I'm not doing that anymore. I'll put it back for scope and collection.

/**
* FindByAnalytics Operations
*
* @author Christoph Strobl
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to "back-date" the javadoc with the correct author.

/**
* Get Operations
*
* @author Christoph Strobl
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

if (getParameters() != null) {
if (getParameters() instanceof JsonArray) {
options.parameters((JsonArray) getParameters());
} else {
options.parameters((JsonObject) getParameters());
}
}
if (scanConsistency == null) {
if (getScanConsistency() != null) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed locally. Need to push.

import org.springframework.data.couchbase.core.query.Query;

public class PseudoArgs<OPTS> {
OPTS options;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in local, needs push.

/**
* @@return the options from the ThreadLocal field of the template
*/
private OPTS getTlOptions(ReactiveCouchbaseTemplate template) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed local, needs push.

mikereiche added a commit that referenced this pull request Apr 26, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.

Closes #963.
Original pull request: #1071.
mikereiche added a commit that referenced this pull request Apr 26, 2021
Draft of changes for scope and collection API to share with Michael Nitschinger.

Closes #963.
Original pull request: #1071.
mikereiche added a commit that referenced this pull request Apr 26, 2021
Scope and Collection API for template.

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche closed this May 6, 2021
mikereiche added a commit that referenced this pull request May 18, 2021
Scope and Collection API for template.

Closes #963.
Original pull request: #1071.
mikereiche added a commit that referenced this pull request Jun 2, 2021
Scope and Collection API for template.

Closes #963.
Original pull request: #1071.
mikereiche added a commit that referenced this pull request Aug 9, 2021
Scope and Collection API for template.

Closes #963.
Original pull request: #1071.
@mikereiche mikereiche deleted the datacouch_963_scope_and_collection_api branch August 11, 2021 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for Scope and Collection API Changes [DATACOUCH-655]
3 participants