You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2022/01/23 13:44:53 UTC
[isis] 02/02: ISIS-2947: sets up schema only after metamodel fully introspected.
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch ISIS-2947
in repository https://gitbox.apache.org/repos/asf/isis.git
commit c641861c9a4cb3143bf3903541c731bd448d6178
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Jan 23 13:44:36 2022 +0000
ISIS-2947: sets up schema only after metamodel fully introspected.
---
.../metamodel/specloader/SpecificationLoader.java | 2 +
.../viewer/source/GraphQlServiceForIsis.java | 37 +++++++
.../viewer/source/GraphQlSourceForIsis.java | 123 +++++++++++++++++++++
.../graphql/viewer/source/MyGraphSource.java | 84 --------------
.../viewer/source/dummydomain/LeaseRepository.java | 9 --
5 files changed, 162 insertions(+), 93 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index a54d242..fec274a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
@@ -18,6 +18,8 @@
*/
package org.apache.isis.core.metamodel.specloader;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
diff --git a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/GraphQlServiceForIsis.java b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/GraphQlServiceForIsis.java
new file mode 100644
index 0000000..260dad7
--- /dev/null
+++ b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/GraphQlServiceForIsis.java
@@ -0,0 +1,37 @@
+package org.apache.isis.viewer.graphql.viewer.source;
+
+import javax.inject.Inject;
+
+import org.springframework.graphql.GraphQlService;
+import org.springframework.graphql.RequestInput;
+import org.springframework.graphql.RequestOutput;
+import org.springframework.graphql.execution.BatchLoaderRegistry;
+import org.springframework.graphql.execution.ExecutionGraphQlService;
+import org.springframework.graphql.execution.GraphQlSource;
+import org.springframework.stereotype.Service;
+
+import lombok.RequiredArgsConstructor;
+
+import reactor.core.publisher.Mono;
+
+/**
+ * Defers calling of {@link GraphQlSourceForIsis#schema()} until after the metamodel is fully introspected.
+ */
+@Service()
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
+public class GraphQlServiceForIsis implements GraphQlService {
+
+ private final BatchLoaderRegistry batchLoaderRegistry;
+ private final GraphQlSource graphQlSource;
+
+ ExecutionGraphQlService delegate;
+
+ @Override
+ public Mono<RequestOutput> execute(RequestInput input) {
+ if(delegate == null) {
+ delegate = new ExecutionGraphQlService(graphQlSource);
+ delegate.addDataLoaderRegistrar(batchLoaderRegistry);
+ }
+ return delegate.execute(input);
+ }
+}
diff --git a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/GraphQlSourceForIsis.java b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/GraphQlSourceForIsis.java
new file mode 100644
index 0000000..82cd012
--- /dev/null
+++ b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/GraphQlSourceForIsis.java
@@ -0,0 +1,123 @@
+package org.apache.isis.viewer.graphql.viewer.source;
+
+import java.util.concurrent.CountDownLatch;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.springframework.graphql.execution.GraphQlSource;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.services.registry.ServiceRegistry;
+import org.apache.isis.core.config.IsisConfiguration;
+import org.apache.isis.core.config.environment.IsisSystemEnvironment;
+import org.apache.isis.core.config.metamodel.specloader.IntrospectionMode;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoaderDefault;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+import graphql.GraphQL;
+import graphql.Scalars;
+import graphql.execution.instrumentation.tracing.TracingInstrumentation;
+import graphql.schema.DataFetcher;
+import graphql.schema.GraphQLCodeRegistry;
+import graphql.schema.GraphQLFieldDefinition;
+import graphql.schema.GraphQLObjectType;
+import graphql.schema.GraphQLSchema;
+
+import static graphql.schema.FieldCoordinates.coordinates;
+
+@Service()
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
+public class GraphQlSourceForIsis implements GraphQlSource {
+
+ private final ServiceRegistry serviceRegistry;
+ private final SpecificationLoaderDefault specificationLoader;
+ private final IsisConfiguration isisConfiguration;
+ private final IsisSystemEnvironment isisSystemEnvironment;
+ private final ExecutionStrategyResolvingWithinInteraction executionStrategy;
+
+ private final CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ @PostConstruct
+ public void init() {
+ boolean fullyIntrospect = IntrospectionMode.isFullIntrospect(isisConfiguration, isisSystemEnvironment);
+ if (!fullyIntrospect) {
+ throw new IllegalStateException("GraphQL requires full introspection mode");
+ }
+ }
+
+ @Override
+ public GraphQL graphQl() {
+ return GraphQL.newGraphQL(schema())
+ .instrumentation(new TracingInstrumentation())
+ .queryExecutionStrategy(executionStrategy)
+ .build();
+ }
+
+ @Override
+ public GraphQLSchema schema() {
+
+ val fullyIntrospected = specificationLoader.isMetamodelFullyIntrospected();
+ if(!fullyIntrospected) {
+ throw new IllegalStateException("Metamodel is not fully introspected");
+ }
+
+// // type LeaseRepository {
+// // numLeases: Int
+// // }
+// val leaseRepository_numLeases = GraphQLFieldDefinition.newFieldDefinition()
+// .name("numLeases")
+// .type(Scalars.GraphQLInt)
+// .build();
+// val leaseRepositoryType = GraphQLObjectType.newObject()
+// .name("LeaseRepository")
+// .field(leaseRepository_numLeases)
+// .build();
+
+// // type Query {
+// // leaseRepo: LeaseRepository
+// // }
+// val query_leaseRepo = GraphQLFieldDefinition.newFieldDefinition()
+// .name("leaseRepo")
+// .type(GraphQLTypeReference.typeRef(leaseRepositoryType.getName()))
+// .build();
+// GraphQLObjectType query = GraphQLObjectType.newObject()
+// .name("Query")
+// .field(query_leaseRepo)
+// .build();
+//
+// val codeRegistry = GraphQLCodeRegistry.newCodeRegistry()
+// .dataFetcher(coordinates(query.getName(), query_leaseRepo.getName()),
+// (DataFetcher<Object>) environment -> leaseRepository)
+// .dataFetcher(coordinates(leaseRepositoryType.getName(), leaseRepository_numLeases.getName()),
+// (DataFetcher<Object>) environment -> leaseRepository.numLeases)
+// .build();
+
+ // type Query {
+ // numServices: Int
+ // }
+ val query_numServices = GraphQLFieldDefinition.newFieldDefinition()
+ .name("numServices")
+ .type(Scalars.GraphQLInt)
+ .build();
+ GraphQLObjectType query = GraphQLObjectType.newObject()
+ .name("Query")
+ .field(query_numServices)
+ .build();
+
+
+ val codeRegistry = GraphQLCodeRegistry.newCodeRegistry()
+ .dataFetcher(coordinates(query.getName(), query_numServices.getName()),
+ (DataFetcher<Object>) environment -> this.serviceRegistry.streamRegisteredBeans().count())
+ .build();
+
+ return GraphQLSchema.newSchema()
+ .query(query)
+ // .additionalType(leaseRepositoryType)
+ .codeRegistry(codeRegistry)
+ .build();
+ }
+
+}
diff --git a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/MyGraphSource.java b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/MyGraphSource.java
deleted file mode 100644
index 18ae6f1..0000000
--- a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/MyGraphSource.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.apache.isis.viewer.graphql.viewer.source;
-
-import javax.inject.Inject;
-
-import org.springframework.graphql.execution.GraphQlSource;
-import org.springframework.stereotype.Service;
-
-import org.apache.isis.viewer.graphql.viewer.source.dummydomain.LeaseRepository;
-
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-
-import graphql.GraphQL;
-import graphql.Scalars;
-import graphql.execution.AsyncExecutionStrategy;
-import graphql.execution.instrumentation.tracing.TracingInstrumentation;
-import graphql.schema.DataFetcher;
-import graphql.schema.GraphQLCodeRegistry;
-import graphql.schema.GraphQLFieldDefinition;
-import graphql.schema.GraphQLObjectType;
-import graphql.schema.GraphQLSchema;
-import graphql.schema.GraphQLTypeReference;
-
-import static graphql.schema.FieldCoordinates.coordinates;
-
-@Service
-@RequiredArgsConstructor(onConstructor_ = {@Inject})
-public class MyGraphSource implements GraphQlSource {
-
- private final LeaseRepository leaseRepository;
- private final ExecutionStrategyResolvingWithinInteraction executionStrategy;
-
- @Override
- public GraphQL graphQl() {
- // val asyncExecutionStrategy = new AsyncExecutionStrategy();
- return GraphQL.newGraphQL(schema())
- .instrumentation(new TracingInstrumentation())
- .queryExecutionStrategy(executionStrategy)
- .build();
- }
-
- @Override
- public GraphQLSchema schema() {
-
- // type LeaseRepository {
- // numLeases: Int
- // }
- val leaseRepository_numLeases = GraphQLFieldDefinition.newFieldDefinition()
- .name("numLeases")
- .type(Scalars.GraphQLInt)
- .build();
- val leaseRepositoryType = GraphQLObjectType.newObject()
- .name("LeaseRepository")
- .field(leaseRepository_numLeases)
- .build();
-
- // type Query {
- // leaseRepo: LeaseRepository
- // }
- val query_leaseRepo = GraphQLFieldDefinition.newFieldDefinition()
- .name("leaseRepo")
- .type(GraphQLTypeReference.typeRef(leaseRepositoryType.getName()))
- .build();
- GraphQLObjectType query = GraphQLObjectType.newObject()
- .name("Query")
- .field(query_leaseRepo)
- .build();
-
- val codeRegistry = GraphQLCodeRegistry.newCodeRegistry()
- .dataFetcher(coordinates(query.getName(), query_leaseRepo.getName()),
- (DataFetcher<Object>) environment -> leaseRepository)
- .dataFetcher(coordinates(leaseRepositoryType.getName(), leaseRepository_numLeases.getName()),
- (DataFetcher<Object>) environment -> leaseRepository.numLeases)
- .build();
-
-
- return GraphQLSchema.newSchema()
- .query(query)
- .additionalType(leaseRepositoryType)
- .codeRegistry(codeRegistry)
- .build();
- }
-
-}
diff --git a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/dummydomain/LeaseRepository.java b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/dummydomain/LeaseRepository.java
deleted file mode 100644
index 2aceb33..0000000
--- a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/dummydomain/LeaseRepository.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.apache.isis.viewer.graphql.viewer.source.dummydomain;
-
-import org.springframework.stereotype.Service;
-
-@Service
-public class LeaseRepository {
-
- public int numLeases = 5;
-}