├── lombok.config
├── graphql-java-kickstart
├── bnd.bnd
├── src
│ └── main
│ │ └── java
│ │ └── graphql
│ │ └── kickstart
│ │ └── execution
│ │ ├── subscriptions
│ │ ├── SubscriptionConnectionListener.java
│ │ ├── apollo
│ │ │ ├── SubscriptionCommand.java
│ │ │ ├── SubscriptionStopCommand.java
│ │ │ ├── SubscriptionConnectionTerminateCommand.java
│ │ │ ├── ApolloSubscriptionConnectionListener.java
│ │ │ ├── ApolloSubscriptionSession.java
│ │ │ ├── SubscriptionConnectionInitCommand.java
│ │ │ ├── ApolloSubscriptionConsumer.java
│ │ │ ├── KeepAliveSubscriptionConnectionListener.java
│ │ │ ├── ApolloCommandProvider.java
│ │ │ ├── OperationMessage.java
│ │ │ ├── ApolloSubscriptionKeepAliveRunner.java
│ │ │ └── SubscriptionStartCommand.java
│ │ ├── GraphQLSubscriptionInvocationInputFactory.java
│ │ ├── SubscriptionException.java
│ │ ├── SubscriptionProtocolFactory.java
│ │ ├── AtomicSubscriptionSubscription.java
│ │ ├── SessionSubscriptions.java
│ │ ├── SubscriptionSession.java
│ │ ├── GraphQLSubscriptionMapper.java
│ │ ├── SessionSubscriber.java
│ │ └── DefaultSubscriptionSession.java
│ │ ├── GraphQLRootObjectBuilder.java
│ │ ├── input
│ │ ├── GraphQLInvocationInput.java
│ │ ├── GraphQLBatchedInvocationInput.java
│ │ ├── PerRequestBatchedInvocationInput.java
│ │ ├── PerQueryBatchedInvocationInput.java
│ │ └── GraphQLSingleInvocationInput.java
│ │ ├── config
│ │ ├── GraphQLBuilderConfigurer.java
│ │ ├── ObjectMapperProvider.java
│ │ ├── InstrumentationProvider.java
│ │ ├── GraphQLServletObjectMapperConfigurer.java
│ │ ├── ExecutionStrategyProvider.java
│ │ ├── GraphQLSchemaProvider.java
│ │ ├── DefaultGraphQLSchemaProvider.java
│ │ ├── DefaultExecutionStrategyProvider.java
│ │ └── ConfiguringObjectMapperProvider.java
│ │ ├── context
│ │ ├── GraphQLContextBuilder.java
│ │ ├── ContextSettingNotConfiguredException.java
│ │ ├── DefaultGraphQLContextBuilder.java
│ │ ├── GraphQLKickstartContext.java
│ │ ├── DefaultGraphQLContext.java
│ │ └── ContextSetting.java
│ │ ├── DefaultGraphQLRootObjectBuilder.java
│ │ ├── instrumentation
│ │ ├── TrackingApproachException.java
│ │ ├── NoOpInstrumentationProvider.java
│ │ ├── RequestLevelTrackingApproach.java
│ │ ├── FieldLevelTrackingApproach.java
│ │ ├── DataLoaderDispatcherInstrumentationState.java
│ │ └── TrackingApproach.java
│ │ ├── GraphQLInvokerProxy.java
│ │ ├── ObjectMapDeserializationException.java
│ │ ├── StringUtils.java
│ │ ├── error
│ │ ├── GraphQLErrorHandler.java
│ │ ├── DefaultGraphQLServletObjectMapperConfigurer.java
│ │ ├── GenericGraphQLError.java
│ │ ├── RenderableNonNullableFieldWasNullError.java
│ │ └── DefaultGraphQLErrorHandler.java
│ │ ├── StaticGraphQLRootObjectBuilder.java
│ │ ├── GraphQLSingleQueryResult.java
│ │ ├── GraphQLBatchedQueryResult.java
│ │ ├── GraphQLErrorQueryResult.java
│ │ ├── FutureErrorExecutionResult.java
│ │ ├── FutureSingleExecutionResult.java
│ │ ├── FutureBatchedExecutionResult.java
│ │ ├── BatchedDataLoaderGraphQLBuilder.java
│ │ ├── VariablesDeserializer.java
│ │ ├── ExtensionsDeserializer.java
│ │ ├── FutureExecutionResult.java
│ │ ├── DecoratedExecutionResult.java
│ │ ├── GraphQLQueryResult.java
│ │ ├── ObjectMapDeserializeHelper.java
│ │ ├── OperationNameExtractor.java
│ │ └── GraphQLRequest.java
└── build.gradle
├── renovate.json
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── graphql-java-servlet
├── src
│ ├── main
│ │ └── java
│ │ │ └── graphql
│ │ │ └── kickstart
│ │ │ └── servlet
│ │ │ ├── osgi
│ │ │ ├── GraphQLProvider.java
│ │ │ ├── GraphQLCodeRegistryProvider.java
│ │ │ ├── GraphQLTypesProvider.java
│ │ │ ├── GraphQLFieldProvider.java
│ │ │ ├── GraphQLDirectiveProvider.java
│ │ │ ├── GraphQLMutationProvider.java
│ │ │ ├── GraphQLSubscriptionProvider.java
│ │ │ └── GraphQLQueryProvider.java
│ │ │ ├── AsyncTaskDecorator.java
│ │ │ ├── PartIOException.java
│ │ │ ├── core
│ │ │ ├── GraphQLMBean.java
│ │ │ ├── internal
│ │ │ │ ├── VariableMapException.java
│ │ │ │ ├── GraphQLThreadFactory.java
│ │ │ │ └── VariableMapper.java
│ │ │ ├── GraphQLServletRootObjectBuilder.java
│ │ │ ├── DefaultGraphQLRootObjectBuilder.java
│ │ │ └── GraphQLServletListener.java
│ │ │ ├── InvocationInputParseException.java
│ │ │ ├── QueryResponseWriter.java
│ │ │ ├── StaticDataPublisher.java
│ │ │ ├── QueryResponseWriterFactory.java
│ │ │ ├── subscriptions
│ │ │ ├── WebSocketSubscriptionProtocolFactory.java
│ │ │ ├── WebSocketSubscriptionSession.java
│ │ │ ├── WebSocketSendSubscriber.java
│ │ │ ├── FallbackSubscriptionProtocolFactory.java
│ │ │ └── FallbackSubscriptionConsumer.java
│ │ │ ├── AsyncTimeoutListener.java
│ │ │ ├── HttpRequestInvoker.java
│ │ │ ├── context
│ │ │ ├── GraphQLWebSocketContext.java
│ │ │ ├── GraphQLServletContext.java
│ │ │ ├── GraphQLServletContextBuilder.java
│ │ │ ├── DefaultGraphQLServletContextBuilder.java
│ │ │ └── DefaultGraphQLWebSocketContext.java
│ │ │ ├── ConfiguredGraphQLHttpServlet.java
│ │ │ ├── ErrorQueryResponseWriter.java
│ │ │ ├── HttpRequestHandler.java
│ │ │ ├── AsyncTaskExecutor.java
│ │ │ ├── GraphQLHttpServlet.java
│ │ │ ├── OsgiGraphQLHttpServletConfiguration.java
│ │ │ ├── input
│ │ │ ├── NoOpBatchInputPreProcessor.java
│ │ │ ├── BatchInputPreProcessor.java
│ │ │ └── BatchInputPreProcessResult.java
│ │ │ ├── AbstractGraphQLInvocationInputParser.java
│ │ │ ├── SubscriptionAsyncListener.java
│ │ │ ├── config
│ │ │ ├── DefaultGraphQLSchemaServletProvider.java
│ │ │ └── GraphQLSchemaServletProvider.java
│ │ │ ├── SingleQueryResponseWriter.java
│ │ │ ├── cache
│ │ │ ├── CachingQueryResponseWriterFactory.java
│ │ │ ├── GraphQLResponseCacheManager.java
│ │ │ ├── CacheReader.java
│ │ │ ├── CachingHttpRequestInvoker.java
│ │ │ ├── CachedResponse.java
│ │ │ └── CachingQueryResponseWriter.java
│ │ │ ├── apollo
│ │ │ ├── ApolloWebSocketSubscriptionSession.java
│ │ │ ├── ApolloScalars.java
│ │ │ └── ApolloWebSocketSubscriptionProtocolFactory.java
│ │ │ ├── QueryResponseWriterFactoryImpl.java
│ │ │ ├── GraphQLInvocationInputParser.java
│ │ │ ├── ExecutionResultSubscriber.java
│ │ │ ├── GraphQLPostInvocationInputParser.java
│ │ │ ├── SingleAsynchronousQueryResponseWriter.java
│ │ │ ├── BatchedQueryResponseWriter.java
│ │ │ ├── ListenerHandler.java
│ │ │ ├── HttpRequestHandlerImpl.java
│ │ │ ├── AbstractGraphQLHttpServlet.java
│ │ │ └── GraphQLGetInvocationInputParser.java
│ └── test
│ │ └── groovy
│ │ └── graphql
│ │ └── kickstart
│ │ └── servlet
│ │ ├── TestException.groovy
│ │ ├── PartIOExceptionTest.groovy
│ │ ├── TestGraphQLErrorException.groovy
│ │ ├── TestBatchInputPreProcessor.java
│ │ ├── SingleAsynchronousQueryResponseWriterTest.groovy
│ │ ├── GraphQLServletListenerSpec.groovy
│ │ ├── TestMultipartPart.groovy
│ │ ├── SingleQueryResponseWriterTest.groovy
│ │ ├── BatchedQueryResponseWriterTest.groovy
│ │ ├── RequestTester.groovy
│ │ └── cache
│ │ └── CacheReaderTest.groovy
├── bnd.bnd
└── build.gradle
├── .idea
└── codeStyles
│ └── codeStyleConfig.xml
├── .gitignore
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── feature_request.md
│ └── bug_report.md
├── release.sh
├── add-javax-suffix.sh
├── replaceJakartaWithJavax.sh
├── tag-release.sh
└── workflows
│ └── pull-request.yml
├── examples
└── osgi
│ ├── buildAndRun.sh
│ ├── apache-karaf-feature
│ └── src
│ │ └── main
│ │ └── feature
│ │ └── feature.xml
│ ├── pom.xml
│ └── providers
│ ├── src
│ └── main
│ │ └── java
│ │ └── graphql
│ │ └── servlet
│ │ └── examples
│ │ └── osgi
│ │ └── ExampleGraphQLProvider.java
│ └── pom.xml
├── LICENSE
├── gradle.properties
├── CONTRIBUTING.md
└── gradlew.bat
/lombok.config:
--------------------------------------------------------------------------------
1 | lombok.addLombokGeneratedAnnotation = true
2 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/bnd.bnd:
--------------------------------------------------------------------------------
1 | Export-Package: graphql.kickstart.*
2 | Import-Package: !lombok,*
3 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "github>graphql-java-kickstart/renovate-config"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'graphql-java-servlet'
2 |
3 | include ':graphql-java-kickstart'
4 | include ':graphql-java-servlet'
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/graphql-java-kickstart/graphql-java-servlet/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | public interface GraphQLProvider {}
4 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/graphql-java-servlet/bnd.bnd:
--------------------------------------------------------------------------------
1 | Export-Package: graphql.kickstart.servlet.*
2 | Import-Package: !lombok,*
3 | Require-Capability: osgi.extender;
4 | filter:="(&(osgi.extender=osgi.component)(version>=1.3)(!(version>=2.0)))"
5 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/test/groovy/graphql/kickstart/servlet/TestException.groovy:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet
2 |
3 | /**
4 | * @author Andrew Potter
5 | */
6 | class TestException extends RuntimeException {
7 | }
8 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AsyncTaskDecorator.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | public interface AsyncTaskDecorator {
4 |
5 | Runnable decorate(Runnable runnable);
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/SubscriptionConnectionListener.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions;
2 |
3 | /** Marker interface */
4 | public interface SubscriptionConnectionListener {}
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle/
2 | build/
3 | *.iml
4 | *.ipr
5 | *.iws
6 | .idea/*
7 | !.idea/codeStyles/
8 | target/
9 | /out/
10 | .classpath
11 | .project
12 | .settings
13 | bin
14 | .DS_Store
15 | /**/out/
16 | /projectFilesBackup/.idea/workspace.xml
17 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/GraphQLRootObjectBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | public interface GraphQLRootObjectBuilder {
4 |
5 | /** @return the graphql root object */
6 | Object build();
7 | }
8 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/input/GraphQLInvocationInput.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.input;
2 |
3 | import java.util.List;
4 |
5 | public interface GraphQLInvocationInput {
6 | List getQueries();
7 | }
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Question
4 | url: https://github.com/graphql-java-kickstart/graphql-java-servlet/discussions
5 | about: Anything you are not sure about? Ask the community in Discussions!
6 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/config/GraphQLBuilderConfigurer.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.config;
2 |
3 | import graphql.GraphQL;
4 |
5 | public interface GraphQLBuilderConfigurer {
6 |
7 | void configure(GraphQL.Builder builder);
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/context/GraphQLContextBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.context;
2 |
3 | public interface GraphQLContextBuilder {
4 |
5 | /** @return the graphql context */
6 | GraphQLKickstartContext build();
7 | }
8 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/config/ObjectMapperProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.config;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | public interface ObjectMapperProvider {
6 |
7 | ObjectMapper provide();
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/PartIOException.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | public class PartIOException extends RuntimeException {
4 |
5 | public PartIOException(String message, Throwable cause) {
6 | super(message, cause);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/core/GraphQLMBean.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.core;
2 |
3 | public interface GraphQLMBean {
4 |
5 | String[] getQueries();
6 |
7 | String[] getMutations();
8 |
9 | String executeQuery(String query);
10 | }
11 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/core/internal/VariableMapException.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.core.internal;
2 |
3 | public class VariableMapException extends RuntimeException {
4 |
5 | VariableMapException(String message) {
6 | super(message);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/config/InstrumentationProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.config;
2 |
3 | import graphql.execution.instrumentation.Instrumentation;
4 |
5 | public interface InstrumentationProvider {
6 |
7 | Instrumentation getInstrumentation();
8 | }
9 |
--------------------------------------------------------------------------------
/examples/osgi/buildAndRun.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | mvn clean install
3 | pushd apache-karaf-package/target || exit 1
4 | tar zxvf graphql-java-servlet-osgi-examples-apache-karaf-package-10.1.0.tar.gz
5 | cd graphql-java-servlet-osgi-examples-apache-karaf-package-10.1.0/bin || exit 1
6 | ./karaf debug
7 | popd || exit 1
8 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLCodeRegistryProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | import graphql.schema.GraphQLCodeRegistry;
4 |
5 | public interface GraphQLCodeRegistryProvider extends GraphQLProvider {
6 |
7 | GraphQLCodeRegistry getCodeRegistry();
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/DefaultGraphQLRootObjectBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | public class DefaultGraphQLRootObjectBuilder extends StaticGraphQLRootObjectBuilder {
4 |
5 | public DefaultGraphQLRootObjectBuilder() {
6 | super(new Object());
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/instrumentation/TrackingApproachException.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.instrumentation;
2 |
3 | public class TrackingApproachException extends RuntimeException {
4 |
5 | TrackingApproachException(String message) {
6 | super(message);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/InvocationInputParseException.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | public class InvocationInputParseException extends RuntimeException {
4 |
5 | public InvocationInputParseException(Throwable t) {
6 | super("Request parsing failed", t);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLTypesProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | import graphql.schema.GraphQLType;
4 | import java.util.Collection;
5 |
6 | public interface GraphQLTypesProvider extends GraphQLProvider {
7 |
8 | Collection getTypes();
9 | }
10 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/context/ContextSettingNotConfiguredException.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.context;
2 |
3 | public class ContextSettingNotConfiguredException extends RuntimeException {
4 |
5 | ContextSettingNotConfiguredException() {
6 | super("Unconfigured context setting type");
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLFieldProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | import graphql.schema.GraphQLFieldDefinition;
4 | import java.util.Collection;
5 |
6 | public interface GraphQLFieldProvider extends GraphQLProvider {
7 |
8 | Collection getFields();
9 | }
10 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/apollo/SubscriptionCommand.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions.apollo;
2 |
3 | import graphql.kickstart.execution.subscriptions.SubscriptionSession;
4 |
5 | interface SubscriptionCommand {
6 |
7 | void apply(SubscriptionSession session, OperationMessage message);
8 | }
9 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/config/GraphQLServletObjectMapperConfigurer.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.config;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | /** @author Andrew Potter */
6 | public interface GraphQLServletObjectMapperConfigurer {
7 |
8 | void configure(ObjectMapper mapper);
9 | }
10 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/context/DefaultGraphQLContextBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.context;
2 |
3 | /** Returns an empty context. */
4 | public class DefaultGraphQLContextBuilder implements GraphQLContextBuilder {
5 |
6 | @Override
7 | public GraphQLKickstartContext build() {
8 | return new DefaultGraphQLContext();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.github/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -ev
3 |
4 | FLAVOUR="${1}"
5 |
6 | removeSnapshots() {
7 | sed -i 's/-SNAPSHOT//' gradle.properties
8 | }
9 |
10 | echo "Publishing release to Maven Central"
11 | removeSnapshots
12 |
13 | if [ "${FLAVOUR}" == 'javax' ]; then
14 | .github/add-javax-suffix.sh
15 | fi
16 |
17 | ./gradlew clean build publishToSonatype closeAndReleaseSonatypeStagingRepository
18 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/test/groovy/graphql/kickstart/servlet/PartIOExceptionTest.groovy:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet
2 |
3 | import spock.lang.Specification
4 |
5 | class PartIOExceptionTest extends Specification {
6 |
7 | def "constructs"() {
8 | when:
9 | def e = new PartIOException("some message", new IOException())
10 | then:
11 | e instanceof RuntimeException
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/QueryResponseWriter.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import java.io.IOException;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 |
7 | public interface QueryResponseWriter {
8 |
9 | void write(HttpServletRequest request, HttpServletResponse response) throws IOException;
10 | }
11 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/GraphQLInvokerProxy.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import graphql.ExecutionInput;
4 | import graphql.ExecutionResult;
5 | import graphql.GraphQL;
6 | import java.util.concurrent.CompletableFuture;
7 |
8 | public interface GraphQLInvokerProxy {
9 |
10 | CompletableFuture executeAsync(GraphQL graphQL, ExecutionInput executionInput);
11 | }
12 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/ObjectMapDeserializationException.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | public class ObjectMapDeserializationException extends RuntimeException {
4 |
5 | ObjectMapDeserializationException(String message) {
6 | super(message);
7 | }
8 |
9 | ObjectMapDeserializationException(String message, Throwable cause) {
10 | super(message, cause);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/config/ExecutionStrategyProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.config;
2 |
3 | import graphql.execution.ExecutionStrategy;
4 |
5 | public interface ExecutionStrategyProvider {
6 |
7 | ExecutionStrategy getQueryExecutionStrategy();
8 |
9 | ExecutionStrategy getMutationExecutionStrategy();
10 |
11 | ExecutionStrategy getSubscriptionExecutionStrategy();
12 | }
13 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/StaticDataPublisher.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import graphql.execution.reactive.SingleSubscriberPublisher;
4 | import org.reactivestreams.Publisher;
5 |
6 | class StaticDataPublisher extends SingleSubscriberPublisher implements Publisher {
7 |
8 | StaticDataPublisher(T data) {
9 | super();
10 | offer(data);
11 | noMoreData();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLDirectiveProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | import graphql.schema.GraphQLDirective;
4 | import java.util.Collection;
5 |
6 |
7 | public interface GraphQLDirectiveProvider extends GraphQLProvider {
8 |
9 | /** @return A collection of directive definitions that will be added to the schema. */
10 | Collection getDirectives();
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLMutationProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | import graphql.schema.GraphQLFieldDefinition;
4 | import java.util.Collection;
5 |
6 | public interface GraphQLMutationProvider extends GraphQLFieldProvider {
7 |
8 | Collection getMutations();
9 |
10 | default Collection getFields() {
11 | return getMutations();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/StringUtils.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import lombok.AccessLevel;
4 | import lombok.NoArgsConstructor;
5 |
6 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
7 | class StringUtils {
8 |
9 | static boolean isNotEmpty(CharSequence cs) {
10 | return !isEmpty(cs);
11 | }
12 |
13 | static boolean isEmpty(final CharSequence cs) {
14 | return cs == null || cs.length() == 0;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/error/GraphQLErrorHandler.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.error;
2 |
3 | import graphql.GraphQLError;
4 | import java.util.List;
5 |
6 | /** @author Andrew Potter */
7 | public interface GraphQLErrorHandler {
8 |
9 | default boolean errorsPresent(List errors) {
10 | return errors != null && !errors.isEmpty();
11 | }
12 |
13 | List processErrors(List errors);
14 | }
15 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/GraphQLSubscriptionInvocationInputFactory.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions;
2 |
3 | import graphql.kickstart.execution.GraphQLRequest;
4 | import graphql.kickstart.execution.input.GraphQLSingleInvocationInput;
5 |
6 | public interface GraphQLSubscriptionInvocationInputFactory {
7 |
8 | GraphQLSingleInvocationInput create(GraphQLRequest graphQLRequest, SubscriptionSession session);
9 | }
10 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLSubscriptionProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | import graphql.schema.GraphQLFieldDefinition;
4 | import java.util.Collection;
5 |
6 | public interface GraphQLSubscriptionProvider extends GraphQLFieldProvider {
7 |
8 | Collection getSubscriptions();
9 |
10 | default Collection getFields() {
11 | return getSubscriptions();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/QueryResponseWriterFactory.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import graphql.kickstart.execution.GraphQLQueryResult;
4 | import graphql.kickstart.execution.input.GraphQLInvocationInput;
5 |
6 | public interface QueryResponseWriterFactory {
7 |
8 | QueryResponseWriter createWriter(
9 | GraphQLInvocationInput invocationInput,
10 | GraphQLQueryResult queryResult,
11 | GraphQLConfiguration configuration);
12 | }
13 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/core/GraphQLServletRootObjectBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.core;
2 |
3 | import graphql.kickstart.execution.GraphQLRootObjectBuilder;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.websocket.server.HandshakeRequest;
6 |
7 | public interface GraphQLServletRootObjectBuilder extends GraphQLRootObjectBuilder {
8 |
9 | Object build(HttpServletRequest req);
10 |
11 | Object build(HandshakeRequest req);
12 | }
13 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/SubscriptionException.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions;
2 |
3 | public class SubscriptionException extends Exception {
4 |
5 | private final transient Object payload;
6 |
7 | public SubscriptionException() {
8 | this(null);
9 | }
10 |
11 | public SubscriptionException(Object payload) {
12 | this.payload = payload;
13 | }
14 |
15 | public Object getPayload() {
16 | return payload;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/subscriptions/WebSocketSubscriptionProtocolFactory.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.subscriptions;
2 |
3 | import graphql.kickstart.execution.subscriptions.SubscriptionSession;
4 | import java.util.function.Consumer;
5 | import jakarta.websocket.Session;
6 |
7 | public interface WebSocketSubscriptionProtocolFactory {
8 |
9 | Consumer createConsumer(SubscriptionSession session);
10 |
11 | SubscriptionSession createSession(Session session);
12 | }
13 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AsyncTimeoutListener.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import java.io.IOException;
4 | import jakarta.servlet.AsyncEvent;
5 | import jakarta.servlet.AsyncListener;
6 |
7 | interface AsyncTimeoutListener extends AsyncListener {
8 |
9 | default void onComplete(AsyncEvent event) throws IOException {}
10 |
11 | default void onError(AsyncEvent event) throws IOException {}
12 |
13 | default void onStartAsync(AsyncEvent event) throws IOException {}
14 | }
15 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/HttpRequestInvoker.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import graphql.kickstart.execution.input.GraphQLInvocationInput;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 |
7 | public interface HttpRequestInvoker {
8 |
9 | void execute(
10 | GraphQLInvocationInput invocationInput,
11 | HttpServletRequest request,
12 | HttpServletResponse response,
13 | ListenerHandler listenerHandler);
14 | }
15 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/osgi/GraphQLQueryProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.osgi;
2 |
3 | import graphql.schema.GraphQLFieldDefinition;
4 | import java.util.Collection;
5 |
6 | /** This interface is used by OSGi bundles to plugin new field into the root query type */
7 | public interface GraphQLQueryProvider extends GraphQLProvider {
8 |
9 | /** @return a collection of field definitions that will be added to the root query type. */
10 | Collection getQueries();
11 | }
12 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/StaticGraphQLRootObjectBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | public class StaticGraphQLRootObjectBuilder implements GraphQLRootObjectBuilder {
4 |
5 | private final Object rootObject;
6 |
7 | public StaticGraphQLRootObjectBuilder(Object rootObject) {
8 | this.rootObject = rootObject;
9 | }
10 |
11 | @Override
12 | public Object build() {
13 | return rootObject;
14 | }
15 |
16 | protected Object getRootObject() {
17 | return rootObject;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/GraphQLSingleQueryResult.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 |
6 | @RequiredArgsConstructor
7 | class GraphQLSingleQueryResult implements GraphQLQueryResult {
8 |
9 | @Getter private final DecoratedExecutionResult result;
10 |
11 | @Override
12 | public boolean isBatched() {
13 | return false;
14 | }
15 |
16 | @Override
17 | public boolean isAsynchronous() {
18 | return result.isAsynchronous();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/context/GraphQLWebSocketContext.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.context;
2 |
3 | import graphql.kickstart.execution.context.GraphQLKickstartContext;
4 | import jakarta.websocket.Session;
5 | import jakarta.websocket.server.HandshakeRequest;
6 |
7 | /** @deprecated Use {@link graphql.kickstart.execution.context.GraphQLKickstartContext} instead */
8 | public interface GraphQLWebSocketContext extends GraphQLKickstartContext {
9 |
10 | Session getSession();
11 |
12 | HandshakeRequest getHandshakeRequest();
13 | }
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2016 Yurii Rashkovskii and Contributors
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/config/GraphQLSchemaProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.config;
2 |
3 | import graphql.schema.GraphQLObjectType;
4 | import graphql.schema.GraphQLSchema;
5 |
6 | public interface GraphQLSchemaProvider {
7 |
8 | static GraphQLSchema copyReadOnly(GraphQLSchema schema) {
9 | return GraphQLSchema.newSchema(schema).mutation((GraphQLObjectType) null).build();
10 | }
11 |
12 | /** @return a schema for handling mbean calls. */
13 | GraphQLSchema getSchema();
14 |
15 | GraphQLSchema getReadOnlySchema();
16 | }
17 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/ConfiguredGraphQLHttpServlet.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import java.util.Objects;
4 |
5 | class ConfiguredGraphQLHttpServlet extends GraphQLHttpServlet {
6 |
7 | private final GraphQLConfiguration configuration;
8 |
9 | ConfiguredGraphQLHttpServlet(GraphQLConfiguration configuration) {
10 | this.configuration = Objects.requireNonNull(configuration, "configuration is required");
11 | }
12 |
13 | @Override
14 | protected GraphQLConfiguration getConfiguration() {
15 | return configuration;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/instrumentation/NoOpInstrumentationProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.instrumentation;
2 |
3 | import graphql.execution.instrumentation.Instrumentation;
4 | import graphql.execution.instrumentation.SimplePerformantInstrumentation;
5 | import graphql.kickstart.execution.config.InstrumentationProvider;
6 |
7 | public class NoOpInstrumentationProvider implements InstrumentationProvider {
8 |
9 | @Override
10 | public Instrumentation getInstrumentation() {
11 | return SimplePerformantInstrumentation.INSTANCE;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/GraphQLBatchedQueryResult.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import graphql.ExecutionResult;
4 | import java.util.List;
5 | import lombok.Getter;
6 | import lombok.RequiredArgsConstructor;
7 |
8 | @RequiredArgsConstructor
9 | class GraphQLBatchedQueryResult implements GraphQLQueryResult {
10 |
11 | @Getter private final List results;
12 |
13 | @Override
14 | public boolean isBatched() {
15 | return true;
16 | }
17 |
18 | @Override
19 | public boolean isAsynchronous() {
20 | return false;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/examples/osgi/apache-karaf-feature/src/main/feature/feature.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 | scr
7 | war
8 | http
9 |
10 |
11 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'biz.aQute.bnd.builder'
2 |
3 | jar {
4 | bndfile = 'bnd.bnd'
5 | }
6 |
7 | apply plugin: 'java-library-distribution'
8 |
9 | dependencies {
10 | // GraphQL
11 | api "com.graphql-java:graphql-java:$LIB_GRAPHQL_JAVA_VER"
12 | implementation "org.slf4j:slf4j-api:$LIB_SLF4J_VER"
13 |
14 | // JSON
15 | api "com.fasterxml.jackson.core:jackson-core:$LIB_JACKSON_VER"
16 | api "com.fasterxml.jackson.core:jackson-annotations:$LIB_JACKSON_VER"
17 | api "com.fasterxml.jackson.core:jackson-databind:2.17.2"
18 | api "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:$LIB_JACKSON_VER"
19 | }
20 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/GraphQLErrorQueryResult.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 |
6 | @Getter
7 | @RequiredArgsConstructor
8 | class GraphQLErrorQueryResult implements GraphQLQueryResult {
9 |
10 | private final int statusCode;
11 | private final String message;
12 |
13 | @Override
14 | public boolean isBatched() {
15 | return false;
16 | }
17 |
18 | @Override
19 | public boolean isAsynchronous() {
20 | return false;
21 | }
22 |
23 | @Override
24 | public boolean isError() {
25 | return true;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/ErrorQueryResponseWriter.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import java.io.IOException;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 | import lombok.RequiredArgsConstructor;
7 |
8 | @RequiredArgsConstructor
9 | class ErrorQueryResponseWriter implements QueryResponseWriter {
10 |
11 | private final int statusCode;
12 | private final String message;
13 |
14 | @Override
15 | public void write(HttpServletRequest request, HttpServletResponse response) throws IOException {
16 | response.sendError(statusCode, message);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/HttpRequestHandler.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import java.io.IOException;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 |
7 | public interface HttpRequestHandler {
8 |
9 | String APPLICATION_JSON_UTF8 = "application/json;charset=UTF-8";
10 | String APPLICATION_EVENT_STREAM_UTF8 = "text/event-stream;charset=UTF-8";
11 |
12 | int STATUS_OK = 200;
13 | int STATUS_BAD_REQUEST = 400;
14 | int STATUS_INTERNAL_SERVER_ERROR = 500;
15 |
16 | void handle(HttpServletRequest request, HttpServletResponse response) throws IOException;
17 | }
18 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/SubscriptionProtocolFactory.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions;
2 |
3 | import java.util.function.Consumer;
4 |
5 | /** @author Andrew Potter */
6 | public abstract class SubscriptionProtocolFactory {
7 |
8 | private final String protocol;
9 |
10 | protected SubscriptionProtocolFactory(String protocol) {
11 | this.protocol = protocol;
12 | }
13 |
14 | public String getProtocol() {
15 | return protocol;
16 | }
17 |
18 | public abstract Consumer createConsumer(SubscriptionSession session);
19 |
20 | public void shutdown() {
21 | // do nothing
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AsyncTaskExecutor.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import java.util.concurrent.Executor;
4 | import lombok.NonNull;
5 | import lombok.RequiredArgsConstructor;
6 |
7 | @RequiredArgsConstructor
8 | class AsyncTaskExecutor implements Executor {
9 |
10 | private final Executor executor;
11 | private final AsyncTaskDecorator taskDecorator;
12 |
13 | @Override
14 | public void execute(@NonNull Runnable command) {
15 | if (taskDecorator != null) {
16 | Runnable decorated = taskDecorator.decorate(command);
17 | executor.execute(decorated);
18 | } else {
19 | executor.execute(command);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLHttpServlet.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import graphql.schema.GraphQLSchema;
4 |
5 | /** @author Michiel Oliemans */
6 | public abstract class GraphQLHttpServlet extends AbstractGraphQLHttpServlet {
7 |
8 | public static GraphQLHttpServlet with(GraphQLSchema schema) {
9 | return new ConfiguredGraphQLHttpServlet(GraphQLConfiguration.with(schema).build());
10 | }
11 |
12 | public static GraphQLHttpServlet with(GraphQLConfiguration configuration) {
13 | return new ConfiguredGraphQLHttpServlet(configuration);
14 | }
15 |
16 | @Override
17 | protected abstract GraphQLConfiguration getConfiguration();
18 | }
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/OsgiGraphQLHttpServletConfiguration.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import org.osgi.service.metatype.annotations.AttributeDefinition;
4 | import org.osgi.service.metatype.annotations.ObjectClassDefinition;
5 |
6 | @ObjectClassDefinition(
7 | name = "GraphQL HTTP Servlet",
8 | description = "GraphQL HTTP Servlet Configuration")
9 | @interface OsgiGraphQLHttpServletConfiguration {
10 |
11 | @AttributeDefinition(name = "alias", description = "Servlet alias")
12 | String alias() default "/graphql";
13 |
14 | @AttributeDefinition(name = "jmx.objectname", description = "JMX object name")
15 | String jmx_objectname() default "graphql.servlet:type=graphql";
16 | }
17 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/apollo/SubscriptionStopCommand.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions.apollo;
2 |
3 | import graphql.kickstart.execution.subscriptions.SubscriptionSession;
4 | import java.util.Collection;
5 | import lombok.RequiredArgsConstructor;
6 |
7 | @RequiredArgsConstructor
8 | class SubscriptionStopCommand implements SubscriptionCommand {
9 |
10 | private final Collection connectionListeners;
11 |
12 | @Override
13 | public void apply(SubscriptionSession session, OperationMessage message) {
14 | connectionListeners.forEach(it -> it.onStop(session, message));
15 | session.unsubscribe(message.getId());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/input/NoOpBatchInputPreProcessor.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.input;
2 |
3 | import graphql.kickstart.execution.input.GraphQLBatchedInvocationInput;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 |
7 | /** A default BatchInputPreProcessor that returns the input. */
8 | public class NoOpBatchInputPreProcessor implements BatchInputPreProcessor {
9 |
10 | @Override
11 | public BatchInputPreProcessResult preProcessBatch(
12 | GraphQLBatchedInvocationInput batchedInvocationInput,
13 | HttpServletRequest request,
14 | HttpServletResponse response) {
15 | return new BatchInputPreProcessResult(batchedInvocationInput);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/core/DefaultGraphQLRootObjectBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.core;
2 |
3 | import graphql.kickstart.execution.StaticGraphQLRootObjectBuilder;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.websocket.server.HandshakeRequest;
6 |
7 | public class DefaultGraphQLRootObjectBuilder extends StaticGraphQLRootObjectBuilder
8 | implements GraphQLServletRootObjectBuilder {
9 |
10 | public DefaultGraphQLRootObjectBuilder() {
11 | super(new Object());
12 | }
13 |
14 | @Override
15 | public Object build(HttpServletRequest req) {
16 | return getRootObject();
17 | }
18 |
19 | @Override
20 | public Object build(HandshakeRequest req) {
21 | return getRootObject();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/context/GraphQLServletContext.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.context;
2 |
3 | import graphql.kickstart.execution.context.GraphQLKickstartContext;
4 | import java.util.List;
5 | import java.util.Map;
6 | import jakarta.servlet.http.HttpServletRequest;
7 | import jakarta.servlet.http.HttpServletResponse;
8 | import jakarta.servlet.http.Part;
9 |
10 | /** @deprecated Use {@link graphql.kickstart.execution.context.GraphQLKickstartContext} instead */
11 | public interface GraphQLServletContext extends GraphQLKickstartContext {
12 |
13 | List getFileParts();
14 |
15 | Map> getParts();
16 |
17 | HttpServletRequest getHttpServletRequest();
18 |
19 | HttpServletResponse getHttpServletResponse();
20 | }
21 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/error/DefaultGraphQLServletObjectMapperConfigurer.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.error;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.databind.SerializationFeature;
6 | import graphql.kickstart.execution.config.GraphQLServletObjectMapperConfigurer;
7 |
8 | /** @author Andrew Potter */
9 | public class DefaultGraphQLServletObjectMapperConfigurer
10 | implements GraphQLServletObjectMapperConfigurer {
11 |
12 | @Override
13 | public void configure(ObjectMapper mapper) {
14 | mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
15 | mapper.setDefaultPropertyInclusion(JsonInclude.Include.ALWAYS);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/context/GraphQLServletContextBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.context;
2 |
3 | import graphql.kickstart.execution.context.GraphQLKickstartContext;
4 | import graphql.kickstart.execution.context.GraphQLContextBuilder;
5 | import jakarta.servlet.http.HttpServletRequest;
6 | import jakarta.servlet.http.HttpServletResponse;
7 | import jakarta.websocket.Session;
8 | import jakarta.websocket.server.HandshakeRequest;
9 |
10 | public interface GraphQLServletContextBuilder extends GraphQLContextBuilder {
11 |
12 | GraphQLKickstartContext build(
13 | HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse);
14 |
15 | GraphQLKickstartContext build(Session session, HandshakeRequest handshakeRequest);
16 | }
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | version=16.0.0
2 | group=com.graphql-java-kickstart
3 | PROJECT_NAME=graphql-java-servlet
4 | PROJECT_DESC=GraphQL Java Kickstart
5 | PROJECT_GIT_REPO_URL=https://github.com/graphql-java-kickstart/graphql-java-servlet
6 | PROJECT_LICENSE=MIT
7 | PROJECT_LICENSE_URL=https://github.com/graphql-java-kickstart/spring-java-servlet/blob/master/LICENSE.md
8 | PROJECT_DEV_ID=oliemansm
9 | PROJECT_DEV_NAME=Michiel Oliemans
10 | LIB_GRAPHQL_JAVA_VER=22.3
11 | LIB_JACKSON_VER=2.17.2
12 | LIB_SLF4J_VER=2.0.16
13 | LIB_LOMBOK_VER=1.18.34
14 | # These constants are necessary to the automatic release of javax flavour
15 | LIB_JAVAX_SERVLET=4.0.1
16 | LIB_JAVAX_WEBSOCKET=1.1
17 | LIB_SPRINGFRAMEWORK_5=5.3.25
18 | SOURCE_COMPATIBILITY=11
19 | TARGET_COMPATIBILITY=11
20 | SOURCE_COMPATIBILITY_TEST=17
21 | TARGET_COMPATIBILITY_TEST=17
22 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/FutureErrorExecutionResult.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import graphql.kickstart.execution.input.GraphQLInvocationInput;
4 | import java.util.concurrent.CompletableFuture;
5 | import lombok.RequiredArgsConstructor;
6 |
7 | @RequiredArgsConstructor
8 | class FutureErrorExecutionResult implements FutureExecutionResult {
9 |
10 | private final GraphQLErrorQueryResult errorQueryResult;
11 |
12 | @Override
13 | public CompletableFuture thenApplyQueryResult() {
14 | return CompletableFuture.completedFuture(errorQueryResult);
15 | }
16 |
17 | @Override
18 | public GraphQLInvocationInput getInvocationInput() {
19 | return null;
20 | }
21 |
22 | @Override
23 | public void cancel() {
24 | // nothing to do
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/FutureSingleExecutionResult.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import graphql.ExecutionResult;
4 | import graphql.kickstart.execution.input.GraphQLInvocationInput;
5 | import java.util.concurrent.CompletableFuture;
6 | import lombok.Getter;
7 | import lombok.RequiredArgsConstructor;
8 |
9 | @RequiredArgsConstructor
10 | class FutureSingleExecutionResult implements FutureExecutionResult {
11 |
12 | @Getter
13 | private final GraphQLInvocationInput invocationInput;
14 | private final CompletableFuture single;
15 |
16 | @Override
17 | public CompletableFuture thenApplyQueryResult() {
18 | return single.thenApply(GraphQLQueryResult::create);
19 | }
20 |
21 | @Override
22 | public void cancel() {
23 | single.cancel(true);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/test/groovy/graphql/kickstart/servlet/TestGraphQLErrorException.groovy:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet
2 |
3 | import graphql.ErrorType
4 | import graphql.GraphQLError
5 | import graphql.language.SourceLocation
6 |
7 | /**
8 | * @author Andrew Potter
9 | */
10 | class TestGraphQLErrorException extends RuntimeException implements GraphQLError {
11 |
12 | TestGraphQLErrorException(String message) {
13 | super(message)
14 | }
15 |
16 | @Override
17 | Map getExtensions() {
18 | Map customAttributes = new LinkedHashMap<>()
19 | customAttributes.put("foo", "bar")
20 | return customAttributes
21 | }
22 |
23 | @Override
24 | List getLocations() {
25 | return null
26 | }
27 |
28 | @Override
29 | ErrorType getErrorType() {
30 | return ErrorType.ValidationError
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/input/GraphQLBatchedInvocationInput.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.input;
2 |
3 | import static java.util.stream.Collectors.toList;
4 |
5 | import graphql.ExecutionInput;
6 | import graphql.kickstart.execution.context.ContextSetting;
7 | import java.util.List;
8 |
9 | /** Interface representing a batched input. */
10 | public interface GraphQLBatchedInvocationInput extends GraphQLInvocationInput {
11 |
12 | /** @return each individual input in the batch, configured with a context. */
13 | List getInvocationInputs();
14 |
15 | default List getExecutionInputs() {
16 | return getInvocationInputs().stream()
17 | .map(GraphQLSingleInvocationInput::getExecutionInput)
18 | .collect(toList());
19 | }
20 |
21 | ContextSetting getContextSetting();
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/FutureBatchedExecutionResult.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import graphql.ExecutionResult;
4 | import graphql.kickstart.execution.input.GraphQLInvocationInput;
5 | import java.util.List;
6 | import java.util.concurrent.CompletableFuture;
7 | import lombok.Getter;
8 | import lombok.RequiredArgsConstructor;
9 |
10 | @RequiredArgsConstructor
11 | class FutureBatchedExecutionResult implements FutureExecutionResult {
12 |
13 | @Getter
14 | private final GraphQLInvocationInput invocationInput;
15 | private final CompletableFuture> batched;
16 |
17 | @Override
18 | public CompletableFuture thenApplyQueryResult() {
19 | return batched.thenApply(GraphQLQueryResult::create);
20 | }
21 |
22 | @Override
23 | public void cancel() {
24 | batched.cancel(true);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/core/internal/GraphQLThreadFactory.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.core.internal;
2 |
3 | import graphql.kickstart.servlet.AbstractGraphQLHttpServlet;
4 | import java.util.concurrent.ThreadFactory;
5 | import java.util.concurrent.atomic.AtomicInteger;
6 |
7 | /**
8 | * {@link ThreadFactory} implementation for {@link AbstractGraphQLHttpServlet} async operations
9 | *
10 | * @author John Nutting
11 | */
12 | public class GraphQLThreadFactory implements ThreadFactory {
13 |
14 | static final String NAME_PREFIX = "GraphQLServlet-";
15 | final AtomicInteger threadNumber = new AtomicInteger(1);
16 |
17 | @Override
18 | public Thread newThread(final Runnable r) {
19 | Thread t = new Thread(r, NAME_PREFIX + threadNumber.getAndIncrement());
20 | t.setDaemon(false);
21 | t.setPriority(Thread.NORM_PRIORITY);
22 | return t;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/input/BatchInputPreProcessor.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet.input;
2 |
3 | import graphql.kickstart.execution.input.GraphQLBatchedInvocationInput;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 |
7 | public interface BatchInputPreProcessor {
8 |
9 | /**
10 | * An injectable object that allows clients to manipulate a batch before executing, or abort
11 | * altogether.
12 | *
13 | * @param batchedInvocationInput the input to process
14 | * @param request the servlet request
15 | * @param response the servlet response
16 | * @return wrapped batch to possibly process.
17 | */
18 | BatchInputPreProcessResult preProcessBatch(
19 | GraphQLBatchedInvocationInput batchedInvocationInput,
20 | HttpServletRequest request,
21 | HttpServletResponse response);
22 | }
23 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/AtomicSubscriptionSubscription.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions;
2 |
3 | import java.util.concurrent.atomic.AtomicReference;
4 | import org.reactivestreams.Subscription;
5 |
6 | public class AtomicSubscriptionSubscription {
7 |
8 | private final AtomicReference reference = new AtomicReference<>(null);
9 |
10 | public void set(Subscription subscription) {
11 | if (reference.get() != null) {
12 | throw new IllegalStateException("Cannot overwrite subscription!");
13 | }
14 |
15 | reference.set(subscription);
16 | }
17 |
18 | public Subscription get() {
19 | Subscription subscription = reference.get();
20 | if (subscription == null) {
21 | throw new IllegalStateException("Subscription has not been initialized yet!");
22 | }
23 |
24 | return subscription;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/config/DefaultGraphQLSchemaProvider.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.config;
2 |
3 | import graphql.schema.GraphQLSchema;
4 |
5 | /** @author Andrew Potter */
6 | public class DefaultGraphQLSchemaProvider implements GraphQLSchemaProvider {
7 |
8 | private final GraphQLSchema schema;
9 | private final GraphQLSchema readOnlySchema;
10 |
11 | public DefaultGraphQLSchemaProvider(GraphQLSchema schema) {
12 | this(schema, GraphQLSchemaProvider.copyReadOnly(schema));
13 | }
14 |
15 | public DefaultGraphQLSchemaProvider(GraphQLSchema schema, GraphQLSchema readOnlySchema) {
16 | this.schema = schema;
17 | this.readOnlySchema = readOnlySchema;
18 | }
19 |
20 | @Override
21 | public GraphQLSchema getSchema() {
22 | return schema;
23 | }
24 |
25 | @Override
26 | public GraphQLSchema getReadOnlySchema() {
27 | return readOnlySchema;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AbstractGraphQLInvocationInputParser.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.servlet;
2 |
3 | import graphql.kickstart.execution.GraphQLObjectMapper;
4 | import graphql.kickstart.execution.context.ContextSetting;
5 | import graphql.kickstart.servlet.input.GraphQLInvocationInputFactory;
6 | import lombok.RequiredArgsConstructor;
7 |
8 | @RequiredArgsConstructor
9 | abstract class AbstractGraphQLInvocationInputParser implements GraphQLInvocationInputParser {
10 |
11 | final GraphQLInvocationInputFactory invocationInputFactory;
12 | final GraphQLObjectMapper graphQLObjectMapper;
13 | final ContextSetting contextSetting;
14 |
15 | boolean isSingleQuery(String query) {
16 | return query != null && !query.trim().isEmpty() && !query.trim().startsWith("[");
17 | }
18 |
19 | boolean isBatchedQuery(String query) {
20 | return query != null && query.trim().startsWith("[");
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/error/GenericGraphQLError.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.error;
2 |
3 | import static java.util.Collections.emptyList;
4 |
5 | import com.fasterxml.jackson.annotation.JsonIgnore;
6 | import graphql.ErrorType;
7 | import graphql.GraphQLError;
8 | import graphql.language.SourceLocation;
9 | import java.util.List;
10 |
11 | /** @author Andrew Potter */
12 | public class GenericGraphQLError implements GraphQLError {
13 |
14 | private final String message;
15 |
16 | public GenericGraphQLError(String message) {
17 | this.message = message;
18 | }
19 |
20 | @Override
21 | public String getMessage() {
22 | return message;
23 | }
24 |
25 | @Override
26 | @JsonIgnore
27 | public List getLocations() {
28 | return emptyList();
29 | }
30 |
31 | @Override
32 | @JsonIgnore
33 | public ErrorType getErrorType() {
34 | return null;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/BatchedDataLoaderGraphQLBuilder.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import graphql.GraphQL;
4 | import graphql.kickstart.execution.config.GraphQLBuilder;
5 | import graphql.kickstart.execution.input.GraphQLBatchedInvocationInput;
6 | import graphql.kickstart.execution.input.GraphQLSingleInvocationInput;
7 |
8 | public class BatchedDataLoaderGraphQLBuilder {
9 |
10 | GraphQL newGraphQL(GraphQLBatchedInvocationInput invocationInput, GraphQLBuilder graphQLBuilder) {
11 | return invocationInput.getInvocationInputs().stream()
12 | .findFirst()
13 | .map(GraphQLSingleInvocationInput::getSchema)
14 | .map(schema -> graphQLBuilder.build(schema, graphQLBuilder.getInstrumentationSupplier()))
15 | .orElseThrow(
16 | () ->
17 | new IllegalArgumentException(
18 | "Batched invocation input must contain at least one query"));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/apollo/SubscriptionConnectionTerminateCommand.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions.apollo;
2 |
3 | import static graphql.kickstart.execution.subscriptions.apollo.OperationMessage.Type.GQL_CONNECTION_TERMINATE;
4 |
5 | import graphql.kickstart.execution.subscriptions.SubscriptionSession;
6 | import java.util.Collection;
7 | import lombok.RequiredArgsConstructor;
8 | import lombok.extern.slf4j.Slf4j;
9 |
10 | @Slf4j
11 | @RequiredArgsConstructor
12 | class SubscriptionConnectionTerminateCommand implements SubscriptionCommand {
13 |
14 | private final Collection connectionListeners;
15 |
16 | @Override
17 | public void apply(SubscriptionSession session, OperationMessage message) {
18 | connectionListeners.forEach(it -> it.onTerminate(session, message));
19 | session.close("client requested " + GQL_CONNECTION_TERMINATE.getValue());
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/subscriptions/apollo/ApolloSubscriptionConnectionListener.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution.subscriptions.apollo;
2 |
3 | import graphql.kickstart.execution.subscriptions.SubscriptionConnectionListener;
4 | import graphql.kickstart.execution.subscriptions.SubscriptionSession;
5 |
6 | public interface ApolloSubscriptionConnectionListener extends SubscriptionConnectionListener {
7 |
8 | default void onConnect(SubscriptionSession session, OperationMessage message) {
9 | // do nothing
10 | }
11 |
12 | default void onStart(SubscriptionSession session, OperationMessage message) {
13 | // do nothing
14 | }
15 |
16 | default void onStop(SubscriptionSession session, OperationMessage message) {
17 | // do nothing
18 | }
19 |
20 | default void onTerminate(SubscriptionSession session, OperationMessage message) {
21 | // do nothing
22 | }
23 |
24 | default void shutdown() {
25 | // do nothing
26 | }
27 | }
--------------------------------------------------------------------------------
/graphql-java-kickstart/src/main/java/graphql/kickstart/execution/VariablesDeserializer.java:
--------------------------------------------------------------------------------
1 | package graphql.kickstart.execution;
2 |
3 | import com.fasterxml.jackson.core.JsonParser;
4 | import com.fasterxml.jackson.core.ObjectCodec;
5 | import com.fasterxml.jackson.databind.DeserializationContext;
6 | import com.fasterxml.jackson.databind.JsonDeserializer;
7 | import java.io.IOException;
8 | import java.util.Map;
9 |
10 | /** @author Andrew Potter */
11 | public class VariablesDeserializer extends JsonDeserializer