Skip to content

Commit 860a914

Browse files
committed
Allow entity extensions to stitch and resolve deprecated fields
1 parent c97643f commit 860a914

File tree

4 files changed

+111
-3
lines changed

4 files changed

+111
-3
lines changed

src/main/java/com/intuit/graphql/orchestrator/federation/EntityTypeMerger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ private void pruneConflictingResolverInfo(EntityMergingContext entityMergingCont
4545
.filter(entityFieldDefinition-> !definitionContainsDirective(entityFieldDefinition, FEDERATION_EXTERNAL_DIRECTIVE))
4646
.forEach(newEntityField -> {
4747
getFieldDefinitions(entityMergingContext.getBaseType()).removeIf(preexistingField ->
48-
definitionContainsDirective(preexistingField, RESOLVER_DIRECTIVE_NAME)
48+
(definitionContainsDirective(preexistingField, RESOLVER_DIRECTIVE_NAME) || definitionContainsDirective(preexistingField, "deprecated"))
4949
&& preexistingField.getName().equals(newEntityField.getName())
5050
);
5151

src/main/java/com/intuit/graphql/orchestrator/schema/transform/FederationTransformerPostMerge.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ private void checkFederationFieldDirectives(EntityMergingContext entityMergingCo
183183

184184
List<FieldDefinition> baseFields = getFieldDefinitions(entityMergingContext.getBaseType());
185185
List<String> baseFieldNames = baseFields.stream()
186-
.map(FieldDefinition::getName).collect(Collectors.toList());
186+
.filter(field -> !definitionContainsDirective(field, "deprecated"))
187+
.map(FieldDefinition::getName)
188+
.collect(Collectors.toList());
187189

188190
List<String> baseFieldResolvers = baseFields.stream()
189191
.filter(fieldDefinition -> definitionContainsDirective(fieldDefinition, RESOLVER_DIRECTIVE_NAME))

src/test/groovy/com/intuit/graphql/orchestrator/federation/EntityTypeMergerSpec.groovy

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,80 @@ class EntityTypeMergerSpec extends Specification {
181181
actualFieldNames containsInAnyOrder("requiredField", "testField2", "ExternalFieldResolver", "testField1")
182182
}
183183

184+
def "merge Into Base Type prunes deprecated base field success"(){
185+
given:
186+
187+
TypeSystemDefinition typeSystemDefinition = createTypeSystemDefinition()
188+
189+
FieldDefinition requiredField = buildFieldDefinition("requiredField")
190+
191+
FieldDefinition entityRequiredField = buildFieldDefinition("requiredField")
192+
entityRequiredField.getDirectives().add(buildDirective(buildDirectiveDefinition("external"), emptyList()))
193+
194+
FieldDefinition deprecatedField = buildFieldDefinition("deprecatedField")
195+
deprecatedField.getDirectives().add(buildDirective(buildDirectiveDefinition("deprecated"), emptyList()))
196+
197+
FieldDefinition extField = buildFieldDefinition("deprecatedField")
198+
199+
200+
ObjectTypeDefinition baseObjectType =
201+
buildObjectTypeDefinition("EntityType", Arrays.asList(
202+
requiredField,
203+
deprecatedField,
204+
))
205+
206+
ObjectTypeExtensionDefinition objectTypeExtension =
207+
buildObjectTypeExtensionDefinition("EntityType", Arrays.asList(
208+
entityRequiredField,
209+
extField
210+
))
211+
212+
typeSystemDefinition.setTypeExtension(objectTypeExtension)
213+
214+
entityMergingContextMock.getBaseType() >> baseObjectType
215+
entityMergingContextMock.getExtensionSystemDefinition() >> typeSystemDefinition
216+
217+
unifiedXtextGraphMock.getFieldResolverContexts() >> fieldResolverContexts
218+
219+
Map<String, FederationMetadata> federationMetadataMap = new HashMap<>()
220+
221+
FederationMetadata baseFederationMetadataMock = Mock(FederationMetadata.class)
222+
FederationMetadata extFederationMetadataMock = Mock(FederationMetadata.class)
223+
224+
FederationMetadata.EntityMetadata baseEntityMetaDataMock = Mock(FederationMetadata.EntityMetadata.class)
225+
Set<String> baseFields = Sets.newHashSet("requiredField", "deprecatedField")
226+
baseEntityMetaDataMock.getFields() >> baseFields
227+
228+
FederationMetadata.EntityMetadata extEntityMetaDataMock = Mock(FederationMetadata.EntityMetadata.class)
229+
Set<String> extFields = Sets.newHashSet( "deprecatedField")
230+
extEntityMetaDataMock.getFields() >> extFields
231+
232+
baseFederationMetadataMock.getEntityMetadataByName("EntityType") >> baseEntityMetaDataMock
233+
extFederationMetadataMock.getEntityMetadataByName("EntityType") >> extEntityMetaDataMock
234+
235+
federationMetadataMap.put("baseService", baseFederationMetadataMock)
236+
federationMetadataMap.put("extService", extFederationMetadataMock)
237+
238+
unifiedXtextGraphMock.getFederationMetadataByNamespace() >> federationMetadataMap
239+
entityMergingContextMock.getTypename() >> "EntityType"
240+
241+
when:
242+
TypeDefinition actual = subjectUnderTest.mergeIntoBaseType(entityMergingContextMock, unifiedXtextGraphMock)
243+
244+
then:
245+
actual == baseObjectType
246+
List<FieldDefinition> actualFieldDefinitions = getFieldDefinitions(actual)
247+
actualFieldDefinitions.size() == 2
248+
249+
baseFields.size() == 1
250+
baseFields containsInAnyOrder("requiredField")
251+
252+
List<String> actualFieldNames = actualFieldDefinitions.stream()
253+
.map({ fieldDefinition -> fieldDefinition.getName() })
254+
.collect(Collectors.toList())
255+
actualFieldNames containsInAnyOrder("requiredField", "deprecatedField")
256+
}
257+
184258
def "merge Into Base Type interface Type Definition success"() {
185259
// TODO
186260
}

src/test/groovy/com/intuit/graphql/orchestrator/schema/transform/FederationTransformerPostMergeSpec.groovy

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ class FederationTransformerPostMergeSpec extends Specification {
2020

2121
private FieldDefinition BASE_FIELD_DEFINITION = buildFieldDefinition("testField1")
2222

23+
private Directive DEPRECATED_DIRECTIVE = buildDirective(buildDirectiveDefinition("deprecated"), null)
24+
25+
private FieldDefinition BASE_DEPRECATED_FIELD_DEFINITION = buildFieldDefinition("deprecatedField", singletonList(DEPRECATED_DIRECTIVE))
26+
2327
private Directive EXTERNAL_DIRECTIVE = buildDirective(buildDirectiveDefinition(FEDERATION_EXTERNAL_DIRECTIVE), null)
2428

2529
private FieldDefinition EXTENSION_FIELD_DEFINITION = buildFieldDefinition("testField1", singletonList(EXTERNAL_DIRECTIVE))
@@ -34,8 +38,10 @@ class FederationTransformerPostMergeSpec extends Specification {
3438
Map<String, TypeDefinition> getEntities() {
3539
Map<String, TypeDefinition> entitiesByTypeName = new HashMap<>()
3640

41+
List<FieldDefinition> baseFields = Arrays.asList(BASE_FIELD_DEFINITION, BASE_DEPRECATED_FIELD_DEFINITION)
42+
3743
ObjectTypeDefinition baseObjectType =
38-
buildObjectTypeDefinition("EntityType", singletonList(BASE_FIELD_DEFINITION))
44+
buildObjectTypeDefinition("EntityType", baseFields)
3945
entitiesByTypeName.put("EntityType", baseObjectType)
4046

4147
return entitiesByTypeName
@@ -148,6 +154,32 @@ class FederationTransformerPostMergeSpec extends Specification {
148154
actual.is(unifiedXtextGraphMock)
149155
}
150156

157+
def "transform success shared field with deprecated field"(){
158+
given:
159+
def unifiedXtextGraphMock = Mock(UnifiedXtextGraph)
160+
161+
Map<String, Map<String, TypeSystemDefinition>> entityExtensionsByNamespace = new HashMap<>()
162+
TypeSystemDefinition typeSystemDefinition = createTypeSystemDefinition()
163+
164+
ObjectTypeDefinition objectTypeExtension =
165+
buildObjectTypeDefinition("EntityType", singletonList(buildFieldDefinition("deprecatedField")))
166+
typeSystemDefinition.setType(objectTypeExtension)
167+
entityExtensionsByNamespace.put("testNamespace", ImmutableMap.of("EntityType", typeSystemDefinition))
168+
169+
1 * unifiedXtextGraphMock.getEntitiesByTypeName() >> getEntities()
170+
1 * unifiedXtextGraphMock.getFieldResolverContexts() >> Collections.emptyList()
171+
2 * unifiedXtextGraphMock.getEntityExtensionsByNamespace() >> entityExtensionsByNamespace
172+
unifiedXtextGraphMock.getEntityExtensionMetadatas() >> []
173+
unifiedXtextGraphMock.getFederationMetadataByNamespace() >> new HashMap<>()
174+
unifiedXtextGraphMock.getValueTypesByName() >> new HashMap<>()
175+
176+
when:
177+
UnifiedXtextGraph actual = subjectUnderTest.transform(unifiedXtextGraphMock)
178+
179+
then:
180+
actual.is(unifiedXtextGraphMock)
181+
}
182+
151183
def "transform adds inaccessible info"() {
152184
given:
153185
def unifiedXtextGraphMock = Mock(UnifiedXtextGraph)

0 commit comments

Comments
 (0)