Skip to content
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

#767 send filter in body instead of URL #771

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ gradle.beforeProject { Project project ->
if (!docs && !examples && !testProject && !legacyBraveProject) {
apply plugin: "jacoco"
jacoco {
toolVersion = "0.7.6.201602180812"
toolVersion = "0.8.5"
}

rootProject.tasks.jacocoMerge.executionData tasks.withType(Test)
Expand Down
33 changes: 26 additions & 7 deletions crnk-client/src/main/java/io/crnk/client/CrnkClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ public class CrnkClient {

private ClientProxyFactory configuredProxyFactory;

private boolean filterCriteriaInRequestBody;

public enum ClientType {
SIMPLE_lINKS,

Expand Down Expand Up @@ -274,13 +276,13 @@ public ModuleRegistry getModuleRegistry() {
}

@Override
public <T> DefaultResourceList<T> getCollection(Class<T> resourceClass, String url) {
public <T> DefaultResourceList<T> getCollection(Class<T> resourceClass, String url, String body) {
RegistryEntry entry = resourceRegistry.findEntry(resourceClass);
ResourceInformation resourceInformation = entry.getResourceInformation();
// TODO add decoration
final ResourceRepositoryStubImpl<T, ?> repositoryStub =
new ResourceRepositoryStubImpl<>(CrnkClient.this, resourceClass, resourceInformation, urlBuilder);
return repositoryStub.findAll(url);
new ResourceRepositoryStubImpl<>(CrnkClient.this, resourceClass, resourceInformation, urlBuilder, filterCriteriaInRequestBody);
return repositoryStub.findAll(url, body);

}
});
Expand Down Expand Up @@ -320,6 +322,7 @@ protected void init() {
setupServiceDiscovery();
initHttpAdapter();

setupUrlMapper();
setupPagingBehavior();
initObjectMapper();
configureObjectMapper();
Expand All @@ -335,6 +338,17 @@ protected void init() {
}
}

private void setupUrlMapper() {
if (filterCriteriaInRequestBody) {
QuerySpecUrlMapper urlMapper = moduleRegistry.getUrlMapper();
if (urlMapper instanceof DefaultQuerySpecUrlMapper) {
((DefaultQuerySpecUrlMapper) urlMapper).setFilterCriteriaInRequestBody(filterCriteriaInRequestBody);
} else {
throw new IllegalStateException("Need DefaultQuerySpecUrlMapper for filterCriteriaInRequestBody option");
}
}
}

protected void initObjectMapper() {
if (objectMapper == null) {
objectMapper = createDefaultObjectMapper();
Expand Down Expand Up @@ -415,7 +429,7 @@ protected <T, I> RegistryEntry allocateRepository(Class<T> resourceClass, Regist
ModuleUtils.adaptInformation(resourceInformation, moduleRegistry);

final ResourceRepository repositoryStub = (ResourceRepository) decorate(
new ResourceRepositoryStubImpl<T, I>(this, resourceClass, resourceInformation, urlBuilder)
new ResourceRepositoryStubImpl<T, I>(this, resourceClass, resourceInformation, urlBuilder, filterCriteriaInRequestBody)
);

// create interface for it!
Expand Down Expand Up @@ -486,7 +500,7 @@ private RelationshipRepositoryAdapter allocateRepositoryRelation(ResourceField f
}

final Object relationshipRepositoryStub = decorate(
new RelationshipRepositoryStubImpl(this, sourceClass, targetClass, sourceEntry.getResourceInformation(), urlBuilder)
new RelationshipRepositoryStubImpl(this, sourceClass, targetClass, sourceEntry.getResourceInformation(), urlBuilder, filterCriteriaInRequestBody)
);

RelationshipRepositoryAdapter adapter = new RelationshipRepositoryAdapterImpl(field, moduleRegistry, relationshipRepositoryStub);
Expand Down Expand Up @@ -543,7 +557,7 @@ public ResourceRepository<Resource, String> getRepositoryForPath(String resource
, null
, PagingSpec.class
);
return (ResourceRepository<Resource, String>) decorate(new ResourceRepositoryStubImpl<>(this, Resource.class, resourceInformation, urlBuilder));
return (ResourceRepository<Resource, String>) decorate(new ResourceRepositoryStubImpl<>(this, Resource.class, resourceInformation, urlBuilder, filterCriteriaInRequestBody));
}

/**
Expand All @@ -558,7 +572,7 @@ public RelationshipRepository<Resource, String, Resource, String> getRepositoryF
PagingSpec.class);
return (RelationshipRepository<Resource, String, Resource, String>) decorate(
new RelationshipRepositoryStubImpl<>(this, Resource.class, Resource.class, sourceResourceInformation,
urlBuilder));
urlBuilder, filterCriteriaInRequestBody));
}


Expand Down Expand Up @@ -734,4 +748,9 @@ public boolean isInitialized(Class<?> clazz) {
return super.getEntry(clazz) != null;
}
}

public void setFilterCriteriaInRequestBody(boolean filterCriteriaInRequestBody) {
PreconditionUtil.verify(!initialized, "CrnkClient already initialized, cannot add filters to body");
this.filterCriteriaInRequestBody = filterCriteriaInRequestBody;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ public HttpClientRequest(CloseableHttpClient impl, String url, HttpMethod method
this.listeners = listeners;
this.requestBody = requestBody;
if (method == HttpMethod.GET) {
requestBase = new HttpGet(url);
if (requestBody == null || requestBody.isEmpty()) {
requestBase = new HttpGet(url);
} else {
requestBase = new HttpGetWithBody(url, requestBody, CONTENT_TYPE);
}
} else if (method == HttpMethod.POST) {
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(requestBody, CONTENT_TYPE));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.crnk.client.http.apache;

import io.crnk.core.engine.http.HttpMethod;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;

import java.net.URI;

public class HttpGetWithBody extends HttpEntityEnclosingRequestBase {
public HttpGetWithBody(String url, String body, ContentType contentType) {
setURI(URI.create(url));
setEntity(new StringEntity(body, contentType));
}

@Override
public String getMethod() {
return HttpMethod.GET.toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package io.crnk.client.internal;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.crnk.client.ClientException;
import io.crnk.client.ClientFormat;
import io.crnk.client.CrnkClient;
import io.crnk.client.ResponseBodyException;
import io.crnk.client.TransportException;
import io.crnk.client.*;
import io.crnk.client.http.HttpAdapter;
import io.crnk.client.http.HttpAdapterRequest;
import io.crnk.client.http.HttpAdapterResponse;
Expand All @@ -19,20 +13,33 @@
import io.crnk.core.engine.error.ExceptionMapper;
import io.crnk.core.engine.http.HttpHeaders;
import io.crnk.core.engine.http.HttpMethod;
import io.crnk.core.engine.information.resource.ResourceInformation;
import io.crnk.core.engine.internal.exception.ExceptionMapperRegistry;
import io.crnk.core.engine.internal.utils.PreconditionUtil;
import io.crnk.core.engine.query.QueryContext;
import io.crnk.core.exception.CrnkException;
import io.crnk.core.queryspec.FilterSpec;
import io.crnk.core.queryspec.QuerySpec;
import io.crnk.core.queryspec.internal.JsonFilterSpecMapper;
import io.crnk.core.queryspec.mapper.DefaultQuerySpecUrlMapper;
import io.crnk.core.queryspec.mapper.UrlBuilder;
import io.crnk.core.resource.list.DefaultResourceList;
import io.crnk.core.resource.meta.JsonLinksInformation;
import io.crnk.core.resource.meta.JsonMetaInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class ClientStubBase {

private static final Logger LOGGER = LoggerFactory.getLogger(ClientStubBase.class);
protected final boolean filterCriteriaInRequestBody;
protected final JsonFilterSpecMapper filterSpecMapper;
protected final ObjectMapper compactMapper;

protected CrnkClient client;

Expand All @@ -41,14 +48,22 @@ public class ClientStubBase {
protected Class<?> resourceClass;


public ClientStubBase(CrnkClient client, UrlBuilder urlBuilder, Class<?> resourceClass) {
public ClientStubBase(CrnkClient client, UrlBuilder urlBuilder, Class<?> resourceClass, boolean filterCriteriaInRequestBody) {
this.client = client;
this.urlBuilder = urlBuilder;
this.resourceClass = resourceClass;
this.filterCriteriaInRequestBody = filterCriteriaInRequestBody;
if (filterCriteriaInRequestBody) {
filterSpecMapper = ((DefaultQuerySpecUrlMapper) client.getUrlMapper()).getJsonParser();
compactMapper = client.getObjectMapper();
} else {
filterSpecMapper = null;
compactMapper = null;
}
}

protected Object executeGet(String requestUrl, ResponseType responseType) {
return execute(requestUrl, responseType, HttpMethod.GET, null);
protected Object executeGet(String requestUrl, String body, ResponseType responseType) {
return execute(requestUrl, responseType, HttpMethod.GET, body);
}

protected Object executeDelete(String requestUrl) {
Expand Down Expand Up @@ -99,8 +114,7 @@ protected Object execute(String url, ResponseType responseType, HttpMethod metho
if (Resource.class.equals(resourceClass)) {
Document document = objectMapper.readValue(body, format.getDocumentClass());
return toResourceResponse(document, objectMapper);
}
else {
} else {
Document document = objectMapper.readValue(body, format.getDocumentClass());

ClientDocumentMapper documentMapper = client.getDocumentMapper();
Expand All @@ -109,8 +123,7 @@ protected Object execute(String url, ResponseType responseType, HttpMethod metho
}
}
return null;
}
catch (IOException e) {
} catch (IOException e) {
throw new TransportException(e);
}
}
Expand All @@ -127,8 +140,7 @@ private static Object toResourceResponse(Document document, ObjectMapper objectM
list.setLinks(new JsonLinksInformation(document.getMeta(), objectMapper));
}
return list;
}
else {
} else {
return data;
}
}
Expand Down Expand Up @@ -165,16 +177,32 @@ public static RuntimeException handleError(CrnkClient client, HttpAdapterRespons
Throwable throwable = mapper.get().fromErrorResponse(errorResponse);
if (throwable instanceof RuntimeException) {
return (RuntimeException) throwable;
}
else {
} else {
return new ClientException(response.code(), response.message(), throwable);
}
}
else {
} else {
return new ClientException(response.code(), response.message());
}
}

protected String serializeFilter(QuerySpec querySpec, ResourceInformation resourceInformation) {
if (querySpec.getFilters() == null || querySpec.getFilters().isEmpty()) {
return null;
}
// filter lists without operator does not work well with JSON serialization -> replace with AND expression
List<FilterSpec> filters = querySpec.getFilters();
if (filters.size() > 1) {
filters = Collections.singletonList(FilterSpec.and(filters));
}
JsonNode jsonNode = filterSpecMapper.serialize(resourceInformation, filters, client.getQueryContext());
try {
return compactMapper.writeValueAsString(jsonNode);
} catch (JsonProcessingException e) {
throw new IllegalStateException(e);
}
}


public enum ResponseType {
NONE, RESOURCE, RESOURCES
}
Expand Down
Loading