Skip to content

Commit

Permalink
Add QueryServiceResolver strategy to GeodeSetup
Browse files Browse the repository at this point in the history
QueryService lookup is specific to local / remote / proxyied region logic.

Copy logic from GemfireTemplate class (spring data geode project).
  • Loading branch information
asereda-gs committed Oct 16, 2019
1 parent c767599 commit ba70629
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2019 Immutables Authors and Contributors
* Copyright 2010-2019 the Spring Data original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.immutables.criteria.geode;

import com.google.common.base.Preconditions;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.internal.cache.LocalRegion;

import java.util.Objects;

/**
* QueryService resolution logic copied from <a href="https://spring.io/projects/spring-data-geode">spring geode-data</a> project.
*
* <p>Specifically <a href="https://github.com/spring-projects/spring-data-geode/blob/9912c646f0edf52bc5b740d6f6b5b79e2f2ba172/src/main/java/org/springframework/data/gemfire/GemfireTemplate.java#L402">GemfireTemplate</a>
*
* @author Costin Leau
* @author John Blum
*/
class DefaultQueryServiceResolver implements QueryServiceResolver {

static final QueryServiceResolver INSTANCE = new DefaultQueryServiceResolver();

private DefaultQueryServiceResolver() {}

/**
* Returns the {@link QueryService} used by this template in its query/finder methods.
*
* @param region {@link Region} used to acquire the {@link QueryService}.
* @return the {@link QueryService} that will perform the query.
* @see Region
* @see Region#getRegionService()
* @see org.apache.geode.cache.RegionService#getQueryService()
* @see org.apache.geode.cache.client.ClientCache#getLocalQueryService()
*/
@Override
public QueryService resolve(Region<?, ?> region) {
Objects.requireNonNull(region, "region");
return region.getRegionService() instanceof ClientCache
? resolveClientQueryService(region)
: queryServiceFrom(region);
}

private QueryService resolveClientQueryService(Region<?, ?> region) {
Preconditions.checkArgument(region.getRegionService() instanceof ClientCache, "Expected to get %s got %s for region %s", ClientCache.class, region.getRegionService(), region.getFullPath());
ClientCache clientCache = (ClientCache) region.getRegionService();

return requiresLocalQueryService(region) ? clientCache.getLocalQueryService()
: (requiresPooledQueryService(region) ? clientCache.getQueryService(poolNameFrom(region))
: queryServiceFrom(region));
}

private boolean requiresLocalQueryService(Region<?, ?> region) {
return Scope.LOCAL.equals(region.getAttributes().getScope()) && isLocalWithNoServerProxy(region);
}

private boolean isLocalWithNoServerProxy(Region<?, ?> region) {
return region instanceof LocalRegion && !((LocalRegion) region).hasServerProxy();
}

private boolean requiresPooledQueryService(Region<?, ?> region) {
String pool = poolNameFrom(region);
return pool != null && !pool.isEmpty();
}

private QueryService queryServiceFrom(Region<?, ?> region) {
return region.getRegionService().getQueryService();
}

private String poolNameFrom(Region<?, ?> region) {
return region.getAttributes().getPoolName();
}
}
21 changes: 9 additions & 12 deletions criteria/geode/src/org/immutables/criteria/geode/GeodeBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,17 @@ public class GeodeBackend implements Backend {

static final Logger logger = Logger.getLogger(GeodeBackend.class.getName());

private final RegionResolver resolver;
private final IdResolver idResolver;
private final GeodeSetup setup;


public GeodeBackend(GeodeSetup setup) {
Objects.requireNonNull(setup, "setup");
this.resolver = setup.regionResolver();
this.idResolver = setup.idResolver();
this.setup = Objects.requireNonNull(setup, "setup");
}

@Override
public Backend.Session open(Class<?> entityType) {
Objects.requireNonNull(entityType, "context");
@SuppressWarnings("unchecked")
Region<Object, Object> region = (Region<Object, Object>) resolver.resolve(entityType);
return new Session(entityType, idResolver, region);
return new Session(entityType, setup);
}

static class Session implements Backend.Session {
Expand All @@ -74,12 +69,14 @@ static class Session implements Backend.Session {
final IdResolver idResolver;
final QueryService queryService;

private Session(Class<?> entityType, IdResolver idResolver, Region<Object, Object> region) {
private Session(Class<?> entityType, GeodeSetup setup) {
this.entityType = Objects.requireNonNull(entityType, "entityType");
this.region = Objects.requireNonNull(region, "region");
this.idResolver = Objects.requireNonNull(idResolver, "idResolver");
@SuppressWarnings("unchecked")
Region<Object, Object> region = (Region<Object, Object>) setup.regionResolver().resolve(entityType);
this.region = region;
this.idResolver = setup.idResolver();
this.idExtractor = IdExtractor.fromResolver(idResolver);
this.queryService = region.getRegionService().getQueryService();
this.queryService = setup.queryServiceResolver().resolve(region);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ default IdResolver idResolver() {
return IdResolver.defaultResolver();
}

@Value.Default
default QueryServiceResolver queryServiceResolver() {
return QueryServiceResolver.defaultResolver();
}

static GeodeSetup of(GemFireCache cache) {
Objects.requireNonNull(cache, "cache");
return of(RegionResolver.defaultResolver(cache));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2019 Immutables Authors and Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.immutables.criteria.geode;

import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionService;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.query.QueryService;

/**
* Strategy to select a {@link QueryService} for a {@link Region}.
*
* <p>Query service can be associated with a {@link org.apache.geode.cache.client.Pool} or
* query only local state (see {@link ClientCache#getLocalQueryService()}.
*
* @see RegionService#getQueryService()
* @see ClientCache#getLocalQueryService()
* @see ClientCache#getQueryService(String)
*/
public interface QueryServiceResolver {

/**
* Find {@linkplain QueryService} for a region.
*/
QueryService resolve(Region<?, ?> region);

static QueryServiceResolver defaultResolver() {
return DefaultQueryServiceResolver.INSTANCE;
}

}

0 comments on commit ba70629

Please sign in to comment.