Skip to content

Commit

Permalink
Declarative contracts (#1060)
Browse files Browse the repository at this point in the history
* Declarative contracts

* Actually using the data structure to read declaritve contracts

* Using declarative contract for jaxrs contracts

* Make possible for contracts to declare parameters as ignored

* Using predicate to decide if an AnnotationProcessor should be invoked

* Restore environment variable for GITHUB_TOKEN
  • Loading branch information
velo authored Sep 10, 2019
1 parent ac57855 commit 97cb786
Show file tree
Hide file tree
Showing 11 changed files with 525 additions and 274 deletions.
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ jobs:
jdk: openjdk8
install: true
script:
- ./mvnw -B -nsu -s ./travis/settings.xml -P release -pl -:feign-benchmark -DskipTests=true deploy
- ./mvnw -B -nsu -s ./travis/settings.xml -P release -pl -:feign-benchmark -DskipTests=true deploy

env:
global:
# Ex. travis encrypt GITHUB_TOKEN=token_for_tests
- secure: "H4PuppuPE3lkvVQ1osulhgWeZmpIkDKj/z74lx4MUeDPNtcuqpwmTVWtL5Zyjf8CxlALX2djx4RIBshaQAu4GtKarPLONinNLZ/TCtoK8dF08/ESxLEiLQzwGkS+geWoEFiZncB5Px2T7ZbUfVFO3crVY9CLn35znR8k1uidocL0JlyVPGwCwuBxFmDhs3BZh3JvbwSikAVRvlCRU6BbREFQbSK1EamuUju/rlo+dx7W5tiiuEJJ50c8vpgatTFyy821YP82fMRrhuBDpS4/rsL9DmLhQTEbCjZW+22DhEFPRlo0XIfidC7APybXnu3oO+jFuGaFKiQdy7sjB03g/Bz5H7jAIAkbl8UpbjN+IoeUU/OgMuBYf5wJjPDYUEdI3CXqywPn0xYZwVsOcSg+UkQGYdW9ux/U+nKsYLXLWWhst2QMFzbmO94KCrpgCW4mshr/5WP4XU6cEJwDsKMAUPWuOk0KMMjIufSgvPvteWZwT9akZwzEMuGaUQ5kLr1X6xTPv1cKXTreitaoOLQs28kmPVfTwVEdareaSVXcRqeflJJBSXkAgBqGhV5CAEUaUgt9/QD0Jj5RGyRPllFcydXVLTPeg62X/L5COswlvJhPkvfNnkbMpDQZYojKKPmAf+UqZJmVYPpOoNEXygldueKeunWkna/wYkMj0YnOkM8="
374 changes: 275 additions & 99 deletions core/src/main/java/feign/Contract.java

Large diffs are not rendered by default.

50 changes: 45 additions & 5 deletions core/src/main/java/feign/MethodMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@
import feign.Param.Expander;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

public final class MethodMetadata implements Serializable {

Expand All @@ -41,6 +37,7 @@ public final class MethodMetadata implements Serializable {
new LinkedHashMap<Integer, Class<? extends Expander>>();
private Map<Integer, Boolean> indexToEncoded = new LinkedHashMap<Integer, Boolean>();
private transient Map<Integer, Expander> indexToExpander;
private BitSet parameterToIgnore = new BitSet();

MethodMetadata() {}

Expand Down Expand Up @@ -157,4 +154,47 @@ public MethodMetadata indexToExpander(Map<Integer, Expander> indexToExpander) {
public Map<Integer, Expander> indexToExpander() {
return indexToExpander;
}

/**
* @param i individual parameter that should be ignored
* @return this instance
*/
public MethodMetadata ignoreParamater(int i) {
this.parameterToIgnore.set(i);
return this;
}

public BitSet parameterToIgnore() {
return parameterToIgnore;
}

public MethodMetadata parameterToIgnore(BitSet parameterToIgnore) {
this.parameterToIgnore = parameterToIgnore;
return this;
}

/**
* @param i individual parameter to check if should be ignored
* @return true when field should not be processed by feign
*/
public boolean shouldIgnoreParamater(int i) {
return parameterToIgnore.get(i);
}

/**
* @param index
* @return true if the parameter {@code index} was already consumed by a any {@link
* MethodMetadata} holder
*/
public boolean isAlreadyProcessed(Integer index) {
return index.equals(urlIndex)
|| index.equals(bodyIndex)
|| index.equals(headerMapIndex)
|| index.equals(queryMapIndex)
|| indexToName.containsKey(index)
|| indexToExpanderClass.containsKey(index)
|| indexToEncoded.containsKey(index)
|| (indexToExpander != null && indexToExpander.containsKey(index))
|| parameterToIgnore.get(index);
}
}
7 changes: 5 additions & 2 deletions core/src/main/java/feign/SynchronousMethodHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,11 @@ Options findOptions(Object[] argv) {
if (argv == null || argv.length == 0) {
return this.options;
}
return (Options)
Stream.of(argv).filter(o -> o instanceof Options).findFirst().orElse(this.options);
return Stream.of(argv)
.filter(Options.class::isInstance)
.map(Options.class::cast)
.findFirst()
.orElse(this.options);
}

static class Factory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Contract contract(BeanFactory beanFactory) {
}
}

static class ContractWithRuntimeInjection extends Contract.Default {
static class ContractWithRuntimeInjection implements Contract {
final BeanFactory beanFactory;

ContractWithRuntimeInjection(BeanFactory beanFactory) {
Expand All @@ -93,7 +93,7 @@ static class ContractWithRuntimeInjection extends Contract.Default {
*/
@Override
public List<MethodMetadata> parseAndValidatateMetadata(Class<?> targetType) {
List<MethodMetadata> result = super.parseAndValidatateMetadata(targetType);
List<MethodMetadata> result = new Contract.Default().parseAndValidatateMetadata(targetType);
for (MethodMetadata md : result) {
Map<Integer, Param.Expander> indexToExpander = new LinkedHashMap<Integer, Param.Expander>();
for (Map.Entry<Integer, Class<? extends Param.Expander>> entry :
Expand Down
3 changes: 2 additions & 1 deletion core/src/test/java/feign/DefaultContractTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,8 @@ interface MissingMethod {
public void missingMethod() throws Exception {
thrown.expect(IllegalStateException.class);
thrown.expectMessage(
"RequestLine annotation didn't start with an HTTP verb on method updateSharing");
"RequestLine annotation didn't start with an HTTP verb on method"
+ " MissingMethod#updateSharing");

contract.parseAndValidatateMetadata(MissingMethod.class);
}
Expand Down
17 changes: 17 additions & 0 deletions core/src/test/java/feign/assertj/RequestTemplateAssert.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,21 @@ public RequestTemplateAssert hasNoHeader(final String encoded) {
objects.assertNull(info, actual.headers().get(encoded));
return this;
}

public RequestTemplateAssert noRequestBody() {
isNotNull();
if (actual.requestBody() != null) {
if (actual.requestBody().bodyTemplate() != null) {
failWithMessage(
"\nExpecting requestBody.bodyTemplate to be null, but was:<%s>",
actual.requestBody().bodyTemplate());
}
if (actual.requestBody().asBytes() != null) {
failWithMessage(
"\nExpecting requestBody.data to be null, but was:<%s>",
actual.requestBody().asString());
}
}
return this;
}
}
Loading

0 comments on commit 97cb786

Please sign in to comment.