private GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, ExecutionIdProvider idProvider, Instrumentation instrumentation, PreparsedDocumentProvider preparsedDocumentProvider) { this.graphQLSchema = assertNotNull(graphQLSchema, "graphQLSchema must be non null"); this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new SubscriptionExecutionStrategy(); this.idProvider = assertNotNull(idProvider, "idProvider must be non null"); this.instrumentation = checkInstrumentation(assertNotNull(instrumentation)); this.preparsedDocumentProvider = assertNotNull(preparsedDocumentProvider, "preparsedDocumentProvider must be non null"); }
private CompletableFuture<ExecutionResult> executeSubscriptionEvent(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object eventPayload) { ExecutionContext newExecutionContext = executionContext.transform(builder -> builder.root(eventPayload)); ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(parameters); FetchedValue fetchedValue = FetchedValue.newFetchedValue().fetchedValue(eventPayload) .rawFetchedValue(eventPayload) .localContext(parameters.getLocalContext()) .build(); return completeField(newExecutionContext, newParameters, fetchedValue).getFieldValue() .thenApply(executionResult -> wrapWithRootFieldName(newParameters, executionResult)); }
@Override public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { CompletableFuture<Publisher<Object>> sourceEventStream = createSourceEventStream(executionContext, parameters); // // when the upstream source event stream completes, subscribe to it and wire in our adapter return sourceEventStream.thenApply((publisher) -> { if (publisher == null) { return new ExecutionResultImpl(null, executionContext.getErrors()); } CompletionStageMappingPublisher<ExecutionResult, Object> mapSourceToResponse = new CompletionStageMappingPublisher<>( publisher, eventPayload -> executeSubscriptionEvent(executionContext, parameters, eventPayload) ); return new ExecutionResultImpl(mapSourceToResponse, executionContext.getErrors()); }); }
private CompletableFuture<Publisher<Object>> createSourceEventStream(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(parameters); CompletableFuture<FetchedValue> fieldFetched = fetchField(executionContext, newParameters); return fieldFetched.thenApply(fetchedValue -> { Object publisher = fetchedValue.getFetchedValue(); if (publisher != null) { assertTrue(publisher instanceof Publisher, "You data fetcher must return a Publisher of events when using graphql subscriptions"); } //noinspection unchecked return (Publisher<Object>) publisher; }); }
private ExecutionResult wrapWithRootFieldName(ExecutionStrategyParameters parameters, ExecutionResult executionResult) { String rootFieldName = getRootFieldName(parameters); return new ExecutionResultImpl( singletonMap(rootFieldName, executionResult.getData()), executionResult.getErrors() ); }
private ExecutionStrategyParameters firstFieldOfSubscriptionSelection(ExecutionStrategyParameters parameters) { MergedSelectionSet fields = parameters.getFields(); MergedField firstField = fields.getSubField(fields.getKeys().get(0)); ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(firstField.getSingleField())); return parameters.transform(builder -> builder.field(firstField).path(fieldPath)); }
private CompletableFuture<Publisher<Object>> createSourceEventStream(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(parameters); CompletableFuture<FetchedValue> fieldFetched = fetchField(executionContext, newParameters); return fieldFetched.thenApply(fetchedValue -> { Object publisher = fetchedValue.getFetchedValue(); if (publisher != null) { assertTrue(publisher instanceof Publisher, "You data fetcher must return a Publisher of events when using graphql subscriptions"); } //noinspection unchecked return (Publisher<Object>) publisher; }); }
private ExecutionResult wrapWithRootFieldName(ExecutionStrategyParameters parameters, ExecutionResult executionResult) { String rootFieldName = getRootFieldName(parameters); return new ExecutionResultImpl( singletonMap(rootFieldName, executionResult.getData()), executionResult.getErrors() ); }
private ExecutionStrategyParameters firstFieldOfSubscriptionSelection(ExecutionStrategyParameters parameters) { MergedSelectionSet fields = parameters.getFields(); MergedField firstField = fields.getSubField(fields.getKeys().get(0)); ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(firstField.getSingleField())); return parameters.transform(builder -> builder.field(firstField).path(fieldPath)); }
void basicSubscriptionExample() { GraphQL graphQL = GraphQL .newGraphQL(schema) .subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()) .build();
private CompletableFuture<ExecutionResult> executeSubscriptionEvent(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object eventPayload) { ExecutionContext newExecutionContext = executionContext.transform(builder -> builder.root(eventPayload)); ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(parameters); FetchedValue fetchedValue = FetchedValue.newFetchedValue().fetchedValue(eventPayload) .rawFetchedValue(eventPayload) .localContext(parameters.getLocalContext()) .build(); return completeField(newExecutionContext, newParameters, fetchedValue).getFieldValue() .thenApply(executionResult -> wrapWithRootFieldName(newParameters, executionResult)); }
@Override public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { CompletableFuture<Publisher<Object>> sourceEventStream = createSourceEventStream(executionContext, parameters); // // when the upstream source event stream completes, subscribe to it and wire in our adapter return sourceEventStream.thenApply((publisher) -> { if (publisher == null) { return new ExecutionResultImpl(null, executionContext.getErrors()); } CompletionStageMappingPublisher<ExecutionResult, Object> mapSourceToResponse = new CompletionStageMappingPublisher<>( publisher, eventPayload -> executeSubscriptionEvent(executionContext, parameters, eventPayload) ); return new ExecutionResultImpl(mapSourceToResponse, executionContext.getErrors()); }); }
@Bean @ConditionalOnMissingBean public ExecutionStrategyProvider executionStrategyProvider() { if (executionStrategies == null || executionStrategies.isEmpty()) { return new DefaultExecutionStrategyProvider(new AsyncExecutionStrategy(), null, new SubscriptionExecutionStrategy()); } else if (executionStrategies.entrySet().size() == 1) { return new DefaultExecutionStrategyProvider(executionStrategies.entrySet().stream().findFirst().get().getValue()); } else { if (!executionStrategies.containsKey(QUERY_EXECUTION_STRATEGY)) { throwIncorrectExecutionStrategyNameException(); } if (executionStrategies.size() == 2 && !(executionStrategies.containsKey(MUTATION_EXECUTION_STRATEGY) || executionStrategies.containsKey(SUBSCRIPTION_EXECUTION_STRATEGY))) { throwIncorrectExecutionStrategyNameException(); } if (executionStrategies.size() >= 3 && !(executionStrategies.containsKey(MUTATION_EXECUTION_STRATEGY) && executionStrategies.containsKey(SUBSCRIPTION_EXECUTION_STRATEGY))) { throwIncorrectExecutionStrategyNameException(); } return new DefaultExecutionStrategyProvider( executionStrategies.get(QUERY_EXECUTION_STRATEGY), executionStrategies.get(MUTATION_EXECUTION_STRATEGY), executionStrategies.get(SUBSCRIPTION_EXECUTION_STRATEGY) ); } }
public DefaultExecutionStrategyProvider(ExecutionStrategy queryExecutionStrategy, ExecutionStrategy mutationExecutionStrategy, ExecutionStrategy subscriptionExecutionStrategy) { this.queryExecutionStrategy = defaultIfNull(queryExecutionStrategy, new AsyncExecutionStrategy()); this.mutationExecutionStrategy = defaultIfNull(mutationExecutionStrategy, this.queryExecutionStrategy); this.subscriptionExecutionStrategy = defaultIfNull(subscriptionExecutionStrategy, new SubscriptionExecutionStrategy()); }
private GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, ExecutionIdProvider idProvider, Instrumentation instrumentation, PreparsedDocumentProvider preparsedDocumentProvider) { this.graphQLSchema = assertNotNull(graphQLSchema, "graphQLSchema must be non null"); this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new SubscriptionExecutionStrategy(); this.idProvider = assertNotNull(idProvider, "idProvider must be non null"); this.instrumentation = checkInstrumentation(assertNotNull(instrumentation)); this.preparsedDocumentProvider = assertNotNull(preparsedDocumentProvider, "preparsedDocumentProvider must be non null"); }