From f4d45a6c131ad9d9731893feca4e6293d6db646b Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Thu, 20 Nov 2025 19:18:56 +0800 Subject: [PATCH 01/12] Update to Spring Boot 4 --- .../test/resources/prepare_SalesDB_tables.sql | 4 +- .../src/test/resources/prepare_tables.sql | 6 +- .../jpa/PersistenceUnitInfoImpl.java | 12 +++ .../datastores/jpa/SupplierEntityManager.java | 77 ++++++++++++- .../datastores/jpa/JpaDataStoreHarness.java | 6 +- .../elide-datastore-search/pom.xml | 2 +- .../test/resources/META-INF/persistence.xml | 14 +-- .../src/test/java/example/Generate.java | 5 +- .../test/resources/META-INF/persistence.xml | 6 +- .../src/test/resources/hibernate.cfg.xml | 5 - elide-quarkus/deployment/pom.xml | 3 - .../deployment/ElideExtensionProcessor.java | 18 ++-- .../extension/test/ElideExtensionTest.java | 9 +- .../src/main/resources/application.properties | 4 +- elide-quarkus/pom.xml | 2 +- elide-quarkus/runtime/pom.xml | 3 - .../elide/extension/runtime/ElideBeans.java | 10 +- .../elide/extension/runtime/ElideConfig.java | 79 +++++++++----- .../spring/config/ElideAutoConfiguration.java | 4 +- .../spring/controllers/ApiDocsController.java | 8 +- .../spring/controllers/GraphqlController.java | 6 +- .../spring/controllers/JsonApiController.java | 15 ++- .../config/ElideAutoConfigurationTest.java | 8 +- ...ElideAutoConfigurationTransactionTest.java | 22 ++-- .../ElideSubscriptionConfigurationTest.java | 6 +- ...SubscriptionScanningConfigurationTest.java | 6 +- .../example/tests/AggregationStoreTest.java | 2 +- .../example/tests/HeaderCleansingTest.java | 4 +- .../example/tests/HeaderIdentityTest.java | 4 +- .../java/example/tests/SubscriptionTest.java | 12 ++- pom.xml | 102 +++++++++--------- 31 files changed, 294 insertions(+), 170 deletions(-) diff --git a/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_SalesDB_tables.sql b/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_SalesDB_tables.sql index 536151e1b8..b8b80edcb5 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_SalesDB_tables.sql +++ b/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_SalesDB_tables.sql @@ -37,7 +37,7 @@ CREATE TABLE IF NOT EXISTS order_details order_id VARCHAR(255) NOT NULL, customer_id VARCHAR(255), order_total NUMERIC(10,2), - created_on DATETIME, + created_on TIMESTAMP, PRIMARY KEY (order_id) ); @@ -56,7 +56,7 @@ CREATE TABLE IF NOT EXISTS delivery_details order_id VARCHAR(255) NOT NULL, tracking_number BIGINT, courier_name VARCHAR(255), - delivered_on DATETIME, + delivered_on TIMESTAMP, PRIMARY KEY (delivery_id) ); diff --git a/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_tables.sql b/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_tables.sql index 1a3a376396..8187a4e71a 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_tables.sql +++ b/elide-datastore/elide-datastore-aggregation/src/test/resources/prepare_tables.sql @@ -8,8 +8,8 @@ CREATE TABLE IF NOT EXISTS playerStats sub_country_id VARCHAR(255), player_id BIGINT, player2_id BIGINT, - recordedDate DATETIME, - updatedDate DATETIME, + recordedDate TIMESTAMP, + updatedDate TIMESTAMP, place_type_ordinal BIGINT, place_type_text VARCHAR(255) ); @@ -94,6 +94,6 @@ CREATE TABLE IF NOT EXISTS gameRevenue country_id VARCHAR(255), player_stats_id VARCHAR(255), category VARCHAR(255), - saleDate DATETIME + saleDate TIMESTAMP ); TRUNCATE TABLE gameRevenue; diff --git a/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/PersistenceUnitInfoImpl.java b/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/PersistenceUnitInfoImpl.java index 27e328f125..16867c6d42 100644 --- a/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/PersistenceUnitInfoImpl.java +++ b/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/PersistenceUnitInfoImpl.java @@ -68,4 +68,16 @@ public boolean excludeUnlistedClasses() { public void addTransformer(ClassTransformer classTransformer) { //Not implemented } + + @Override + public String getScopeAnnotationName() { + //Not implemented + return null; + } + + @Override + public List getQualifierAnnotationNames() { + //Not implemented + return null; + } } diff --git a/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/SupplierEntityManager.java b/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/SupplierEntityManager.java index 72ce57a094..c737a0c086 100644 --- a/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/SupplierEntityManager.java +++ b/elide-datastore/elide-datastore-jpa/src/main/java/com/yahoo/elide/datastores/jpa/SupplierEntityManager.java @@ -5,18 +5,27 @@ */ package com.yahoo.elide.datastores.jpa; +import jakarta.persistence.CacheRetrieveMode; +import jakarta.persistence.CacheStoreMode; +import jakarta.persistence.ConnectionConsumer; +import jakarta.persistence.ConnectionFunction; import jakarta.persistence.EntityGraph; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; +import jakarta.persistence.FindOption; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; +import jakarta.persistence.LockOption; import jakarta.persistence.Query; +import jakarta.persistence.RefreshOption; import jakarta.persistence.StoredProcedureQuery; import jakarta.persistence.TypedQuery; +import jakarta.persistence.TypedQueryReference; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.metamodel.Metamodel; @@ -218,9 +227,8 @@ public Query createNativeQuery(String sqlString) { return getEntityManager().createNativeQuery(sqlString); } - @SuppressWarnings("rawtypes") @Override - public Query createNativeQuery(String sqlString, Class resultClass) { + public Query createNativeQuery(String sqlString, Class resultClass) { return getEntityManager().createNativeQuery(sqlString, resultClass); } @@ -326,4 +334,69 @@ public EntityGraph getEntityGraph(String graphName) { public List> getEntityGraphs(Class entityClass) { return getEntityManager().getEntityGraphs(entityClass); } + + @Override + public T find(Class entityClass, Object primaryKey, FindOption... options) { + return getEntityManager().find(entityClass, primaryKey, options); + } + + @Override + public T find(EntityGraph entityGraph, Object primaryKey, FindOption... options) { + return getEntityManager().find(entityGraph, primaryKey, options); + } + + @Override + public T getReference(T entity) { + return getEntityManager().getReference(entity); + } + + @Override + public void lock(Object entity, LockModeType lockMode, LockOption... options) { + getEntityManager().lock(entity, lockMode, options); + } + + @Override + public void refresh(Object entity, RefreshOption... options) { + getEntityManager().refresh(entity, options); + } + + @Override + public void setCacheRetrieveMode(CacheRetrieveMode cacheRetrieveMode) { + getEntityManager().setCacheRetrieveMode(cacheRetrieveMode); + } + + @Override + public void setCacheStoreMode(CacheStoreMode cacheStoreMode) { + getEntityManager().setCacheStoreMode(cacheStoreMode); + } + + @Override + public CacheRetrieveMode getCacheRetrieveMode() { + return getEntityManager().getCacheRetrieveMode(); + } + + @Override + public CacheStoreMode getCacheStoreMode() { + return getEntityManager().getCacheStoreMode(); + } + + @Override + public TypedQuery createQuery(CriteriaSelect selectQuery) { + return getEntityManager().createQuery(selectQuery); + } + + @Override + public TypedQuery createQuery(TypedQueryReference reference) { + return getEntityManager().createQuery(reference); + } + + @Override + public void runWithConnection(ConnectionConsumer action) { + getEntityManager().runWithConnection(action); + } + + @Override + public T callWithConnection(ConnectionFunction function) { + return getEntityManager().callWithConnection(function); + } } diff --git a/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/JpaDataStoreHarness.java b/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/JpaDataStoreHarness.java index 19c061c97b..e955181f08 100644 --- a/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/JpaDataStoreHarness.java +++ b/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/JpaDataStoreHarness.java @@ -100,9 +100,9 @@ public JpaDataStoreHarness(QueryLogger logger, boolean delegateToInMemoryStore, new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml") .applySetting(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread") - .applySetting(Environment.URL, JDBC) - .applySetting(Environment.USER, ROOT) - .applySetting(Environment.PASS, ROOT) + .applySetting(Environment.JAKARTA_JDBC_URL, JDBC) + .applySetting(Environment.JAKARTA_JDBC_USER, ROOT) + .applySetting(Environment.JAKARTA_JDBC_PASSWORD, ROOT) .applySetting(Environment.DIALECT, "org.hibernate.dialect.H2Dialect") .build()); diff --git a/elide-datastore/elide-datastore-search/pom.xml b/elide-datastore/elide-datastore-search/pom.xml index d434b0d5ac..300018cd81 100644 --- a/elide-datastore/elide-datastore-search/pom.xml +++ b/elide-datastore/elide-datastore-search/pom.xml @@ -62,7 +62,7 @@ org.hibernate.search - hibernate-search-mapper-orm-orm6 + hibernate-search-mapper-orm diff --git a/elide-datastore/elide-datastore-search/src/test/resources/META-INF/persistence.xml b/elide-datastore/elide-datastore-search/src/test/resources/META-INF/persistence.xml index 9db402abf3..ec20195f23 100644 --- a/elide-datastore/elide-datastore-search/src/test/resources/META-INF/persistence.xml +++ b/elide-datastore/elide-datastore-search/src/test/resources/META-INF/persistence.xml @@ -5,10 +5,10 @@ ~ See LICENSE file in project root for terms. --> - + xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" + version="3.0"> com.yahoo.elide.datastores.search.models.Item @@ -16,10 +16,10 @@ - - - - + + + + diff --git a/elide-integration-tests/src/test/java/example/Generate.java b/elide-integration-tests/src/test/java/example/Generate.java index d175598089..243b2dc4c0 100644 --- a/elide-integration-tests/src/test/java/example/Generate.java +++ b/elide-integration-tests/src/test/java/example/Generate.java @@ -7,7 +7,7 @@ import com.yahoo.elide.annotation.Include; import org.hibernate.annotations.Generated; -import org.hibernate.annotations.GenerationTime; +import org.hibernate.generator.EventType; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -18,7 +18,6 @@ import java.util.Date; -@SuppressWarnings("deprecation") @Entity @Include public class Generate { @@ -33,7 +32,7 @@ public long getId() { return id; } - @Generated(GenerationTime.INSERT) + @Generated(event = EventType.INSERT) @Column(updatable = false, insertable = false, columnDefinition = "timestamp default current_timestamp") @Temporal(TemporalType.TIMESTAMP) public Date getCreated() { diff --git a/elide-integration-tests/src/test/resources/META-INF/persistence.xml b/elide-integration-tests/src/test/resources/META-INF/persistence.xml index 47aa6021c9..903aa0ed82 100644 --- a/elide-integration-tests/src/test/resources/META-INF/persistence.xml +++ b/elide-integration-tests/src/test/resources/META-INF/persistence.xml @@ -5,10 +5,10 @@ ~ See LICENSE file in project root for terms. --> - + xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" + version="3.0"> false diff --git a/elide-integration-tests/src/test/resources/hibernate.cfg.xml b/elide-integration-tests/src/test/resources/hibernate.cfg.xml index b6f10963d2..f39fcc74dc 100644 --- a/elide-integration-tests/src/test/resources/hibernate.cfg.xml +++ b/elide-integration-tests/src/test/resources/hibernate.cfg.xml @@ -21,16 +21,11 @@ false - org.hibernate.transaction.JDBCTransactionFactory - false false true false thread - - 60 - true diff --git a/elide-quarkus/deployment/pom.xml b/elide-quarkus/deployment/pom.xml index e926203197..d57d173174 100644 --- a/elide-quarkus/deployment/pom.xml +++ b/elide-quarkus/deployment/pom.xml @@ -105,9 +105,6 @@ ${quarkus.version} - - -AlegacyConfigRoot=true - diff --git a/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java b/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java index c8410d32cb..e12e39bb46 100644 --- a/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java +++ b/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java @@ -134,26 +134,26 @@ public void registerElideBeans(BuildProducer additional @BuildStep public void configureElideEndpoints(ElideConfig config, BuildProducer generatedJaxRsResourceBuildItemBuildProducer) { - if (config.jsonApiPath != null) { - LOG.infof("Enabling JSON-API Endpoint for path: %s", config.jsonApiPath); + if (config.jsonApi().path() != null) { + LOG.infof("Enabling JSON-API Endpoint for path: %s", config.jsonApi().path()); generateEndpointClass(generatedJaxRsResourceBuildItemBuildProducer, "JsonApi", - JsonApiEndpoint.class, config.jsonApiPath, + JsonApiEndpoint.class, config.jsonApi().path(), new Param("elide", Elide.class, null), new Param(Optional.class, RouteResolver.class)); } - if (config.graphqlPath != null) { - LOG.infof("Enabling GraphQL Endpoint for path: %s", config.graphqlPath); + if (config.graphql().path() != null) { + LOG.infof("Enabling GraphQL Endpoint for path: %s", config.graphql().path()); generateEndpointClass(generatedJaxRsResourceBuildItemBuildProducer, "GraphQL", - GraphQLEndpoint.class, config.graphqlPath, + GraphQLEndpoint.class, config.graphql().path(), new Param("elide", Elide.class, null), new Param(Optional.class, DataFetcherExceptionHandler.class), new Param(Optional.class, RouteResolver.class)); } - if (config.apiDocsPath != null && config.jsonApiPath != null) { - LOG.infof("Enabling Swagger Endpoint for path: %s", config.apiDocsPath); + if (config.apiDocs().path() != null && config.jsonApi().path() != null) { + LOG.infof("Enabling Swagger Endpoint for path: %s", config.apiDocs().path()); generateEndpointClass(generatedJaxRsResourceBuildItemBuildProducer, "ApiDocs", - ApiDocsEndpoint.class, config.apiDocsPath, + ApiDocsEndpoint.class, config.apiDocs().path(), new Param("apiDocs", List.class, ApiDocsEndpoint.ApiDocsRegistration.class), new Param("elide", Elide.class, null), new Param(Optional.class, RouteResolver.class)); diff --git a/elide-quarkus/deployment/src/test/java/com/yahoo/elide/extension/test/ElideExtensionTest.java b/elide-quarkus/deployment/src/test/java/com/yahoo/elide/extension/test/ElideExtensionTest.java index 3e297ba769..3a77675246 100644 --- a/elide-quarkus/deployment/src/test/java/com/yahoo/elide/extension/test/ElideExtensionTest.java +++ b/elide-quarkus/deployment/src/test/java/com/yahoo/elide/extension/test/ElideExtensionTest.java @@ -27,11 +27,10 @@ import com.yahoo.elide.extension.test.models.DenyCheck; import com.yahoo.elide.extension.test.models.Supplier; import org.apache.http.HttpStatus; -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import io.quarkus.test.QuarkusUnitTest; + +import io.quarkus.test.QuarkusExtensionTest; import io.restassured.RestAssured; import jakarta.inject.Inject; @@ -43,8 +42,8 @@ public class ElideExtensionTest { // Start unit test with your extension loaded @RegisterExtension - static final QuarkusUnitTest UNIT_TEST = new QuarkusUnitTest() - .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) + static final QuarkusExtensionTest UNIT_TEST = new QuarkusExtensionTest() + .withApplicationRoot(jar -> jar .addAsResource("application.properties") .addClass(Book.class) .addClass(Supplier.class) diff --git a/elide-quarkus/integration-tests/src/main/resources/application.properties b/elide-quarkus/integration-tests/src/main/resources/application.properties index 4715c18646..40ecb1def5 100644 --- a/elide-quarkus/integration-tests/src/main/resources/application.properties +++ b/elide-quarkus/integration-tests/src/main/resources/application.properties @@ -1,2 +1,2 @@ -elide.base-jsonapi=/it-jsonapi -elide.base-graphql=/it-graphql +elide.json-api.path=/it-jsonapi +elide.graphql.path=/it-graphql diff --git a/elide-quarkus/pom.xml b/elide-quarkus/pom.xml index 7ba4209755..2fd97202e1 100644 --- a/elide-quarkus/pom.xml +++ b/elide-quarkus/pom.xml @@ -49,7 +49,7 @@ 11 UTF-8 UTF-8 - 3.20.3 + 3.30.1 7.1.18-SNAPSHOT 3.2.5 ${project.basedir}/../.. diff --git a/elide-quarkus/runtime/pom.xml b/elide-quarkus/runtime/pom.xml index 68caf182a7..ddaeb89d0b 100644 --- a/elide-quarkus/runtime/pom.xml +++ b/elide-quarkus/runtime/pom.xml @@ -108,9 +108,6 @@ ${quarkus.version} - - -AlegacyConfigRoot=true - diff --git a/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideBeans.java b/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideBeans.java index 1945aa2395..fe723a27db 100644 --- a/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideBeans.java +++ b/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideBeans.java @@ -59,20 +59,20 @@ public void setElideConfig(ElideConfig config) { public Elide produceElide(DataStore store, EntityDictionary dictionary) { LOG.debug("Creating Elide bean"); JsonApiSettings.JsonApiSettingsBuilder jsonApiSettingsBuilder = new JsonApiSettings.JsonApiSettingsBuilder(); - jsonApiSettingsBuilder.path(config.jsonApiPath); + jsonApiSettingsBuilder.path(config.jsonApi().path()); GraphQLSettings.GraphQLSettingsBuilder graphQLSettingsBuilder = new GraphQLSettings.GraphQLSettingsBuilder(); - graphQLSettingsBuilder.path(config.graphqlPath); + graphQLSettingsBuilder.path(config.graphql().path()); ElideSettings.ElideSettingsBuilder builder = ElideSettings.builder() .entityDictionary(dictionary) - .maxPageSize(config.defaultMaxPageSize) - .defaultPageSize(config.defaultPageSize) + .maxPageSize(config.defaultMaxPageSize()) + .defaultPageSize(config.defaultPageSize()) .auditLogger(new Slf4jLogger()) .baseUrl(rootPath) .settings(jsonApiSettingsBuilder) .settings(graphQLSettingsBuilder) .dataStore(store); - if (config.verboseErrors) { + if (config.verboseErrors()) { builder = builder.verboseErrors(true); } diff --git a/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideConfig.java b/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideConfig.java index c377367232..640b9f5141 100644 --- a/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideConfig.java +++ b/elide-quarkus/runtime/src/main/java/com/yahoo/elide/extension/runtime/ElideConfig.java @@ -6,54 +6,81 @@ package com.yahoo.elide.extension.runtime; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; -@ConfigRoot(prefix = "", name = "elide", phase = ConfigPhase.BUILD_TIME) -public class ElideConfig { - +@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +@ConfigMapping(prefix = "elide") +public interface ElideConfig { public static final String JSONAPI_PATH = "/jsonapi"; public static final String GRAPHQL_PATH = "/graphql"; public static final String APIDOCS_PATH = "/apiDocs"; + interface JsonApiConfig { + /** + * The base URL path prefix for Elide JSON-API service endpoints. + * This is appended to the basePath. + */ + @WithDefault(JSONAPI_PATH) + String path(); + } + + interface GraphqlConfig { + /** + * The base URL path prefix for Elide GraphQL service endpoints. + * This is appended to the basePath. + */ + @WithDefault(GRAPHQL_PATH) + String path(); + } + + interface ApiDocsConfig { + /** + * The base URL path prefix for the Elide Swagger document. + * This is appended to the basePath. + */ + @WithDefault(APIDOCS_PATH) + String path(); + } + /** - * Default page size if client doesn't request any. + * JSON-API configuration. + * + * @return the configuration */ - @ConfigItem(defaultValue = "100") - public int defaultPageSize; + JsonApiConfig jsonApi(); /** - * Maximum page size that can be requested by a client. + * GraphQL configuration. + * + * @return the configuration */ - @ConfigItem(defaultValue = "10000") - public int defaultMaxPageSize; + GraphqlConfig graphql(); /** - * Turns on verbose errors in HTTP responses. + * API Docs configuration. + * + * @return the configuration */ - @ConfigItem(defaultValue = "true") - public boolean verboseErrors; + ApiDocsConfig apiDocs(); /** - * The base URL path prefix for Elide JSON-API service endpoints. - * This is appended to the basePath. + * Default page size if client doesn't request any. */ - @ConfigItem(name = "json-api.path", defaultValue = JSONAPI_PATH) - public String jsonApiPath; + @WithDefault("100") + int defaultPageSize(); /** - * The base URL path prefix for Elide GraphQL service endpoints. - * This is appended to the basePath. + * Maximum page size that can be requested by a client. */ - @ConfigItem(name = "graphql.path", defaultValue = GRAPHQL_PATH) - public String graphqlPath; - + @WithDefault("10000") + int defaultMaxPageSize(); /** - * The base URL path prefix for the Elide Swagger document. - * This is appended to the basePath. + * Turns on verbose errors in HTTP responses. */ - @ConfigItem(name = "api-docs.path", defaultValue = APIDOCS_PATH) - public String apiDocsPath; + @WithDefault("true") + boolean verboseErrors(); } diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java index 01e6793d9b..c2363739fd 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java @@ -130,9 +130,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/ApiDocsController.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/ApiDocsController.java index 0120555f52..d9de8102f5 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/ApiDocsController.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/ApiDocsController.java @@ -113,8 +113,8 @@ public Callable> listJson(@RequestHeader HttpHeaders requ String prefix = elideConfigProperties.getApiDocs().getPath(); String pathname = getPath(request, prefix); final String baseUrl = getBaseUrl(prefix); - Route route = routeResolver.resolve(MediaType.APPLICATION_JSON, baseUrl, pathname, requestHeaders, - allRequestParams); + Route route = routeResolver.resolve(MediaType.APPLICATION_JSON, baseUrl, pathname, + requestHeaders.asMultiValueMap(), allRequestParams); String path = route.getPath(); if (path.startsWith("/")) { path = path.substring(1); @@ -132,8 +132,8 @@ public Callable> listYaml(@RequestHeader HttpHeaders requ String prefix = elideConfigProperties.getApiDocs().getPath(); String pathname = getPath(request, prefix); final String baseUrl = getBaseUrl(prefix); - Route route = routeResolver.resolve(MediaType.APPLICATION_YAML, baseUrl, pathname, requestHeaders, - allRequestParams); + Route route = routeResolver.resolve(MediaType.APPLICATION_YAML, baseUrl, pathname, + requestHeaders.asMultiValueMap(), allRequestParams); String path = route.getPath(); if (path.startsWith("/")) { path = path.substring(1); diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/GraphqlController.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/GraphqlController.java index 2dbde0fd21..a9b3ca722f 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/GraphqlController.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/GraphqlController.java @@ -84,11 +84,13 @@ public Callable> post(@RequestHeader HttpHeaders requestH @RequestParam MultiValueMap allRequestParams, @RequestBody String graphQLDocument, HttpServletRequest request) { final User user = new HttpServletRequestUser(request); - final Map> requestHeadersCleaned = headerProcessor.process(requestHeaders); + final Map> requestHeadersCleaned = headerProcessor + .process(requestHeaders.asMultiValueMap()); final String prefix = settings.getGraphql().getPath(); final String baseUrl = getBaseUrl(prefix); final String pathname = getPath(request, prefix); - Route route = routeResolver.resolve(JSON_CONTENT_TYPE, baseUrl, pathname, requestHeaders, allRequestParams); + Route route = routeResolver.resolve(JSON_CONTENT_TYPE, baseUrl, pathname, requestHeadersCleaned, + allRequestParams); final QueryRunner runner = runners.getRunner(route.getApiVersion()); diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/JsonApiController.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/JsonApiController.java index 3dcf4a00a5..181591459f 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/JsonApiController.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/JsonApiController.java @@ -67,7 +67,8 @@ public JsonApiController(JsonApi jsonApi, ElideConfigProperties settings, public Callable> elideGet(@RequestHeader HttpHeaders requestHeaders, @RequestParam MultiValueMap allRequestParams, HttpServletRequest request) { - final Map> requestHeadersCleaned = headerProcessor.process(requestHeaders); + final Map> requestHeadersCleaned = headerProcessor + .process(requestHeaders.asMultiValueMap()); final String prefix = settings.getJsonApi().getPath(); final String baseUrl = getBaseUrl(prefix); final String pathname = getPath(request, prefix); @@ -90,7 +91,8 @@ public Callable> elidePost(@RequestHeader HttpHeaders req @RequestParam MultiValueMap allRequestParams, @RequestBody String body, HttpServletRequest request) { - final Map> requestHeadersCleaned = headerProcessor.process(requestHeaders); + final Map> requestHeadersCleaned = headerProcessor + .process(requestHeaders.asMultiValueMap()); String prefix = settings.getJsonApi().getPath(); final String baseUrl = getBaseUrl(prefix); final String pathname = getPath(request, prefix); @@ -125,7 +127,8 @@ public Callable> elidePatch(@RequestHeader HttpHeaders re @RequestParam MultiValueMap allRequestParams, @RequestBody String body, HttpServletRequest request) { - final Map> requestHeadersCleaned = headerProcessor.process(requestHeaders); + final Map> requestHeadersCleaned = headerProcessor + .process(requestHeaders.asMultiValueMap()); final String prefix = settings.getJsonApi().getPath(); final String baseUrl = getBaseUrl(prefix); final String pathname = getPath(request, prefix); @@ -146,7 +149,8 @@ public ResponseEntity call() throws Exception { public Callable> elideDelete(@RequestHeader HttpHeaders requestHeaders, @RequestParam MultiValueMap allRequestParams, HttpServletRequest request) { - final Map> requestHeadersCleaned = headerProcessor.process(requestHeaders); + final Map> requestHeadersCleaned = headerProcessor + .process(requestHeaders.asMultiValueMap()); final String prefix = settings.getJsonApi().getPath(); final String baseUrl = getBaseUrl(prefix); final String pathname = getPath(request, prefix); @@ -169,7 +173,8 @@ public Callable> elideDeleteRelation( @RequestParam MultiValueMap allRequestParams, @RequestBody String body, HttpServletRequest request) { - final Map> requestHeadersCleaned = headerProcessor.process(requestHeaders); + final Map> requestHeadersCleaned = headerProcessor + .process(requestHeaders.asMultiValueMap()); final String prefix = settings.getJsonApi().getPath(); final String baseUrl = getBaseUrl(prefix); final String pathname = getPath(request, prefix); diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTest.java index 4f3ed4adf6..af308ed165 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTest.java @@ -48,13 +48,13 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.annotation.UserConfigurations; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java index 9c21aac8b0..d48f41443d 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java @@ -31,20 +31,21 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.context.annotation.UserConfigurations; +import org.springframework.boot.hibernate.SpringJtaPlatform; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; -import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryBuilderCustomizer; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -64,6 +65,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -221,7 +223,7 @@ public EntityManagerFactoryBuilder entityManagerFactoryBuilder( ObjectProvider persistenceUnitManager, ObjectProvider customizers) { EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), - new HashMap<>(), persistenceUnitManager.getIfAvailable()); + datasource -> Collections.emptyMap(), persistenceUnitManager.getIfAvailable()); customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); return builder; } @@ -451,7 +453,7 @@ public EntityManagerFactoryBuilder entityManagerFactoryBuilder( ObjectProvider persistenceUnitManager, ObjectProvider customizers) { EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), - new HashMap<>(), persistenceUnitManager.getIfAvailable()); + datasource -> Collections.emptyMap(), persistenceUnitManager.getIfAvailable()); customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); return builder; } @@ -489,6 +491,7 @@ public LocalContainerEntityManagerFactoryBean entityManagerFactoryV3(EntityManag } @Test + @Disabled // Disabled as no Spring Boot 4 compatible atomikos starter void multiplexDataStoreJtaTransaction() { contextRunner .withPropertyValues("spring.cloud.refresh.enabled=false", @@ -555,6 +558,7 @@ void multiplexDataStoreJtaTransaction() { } @Test + @Disabled // Disabled as no Spring Boot 4 compatible atomikos starter void multipleDataStoreJtaTransaction() { contextRunner.withPropertyValues("spring.cloud.refresh.enabled=false", "atomikos.properties.max-timeout=0") .withConfiguration(AutoConfigurations.of(AtomikosAutoConfiguration.class)) diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionConfigurationTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionConfigurationTest.java index 8d0781eaa0..bb91a0ca4e 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionConfigurationTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionConfigurationTest.java @@ -13,10 +13,10 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfigurationTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfigurationTest.java index e2d31cec64..00daefe2de 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfigurationTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfigurationTest.java @@ -14,11 +14,11 @@ import org.mockito.Mockito; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.context.annotation.UserConfigurations; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/AggregationStoreTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/AggregationStoreTest.java index 5ec9dc87e9..0147b56501 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/AggregationStoreTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/AggregationStoreTest.java @@ -91,7 +91,7 @@ public void jsonApiGetTest(@Autowired MeterRegistry metrics) { requestHeaders.put("bypassCache", "true"); HttpHeaders headers = new HttpHeaders(); headers.set("bypassCache", "true"); - given().headers(headers) + given().headers(headers.asMultiValueMap()) .get("/json/stats?fields[stats]=measure") .then() .body(equalTo( diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderCleansingTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderCleansingTest.java index 494347df5a..e06fcf7761 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderCleansingTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderCleansingTest.java @@ -27,11 +27,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlMergeMode; @@ -61,7 +61,7 @@ public class HeaderCleansingTest extends IntegrationTest { public static final String SORT_PARAM = "sort"; - @SpyBean + @MockitoSpyBean private JsonApi jsonApi; @BeforeAll diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderIdentityTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderIdentityTest.java index 5f2392189a..14c6491e26 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderIdentityTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/HeaderIdentityTest.java @@ -27,11 +27,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlMergeMode; @@ -62,7 +62,7 @@ class HeaderIdentityTest extends IntegrationTest { public static final String SORT_PARAM = "sort"; - @SpyBean + @MockitoSpyBean private JsonApi jsonApi; @BeforeAll diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java index 303b55a2f4..780fb10225 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java @@ -30,12 +30,14 @@ import com.yahoo.elide.datastores.jms.websocket.SubscriptionWebSocketTestClient; import com.yahoo.elide.graphql.GraphQLExceptionHandler; import com.yahoo.elide.jsonapi.JsonApi; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.apache.http.HttpStatus; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.context.annotation.Bean; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import graphql.ExecutionResult; import jakarta.websocket.ContainerProvider; @@ -57,6 +59,12 @@ SerdesBuilderCustomizer serdesBuilderCustomzer() { serdesBuilder.entry(OffsetDateTime.class, serde); }; } + + @Bean + Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() { + Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json().modules(new JavaTimeModule()); + return builder; + } } @SuppressWarnings("unchecked") @@ -65,7 +73,7 @@ public void resetMocks() { reset(serde); } - @SpyBean + @MockitoSpyBean GraphQLExceptionHandler graphqlExceptionHandler; @Test diff --git a/pom.xml b/pom.xml index 629f70dc30..16f300e079 100644 --- a/pom.xml +++ b/pom.xml @@ -80,64 +80,64 @@ ${project.basedir}/target/lombok - 4.13.2 - 2.40.0 + 4.13.1 + 2.43.0 6.0.0 - 1.41.0 - 3.2.3 - 4.8.184 + 1.37.0 + 3.2.0 + 4.8.172 1.11.0 - 1.11.0 - 4.5.0 - 1.28.0 - 3.20.0 - 0.11.0 - 1.4.0 - 5.4.0 - 24.3 - 24.0 - 25.0.1 - 33.5.0-jre - 4.5.0 - 6.6.49.Final - 8.0.3.Final - 6.2.4.Final + 1.9.0 + 4.4 + 1.26.2 + 3.14.0 + 1.4.3 + 1.2.3 + 5.1.0 + 22.0 + 24.0.1 + 33.4.0-jre + 4.4.0 + 7.1.8.Final + 9.0.1.Final + 8.1.2.Final 3.1.0 - 5.5.2 - 2.13.2 - 2.3.232 - 6.3.3 - 2.21.2 - 2.0.1 + 5.4.3 + 4.0.29 + 2.11.0 + 2.4.240 + 5.1.0 + 2.17.1 + 2.0.1.MR 3.1.0 - 3.1.0 + 3.2.0 2.0.1 2.2.0 4.0.0 - 3.1.0 - 2.4.2 - 3.1.11 - 12.0.34 - 6.0.0 + 3.1.1 + 2.4.1 + 3.1.8 + 12.0.15 + 5.1.5 1.5.3 - 2.10.0 - 1.5.9 + 2.9.0 + 1.5.6 5.10.2 - 1.5.32 + 1.5.18 1.18.36 - 5.5.1 - 5.5.7 - 2024.0.12 + 5.4.0 + 5.5.6 + 2023.0.6 2.1.0 2.0.17 - 3.5.14 - 6.2.18 - 4.3.2 - 2.8.17 - 2.2.48 + 4.0.0 + 7.0.1 + 5.0.0 + 3.0.0 + 2.2.41 1.2.1 - 11.0.21 - 5.20.0 + 11.0.6 + 5.12.0 3.6.0 4.3.0 10.21.4 @@ -272,7 +272,7 @@ com.graphql-java graphql-java-extended-scalars - ${graphql-java-extended-scalars.version} + ${graphql-java.version} com.google.code.gson @@ -321,7 +321,7 @@ org.hibernate.search - hibernate-search-mapper-orm-orm6 + hibernate-search-mapper-orm ${hibernate-search.version} @@ -572,6 +572,12 @@ jakarta.persistence-api ${jakarta-persistence.version} + + org.apache.groovy + groovy + ${groovy.version} + test + @@ -922,4 +928,4 @@ - + \ No newline at end of file From 052a74c668d4deeab55b4ebb5aece3269507781c Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sun, 30 Nov 2025 09:29:05 +0800 Subject: [PATCH 02/12] Update to Jersey 4 --- .../integration/AggregationDataStoreIntegrationTest.java | 2 +- .../integration/MetaDataStoreIntegrationTest.java | 2 +- .../AsyncIntegrationTestApplicationResourceConfig.java | 2 +- .../IdObfuscationTestApplicationResourceConfig.java | 2 +- ...LifeCycleIntegrationTestApplicationResourceConfig.java | 2 +- .../elide/standalone/config/ElideResourceConfig.java | 2 +- pom.xml | 8 ++++---- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java index adff2e8562..2b4f313037 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java @@ -32,7 +32,7 @@ import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import example.TestCheckMappings; -import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.inject.hk2.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/MetaDataStoreIntegrationTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/MetaDataStoreIntegrationTest.java index 45541d7499..e808cce2df 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/MetaDataStoreIntegrationTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/MetaDataStoreIntegrationTest.java @@ -42,7 +42,7 @@ import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import example.TestCheckMappings; -import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.inject.hk2.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import org.junit.jupiter.api.Test; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/framework/AsyncIntegrationTestApplicationResourceConfig.java b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/framework/AsyncIntegrationTestApplicationResourceConfig.java index 556063d31b..a863875d16 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/framework/AsyncIntegrationTestApplicationResourceConfig.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/framework/AsyncIntegrationTestApplicationResourceConfig.java @@ -52,7 +52,7 @@ import example.models.triggers.services.BillingService; import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.inject.hk2.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import graphql.execution.SimpleDataFetcherExceptionHandler; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IdObfuscationTestApplicationResourceConfig.java b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IdObfuscationTestApplicationResourceConfig.java index 0082cf87b0..9eefcd9eaa 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IdObfuscationTestApplicationResourceConfig.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IdObfuscationTestApplicationResourceConfig.java @@ -26,7 +26,7 @@ import example.models.triggers.InvoiceCompletionHook; import example.models.triggers.services.BillingService; import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.inject.hk2.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import jakarta.inject.Inject; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/LifeCycleIntegrationTestApplicationResourceConfig.java b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/LifeCycleIntegrationTestApplicationResourceConfig.java index 33612ade32..1663c5ef5e 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/LifeCycleIntegrationTestApplicationResourceConfig.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/LifeCycleIntegrationTestApplicationResourceConfig.java @@ -23,7 +23,7 @@ import example.models.triggers.InvoiceCompletionHook; import example.models.triggers.services.BillingService; import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.inject.hk2.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import jakarta.inject.Inject; diff --git a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java index ea834fc74e..8531c01666 100644 --- a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java +++ b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java @@ -47,7 +47,7 @@ import com.codahale.metrics.health.HealthCheckRegistry; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.api.TypeLiteral; -import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.inject.hk2.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import graphql.execution.DataFetcherExceptionHandler; diff --git a/pom.xml b/pom.xml index 16f300e079..e0fb23de28 100644 --- a/pom.xml +++ b/pom.xml @@ -107,8 +107,8 @@ 2.11.0 2.4.240 5.1.0 - 2.17.1 - 2.0.1.MR + 2.20.1 + 2.0.1 3.1.0 3.2.0 2.0.1 @@ -116,8 +116,8 @@ 4.0.0 3.1.1 2.4.1 - 3.1.8 - 12.0.15 + 4.0.0 + 12.1.4 5.1.5 1.5.3 2.9.0 From 464be23ac79f1cc044c86f775643ec7c0dfd674c Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sun, 30 Nov 2025 22:33:12 +0800 Subject: [PATCH 03/12] Update GraphQL --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index e0fb23de28..6669e098e6 100644 --- a/pom.xml +++ b/pom.xml @@ -93,8 +93,9 @@ 3.14.0 1.4.3 1.2.3 - 5.1.0 - 22.0 + 5.4.0 + 25.0 + 24.0 24.0.1 33.4.0-jre 4.4.0 @@ -272,7 +273,7 @@ com.graphql-java graphql-java-extended-scalars - ${graphql-java.version} + ${graphql-java-extended-scalars.version} com.google.code.gson From 8a5c169a067b43a5da306bbd6035fb8df8141f5d Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sun, 30 Nov 2025 12:01:55 +0800 Subject: [PATCH 04/12] Update dependencies --- elide-quarkus/pom.xml | 4 +-- elide-standalone/pom.xml | 2 +- pom.xml | 72 ++++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/elide-quarkus/pom.xml b/elide-quarkus/pom.xml index 2fd97202e1..fa6a6197ad 100644 --- a/elide-quarkus/pom.xml +++ b/elide-quarkus/pom.xml @@ -43,7 +43,7 @@ 3.13.0 - 3.2.5 + 3.5.4 true 11 11 @@ -51,7 +51,7 @@ UTF-8 3.30.1 7.1.18-SNAPSHOT - 3.2.5 + 3.5.4 ${project.basedir}/../.. diff --git a/elide-standalone/pom.xml b/elide-standalone/pom.xml index 9484e86e30..489e8751a2 100644 --- a/elide-standalone/pom.xml +++ b/elide-standalone/pom.xml @@ -44,7 +44,7 @@ - 4.2.25 + 4.2.37 utf-8 diff --git a/pom.xml b/pom.xml index 6669e098e6..eb91f550fd 100644 --- a/pom.xml +++ b/pom.xml @@ -80,34 +80,34 @@ ${project.basedir}/target/lombok - 4.13.1 + 4.13.2 2.43.0 6.0.0 - 1.37.0 - 3.2.0 - 4.8.172 + 1.41.0 + 3.2.3 + 4.8.184 1.11.0 - 1.9.0 - 4.4 - 1.26.2 - 3.14.0 + 1.11.0 + 4.5.0 + 1.28.0 + 3.20.0 1.4.3 - 1.2.3 + 1.4.0 5.4.0 25.0 24.0 - 24.0.1 - 33.4.0-jre - 4.4.0 - 7.1.8.Final - 9.0.1.Final + 25.0.1 + 33.5.0-jre + 4.5.0 + 7.1.10.Final + 9.1.0.Final 8.1.2.Final 3.1.0 - 5.4.3 + 5.5.1 4.0.29 - 2.11.0 + 2.13.2 2.4.240 - 5.1.0 + 7.0.2 2.20.1 2.0.1 3.1.0 @@ -116,19 +116,19 @@ 2.2.0 4.0.0 3.1.1 - 2.4.1 + 2.4.2 4.0.0 12.1.4 - 5.1.5 + 7.1.0 1.5.3 - 2.9.0 + 2.10.0 1.5.6 5.10.2 - 1.5.18 - 1.18.36 - 5.4.0 + 1.5.21 + 1.18.42 + 5.5.0 5.5.6 - 2023.0.6 + 2025.0.0 2.1.0 2.0.17 4.0.0 @@ -137,29 +137,29 @@ 3.0.0 2.2.41 1.2.1 - 11.0.6 - 5.12.0 - 3.6.0 + 11.0.14 + 5.20.0 + 3.6.1 4.3.0 10.21.4 - 12.1.1 - 0.8.13 + 12.1.9 + 0.8.14 2.3.1 3.6.0 3.13.0 3.1.3 - 3.4.1 - 3.10.0 + 3.6.2 + 3.12.0 3.4.2 3.2.4 - 3.2.5 + 3.5.4 3.3.1 - 3.2.5 + 3.5.4 3.21.0 2.5.3 - 2.1.0 - 3.1.1 - 2.1.0 + 2.2.1 + 3.2.0 + 2.2.1 1.18.20.0 3.11.4 3.5.3 From ba95c3c1ef0507d6af6017174f66d449195b3ef1 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sat, 17 Jan 2026 13:04:04 +0800 Subject: [PATCH 05/12] Update Hibernate --- elide-quarkus/pom.xml | 2 +- pom.xml | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/elide-quarkus/pom.xml b/elide-quarkus/pom.xml index fa6a6197ad..d51041abf7 100644 --- a/elide-quarkus/pom.xml +++ b/elide-quarkus/pom.xml @@ -49,7 +49,7 @@ 11 UTF-8 UTF-8 - 3.30.1 + 3.31.0.CR1 7.1.18-SNAPSHOT 3.5.4 ${project.basedir}/../.. diff --git a/pom.xml b/pom.xml index eb91f550fd..80f6d0647e 100644 --- a/pom.xml +++ b/pom.xml @@ -93,18 +93,18 @@ 3.20.0 1.4.3 1.4.0 - 5.4.0 + 5.5.0 25.0 24.0 25.0.1 33.5.0-jre 4.5.0 - 7.1.10.Final + 7.2.1.Final 9.1.0.Final - 8.1.2.Final + 8.2.1.Final 3.1.0 - 5.5.1 - 4.0.29 + 5.6 + 5.0.3 2.13.2 2.4.240 7.0.2 @@ -118,17 +118,17 @@ 3.1.1 2.4.2 4.0.0 - 12.1.4 - 7.1.0 + 12.1.5 + 7.2.1 1.5.3 2.10.0 1.5.6 - 5.10.2 - 1.5.21 + 6.0.2 + 1.5.24 1.18.42 - 5.5.0 - 5.5.6 - 2025.0.0 + 5.5.1 + 6.0.0 + 2025.0.2 2.1.0 2.0.17 4.0.0 @@ -137,12 +137,12 @@ 3.0.0 2.2.41 1.2.1 - 11.0.14 - 5.20.0 + 11.0.15 + 5.21.0 3.6.1 4.3.0 10.21.4 - 12.1.9 + 12.2.0 0.8.14 2.3.1 3.6.0 @@ -158,7 +158,7 @@ 3.21.0 2.5.3 2.2.1 - 3.2.0 + 3.3.1 2.2.1 1.18.20.0 3.11.4 From 7ba5e1091951b25a257298a2f4268d0e5b17fcc8 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:24:27 +0800 Subject: [PATCH 06/12] Update dependencies --- elide-quarkus/pom.xml | 2 +- elide-standalone/pom.xml | 2 +- pom.xml | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/elide-quarkus/pom.xml b/elide-quarkus/pom.xml index d51041abf7..e420484e4b 100644 --- a/elide-quarkus/pom.xml +++ b/elide-quarkus/pom.xml @@ -49,7 +49,7 @@ 11 UTF-8 UTF-8 - 3.31.0.CR1 + 3.31.1 7.1.18-SNAPSHOT 3.5.4 ${project.basedir}/../.. diff --git a/elide-standalone/pom.xml b/elide-standalone/pom.xml index 489e8751a2..d2f7ae0643 100644 --- a/elide-standalone/pom.xml +++ b/elide-standalone/pom.xml @@ -44,7 +44,7 @@ - 4.2.37 + 4.2.38 utf-8 diff --git a/pom.xml b/pom.xml index 80f6d0647e..c71864dd2e 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 4.13.2 - 2.43.0 + 2.50.0 6.0.0 1.41.0 3.2.3 @@ -96,7 +96,7 @@ 5.5.0 25.0 24.0 - 25.0.1 + 25.0.2 33.5.0-jre 4.5.0 7.2.1.Final @@ -104,11 +104,11 @@ 8.2.1.Final 3.1.0 5.6 - 5.0.3 + 5.0.4 2.13.2 2.4.240 7.0.2 - 2.20.1 + 2.21.0 2.0.1 3.1.0 3.2.0 @@ -117,14 +117,14 @@ 4.0.0 3.1.1 2.4.2 - 4.0.0 - 12.1.5 + 4.0.2 + 12.1.6 7.2.1 1.5.3 2.10.0 1.5.6 6.0.2 - 1.5.24 + 1.5.27 1.18.42 5.5.1 6.0.0 @@ -135,9 +135,9 @@ 7.0.1 5.0.0 3.0.0 - 2.2.41 + 2.2.42 1.2.1 - 11.0.15 + 11.0.18 5.21.0 3.6.1 4.3.0 From 08e5e371b12a4637dacc208b75d0525974f47e5e Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sat, 14 Mar 2026 09:38:43 +0800 Subject: [PATCH 07/12] Update dependencies --- elide-quarkus/pom.xml | 6 +++--- pom.xml | 38 +++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/elide-quarkus/pom.xml b/elide-quarkus/pom.xml index e420484e4b..5cc2b702e8 100644 --- a/elide-quarkus/pom.xml +++ b/elide-quarkus/pom.xml @@ -43,15 +43,15 @@ 3.13.0 - 3.5.4 + 3.5.5 true 11 11 UTF-8 UTF-8 - 3.31.1 + 3.32.3 7.1.18-SNAPSHOT - 3.5.4 + 3.5.5 ${project.basedir}/../.. diff --git a/pom.xml b/pom.xml index c71864dd2e..975db87292 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 4.13.2 - 2.50.0 + 2.52.0 6.0.0 1.41.0 3.2.3 @@ -93,22 +93,22 @@ 3.20.0 1.4.3 1.4.0 - 5.5.0 + 6.0.0 25.0 24.0 25.0.2 33.5.0-jre 4.5.0 - 7.2.1.Final + 7.2.6.Final 9.1.0.Final - 8.2.1.Final + 8.2.2.Final 3.1.0 5.6 5.0.4 2.13.2 2.4.240 7.0.2 - 2.21.0 + 2.21.1 2.0.1 3.1.0 3.2.0 @@ -118,27 +118,27 @@ 3.1.1 2.4.2 4.0.2 - 12.1.6 - 7.2.1 + 12.1.7 + 7.4.0 1.5.3 - 2.10.0 + 3.0.0 1.5.6 6.0.2 - 1.5.27 - 1.18.42 + 1.5.32 + 1.18.44 5.5.1 6.0.0 - 2025.0.2 + 2025.0.4 2.1.0 2.0.17 - 4.0.0 - 7.0.1 - 5.0.0 - 3.0.0 - 2.2.42 + 4.0.3 + 7.0.5 + 5.0.1 + 3.0.2 + 2.2.45 1.2.1 11.0.18 - 5.21.0 + 5.23.0 3.6.1 4.3.0 10.21.4 @@ -152,9 +152,9 @@ 3.12.0 3.4.2 3.2.4 - 3.5.4 + 3.5.5 3.3.1 - 3.5.4 + 3.5.5 3.21.0 2.5.3 2.2.1 From 63b374490fe3d3eddb21e26e9a22783dd2e07d99 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sat, 14 Mar 2026 11:46:10 +0800 Subject: [PATCH 08/12] Update json schema validator --- .../DynamicConfigSchemaValidator.java | 70 ++++++++----------- ...ElideMetaSchema.java => ElideDialect.java} | 15 ++-- .../modelconfig/InvalidSchemaException.java | 12 ++-- ...ionMessages.java => ValidationErrors.java} | 11 ++- .../jsonformats/ElideRSQLFilterFormat.java | 4 +- .../main/resources/elideDBConfigSchema.json | 6 +- .../resources/elideNamespaceConfigSchema.json | 2 +- .../main/resources/elideSecuritySchema.json | 2 +- .../src/main/resources/elideTableSchema.json | 28 ++++---- pom.xml | 2 +- 10 files changed, 71 insertions(+), 81 deletions(-) rename elide-model-config/src/main/java/com/yahoo/elide/modelconfig/{ElideMetaSchema.java => ElideDialect.java} (68%) rename elide-model-config/src/main/java/com/yahoo/elide/modelconfig/{ValidationMessages.java => ValidationErrors.java} (54%) diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigSchemaValidator.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigSchemaValidator.java index 596860aadb..fca5501bc0 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigSchemaValidator.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigSchemaValidator.java @@ -5,19 +5,19 @@ */ package com.yahoo.elide.modelconfig; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.networknt.schema.JsonMetaSchema; -import com.networknt.schema.JsonSchema; -import com.networknt.schema.JsonSchemaFactory; -import com.networknt.schema.SchemaValidatorsConfig; -import com.networknt.schema.ValidationMessage; +import com.networknt.schema.Error; +import com.networknt.schema.InputFormat; +import com.networknt.schema.Schema; +import com.networknt.schema.SchemaRegistry; +import com.networknt.schema.SchemaRegistryConfig; +import com.networknt.schema.dialect.Dialect; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; -import java.util.Set; +import java.util.List; /** * Dynamic Model Schema validation. @@ -25,30 +25,24 @@ @Slf4j public class DynamicConfigSchemaValidator { - private final JsonSchema tableSchema; - private final JsonSchema securitySchema; - private final JsonSchema variableSchema; - private final JsonSchema dbConfigSchema; - private final JsonSchema namespaceConfigSchema; - private final ObjectMapper objectMapper; + private final Schema tableSchema; + private final Schema securitySchema; + private final Schema variableSchema; + private final Schema dbConfigSchema; + private final Schema namespaceConfigSchema; public DynamicConfigSchemaValidator() { - this(new ObjectMapper()); - } - - public DynamicConfigSchemaValidator(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - JsonMetaSchema jsonMetaSchema = ElideMetaSchema.getInstance(); - JsonSchemaFactory factory = JsonSchemaFactory.builder() - .defaultMetaSchemaIri(jsonMetaSchema.getIri()) - .metaSchema(jsonMetaSchema) - .build(); + Dialect jsonMetaSchema = ElideDialect.getInstance(); + SchemaRegistryConfig schemaRegistryConfig = SchemaRegistryConfig.builder().formatAssertionsEnabled(true) + .errorMessageKeyword("errorMessage").build(); + SchemaRegistry schemaRegistry = SchemaRegistry.withDefaultDialect(jsonMetaSchema, + builder -> builder.schemaRegistryConfig(schemaRegistryConfig)); - tableSchema = loadSchema(factory, objectMapper, Config.TABLE.getConfigSchema()); - securitySchema = loadSchema(factory, objectMapper, Config.SECURITY.getConfigSchema()); - variableSchema = loadSchema(factory, objectMapper, Config.MODELVARIABLE.getConfigSchema()); - dbConfigSchema = loadSchema(factory, objectMapper, Config.SQLDBConfig.getConfigSchema()); - namespaceConfigSchema = loadSchema(factory, objectMapper, Config.NAMESPACEConfig.getConfigSchema()); + tableSchema = loadSchema(schemaRegistry, Config.TABLE.getConfigSchema()); + securitySchema = loadSchema(schemaRegistry, Config.SECURITY.getConfigSchema()); + variableSchema = loadSchema(schemaRegistry, Config.MODELVARIABLE.getConfigSchema()); + dbConfigSchema = loadSchema(schemaRegistry, Config.SQLDBConfig.getConfigSchema()); + namespaceConfigSchema = loadSchema(schemaRegistry, Config.NAMESPACEConfig.getConfigSchema()); } /** @@ -61,23 +55,23 @@ public DynamicConfigSchemaValidator(ObjectMapper objectMapper) { */ public boolean verifySchema(Config configType, String jsonConfig, String fileName) throws IOException { - Set results = null; + List results = null; switch (configType) { case TABLE : - results = this.tableSchema.validate(objectMapper.readTree(jsonConfig)); + results = this.tableSchema.validate(jsonConfig, InputFormat.JSON); break; case SECURITY : - results = this.securitySchema.validate(objectMapper.readTree(jsonConfig)); + results = this.securitySchema.validate(jsonConfig, InputFormat.JSON); break; case MODELVARIABLE : case DBVARIABLE : - results = this.variableSchema.validate(objectMapper.readTree(jsonConfig)); + results = this.variableSchema.validate(jsonConfig, InputFormat.JSON); break; case SQLDBConfig : - results = this.dbConfigSchema.validate(objectMapper.readTree(jsonConfig)); + results = this.dbConfigSchema.validate(jsonConfig, InputFormat.JSON); break; case NAMESPACEConfig : - results = this.namespaceConfigSchema.validate(objectMapper.readTree(jsonConfig)); + results = this.namespaceConfigSchema.validate(jsonConfig, InputFormat.JSON); break; default : log.error("Not a valid config type :" + configType); @@ -89,13 +83,9 @@ public boolean verifySchema(Config configType, String jsonConfig, String fileNam return true; } - private static JsonSchema loadSchema(JsonSchemaFactory factory, ObjectMapper objectMapper, String resource) { + private static Schema loadSchema(SchemaRegistry factory, String resource) { try (InputStream is = DynamicConfigHelpers.class.getResourceAsStream(resource)) { - SchemaValidatorsConfig config = SchemaValidatorsConfig.builder() - .formatAssertionsEnabled(true) - .errorMessageKeyword("errorMessage") - .build(); - return factory.getSchema(objectMapper.readTree(is), config); + return factory.getSchema(is); } catch (IOException e) { log.error("Error loading schema file " + resource + " to verify"); throw new UncheckedIOException(e.getMessage(), e); diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ElideMetaSchema.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ElideDialect.java similarity index 68% rename from elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ElideMetaSchema.java rename to elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ElideDialect.java index a6bd7153d8..75083ca94c 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ElideMetaSchema.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ElideDialect.java @@ -7,16 +7,17 @@ import com.yahoo.elide.modelconfig.jsonformats.ElideRSQLFilterFormat; -import com.networknt.schema.Format; -import com.networknt.schema.JsonMetaSchema; +import com.networknt.schema.dialect.Dialect; +import com.networknt.schema.dialect.Dialects; +import com.networknt.schema.format.Format; import java.util.ArrayList; import java.util.List; /** - * The Elide {@link JsonMetaSchema}. + * The Elide {@link Dialect}. */ -public class ElideMetaSchema { +public class ElideDialect { public static final List FORMATS; static { @@ -26,9 +27,9 @@ public class ElideMetaSchema { } private static class Holder { - static final JsonMetaSchema INSTANCE; + static final Dialect INSTANCE; static { - INSTANCE = JsonMetaSchema.builder(JsonMetaSchema.getV202012()) + INSTANCE = Dialect.builder(Dialects.getDraft202012()) .formats(FORMATS) // add your custom keywords .build(); @@ -36,7 +37,7 @@ private static class Holder { } } - public static JsonMetaSchema getInstance() { + public static Dialect getInstance() { return Holder.INSTANCE; } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/InvalidSchemaException.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/InvalidSchemaException.java index 2bc909b5f0..29e523be72 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/InvalidSchemaException.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/InvalidSchemaException.java @@ -6,10 +6,10 @@ package com.yahoo.elide.modelconfig; -import com.networknt.schema.ValidationMessage; +import com.networknt.schema.Error; import java.io.IOException; -import java.util.Set; +import java.util.List; /** * Indicates that the schema is not valid. @@ -18,16 +18,16 @@ public class InvalidSchemaException extends IOException { private static final long serialVersionUID = 1L; - private final Set validationMessages; + private final List validationMessages; private final String fileName; - public InvalidSchemaException(String fileName, Set validationMessages) { - super("Schema validation failed for: " + fileName + ValidationMessages.toString(validationMessages)); + public InvalidSchemaException(String fileName, List validationMessages) { + super("Schema validation failed for: " + fileName + ValidationErrors.toString(validationMessages)); this.fileName = fileName; this.validationMessages = validationMessages; } - public Set getValidationMessages() { + public List getValidationMessages() { return validationMessages; } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ValidationMessages.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ValidationErrors.java similarity index 54% rename from elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ValidationMessages.java rename to elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ValidationErrors.java index 783c03cdab..397b742402 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ValidationMessages.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/ValidationErrors.java @@ -5,19 +5,18 @@ */ package com.yahoo.elide.modelconfig; -import com.networknt.schema.ValidationMessage; +import com.networknt.schema.Error; import java.util.List; -import java.util.Set; -public class ValidationMessages { +public class ValidationErrors { private static final String NEWLINE = System.lineSeparator(); - public static String toString(Set results) { - if (results == null || results.isEmpty()) { + public static String toString(List errors) { + if (errors == null || errors.isEmpty()) { return null; } - List list = results.stream().map(message -> message.getMessage()).toList(); + List list = errors.stream().map(error -> error.toString()).toList(); return NEWLINE + String.join(NEWLINE, list); } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/jsonformats/ElideRSQLFilterFormat.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/jsonformats/ElideRSQLFilterFormat.java index bf89606459..e04e5a0f8d 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/jsonformats/ElideRSQLFilterFormat.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/jsonformats/ElideRSQLFilterFormat.java @@ -8,7 +8,7 @@ import static com.yahoo.elide.core.filter.dialect.RSQLFilterDialect.getDefaultOperatorsWithIsnull; import com.networknt.schema.ExecutionContext; -import com.networknt.schema.Format; +import com.networknt.schema.format.Format; import cz.jirutka.rsql.parser.RSQLParser; import cz.jirutka.rsql.parser.RSQLParserException; @@ -22,7 +22,7 @@ public class ElideRSQLFilterFormat implements Format { public static final String NAME = "elideRSQLFilter"; - public static final String ERROR_MESSAGE_DESCRIPTION = "{0}: does not match the elideRSQLFilter pattern " + public static final String ERROR_MESSAGE_DESCRIPTION = "does not match the elideRSQLFilter pattern " + "is not a valid RSQL filter expression." + " Please visit page https://elide.io/pages/guide/v5/11-graphql.html#operators for samples."; diff --git a/elide-model-config/src/main/resources/elideDBConfigSchema.json b/elide-model-config/src/main/resources/elideDBConfigSchema.json index ce3d6a7d46..902b8c3899 100644 --- a/elide-model-config/src/main/resources/elideDBConfigSchema.json +++ b/elide-model-config/src/main/resources/elideDBConfigSchema.json @@ -5,21 +5,21 @@ "type": "string", "pattern": "^[A-Za-z][0-9A-Za-z_]*$", "errorMessage": { - "pattern": "{0}: does not match the elideName pattern must start with an alphabetic character and can include alphabets, numbers and ''_'' only." + "pattern": "does not match the elideName pattern must start with an alphabetic character and can include alphabets, numbers and '_' only." } }, "elideJdbcUrl" : { "type": "string", "pattern": "^(jdbc:).*$", "errorMessage": { - "pattern": "{0}: does not match the elideJdbcUrl pattern must start with ''jdbc:''." + "pattern": "does not match the elideJdbcUrl pattern must start with 'jdbc:'." } }, "javaClassName" : { "type": "string", "pattern": "^(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)+(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*$", "errorMessage": { - "pattern": "{0}: does not match the javaClassName pattern is not a valid Java class name." + "pattern": "does not match the javaClassName pattern is not a valid Java class name." } } }, diff --git a/elide-model-config/src/main/resources/elideNamespaceConfigSchema.json b/elide-model-config/src/main/resources/elideNamespaceConfigSchema.json index ac859c0551..cd9598014f 100644 --- a/elide-model-config/src/main/resources/elideNamespaceConfigSchema.json +++ b/elide-model-config/src/main/resources/elideNamespaceConfigSchema.json @@ -5,7 +5,7 @@ "type": "string", "pattern": "^default$|^(?!(?i)default$)^[A-Za-z][0-9A-Za-z_]*$", "errorMessage": { - "pattern": "{0}: does not match the elideNamespaceName pattern must start with an alphabetic character and can include alphabets, numbers and ''_'' only and must not clash with the ''default'' namespace." + "pattern": "does not match the elideNamespaceName pattern must start with an alphabetic character and can include alphabets, numbers and '_' only and must not clash with the 'default' namespace." } } }, diff --git a/elide-model-config/src/main/resources/elideSecuritySchema.json b/elide-model-config/src/main/resources/elideSecuritySchema.json index d64c4f9f5f..f3b98e13c6 100644 --- a/elide-model-config/src/main/resources/elideSecuritySchema.json +++ b/elide-model-config/src/main/resources/elideSecuritySchema.json @@ -5,7 +5,7 @@ "type": "string", "pattern": "^[A-Za-z][0-9A-Za-z. ]*$", "errorMessage": { - "pattern": "{0}: does not match the elideRole pattern must start with an alphabetic character and can include alphabets, numbers, spaces and ''.'' only." + "pattern": "does not match the elideRole pattern must start with an alphabetic character and can include alphabets, numbers, spaces and '.' only." } } }, diff --git a/elide-model-config/src/main/resources/elideTableSchema.json b/elide-model-config/src/main/resources/elideTableSchema.json index ab52b75b7f..dbce868c0a 100644 --- a/elide-model-config/src/main/resources/elideTableSchema.json +++ b/elide-model-config/src/main/resources/elideTableSchema.json @@ -5,84 +5,84 @@ "type": "string", "pattern": "^(?!(?i)grain$)^[A-Za-z][0-9A-Za-z_]*$", "errorMessage": { - "pattern": "{0}: does not match the elideArgumentName pattern must start with an alphabetic character and can include alphabets, numbers and ''_'' only and cannot be ''grain''." + "pattern": "does not match the elideArgumentName pattern must start with an alphabetic character and can include alphabets, numbers and '_' only and cannot be 'grain'." } }, "elideFieldType" : { "type": "string", "pattern": "^(?i)(Integer|Decimal|Money|Text|Coordinate|Boolean|Enum_Text|Enum_Ordinal)$", "errorMessage": { - "pattern": "{0}: does not match the elideFieldType pattern must be one of [Integer, Decimal, Money, Text, Coordinate, Boolean, Enum_Text, Enum_Ordinal]." + "pattern": "does not match the elideFieldType pattern must be one of [Integer, Decimal, Money, Text, Coordinate, Boolean, Enum_Text, Enum_Ordinal]." } }, "elideFieldName" : { "type": "string", "pattern": "^(?!(?i)(id|sql)$)^[a-z][0-9A-Za-z_]*$", "errorMessage": { - "pattern": "{0}: does not match the elideFieldName pattern must start with lower case alphabet and can include alphabets, numbers and ''_'' only and cannot be one of [id, sql]" + "pattern": "does not match the elideFieldName pattern must start with lower case alphabet and can include alphabets, numbers and '_' only and cannot be one of [id, sql]" } }, "elideName" : { "type": "string", "pattern": "^[A-Za-z][0-9A-Za-z_]*$", "errorMessage": { - "pattern": "{0}: does not match the elideName pattern must start with an alphabetic character and can include alphabets, numbers and ''_'' only." + "pattern": "does not match the elideName pattern must start with an alphabetic character and can include alphabets, numbers and '_' only." } }, "elideNamespaceName" : { "type": "string", "pattern": "^default$|^(?!(?i)default$)^[A-Za-z][0-9A-Za-z_]*$", "errorMessage": { - "pattern": "{0}: does not match the elideNamespaceName pattern must start with an alphabetic character and can include alphabets, numbers and ''_'' only and must not clash with the ''default'' namespace." + "pattern": "does not match the elideNamespaceName pattern must start with an alphabetic character and can include alphabets, numbers and '_' only and must not clash with the 'default' namespace." } }, "elideJoinType" : { "type": "string", "pattern": "^(?i)(left|inner|full|cross)$", "errorMessage": { - "pattern": "{0}: does not match the elideJoinType pattern must be one of [left, inner, full, cross]." + "pattern": "does not match the elideJoinType pattern must be one of [left, inner, full, cross]." } }, "elideJoinKind" : { "type": "string", "pattern": "^(?i)(ToOne|ToMany)$", "errorMessage": { - "pattern": "{0}: does not match the elideJoinKind pattern must be one of [ToOne, ToMany]." + "pattern": "does not match the elideJoinKind pattern must be one of [ToOne, ToMany]." } }, "javaClassName" : { "type": "string", "pattern": "^(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)+(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*$", "errorMessage": { - "pattern": "{0}: does not match the javaClassName pattern is not a valid Java class name." + "pattern": "does not match the javaClassName pattern is not a valid Java class name." } }, "javaClassNameWithExt" : { "type": "string", "pattern": "^(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)+(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*class$", "errorMessage": { - "pattern": "{0}: does not match the javaClassNameWithExt pattern is not a valid Java class name with .class extension." + "pattern": "does not match the javaClassNameWithExt pattern is not a valid Java class name with .class extension." } }, "elideCardinality" : { "type": "string", "pattern": "^(?i)(Tiny|Small|Medium|Large|Huge)$", "errorMessage": { - "pattern": "{0}: does not match the elideCardinality pattern must be one of [Tiny, Small, Medium, Large, Huge]." + "pattern": "does not match the elideCardinality pattern must be one of [Tiny, Small, Medium, Large, Huge]." } }, "elideTimeFieldType" : { "type": "string", "pattern": "^(?i)(Time)$", "errorMessage": { - "pattern": "{0}: does not match the elideTimeFieldType pattern must be [Time] for any time dimension." + "pattern": "does not match the elideTimeFieldType pattern must be [Time] for any time dimension." } }, "elideGrainType" : { "type": "string", "pattern": "^(?i)(Second|Minute|Hour|Day|IsoWeek|Week|Month|Quarter|Year)$", "errorMessage": { - "pattern": "{0}: does not match the elideGrainType pattern must be one of [Second, Minute, Hour, Day, IsoWeek, Week, Month, Quarter, Year]." + "pattern": "does not match the elideGrainType pattern must be one of [Second, Minute, Hour, Day, IsoWeek, Week, Month, Quarter, Year]." } }, "argument" : { @@ -140,7 +140,7 @@ }, "additionalProperties": false, "errorMessage": { - "not": "{0}: tableSource and values cannot both be defined for an argument. Choose One or None." + "not": "tableSource and values cannot both be defined for an argument. Choose One or None." } }, "join": { @@ -448,7 +448,7 @@ ] }, "errorMessage": { - "not": "{0}: tableSource and values cannot both be defined for a dimension. Choose One or None." + "not": "tableSource and values cannot both be defined for a dimension. Choose One or None." } }, "timeDimension": { diff --git a/pom.xml b/pom.xml index 975db87292..f16e26e344 100644 --- a/pom.xml +++ b/pom.xml @@ -122,7 +122,7 @@ 7.4.0 1.5.3 3.0.0 - 1.5.6 + 3.0.1 6.0.2 1.5.32 1.18.44 From dfb062b5c7ecb603c28282041fa874a275bf2298 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sat, 28 Mar 2026 10:58:58 +0800 Subject: [PATCH 09/12] Upgrade to Jackson 3 --- elide-async/pom.xml | 7 +- .../async/export/formatter/Attributes.java | 12 +- .../export/formatter/CsvExportFormatter.java | 2 +- .../export/formatter/CsvResourceWriter.java | 19 +- .../export/formatter/JsonExportFormatter.java | 2 +- .../export/formatter/JsonResourceWriter.java | 8 +- .../export/formatter/XlsxExportFormatter.java | 2 +- .../export/formatter/XlsxResourceWriter.java | 9 +- .../GraphQLTableExportOperation.java | 5 +- .../formatter/CsvExportFormatterTest.java | 2 +- .../formatter/CsvResourceWriterTest.java | 13 +- .../formatter/JsonExportFormatterTest.java | 2 +- .../formatter/XlsxResourceWriterTest.java | 4 +- elide-core/pom.xml | 2 +- .../src/main/java/com/yahoo/elide/Elide.java | 14 +- .../java/com/yahoo/elide/ElideMapper.java | 27 +- .../java/com/yahoo/elide/ElideSettings.java | 22 +- .../yahoo/elide/core/SerdeRegistrations.java | 31 +- .../JsonApiAtomicOperationsException.java | 2 +- .../JsonPatchExtensionException.java | 2 +- .../elide/core/utils/coerce/CoerceUtil.java | 5 +- .../coerce/converters/FromMapConverter.java | 2 +- .../DefaultJsonApiExceptionHandler.java | 21 +- .../java/com/yahoo/elide/jsonapi/JsonApi.java | 8 +- .../yahoo/elide/jsonapi/JsonApiMapper.java | 45 ++- .../extensions/JsonApiAtomicOperations.java | 31 +- .../JsonApiAtomicOperationsMapper.java | 21 +- .../jsonapi/extensions/JsonApiJsonPatch.java | 28 +- .../extensions/JsonApiJsonPatchMapper.java | 26 +- .../com/yahoo/elide/jsonapi/models/Data.java | 7 +- .../elide/jsonapi/models/JsonApiDocument.java | 10 + .../com/yahoo/elide/jsonapi/models/Meta.java | 2 +- .../yahoo/elide/jsonapi/models/Operation.java | 4 +- .../com/yahoo/elide/jsonapi/models/Patch.java | 4 +- .../yahoo/elide/jsonapi/models/Resource.java | 3 +- .../parser/state/CollectionTerminalState.java | 4 +- .../parser/state/RecordTerminalState.java | 2 +- .../serialization/DataDeserializer.java | 30 +- .../jsonapi/serialization/DataSerializer.java | 18 +- .../serialization/JsonApiErrorSerializer.java | 30 +- .../jsonapi/serialization/JsonApiModule.java | 4 +- .../serialization/JsonApiSetSerializer.java | 14 +- .../jsonapi/serialization/KeySerializer.java | 14 +- .../serialization/MetaDeserializer.java | 18 +- .../java/com/yahoo/elide/ElideMapperTest.java | 3 +- .../core/PersistenceResourceTestSetup.java | 9 +- .../core/exceptions/ExceptionMapperTest.java | 17 +- .../elide/core/lifecycle/LifeCycleTest.java | 9 +- .../DefaultJsonApiErrorMapperTest.java | 17 +- .../DefaultJsonApiExceptionHandlerTest.java | 12 +- .../com/yahoo/elide/jsonapi/JsonApiTest.java | 35 +- .../JsonApiAtomicOperationsMapperTest.java | 24 +- .../JsonApiAtomicOperationsTest.java | 49 +-- .../jsonapi/models/JsonApiErrorTest.java | 18 +- .../jsonapi/models/JsonApiErrorsTest.java | 13 +- .../elide/jsonapi/models/OperationTest.java | 15 +- .../elide/jsonapi/models/OperationsTest.java | 7 +- .../yahoo/elide/jsonapi/models/PatchTest.java | 13 +- .../JsonApiErrorSerializerTest.java | 30 +- .../serialization/MetaDeserializerTest.java | 7 +- .../aggregation/core/Slf4jQueryLogger.java | 8 +- .../AggregationDataStoreIntegrationTest.java | 7 +- elide-datastore/elide-datastore-jms/pom.xml | 4 +- .../elide/datastores/jms/JMSDataStore.java | 18 +- .../jms/JMSDataStoreTransaction.java | 12 +- .../datastores/jms/MessageDeserializer.java | 17 +- .../SubscriptionWebSocketConfigurator.java | 16 +- .../SubscriptionWebSocketTestClient.java | 10 +- .../datastores/jms/JMSDataStoreTest.java | 6 +- .../jms/MessageDeserializerTest.java | 5 +- .../datastores/jms/MessageIterableTest.java | 10 +- .../elide/datastores/jms/TestBinder.java | 2 +- .../java/example/hooks/ChatBotCreateHook.java | 6 +- .../jpa/usertypes/JsonConverter.java | 11 +- .../datastores/jpa/usertypes/JsonType.java | 10 +- elide-datastore/elide-datastore-jpql/pom.xml | 2 +- .../jpql/query/JacksonCursorEncoder.java | 17 +- .../AbstractHibernateTestService.java | 4 +- .../elide-datastore-multiplex/pom.xml | 2 +- elide-datastore/elide-datastore-noop/pom.xml | 4 +- .../datastores/noop/NoopTransactionTest.java | 2 +- .../elide-datastore-search/pom.xml | 2 +- elide-graphql/pom.xml | 2 +- .../DefaultGraphQLExceptionHandler.java | 15 +- .../com/yahoo/elide/graphql/DeferredId.java | 17 +- .../elide/graphql/GraphQLErrorContext.java | 2 +- .../com/yahoo/elide/graphql/QueryRunner.java | 33 +- .../elide/graphql/models/GraphQLError.java | 4 +- .../elide/graphql/parser/QueryParser.java | 15 +- .../ExecutionResultDeserializer.java | 21 +- .../ExecutionResultSerializer.java | 24 +- .../GraphQLErrorDeserializer.java | 23 +- .../serialization/GraphQLErrorSerializer.java | 28 +- .../graphql/serialization/GraphQLModule.java | 6 +- .../hooks/NotifyTopicLifeCycleHook.java | 14 +- .../hooks/SubscriptionScanner.java | 20 +- .../GraphQLSubscriptionModule.java | 6 +- .../SubscriptionBeanSerializerModifier.java | 16 +- .../websocket/RequestHandler.java | 24 +- .../websocket/SessionHandler.java | 18 +- .../websocket/protocol/Error.java | 3 +- .../websocket/protocol/Next.java | 4 +- .../DefaultGraphQLErrorMapperTest.java | 26 +- .../DefaultGraphQLExceptionHandlerTest.java | 12 +- .../ExecutionResultDeserializerTest.java | 16 +- .../elide/graphql/GraphQLEndpointTest.java | 17 +- .../graphql/GraphQLErrorDeserializerTest.java | 12 +- .../PersistentResourceFetcherTest.java | 11 +- .../yahoo/elide/graphql/QueryRunnerTest.java | 7 +- .../graphql/models/GraphQLErrorTest.java | 13 +- .../graphql/models/GraphQLErrorsTest.java | 5 +- .../serialization/GraphQLModuleTest.java | 14 +- .../SubscriptionDataFetcherTest.java | 6 +- .../SubscriptionWebSocketTest.java | 6 +- .../hooks/NotifyTopicLifeCycleHookTest.java | 5 +- .../hooks/SubscriptionScannerTest.java | 5 +- ...ubscriptionBeanSerializerModifierTest.java | 12 +- .../src/test/java/example/Price.java | 19 +- .../async/integration/tests/AsyncApiIT.java | 6 +- .../async/integration/tests/AsyncIT.java | 5 +- .../integration/tests/TableExportIT.java | 5 +- .../yahoo/elide/core/utils/JsonParser.java | 7 +- .../EncodedErrorObjectsIT.java | 6 + .../VerboseEncodedErrorResponsesIT.java | 7 + .../errorObjectsTests/ErrorObjectsIT.java | 4 +- .../GraphQLIntegrationTest.java | 8 +- .../elide/initialization/IntegrationTest.java | 13 +- .../initialization/StandardTestBinder.java | 14 +- .../VerboseErrorResponsesTestBinder.java | 13 +- .../com/yahoo/elide/tests/BookAuthorIT.java | 2 +- .../com/yahoo/elide/tests/DataStoreIT.java | 32 +- .../java/com/yahoo/elide/tests/FilterIT.java | 298 +++++++++--------- .../java/com/yahoo/elide/tests/GraphQLIT.java | 9 +- .../com/yahoo/elide/tests/ResourceIT.java | 4 +- .../java/com/yahoo/elide/tests/SortingIT.java | 33 +- .../com/yahoo/elide/tests/TransferableIT.java | 17 +- .../src/test/java/example/Address.java | 21 +- .../example/models/targetEntity/Manager.java | 2 +- elide-model-config/pom.xml | 4 +- .../modelconfig/DynamicConfigHelpers.java | 9 +- .../elide/modelconfig/model/Argument.java | 9 +- .../elide/modelconfig/model/DBConfig.java | 4 +- .../elide/modelconfig/model/Dimension.java | 10 +- .../modelconfig/model/ElideDBConfig.java | 2 +- .../model/ElideNamespaceConfig.java | 2 +- .../model/ElideSecurityConfig.java | 2 +- .../modelconfig/model/ElideTableConfig.java | 2 +- .../yahoo/elide/modelconfig/model/Grain.java | 7 + .../yahoo/elide/modelconfig/model/Join.java | 9 + .../elide/modelconfig/model/Measure.java | 9 +- .../modelconfig/model/NamespaceConfig.java | 7 + .../yahoo/elide/modelconfig/model/Table.java | 8 +- .../elide/modelconfig/model/TableSource.java | 10 +- .../validator/DynamicConfigValidatorTest.java | 14 +- .../spring/config/ElideAutoConfiguration.java | 19 +- .../ElideSubscriptionConfiguration.java | 2 +- ...lideSubscriptionScanningConfiguration.java | 2 +- .../spring/jackson/ObjectMapperBuilder.java | 4 +- .../models/jpa/usertypes/JsonConverter.java | 9 +- .../models/jpa/usertypes/JsonType.java | 10 +- .../java/example/tests/ControllerTest.java | 11 +- .../example/tests/IntegrationTestSetup.java | 4 +- .../java/example/tests/SubscriptionTest.java | 8 - .../tests/Update200StatusTestSetup.java | 4 +- elide-standalone/pom.xml | 12 +- .../elide/standalone/ElideStandalone.java | 8 +- .../config/ElideResourceConfig.java | 7 +- .../config/ElideStandaloneSettings.java | 25 +- .../ElideStandaloneSubscriptionSettings.java | 4 +- .../java/example/ElideStandaloneTest.java | 2 +- elide-swagger/pom.xml | 7 +- .../converter/JsonApiModelResolver.java | 3 +- .../elide/swagger/OpenApiBuilderTest.java | 15 +- .../com/yahoo/elide/swagger/OpenApiIT.java | 8 +- .../models/media/AtomicOperationTest.java | 20 +- elide-test/pom.xml | 2 +- .../test/graphql/EnumFieldSerializer.java | 12 +- .../yahoo/elide/test/graphql/GraphQLDSL.java | 42 +-- .../test/graphql/VariableFieldSerializer.java | 12 +- pom.xml | 10 +- 180 files changed, 1229 insertions(+), 1119 deletions(-) diff --git a/elide-async/pom.xml b/elide-async/pom.xml index ab089006c1..654612ca4a 100644 --- a/elide-async/pom.xml +++ b/elide-async/pom.xml @@ -78,14 +78,9 @@ json-path - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - test - org.apache.poi poi-ooxml diff --git a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/Attributes.java b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/Attributes.java index e6ad09a6d8..aa65c2b518 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/Attributes.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/Attributes.java @@ -8,12 +8,12 @@ import com.yahoo.elide.core.PersistentResource; import com.yahoo.elide.core.request.Attribute; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ser.PropertyWriter; - import org.apache.commons.lang3.StringUtils; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ser.PropertyWriter; + import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -62,12 +62,12 @@ public static Map getProperties(ObjectMapper objectMapper, public static Map getProperties(ObjectMapper objectMapper, Class propertyClass) { Map result = new LinkedHashMap<>(); try { - for (Iterator iterator = objectMapper.getSerializerProviderInstance() + for (Iterator iterator = objectMapper._serializationContext() .findValueSerializer(propertyClass).properties(); iterator.hasNext();) { PropertyWriter property = iterator.next(); result.put(property.getName(), getProperties(objectMapper, property.getType().getRawClass())); } - } catch (JsonMappingException e) { + } catch (JacksonException e) { // Do nothing } if (result.isEmpty()) { diff --git a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvExportFormatter.java b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvExportFormatter.java index b3c41cf04e..bf378ff884 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvExportFormatter.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvExportFormatter.java @@ -9,7 +9,7 @@ import com.yahoo.elide.async.models.TableExport; import com.yahoo.elide.core.request.EntityProjection; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import java.io.OutputStream; diff --git a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvResourceWriter.java b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvResourceWriter.java index 46cc2713d9..d991e8204b 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvResourceWriter.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/CsvResourceWriter.java @@ -10,15 +10,17 @@ import com.yahoo.elide.core.request.EntityProjection; import com.yahoo.elide.core.utils.coerce.CoerceUtil; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.apache.commons.lang3.StringUtils; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; + import java.io.IOException; import java.io.OutputStream; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -64,9 +66,12 @@ public CsvResourceWriter(OutputStream outputStream, ObjectMapper objectMapper, b EntityProjection entityProjection) { super(outputStream); this.writeHeader = writeHeader; - this.objectMapper = objectMapper; + // Keep the declaration order + this.objectMapper = objectMapper.rebuild().configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false) + .build(); this.entityProjection = entityProjection; - this.headers = entityProjection != null ? Attributes.getHeaders(objectMapper, entityProjection.getAttributes()) + this.headers = entityProjection != null + ? Attributes.getHeaders(this.objectMapper, entityProjection.getAttributes()) : Collections.emptyList(); } @@ -138,8 +143,8 @@ protected String generateHeader(EntityProjection projection) { return ""; } - Map attributes = projection.getAttributes().stream() - .collect(Collectors.toMap(Attribute::getName, Function.identity())); + Map attributes = projection.getAttributes().stream().collect(Collectors.toMap( + Attribute::getName, Function.identity(), (existing, replacement) -> existing, LinkedHashMap::new)); String result = headers.stream().map(header -> { String headerValue = getHeader(header, attributes); return quote(headerValue); diff --git a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonExportFormatter.java b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonExportFormatter.java index b8ac02408d..6f8a03f55d 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonExportFormatter.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonExportFormatter.java @@ -9,7 +9,7 @@ import com.yahoo.elide.async.models.TableExport; import com.yahoo.elide.core.request.EntityProjection; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import java.io.OutputStream; diff --git a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonResourceWriter.java b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonResourceWriter.java index 4df86fad62..7cb16f8d57 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonResourceWriter.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/JsonResourceWriter.java @@ -7,11 +7,11 @@ import com.yahoo.elide.core.PersistentResource; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; + import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; @@ -79,7 +79,7 @@ protected String convert(ObjectMapper mapper, PersistentResource resource) { protected String convert(ObjectMapper mapper, Map attributes) { try { return mapper.writeValueAsString(attributes); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error("Exception when converting to JSON {}", e.getMessage()); throw new IllegalStateException(e); } diff --git a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxExportFormatter.java b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxExportFormatter.java index bc62330572..aa9cf3c1c8 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxExportFormatter.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxExportFormatter.java @@ -9,7 +9,7 @@ import com.yahoo.elide.async.models.TableExport; import com.yahoo.elide.core.request.EntityProjection; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import java.io.OutputStream; diff --git a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriter.java b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriter.java index df644bd1a2..c12b747233 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriter.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriter.java @@ -11,8 +11,6 @@ import com.yahoo.elide.core.utils.ObjectProperties; import com.yahoo.elide.core.utils.coerce.CoerceUtil; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CreationHelper; @@ -25,6 +23,9 @@ import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; + import java.io.IOException; import java.io.OutputStream; import java.time.Instant; @@ -78,7 +79,9 @@ public XlsxResourceWriter(OutputStream outputStream, ObjectMapper objectMapper, // Rows exceeding the row access window size are flushed to disk this.workbook = new SXSSFWorkbook(rowAccessWindowSize); this.sheet = this.workbook.createSheet(); - this.headers = entityProjection != null ? Attributes.getHeaders(objectMapper, entityProjection.getAttributes()) + ObjectMapper notSorted = objectMapper.rebuild().configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false) + .build(); + this.headers = entityProjection != null ? Attributes.getHeaders(notSorted, entityProjection.getAttributes()) : Collections.emptyList(); this.attributes = entityProjection != null && entityProjection.getAttributes() != null ? entityProjection .getAttributes().stream().collect(Collectors.toMap(Attribute::getName, Function.identity())) diff --git a/elide-async/src/main/java/com/yahoo/elide/async/operation/GraphQLTableExportOperation.java b/elide-async/src/main/java/com/yahoo/elide/async/operation/GraphQLTableExportOperation.java index 776a134a98..6cb67e951a 100644 --- a/elide-async/src/main/java/com/yahoo/elide/async/operation/GraphQLTableExportOperation.java +++ b/elide-async/src/main/java/com/yahoo/elide/async/operation/GraphQLTableExportOperation.java @@ -23,10 +23,9 @@ import com.yahoo.elide.graphql.QueryRunner; import com.yahoo.elide.graphql.parser.GraphQLEntityProjectionMaker; import com.yahoo.elide.graphql.parser.GraphQLProjectionInfo; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - import lombok.extern.slf4j.Slf4j; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.Arrays; diff --git a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvExportFormatterTest.java b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvExportFormatterTest.java index 09a0de346e..0a13208caf 100644 --- a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvExportFormatterTest.java +++ b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvExportFormatterTest.java @@ -47,7 +47,7 @@ import java.util.function.Consumer; public class CsvExportFormatterTest { - public static final String FORMAT = "yyyy-MM-dd'T'HH:mm'Z'"; + public static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; private static final FastDateFormat FORMATTER = FastDateFormat.getInstance(FORMAT, TimeZone.getTimeZone("GMT")); private HashMapDataStore dataStore; private Elide elide; diff --git a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvResourceWriterTest.java b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvResourceWriterTest.java index c24201d3d8..ac9d2681f5 100644 --- a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvResourceWriterTest.java +++ b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/CsvResourceWriterTest.java @@ -15,10 +15,6 @@ import com.yahoo.elide.core.RequestScope; import com.yahoo.elide.core.request.Attribute; import com.yahoo.elide.core.request.EntityProjection; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.json.JsonMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.junit.jupiter.api.Test; @@ -28,6 +24,10 @@ import jakarta.persistence.Id; import lombok.Data; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.cfg.DateTimeFeature; +import tools.jackson.databind.json.JsonMapper; + import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -149,7 +149,7 @@ void set() throws IOException { """; assertEquals(header, results.get(0)); String row = """ - "name","a;b;c","VALUE1","1.0","1.0","1","1","2023-12-25T12:30:30.000000010Z","2023-12-25T12:30:30.000+00:00","2023-12-25T12:30:30.00000001","2023-12-25","2023-12-25T12:30:30.00000001Z","2023-12-25T12:30:30.00000001Z"\ + "name","a;b;c","VALUE1","1.0","1.0","1","1","2023-12-25T12:30:30.000000010Z","2023-12-25T12:30:30.000Z","2023-12-25T12:30:30.00000001","2023-12-25","2023-12-25T12:30:30.00000001Z","2023-12-25T12:30:30.00000001Z"\ """; assertEquals(row, results.get(1)); } @@ -166,8 +166,7 @@ List read(byte[] data) { byte[] process(EntityProjection entityProjection, ResourceWriterProcessor processor) { ObjectMapper objectMapper = JsonMapper.builder() - .addModule(new JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) + .disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) .build(); try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ResourceWriter writer = new CsvResourceWriter(outputStream, objectMapper, true, entityProjection)) { diff --git a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/JsonExportFormatterTest.java b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/JsonExportFormatterTest.java index 851263b880..f28a7fbf98 100644 --- a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/JsonExportFormatterTest.java +++ b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/JsonExportFormatterTest.java @@ -45,7 +45,7 @@ import java.util.function.Consumer; public class JsonExportFormatterTest { - public static final String FORMAT = "yyyy-MM-dd'T'HH:mm'Z'"; + public static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; private static final FastDateFormat FORMATTER = FastDateFormat.getInstance(FORMAT, TimeZone.getTimeZone("GMT")); private HashMapDataStore dataStore; private Elide elide; diff --git a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriterTest.java b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriterTest.java index d3132bf818..312c78d203 100644 --- a/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriterTest.java +++ b/elide-async/src/test/java/com/yahoo/elide/async/export/formatter/XlsxResourceWriterTest.java @@ -16,8 +16,6 @@ import com.yahoo.elide.core.request.Attribute; import com.yahoo.elide.core.request.EntityProjection; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; import jakarta.persistence.AttributeConverter; @@ -26,6 +24,8 @@ import jakarta.persistence.Id; import lombok.Data; +import tools.jackson.databind.ObjectMapper; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/elide-core/pom.xml b/elide-core/pom.xml index 7311cf72da..84ea4dcf94 100644 --- a/elide-core/pom.xml +++ b/elide-core/pom.xml @@ -85,7 +85,7 @@ jakarta.inject-api - com.fasterxml.jackson.core + tools.jackson.core jackson-databind provided diff --git a/elide-core/src/main/java/com/yahoo/elide/Elide.java b/elide-core/src/main/java/com/yahoo/elide/Elide.java index c49f3db5a0..3359059c14 100644 --- a/elide-core/src/main/java/com/yahoo/elide/Elide.java +++ b/elide-core/src/main/java/com/yahoo/elide/Elide.java @@ -15,13 +15,13 @@ import com.yahoo.elide.core.utils.coerce.CoerceUtil; import com.yahoo.elide.core.utils.coerce.converters.ElideTypeConverter; import com.yahoo.elide.core.utils.coerce.converters.Serde; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import java.util.Set; +import tools.jackson.databind.ObjectMapper; +import java.util.Set; /** * Elide. @@ -31,7 +31,6 @@ public class Elide { @Getter private final ElideSettings elideSettings; @Getter private final AuditLogger auditLogger; @Getter private final DataStore dataStore; - @Getter private final ObjectMapper objectMapper; @Getter private final TransactionRegistry transactionRegistry; @Getter private final ClassScanner scanner; private boolean initialized = false; @@ -78,7 +77,6 @@ public Elide( this.scanner = scanner; this.auditLogger = elideSettings.getAuditLogger(); this.dataStore = new InMemoryDataStore(elideSettings.getDataStore()); - this.objectMapper = elideSettings.getObjectMapper(); this.transactionRegistry = transactionRegistry; if (doScans) { @@ -136,7 +134,9 @@ protected void registerCustomSerde(Class type, Serde serde, Stri } protected void registerCustomSerdeInObjectMapper(Class type, Serde serde, String name) { - SerdeRegistrations.register(objectMapper, type, serde, name); + elideSettings.getElideMapper().customizeObjectMapper(builder -> { + SerdeRegistrations.register(builder, type, serde, name); + }); } protected Set> registerCustomSerdeScan() { @@ -146,4 +146,8 @@ protected Set> registerCustomSerdeScan() { public T getSettings(Class clazz) { return this.elideSettings.getSettings(clazz); } + + public ObjectMapper getObjectMapper() { + return this.elideSettings.getElideMapper().getObjectMapper(); + } } diff --git a/elide-core/src/main/java/com/yahoo/elide/ElideMapper.java b/elide-core/src/main/java/com/yahoo/elide/ElideMapper.java index f761d20512..7f84dc4b90 100644 --- a/elide-core/src/main/java/com/yahoo/elide/ElideMapper.java +++ b/elide-core/src/main/java/com/yahoo/elide/ElideMapper.java @@ -5,16 +5,29 @@ */ package com.yahoo.elide; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.cfg.MapperBuilder; -import lombok.AllArgsConstructor; -import lombok.Getter; +import java.util.function.Consumer; /** - * Used to store the singleton shared {@link ObjectMapper} instance. + * Used to store the shared {@link ObjectMapper} instance. */ -@Getter -@AllArgsConstructor public class ElideMapper { - private final ObjectMapper objectMapper; + private ObjectMapper objectMapper; + + public ElideMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + public ObjectMapper getObjectMapper() { + return objectMapper; + } + + public ElideMapper customizeObjectMapper(Consumer customizer) { + MapperBuilder builder = objectMapper.rebuild(); + customizer.accept(builder); + this.objectMapper = builder.build(); + return this; + } } diff --git a/elide-core/src/main/java/com/yahoo/elide/ElideSettings.java b/elide-core/src/main/java/com/yahoo/elide/ElideSettings.java index 537d8649ea..5451dc8abf 100644 --- a/elide-core/src/main/java/com/yahoo/elide/ElideSettings.java +++ b/elide-core/src/main/java/com/yahoo/elide/ElideSettings.java @@ -18,10 +18,12 @@ import com.yahoo.elide.core.security.executors.ActivePermissionExecutor; import com.yahoo.elide.utils.HeaderProcessor; import com.yahoo.elide.utils.Headers; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Getter; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; @@ -38,7 +40,7 @@ public class ElideSettings { private final AuditLogger auditLogger; private final DataStore dataStore; private final EntityDictionary entityDictionary; - private final ObjectMapper objectMapper; + private final ElideMapper elideMapper; private final Function permissionExecutor; private final HeaderProcessor headerProcessor; private final int maxPageSize; @@ -49,14 +51,14 @@ public class ElideSettings { private final Map, Settings> settings; public ElideSettings(AuditLogger auditLogger, DataStore dataStore, EntityDictionary entityDictionary, - ObjectMapper objectMapper, Function permissionExecutor, + ElideMapper elideMapper, Function permissionExecutor, HeaderProcessor headerProcessor, int maxPageSize, int defaultPageSize, Serdes serdes, String baseUrl, boolean verboseErrors, Map, Settings> settings) { super(); this.auditLogger = auditLogger; this.dataStore = dataStore; this.entityDictionary = entityDictionary; - this.objectMapper = objectMapper; + this.elideMapper = elideMapper; this.permissionExecutor = permissionExecutor; this.headerProcessor = headerProcessor; this.maxPageSize = maxPageSize; @@ -77,7 +79,7 @@ public ElideSettingsBuilder mutate() { .auditLogger(this.auditLogger) .dataStore(this.dataStore) .entityDictionary(this.entityDictionary) - .objectMapper(this.objectMapper) + .elideMapper(this.elideMapper) .permissionExecutor(this.permissionExecutor) .headerProcessor(this.headerProcessor) .maxPageSize(this.maxPageSize) @@ -130,7 +132,7 @@ public ElideSettings build() { Settings result = value.build(); settings.put(result.getClass(), result); }); - return new ElideSettings(this.auditLogger, this.dataStore, this.entityDictionary, this.objectMapper, + return new ElideSettings(this.auditLogger, this.dataStore, this.entityDictionary, this.elideMapper, this.permissionExecutor, this.headerProcessor, this.maxPageSize, this.defaultPageSize, this.serdes.build(), this.baseUrl, this.verboseErrors, settings); } @@ -141,7 +143,7 @@ public abstract static class ElideSettingsBuilderSupport { protected String baseUrl = ""; protected AuditLogger auditLogger = new Slf4jLogger(); protected HeaderProcessor headerProcessor = Headers::removeAuthorizationHeaders; - protected ObjectMapper objectMapper = new ObjectMapper(); + protected ElideMapper elideMapper = new ElideMapper(JsonMapper.shared()); protected int maxPageSize = Pagination.MAX_PAGE_SIZE; protected int defaultPageSize = Pagination.DEFAULT_PAGE_SIZE; protected Function permissionExecutor = ActivePermissionExecutor::new; @@ -241,11 +243,11 @@ public S headerProcessor(HeaderProcessor headerProcessor) { /** * Sets the Jackson {@link ObjectMapper} for serialization and deserialization. * - * @param objectMapper the object mapper + * @param elideMapper the object mapper * @return the builder */ - public S objectMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; + public S elideMapper(ElideMapper elideMapper) { + this.elideMapper = elideMapper; return self(); } diff --git a/elide-core/src/main/java/com/yahoo/elide/core/SerdeRegistrations.java b/elide-core/src/main/java/com/yahoo/elide/core/SerdeRegistrations.java index 54b65fa76d..de328ee16c 100644 --- a/elide-core/src/main/java/com/yahoo/elide/core/SerdeRegistrations.java +++ b/elide-core/src/main/java/com/yahoo/elide/core/SerdeRegistrations.java @@ -7,14 +7,12 @@ import com.yahoo.elide.core.utils.coerce.converters.Serde; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.module.SimpleModule; - -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; +import tools.jackson.databind.cfg.MapperBuilder; +import tools.jackson.databind.module.SimpleModule; /** * Methods for operating on a {@link Serde}. @@ -25,12 +23,12 @@ public class SerdeRegistrations { * * @param The serialized type * @param The deserialized type - * @param objectMapper the object mapper to register with + * @param builder the object mapper to register with * @param type the deserialized type * @param serde the serde */ - public static void register(ObjectMapper objectMapper, Class type, Serde serde) { - register(objectMapper, type, serde, type.getSimpleName()); + public static void register(MapperBuilder builder, Class type, Serde serde) { + register(builder, type, serde, type.getSimpleName()); } /** @@ -38,18 +36,17 @@ public static void register(ObjectMapper objectMapper, Class type, Ser * * @param The serialized type * @param The deserialized type - * @param objectMapper the object mapper to register with + * @param builder the object mapper to register with * @param type the deserialized type * @param serde the serde * @param name the name to register with */ - public static void register(ObjectMapper objectMapper, Class type, Serde serde, + public static void register(MapperBuilder builder, Class type, Serde serde, String name) { - objectMapper.registerModule(new SimpleModule(name).addSerializer(type, new JsonSerializer() { + builder.addModule(new SimpleModule(name).addSerializer(type, new ValueSerializer() { @Override - public void serialize(T value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) - throws IOException, JsonProcessingException { - jsonGenerator.writeObject(serde.serialize(value)); + public void serialize(T value, JsonGenerator jsonGenerator, SerializationContext serializationContext) { + jsonGenerator.writePOJO(serde.serialize(value)); } })); } diff --git a/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonApiAtomicOperationsException.java b/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonApiAtomicOperationsException.java index 7de085f838..eafa9db58f 100644 --- a/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonApiAtomicOperationsException.java +++ b/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonApiAtomicOperationsException.java @@ -7,7 +7,7 @@ import com.yahoo.elide.ElideErrorResponse; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; /** * Exception describing error caused from JSON API Atomic Extension request. diff --git a/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonPatchExtensionException.java b/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonPatchExtensionException.java index 3f45bbcdd1..1eb44b6219 100644 --- a/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonPatchExtensionException.java +++ b/elide-core/src/main/java/com/yahoo/elide/core/exceptions/JsonPatchExtensionException.java @@ -7,7 +7,7 @@ import com.yahoo.elide.ElideErrorResponse; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; /** * Exception describing error caused from Json Patch Extension request. diff --git a/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/CoerceUtil.java b/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/CoerceUtil.java index 673abe155f..7d314d51ee 100644 --- a/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/CoerceUtil.java +++ b/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/CoerceUtil.java @@ -15,6 +15,7 @@ import com.yahoo.elide.core.utils.coerce.converters.Serde; import com.yahoo.elide.core.utils.coerce.converters.ToEnumConverter; import com.yahoo.elide.core.utils.coerce.converters.ToUUIDConverter; + import com.google.common.base.Preconditions; import com.google.common.collect.MapMaker; import org.apache.commons.beanutils.BeanUtilsBean; @@ -22,6 +23,8 @@ import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.Converter; +import tools.jackson.core.JacksonException; + import java.lang.reflect.Array; import java.util.Collections; import java.util.LinkedHashMap; @@ -71,7 +74,7 @@ public static T coerce(Object value, Class cls) { try { return (T) ConvertUtils.convert(value, cls); - } catch (ConversionException | InvalidAttributeException | IllegalArgumentException e) { + } catch (ConversionException | InvalidAttributeException | IllegalArgumentException | JacksonException e) { throw new InvalidValueException(value, e.getMessage()); } } diff --git a/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/converters/FromMapConverter.java b/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/converters/FromMapConverter.java index 095c996cf4..825d1d81f5 100644 --- a/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/converters/FromMapConverter.java +++ b/elide-core/src/main/java/com/yahoo/elide/core/utils/coerce/converters/FromMapConverter.java @@ -5,8 +5,8 @@ */ package com.yahoo.elide.core.utils.coerce.converters; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.beanutils.Converter; +import tools.jackson.databind.ObjectMapper; /** * Uses Jackson to Convert from Map to target object. diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandler.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandler.java index f853a92eb1..8968b67d00 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandler.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandler.java @@ -22,14 +22,13 @@ import com.yahoo.elide.core.exceptions.TransactionException; import com.yahoo.elide.jsonapi.models.JsonApiErrors; -import com.fasterxml.jackson.core.JacksonException; - import org.antlr.v4.runtime.misc.ParseCancellationException; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; import java.io.IOException; import java.io.UncheckedIOException; @@ -55,6 +54,15 @@ public ElideResponse handleException(Throwable exception, JsonApiErrorContext @Override protected ElideResponse handleRuntimeException(RuntimeException exception, JsonApiErrorContext errorContext) { + if (exception instanceof JacksonException jacksonException) { + String message = (jacksonException.getLocation() != null + && jacksonException.getLocation().contentReference().getRawContent() != null) + ? exception.getMessage() //This will leak Java class info if the location isn't known. + : jacksonException.getOriginalMessage(); + + return buildResponse(new BadRequestException(message), errorContext); + } + if (exception instanceof ForbiddenAccessException e) { return buildResponse(e, errorContext); } @@ -103,15 +111,6 @@ protected ElideResponse handleRuntimeException(RuntimeException exception, Js @Override protected ElideResponse handleNonRuntimeException(Exception exception, JsonApiErrorContext errorContext) { - if (exception instanceof JacksonException jacksonException) { - String message = (jacksonException.getLocation() != null - && jacksonException.getLocation().contentReference().getRawContent() != null) - ? exception.getMessage() //This will leak Java class info if the location isn't known. - : jacksonException.getOriginalMessage(); - - return buildResponse(new BadRequestException(message), errorContext); - } - if (exception instanceof IOException) { return buildResponse(new TransactionException(exception), errorContext); } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApi.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApi.java index db72ed9696..91b76d05b5 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApi.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApi.java @@ -29,15 +29,15 @@ import com.yahoo.elide.jsonapi.parser.PatchVisitor; import com.yahoo.elide.jsonapi.parser.PostVisitor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; - import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; + import java.io.IOException; import java.util.Collections; import java.util.List; @@ -314,7 +314,7 @@ protected ElideResponse toResponse(int status, Object body) { } else { try { result = body != null ? this.mapper.writeJsonApiDocument(body) : null; - } catch (JsonProcessingException e) { + } catch (JacksonException e) { return ElideResponse.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).body(e.toString()); } } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApiMapper.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApiMapper.java index 9dffb86be0..a61f5bfa3b 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApiMapper.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/JsonApiMapper.java @@ -5,21 +5,21 @@ */ package com.yahoo.elide.jsonapi; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.jsonapi.extensions.JsonApiAtomicOperationsMapper; import com.yahoo.elide.jsonapi.extensions.JsonApiJsonPatchMapper; import com.yahoo.elide.jsonapi.models.JsonApiDocument; import com.yahoo.elide.jsonapi.serialization.JsonApiModule; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * Serializer/Deserializer for JSON API. */ public class JsonApiMapper { - protected final ObjectMapper mapper; + protected final ElideMapper elideMapper; protected final JsonApiJsonPatchMapper jsonPatchMapper; protected final JsonApiAtomicOperationsMapper atomicOperationsMapper; @@ -27,31 +27,29 @@ public class JsonApiMapper { * Instantiates a new Json Api Mapper. */ public JsonApiMapper() { - this(new ObjectMapper()); + this(new ElideMapper(JsonMapper.shared())); } /** * Instantiates a new Json Api Mapper. - * - * @param mapper Custom object mapper to use internally for serializing/deserializing */ - public JsonApiMapper(ObjectMapper mapper) { - this(mapper, new JsonApiJsonPatchMapper(mapper), new JsonApiAtomicOperationsMapper(mapper)); + public JsonApiMapper(ElideMapper elideMapper) { + this(elideMapper, new JsonApiJsonPatchMapper(elideMapper), new JsonApiAtomicOperationsMapper(elideMapper)); } /** * Instantiates a new Json Api Mapper. * - * @param mapper Custom object mapper to use internally for serializing/deserializing + * @param elideMapper Custom object mapper to use internally for serializing/deserializing * @param jsonPatchMapper the mapper for the JSON Patch extension * @param atomicOperationsMapper the mapper for the Atomic Operations extension */ - public JsonApiMapper(ObjectMapper mapper, JsonApiJsonPatchMapper jsonPatchMapper, + public JsonApiMapper(ElideMapper elideMapper, JsonApiJsonPatchMapper jsonPatchMapper, JsonApiAtomicOperationsMapper atomicOperationsMapper) { - this.mapper = mapper; - this.mapper.registerModule(new JsonApiModule()); + this.elideMapper = elideMapper; this.jsonPatchMapper = jsonPatchMapper; this.atomicOperationsMapper = atomicOperationsMapper; + this.elideMapper.customizeObjectMapper(builder -> builder.addModule(new JsonApiModule())); } /** @@ -61,7 +59,7 @@ public JsonApiMapper(ObjectMapper mapper, JsonApiJsonPatchMapper jsonPatchMapper * @return the json node */ public JsonNode toJsonObject(JsonApiDocument jsonApiDocument) { - return mapper.convertValue(jsonApiDocument, JsonNode.class); + return elideMapper.getObjectMapper().convertValue(jsonApiDocument, JsonNode.class); } /** @@ -70,10 +68,9 @@ public JsonNode toJsonObject(JsonApiDocument jsonApiDocument) { * @param doc the document * @param The type of document object so serialize * @return the string - * @throws JsonProcessingException the json processing exception */ - public String writeJsonApiDocument(T doc) throws JsonProcessingException { - return mapper.writeValueAsString(doc); + public String writeJsonApiDocument(T doc) { + return elideMapper.getObjectMapper().writeValueAsString(doc); } /** @@ -81,10 +78,9 @@ public String writeJsonApiDocument(T doc) throws JsonProcessingException { * * @param doc the doc * @return the json api document - * @throws IOException the iO exception */ - public JsonApiDocument readJsonApiDocument(String doc) throws IOException { - JsonNode node = mapper.readTree(doc); + public JsonApiDocument readJsonApiDocument(String doc) { + JsonNode node = elideMapper.getObjectMapper().readTree(doc); return readJsonApiDocument(node); } @@ -93,10 +89,9 @@ public JsonApiDocument readJsonApiDocument(String doc) throws IOException { * * @param node the node * @return the json api document - * @throws IOException the iO exception */ - public JsonApiDocument readJsonApiDocument(JsonNode node) throws IOException { - return mapper.treeToValue(node, JsonApiDocument.class); + public JsonApiDocument readJsonApiDocument(JsonNode node) { + return elideMapper.getObjectMapper().treeToValue(node, JsonApiDocument.class); } /** @@ -105,7 +100,7 @@ public JsonApiDocument readJsonApiDocument(JsonNode node) throws IOException { * @return the Jackson ObjectMapper */ public ObjectMapper getObjectMapper() { - return mapper; + return elideMapper.getObjectMapper(); } /** diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperations.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperations.java index 115512d4b9..636c8bca00 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperations.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperations.java @@ -25,18 +25,17 @@ import com.yahoo.elide.jsonapi.parser.JsonApiParser; import com.yahoo.elide.jsonapi.parser.PatchVisitor; import com.yahoo.elide.jsonapi.parser.PostVisitor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.collections4.IterableUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.owasp.encoder.Encode; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.exc.InvalidFormatException; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -94,11 +93,11 @@ public void postProcess(JsonApiAtomicOperationsRequestScope requestScope) { static { ERR_NODE_OPERATION_NOT_RUN = JsonNodeFactory.instance.objectNode(); ERR_NODE_OPERATION_NOT_RUN.set("detail", - JsonNodeFactory.instance.textNode("Operation not executed. Terminated by earlier failure.")); + JsonNodeFactory.instance.stringNode("Operation not executed. Terminated by earlier failure.")); ERR_NODE_ERR_IN_SUBSEQUENT_OPERATION = JsonNodeFactory.instance.objectNode(); ERR_NODE_ERR_IN_SUBSEQUENT_OPERATION.set("detail", - JsonNodeFactory.instance.textNode("Subsequent operation failed.")); + JsonNodeFactory.instance.stringNode("Subsequent operation failed.")); } /** @@ -127,7 +126,7 @@ public static Supplier> processAtomicOperations(DataStor } else { throw new InvalidEntityBodyException(operationsDoc); } - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException(operationsDoc); } JsonApiAtomicOperations processor = new JsonApiAtomicOperations(dataStore, actions, uri, requestScope); @@ -318,7 +317,7 @@ private Ref inferRef(JsonApiMapper mapper, Operation operation) { } } } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { // Do nothing as it will fall back on InvalidEntityBodyException } } @@ -385,7 +384,7 @@ private Supplier> handleAddOp( } catch (HttpStatusException e) { action.cause = e; throw e; - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException("Could not parse Atomic Operations extension value: " + dataValue); } } @@ -411,7 +410,7 @@ private Supplier> handleUpdateOp( // Defer relationship updating until the end PatchVisitor visitor = new PatchVisitor(new JsonApiAtomicOperationsRequestScope(path, value, requestScope)); return visitor.visit(JsonApiParser.parse(path)); - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException("Could not parse Atomic Operations extension value: " + dataValue); } } @@ -440,7 +439,7 @@ private Supplier> handleRemoveOp(String path, DeleteVisitor visitor = new DeleteVisitor( new JsonApiAtomicOperationsRequestScope(path, value, requestScope)); return visitor.visit(JsonApiParser.parse(fullPath)); - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException("Could not parse Atomic Operations extension value: " + dataValue); } } @@ -537,9 +536,9 @@ private static void clearAllExceptRelationships(Resource resource) { */ private static JsonNode toErrorNode(String detail, Integer status) { ObjectNode formattedError = JsonNodeFactory.instance.objectNode(); - formattedError.set("detail", JsonNodeFactory.instance.textNode(Encode.forHtml(detail))); + formattedError.set("detail", JsonNodeFactory.instance.stringNode(Encode.forHtml(detail))); if (status != null) { - formattedError.set("status", JsonNodeFactory.instance.textNode(status.toString())); + formattedError.set("status", JsonNodeFactory.instance.stringNode(status.toString())); } return formattedError; } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapper.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapper.java index f993701dec..1a4b114ea8 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapper.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapper.java @@ -5,14 +5,13 @@ */ package com.yahoo.elide.jsonapi.extensions; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.jsonapi.models.Data; import com.yahoo.elide.jsonapi.models.JsonApiDocument; import com.yahoo.elide.jsonapi.models.Operations; import com.yahoo.elide.jsonapi.models.Resource; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; import java.util.ArrayList; import java.util.List; @@ -21,21 +20,21 @@ * The mapper for the JSON API Atomic Operations extension. */ public class JsonApiAtomicOperationsMapper { - protected final ObjectMapper objectMapper; + protected final ElideMapper elideMapper; - public JsonApiAtomicOperationsMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; + public JsonApiAtomicOperationsMapper(ElideMapper elideMapper) { + this.elideMapper = elideMapper; } - public Operations readDoc(String operationsDoc) throws JsonProcessingException { - return this.objectMapper.readValue(operationsDoc, Operations.class); + public Operations readDoc(String operationsDoc) { + return this.elideMapper.getObjectMapper().readValue(operationsDoc, Operations.class); } - public Resource readResource(JsonNode resource) throws JsonProcessingException { - return objectMapper.treeToValue(resource, Resource.class); + public Resource readResource(JsonNode resource) { + return elideMapper.getObjectMapper().treeToValue(resource, Resource.class); } - public JsonApiDocument readData(JsonNode data) throws JsonProcessingException { + public JsonApiDocument readData(JsonNode data) { JsonApiDocument value = new JsonApiDocument(); if (data != null) { if (data.isArray()) { diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatch.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatch.java index 31c75a34d1..133822f824 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatch.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatch.java @@ -20,17 +20,19 @@ import com.yahoo.elide.jsonapi.parser.JsonApiParser; import com.yahoo.elide.jsonapi.parser.PatchVisitor; import com.yahoo.elide.jsonapi.parser.PostVisitor; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; + import org.apache.commons.collections4.IterableUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.owasp.encoder.Encode; -import java.io.IOException; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -87,11 +89,11 @@ public void postProcess(JsonApiJsonPatchRequestScope requestScope) { static { ERR_NODE_OPERATION_NOT_RUN = JsonNodeFactory.instance.objectNode(); ERR_NODE_OPERATION_NOT_RUN.set("detail", - JsonNodeFactory.instance.textNode("Operation not executed. Terminated by earlier failure.")); + JsonNodeFactory.instance.stringNode("Operation not executed. Terminated by earlier failure.")); ERR_NODE_ERR_IN_SUBSEQUENT_OPERATION = JsonNodeFactory.instance.objectNode(); ERR_NODE_ERR_IN_SUBSEQUENT_OPERATION.set("detail", - JsonNodeFactory.instance.textNode("Subsequent operation failed.")); + JsonNodeFactory.instance.stringNode("Subsequent operation failed.")); } /** @@ -110,7 +112,7 @@ public static Supplier> processJsonPatch(DataStore dataS List actions; try { actions = requestScope.getMapper().forJsonPatch().readDoc(patchDoc); - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException(patchDoc); } JsonApiJsonPatch processor = new JsonApiJsonPatch(dataStore, actions, uri, requestScope); @@ -236,7 +238,7 @@ private Supplier> handleAddOp( } catch (HttpStatusException e) { action.cause = e; throw e; - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException("Could not parse patch extension value: " + patchValue); } } @@ -262,7 +264,7 @@ private Supplier> handleReplaceOp( // Defer relationship updating until the end PatchVisitor visitor = new PatchVisitor(new JsonApiJsonPatchRequestScope(path, value, requestScope)); return visitor.visit(JsonApiParser.parse(path)); - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException("Could not parse patch extension value: " + patchVal); } } @@ -291,7 +293,7 @@ private Supplier> handleRemoveOp(String path, DeleteVisitor visitor = new DeleteVisitor( new JsonApiJsonPatchRequestScope(path, value, requestScope)); return visitor.visit(JsonApiParser.parse(fullPath)); - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidEntityBodyException("Could not parse patch extension value: " + patchValue); } } @@ -384,9 +386,9 @@ private static void clearAllExceptRelationships(Resource resource) { */ private static JsonNode toErrorNode(String detail, Integer status) { ObjectNode formattedError = JsonNodeFactory.instance.objectNode(); - formattedError.set("detail", JsonNodeFactory.instance.textNode(Encode.forHtml(detail))); + formattedError.set("detail", JsonNodeFactory.instance.stringNode(Encode.forHtml(detail))); if (status != null) { - formattedError.set("status", JsonNodeFactory.instance.textNode(status.toString())); + formattedError.set("status", JsonNodeFactory.instance.stringNode(status.toString())); } return formattedError; } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatchMapper.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatchMapper.java index 6d299f1058..fe24516f86 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatchMapper.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/extensions/JsonApiJsonPatchMapper.java @@ -5,13 +5,13 @@ */ package com.yahoo.elide.jsonapi.extensions; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.jsonapi.models.JsonApiDocument; import com.yahoo.elide.jsonapi.models.Patch; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.JsonNodeFactory; import java.io.IOException; import java.util.List; @@ -20,10 +20,10 @@ * The mapper for the JSON API JSON Patch extension. */ public class JsonApiJsonPatchMapper { - protected final ObjectMapper objectMapper; + protected final ElideMapper elideMapper; - public JsonApiJsonPatchMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; + public JsonApiJsonPatchMapper(ElideMapper elideMapper) { + this.elideMapper = elideMapper; } /** @@ -31,11 +31,10 @@ public JsonApiJsonPatchMapper(ObjectMapper objectMapper) { * * @param value the value * @return the json api document - * @throws JsonProcessingException the json processing exception */ - public JsonApiDocument readValue(JsonNode value) throws JsonProcessingException { + public JsonApiDocument readValue(JsonNode value) { JsonNode data = JsonNodeFactory.instance.objectNode().set("data", value); - return this.objectMapper.treeToValue(data, JsonApiDocument.class); + return this.elideMapper.getObjectMapper().treeToValue(data, JsonApiDocument.class); } /** @@ -45,8 +44,9 @@ public JsonApiDocument readValue(JsonNode value) throws JsonProcessingException * @return the list * @throws IOException the iO exception */ - public List readDoc(String doc) throws IOException { - return this.objectMapper.readValue(doc, - this.objectMapper.getTypeFactory().constructCollectionType(List.class, Patch.class)); + public List readDoc(String doc) { + ObjectMapper objectMapper = elideMapper.getObjectMapper(); + return objectMapper.readValue(doc, + objectMapper.getTypeFactory().constructCollectionType(List.class, Patch.class)); } } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Data.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Data.java index 454d8448e2..18f2bcf14b 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Data.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Data.java @@ -8,15 +8,16 @@ import com.yahoo.elide.core.dictionary.RelationshipType; import com.yahoo.elide.jsonapi.serialization.DataDeserializer; import com.yahoo.elide.jsonapi.serialization.DataSerializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - import lombok.ToString; import reactor.core.publisher.Flux; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; + import java.util.Collection; import java.util.Comparator; + /** * Container for different representations of top-level data in JSON API. * diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/JsonApiDocument.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/JsonApiDocument.java index 210b35404c..dfc7462c0e 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/JsonApiDocument.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/JsonApiDocument.java @@ -68,11 +68,21 @@ public void addLink(String key, String val) { this.links.put(key, val); } + public void setLinks(Map links) { + this.links.clear(); + this.links.putAll(links); + } + @JsonInclude(Include.NON_NULL) public List getIncluded() { return included.isEmpty() ? null : included; } + public void setIncluded(List included) { + this.included.clear(); + this.included.addAll(included); + } + public void addIncluded(Resource resource) { if (!includedRecs.contains(resource)) { included.add(resource); diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Meta.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Meta.java index ba26533aad..f6fe1b8549 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Meta.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Meta.java @@ -8,7 +8,7 @@ import com.yahoo.elide.jsonapi.serialization.MetaDeserializer; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonDeserialize; import java.util.Map; diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Operation.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Operation.java index 9e57ae0d86..aca9a5dac8 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Operation.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Operation.java @@ -11,8 +11,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonValue; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.exc.InvalidFormatException; import java.io.IOException; import java.util.Locale; diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Patch.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Patch.java index dbd1741d6a..ca6e2cfe03 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Patch.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Patch.java @@ -9,8 +9,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonValue; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.exc.InvalidFormatException; import java.io.IOException; import java.util.Locale; diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Resource.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Resource.java index 089c16d957..73bb060c76 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Resource.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/models/Resource.java @@ -16,12 +16,13 @@ import com.yahoo.elide.jsonapi.serialization.KeySerializer; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.builder.HashCodeBuilder; import lombok.ToString; +import tools.jackson.databind.annotation.JsonSerialize; + import java.util.Map; import java.util.Objects; diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/CollectionTerminalState.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/CollectionTerminalState.java index e20ef772d9..87b80b9755 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/CollectionTerminalState.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/CollectionTerminalState.java @@ -29,13 +29,13 @@ import com.yahoo.elide.jsonapi.models.Meta; import com.yahoo.elide.jsonapi.models.Relationship; import com.yahoo.elide.jsonapi.models.Resource; -import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.base.Preconditions; import org.apache.commons.collections4.IterableUtils; import org.apache.commons.lang3.tuple.Pair; import lombok.ToString; import reactor.core.publisher.Flux; +import tools.jackson.core.JacksonException; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; @@ -200,7 +200,7 @@ private PersistentResource createObject(JsonApiRequestScope requestScope) if (resource == null) { try { throw new InvalidEntityBodyException(mapper.writeJsonApiDocument(doc)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new InternalServerErrorException(e); } } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/RecordTerminalState.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/RecordTerminalState.java index 43df1c68bd..3e45bbaea4 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/RecordTerminalState.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/parser/state/RecordTerminalState.java @@ -14,11 +14,11 @@ import com.yahoo.elide.jsonapi.models.JsonApiDocument; import com.yahoo.elide.jsonapi.models.Relationship; import com.yahoo.elide.jsonapi.models.Resource; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.tuple.Pair; import lombok.ToString; +import tools.jackson.databind.ObjectMapper; import java.util.Map; import java.util.Optional; import java.util.Set; diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataDeserializer.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataDeserializer.java index b178dcdb41..abf76fc5f2 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataDeserializer.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataDeserializer.java @@ -7,45 +7,39 @@ import com.yahoo.elide.jsonapi.models.Data; import com.yahoo.elide.jsonapi.models.Resource; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.MappingJsonFactory; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DatabindException; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ValueDeserializer; -import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Custom deserializer for top-level data. */ -public class DataDeserializer extends JsonDeserializer> { - private static final ObjectMapper MAPPER = new MappingJsonFactory().getCodec(); - +public class DataDeserializer extends ValueDeserializer> { @Override - public Data deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - JsonNode node = jsonParser.getCodec().readTree(jsonParser); + public Data deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) { + JsonNode node = deserializationContext.readTree(jsonParser); if (node.isArray()) { List resources = new ArrayList<>(); for (JsonNode n : node) { - Resource r = MAPPER.convertValue(n, Resource.class); + Resource r = deserializationContext.readTreeAsValue(n, Resource.class); validateResource(jsonParser, r); resources.add(r); } return new Data<>(resources); } - Resource resource = MAPPER.convertValue(node, Resource.class); + Resource resource = deserializationContext.readTreeAsValue(node, Resource.class); validateResource(jsonParser, resource); return new Data<>(resource); } - private void validateResource(JsonParser jsonParser, Resource resource) throws IOException { + private void validateResource(JsonParser jsonParser, Resource resource) { if (resource.getType() == null || resource.getType().isEmpty()) { - throw JsonMappingException.from(jsonParser, "Resource 'type' field is missing or empty."); + throw DatabindException.from(jsonParser, "Resource 'type' field is missing or empty."); } } } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataSerializer.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataSerializer.java index 6ad2055a43..a10b072905 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataSerializer.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/DataSerializer.java @@ -7,33 +7,31 @@ import com.yahoo.elide.jsonapi.models.Data; import com.yahoo.elide.jsonapi.models.Resource; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.IterableUtils; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; -import java.io.IOException; import java.util.Collection; import java.util.Collections; /** * Custom serializer for top-level data. */ -public class DataSerializer extends JsonSerializer> { +public class DataSerializer extends ValueSerializer> { @Override - public void serialize(Data data, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) - throws IOException { + public void serialize(Data data, JsonGenerator jsonGenerator, SerializationContext serializerProvider) { Collection list = data.get(); if (data.isToOne()) { if (CollectionUtils.isEmpty(list)) { - jsonGenerator.writeObject(null); + jsonGenerator.writePOJO(null); return; } - jsonGenerator.writeObject(IterableUtils.first(list)); + jsonGenerator.writePOJO(IterableUtils.first(list)); return; } - jsonGenerator.writeObject((list == null) ? Collections.emptyList() : list); + jsonGenerator.writePOJO((list == null) ? Collections.emptyList() : list); } } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializer.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializer.java index 1cf2d408ae..f4495541a5 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializer.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializer.java @@ -7,37 +7,36 @@ import com.yahoo.elide.jsonapi.models.JsonApiError; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import org.owasp.encoder.Encode; -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ser.std.StdSerializer; + import java.util.Map; /** * JSON API Error Serializer. */ public class JsonApiErrorSerializer extends StdSerializer { - private static final long serialVersionUID = 1L; public JsonApiErrorSerializer() { super(JsonApiError.class); } @Override - public void serialize(JsonApiError jsonApiError, JsonGenerator jsonGenerator, SerializerProvider provider) - throws IOException { + public void serialize(JsonApiError jsonApiError, JsonGenerator jsonGenerator, SerializationContext provider) { jsonGenerator.writeStartObject(); writeStringField(jsonGenerator, "id", jsonApiError.getId()); if (jsonApiError.getLinks() != null) { - jsonGenerator.writeObjectField("links", jsonApiError.getLinks()); + jsonGenerator.writeName("links"); + jsonGenerator.writePOJO(jsonApiError.getLinks()); } writeStringField(jsonGenerator, "status", jsonApiError.getStatus()); writeStringField(jsonGenerator, "code", jsonApiError.getCode()); if (jsonApiError.getSource() != null) { - jsonGenerator.writeObjectField("source", jsonApiError.getSource()); + jsonGenerator.writeName("source"); + jsonGenerator.writePOJO(jsonApiError.getSource()); } writeStringField(jsonGenerator, "title", jsonApiError.getTitle()); if (jsonApiError.getDetail() != null && !jsonApiError.getDetail().isBlank()) { @@ -45,18 +44,21 @@ public void serialize(JsonApiError jsonApiError, JsonGenerator jsonGenerator, Se } if (jsonApiError.getMeta() instanceof Map map) { if (!map.isEmpty()) { - jsonGenerator.writeObjectField("meta", jsonApiError.getMeta()); + jsonGenerator.writeName("meta"); + jsonGenerator.writePOJO(jsonApiError.getMeta()); } } else if (jsonApiError.getMeta() != null) { - jsonGenerator.writeObjectField("meta", jsonApiError.getMeta()); + jsonGenerator.writeName("meta"); + jsonGenerator.writePOJO(jsonApiError.getMeta()); } jsonGenerator.writeEndObject(); } - private void writeStringField(JsonGenerator jsonGenerator, String fieldName, String value) throws IOException { + private void writeStringField(JsonGenerator jsonGenerator, String fieldName, String value) { if (value != null && !value.isBlank()) { - jsonGenerator.writeStringField(fieldName, value); + jsonGenerator.writeName(fieldName); + jsonGenerator.writeString(value); } } } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiModule.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiModule.java index a76382df25..b6f33f34ce 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiModule.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiModule.java @@ -5,8 +5,8 @@ */ package com.yahoo.elide.jsonapi.serialization; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.databind.module.SimpleModule; +import tools.jackson.core.Version; +import tools.jackson.databind.module.SimpleModule; /** * JSON API Module. diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiSetSerializer.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiSetSerializer.java index 26e26e5b09..627ff213d3 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiSetSerializer.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/JsonApiSetSerializer.java @@ -5,29 +5,25 @@ */ package com.yahoo.elide.jsonapi.serialization; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ser.std.StdSerializer; -import java.io.IOException; import java.util.Set; /** * JSON API Set Serializer. */ public class JsonApiSetSerializer extends StdSerializer { - private static final long serialVersionUID = 1L; - JsonApiSetSerializer() { super(Set.class); } @Override - public void serialize(Set set, JsonGenerator jsonGenerator, SerializerProvider provider) - throws IOException { + public void serialize(Set set, JsonGenerator jsonGenerator, SerializationContext provider) { jsonGenerator.writeStartArray(); for (Object value : set) { - jsonGenerator.writeObject(value); + jsonGenerator.writePOJO(value); } jsonGenerator.writeEndArray(); } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/KeySerializer.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/KeySerializer.java index b73204d2aa..f58f3d9f26 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/KeySerializer.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/KeySerializer.java @@ -5,11 +5,10 @@ */ package com.yahoo.elide.jsonapi.serialization; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdKeySerializer; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; -import java.io.IOException; import java.util.Date; /** @@ -17,10 +16,9 @@ * Change from StdKeySerializer - In cases of enum value it uses * name() instead of defaulting to toString() since that may be overridden */ -public class KeySerializer extends StdKeySerializer { +public class KeySerializer extends ValueSerializer { @Override - public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) - throws IOException { + public void serialize(Object value, JsonGenerator jgen, SerializationContext provider) { String str; Class cls = value.getClass(); @@ -36,6 +34,6 @@ public void serialize(Object value, JsonGenerator jgen, SerializerProvider provi } else { str = value.toString(); } - jgen.writeFieldName(str); + jgen.writeName(str); } } diff --git a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializer.java b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializer.java index 921f786056..f8a71c3f12 100644 --- a/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializer.java +++ b/elide-core/src/main/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializer.java @@ -6,24 +6,22 @@ package com.yahoo.elide.jsonapi.serialization; import com.yahoo.elide.jsonapi.models.Meta; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ValueDeserializer; -import java.io.IOException; import java.util.Map; /** * Custom deserializer for top-level meta object. */ -public class MetaDeserializer extends JsonDeserializer { +public class MetaDeserializer extends ValueDeserializer { @SuppressWarnings("unchecked") @Override - public Meta deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - JsonNode node = jsonParser.getCodec().readTree(jsonParser); + public Meta deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) { + JsonNode node = deserializationContext.readTree(jsonParser); // Optional top-level meta member must be an object - return node.isObject() ? new Meta(jsonParser.getCodec().treeToValue(node, Map.class)) : null; + return node.isObject() ? new Meta(deserializationContext.readTreeAsValue(node, Map.class)) : null; } } diff --git a/elide-core/src/test/java/com/yahoo/elide/ElideMapperTest.java b/elide-core/src/test/java/com/yahoo/elide/ElideMapperTest.java index a6d8d6c48c..a3927f41d2 100644 --- a/elide-core/src/test/java/com/yahoo/elide/ElideMapperTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/ElideMapperTest.java @@ -7,9 +7,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; /** * Test for ElideMapper. diff --git a/elide-core/src/test/java/com/yahoo/elide/core/PersistenceResourceTestSetup.java b/elide-core/src/test/java/com/yahoo/elide/core/PersistenceResourceTestSetup.java index c4588dbbe2..6d51370c3e 100644 --- a/elide-core/src/test/java/com/yahoo/elide/core/PersistenceResourceTestSetup.java +++ b/elide-core/src/test/java/com/yahoo/elide/core/PersistenceResourceTestSetup.java @@ -8,6 +8,7 @@ import static com.yahoo.elide.core.dictionary.EntityDictionary.NO_VERSION; import static org.mockito.Mockito.mock; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.annotation.CreatePermission; import com.yahoo.elide.annotation.DeletePermission; @@ -27,6 +28,7 @@ import com.yahoo.elide.core.security.User; import com.yahoo.elide.core.security.checks.OperationCheck; import com.yahoo.elide.core.type.Type; +import com.yahoo.elide.jsonapi.JsonApiMapper; import com.yahoo.elide.jsonapi.JsonApiRequestScope; import com.yahoo.elide.jsonapi.JsonApiSettings; import com.yahoo.elide.jsonapi.models.JsonApiDocument; @@ -65,6 +67,7 @@ import lombok.EqualsAndHashCode; import nocreate.NoCreateEntity; import reactor.core.publisher.Flux; +import tools.jackson.databind.json.JsonMapper; import java.util.Collection; import java.util.HashSet; @@ -126,14 +129,16 @@ protected static EntityDictionary initDictionary() { } protected static ElideSettings initSettings() { - JsonApiSettings.JsonApiSettingsBuilder jsonApiSettings = JsonApiSettings.builder(); + ElideMapper elideMapper = new ElideMapper(JsonMapper.shared()); + JsonApiMapper jsonApiMapper = new JsonApiMapper(elideMapper); + JsonApiSettings.JsonApiSettingsBuilder jsonApiSettings = JsonApiSettings.builder().jsonApiMapper(jsonApiMapper); return ElideSettings.builder().dataStore(null) .entityDictionary(initDictionary()) .auditLogger(MOCK_AUDIT_LOGGER) .maxPageSize(10) .defaultPageSize(10) .settings(jsonApiSettings) - .objectMapper(jsonApiSettings.build().getJsonApiMapper().getObjectMapper()) + .elideMapper(elideMapper) .build(); } diff --git a/elide-core/src/test/java/com/yahoo/elide/core/exceptions/ExceptionMapperTest.java b/elide-core/src/test/java/com/yahoo/elide/core/exceptions/ExceptionMapperTest.java index 831ac79639..01e4c96799 100644 --- a/elide-core/src/test/java/com/yahoo/elide/core/exceptions/ExceptionMapperTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/core/exceptions/ExceptionMapperTest.java @@ -20,6 +20,7 @@ import com.yahoo.elide.Elide; import com.yahoo.elide.ElideErrorResponse; import com.yahoo.elide.ElideErrors; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideResponse; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.core.TransactionRegistry; @@ -35,12 +36,13 @@ import com.yahoo.elide.jsonapi.DefaultJsonApiErrorMapper; import com.yahoo.elide.jsonapi.DefaultJsonApiExceptionHandler; import com.yahoo.elide.jsonapi.JsonApi; +import com.yahoo.elide.jsonapi.JsonApiMapper; import com.yahoo.elide.jsonapi.JsonApiSettings; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; - -import java.io.IOException; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.json.JsonMapper; /** * Tests the error mapping logic. @@ -141,7 +143,7 @@ public void testElideRuntimeExceptionWithErrorResponseMapperUnmapped() throws Ex } @Test - public void testElideIOExceptionWithErrorResponseMapperUnmapped() throws Exception { + public void testElideJacksonExceptionWithErrorResponseMapperUnmapped() throws Exception { DataStore store = mock(DataStore.class); DataStoreTransaction tx = mock(DataStoreTransaction.class); FieldTestModel mockModel = mock(FieldTestModel.class); @@ -192,7 +194,7 @@ void testElideRuntimeExceptionWithErrorResponseMapperMapped() throws Exception { } @Test - void testElideIOExceptionWithErrorResponseMapperMapped() throws Exception { + void testElideJacksonExceptionWithErrorResponseMapperMapped() throws Exception { DataStore store = mock(DataStore.class); DataStoreTransaction tx = mock(DataStoreTransaction.class); FieldTestModel mockModel = mock(FieldTestModel.class); @@ -206,7 +208,7 @@ void testElideIOExceptionWithErrorResponseMapperMapped() throws Exception { when(store.beginTransaction()).thenReturn(tx); when(tx.createNewObject(eq(ClassType.of(FieldTestModel.class)), any())).thenReturn(mockModel); - when(MOCK_EXCEPTION_MAPPER.toErrorResponse(isA(IOException.class), any())).thenReturn((ElideErrorResponse) MAPPED_EXCEPTION.getErrorResponse()); + when(MOCK_EXCEPTION_MAPPER.toErrorResponse(isA(JacksonException.class), any())).thenReturn((ElideErrorResponse) MAPPED_EXCEPTION.getErrorResponse()); Route route = Route.builder().baseUrl(baseUrl).path("/testModel").apiVersion(NO_VERSION).build(); ElideResponse response = jsonApi.post(route, body, null, null); @@ -224,14 +226,17 @@ private Elide getElide(DataStore dataStore, EntityDictionary dictionary, Excepti } private ElideSettings getElideSettings(DataStore dataStore, EntityDictionary dictionary, ExceptionMappers exceptionMappers) { + ElideMapper elideMapper = new ElideMapper(JsonMapper.shared()); + JsonApiMapper jsonApiMapper = new JsonApiMapper(elideMapper); JsonApiSettings.JsonApiSettingsBuilder jsonApiSettings = JsonApiSettings.builder() + .jsonApiMapper(jsonApiMapper) .jsonApiExceptionHandler(new DefaultJsonApiExceptionHandler(new Slf4jExceptionLogger(), exceptionMappers, new DefaultJsonApiErrorMapper())); return ElideSettings.builder().dataStore(dataStore) .entityDictionary(dictionary) .verboseErrors(true) .settings(jsonApiSettings) - .objectMapper(jsonApiSettings.build().getJsonApiMapper().getObjectMapper()) + .elideMapper(elideMapper) .build(); } } diff --git a/elide-core/src/test/java/com/yahoo/elide/core/lifecycle/LifeCycleTest.java b/elide-core/src/test/java/com/yahoo/elide/core/lifecycle/LifeCycleTest.java index 5d0411269d..fac6ce063d 100644 --- a/elide-core/src/test/java/com/yahoo/elide/core/lifecycle/LifeCycleTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/core/lifecycle/LifeCycleTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.when; import com.yahoo.elide.Elide; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideResponse; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.core.PersistentResource; @@ -52,6 +53,7 @@ import com.yahoo.elide.core.security.User; import com.yahoo.elide.core.type.ClassType; import com.yahoo.elide.jsonapi.JsonApi; +import com.yahoo.elide.jsonapi.JsonApiMapper; import com.yahoo.elide.jsonapi.JsonApiRequestScope; import com.yahoo.elide.jsonapi.JsonApiSettings; import com.google.common.collect.ImmutableSet; @@ -59,6 +61,7 @@ import org.mockito.ArgumentCaptor; import jakarta.validation.ConstraintViolationException; +import tools.jackson.databind.json.JsonMapper; import java.util.Arrays; import java.util.HashSet; @@ -1849,12 +1852,14 @@ private Elide getElide(DataStore dataStore, EntityDictionary dictionary, AuditLo } private ElideSettings getElideSettings(DataStore dataStore, EntityDictionary dictionary, AuditLogger auditLogger) { - JsonApiSettings.JsonApiSettingsBuilder jsonApiSettings = JsonApiSettings.builder(); + ElideMapper elideMapper = new ElideMapper(JsonMapper.shared()); + JsonApiMapper jsonApiMapper = new JsonApiMapper(elideMapper); + JsonApiSettings.JsonApiSettingsBuilder jsonApiSettings = JsonApiSettings.builder().jsonApiMapper(jsonApiMapper); return ElideSettings.builder().dataStore(dataStore) .entityDictionary(dictionary) .auditLogger(auditLogger) .verboseErrors(true) - .objectMapper(jsonApiSettings.build().getJsonApiMapper().getObjectMapper()) + .elideMapper(elideMapper) .settings(jsonApiSettings) .build(); } diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiErrorMapperTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiErrorMapperTest.java index 0061d6758a..6f37f9625d 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiErrorMapperTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiErrorMapperTest.java @@ -12,11 +12,10 @@ import com.yahoo.elide.jsonapi.models.JsonApiError.Links; import com.yahoo.elide.jsonapi.models.JsonApiError.Source; import com.yahoo.elide.jsonapi.serialization.JsonApiModule; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.util.Map; @@ -25,16 +24,16 @@ */ class DefaultJsonApiErrorMapperTest { - private ObjectMapper objectMapper = new ObjectMapper(); + private ObjectMapper objectMapper; private JsonApiErrorMapper mapper = new DefaultJsonApiErrorMapper(); @BeforeEach public void setup() { - objectMapper.registerModule(new JsonApiModule()); + objectMapper = JsonMapper.builder().addModule(new JsonApiModule()).build(); } @Test - void toJsonApiError() throws JsonProcessingException { + void toJsonApiError() { JsonApiError jsonApiError = mapper .toJsonApiError(ElideError.builder() .message("") @@ -52,7 +51,7 @@ void toJsonApiError() throws JsonProcessingException { } @Test - void toJsonApiErrorMeta() throws JsonProcessingException { + void toJsonApiErrorMeta() { JsonApiError jsonApiError = mapper .toJsonApiError(ElideError.builder() .message("message") @@ -65,7 +64,7 @@ void toJsonApiErrorMeta() throws JsonProcessingException { } @Test - void toJsonApiErrorLinks() throws JsonProcessingException { + void toJsonApiErrorLinks() { JsonApiError jsonApiError = mapper .toJsonApiError(ElideError.builder() .message("message") @@ -78,7 +77,7 @@ void toJsonApiErrorLinks() throws JsonProcessingException { } @Test - void toJsonApiErrorSource() throws JsonProcessingException { + void toJsonApiErrorSource() { JsonApiError jsonApiError = mapper .toJsonApiError(ElideError.builder() .message("message") diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandlerTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandlerTest.java index f91a7edc2c..a16cc71b77 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandlerTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/DefaultJsonApiExceptionHandlerTest.java @@ -21,10 +21,6 @@ import com.yahoo.elide.core.exceptions.Slf4jExceptionLogger; import com.yahoo.elide.jsonapi.models.JsonApiError; import com.yahoo.elide.jsonapi.models.JsonApiErrors; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.JsonMappingException; - import org.antlr.v4.runtime.misc.ParseCancellationException; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -40,6 +36,10 @@ import jakarta.validation.constraints.NotNull; import jakarta.ws.rs.WebApplicationException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.exc.StreamReadException; +import tools.jackson.databind.DatabindException; + import java.io.IOException; import java.util.List; import java.util.Set; @@ -56,8 +56,8 @@ enum ExceptionStatusInput { INVALID_API(new InvalidApiVersionException(""), JsonApiErrorContext.builder().build(), 400), INVALID_ENTITY_BODY(new InvalidEntityBodyException(""), JsonApiErrorContext.builder().build(), 400), INVALID_CONSTRAINT(new InvalidConstraintException(""), JsonApiErrorContext.builder().build(), 400), - INVALID_ENTITY_BODY_JSON_PARSE(new InvalidEntityBodyException("", new JsonParseException("")), JsonApiErrorContext.builder().build(), 400), - JSON_PROCESSING(JsonMappingException.from((JsonParser) null, ""), JsonApiErrorContext.builder().build(), 400), + INVALID_ENTITY_BODY_JSON_PARSE(new InvalidEntityBodyException("", new StreamReadException("")), JsonApiErrorContext.builder().build(), 400), + JSON_PROCESSING(DatabindException.from((JsonParser) null, ""), JsonApiErrorContext.builder().build(), 400), IO(new IOException(""), JsonApiErrorContext.builder().build(), 423), FORBIDDEN_ACCESS(new ForbiddenAccessException(UpdatePermission.class), JsonApiErrorContext.builder().build(), 403), JSON_PATCH(new JsonPatchExtensionException(403, null), JsonApiErrorContext.builder().build(), 403), diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/JsonApiTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/JsonApiTest.java index 05b89c1ba8..076b91e29d 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/JsonApiTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/JsonApiTest.java @@ -44,8 +44,6 @@ import com.yahoo.elide.jsonapi.models.Relationship; import com.yahoo.elide.jsonapi.models.Resource; import com.yahoo.elide.jsonapi.models.ResourceIdentifier; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -68,8 +66,9 @@ import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; +import tools.jackson.databind.DatabindException; + import java.io.IOException; -import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -102,7 +101,7 @@ void init() { } @Test - public void writeSingleNoAttributesNoRel() throws JsonProcessingException { + public void writeSingleNoAttributesNoRel() { Parent parent = new Parent(); parent.setId(123L); @@ -133,7 +132,7 @@ public void writeSingleNoAttributesNoRel() throws JsonProcessingException { } @Test - public void writeSingle() throws JsonProcessingException { + public void writeSingle() { Parent parent = new Parent(); Child child = new Child(); parent.setId(123L); @@ -170,7 +169,7 @@ public void writeSingle() throws JsonProcessingException { } @Test - public void writeSingleWithMeta() throws JsonProcessingException { + public void writeSingleWithMeta() { Child child = new Child(); child.setId(2); child.setMetadataField("foo", "bar"); @@ -191,7 +190,7 @@ public void writeSingleWithMeta() throws JsonProcessingException { } @Test - public void writeSingleIncluded() throws JsonProcessingException { + public void writeSingleIncluded() { Parent parent = new Parent(); Child child = new Child(); parent.setId(123L); @@ -248,7 +247,7 @@ public void writeSingleIncluded() throws JsonProcessingException { } @Test - public void writeList() throws JsonProcessingException { + public void writeList() { Parent parent = new Parent(); Child child = new Child(); parent.setId(123L); @@ -287,7 +286,7 @@ public void writeList() throws JsonProcessingException { } @Test - public void writeListIncluded() throws JsonProcessingException { + public void writeListIncluded() { Parent parent = new Parent(); Child child = new Child(); parent.setId(123L); @@ -348,7 +347,7 @@ public void writeListIncluded() throws JsonProcessingException { } @Test - public void writeEmptyList() throws JsonProcessingException { + public void writeEmptyList() { String expected = "{\"data\":[]}"; Data empty = new Data<>(new ArrayList<>()); @@ -365,7 +364,7 @@ public void writeEmptyList() throws JsonProcessingException { } @Test - public void writeEmptyObject() throws JsonProcessingException { + public void writeEmptyObject() { String expected = "{\"data\":null}"; Data empty = new Data<>((Resource) null); @@ -382,7 +381,7 @@ public void writeEmptyObject() throws JsonProcessingException { } @Test - public void writeNullObject() throws JsonProcessingException { + public void writeNullObject() { String expected = "{\"data\":null}"; JsonApiDocument jsonApiDocument = new JsonApiDocument(); @@ -400,14 +399,14 @@ public void writeNullObject() throws JsonProcessingException { public void testMissingTypeInResource() { String doc = "{ \"data\": { \"id\": \"22\", \"attributes\": { \"title\": \"works fine\" } } }"; - assertThrows(JsonMappingException.class, () -> mapper.readJsonApiDocument(doc)); + assertThrows(DatabindException.class, () -> mapper.readJsonApiDocument(doc)); } @Test public void testMissingTypeInResourceList() { String doc = "{ \"data\": [{ \"id\": \"22\", \"attributes\": { \"title\": \"works fine\" } } ]}"; - assertThrows(JsonMappingException.class, () -> mapper.readJsonApiDocument(doc)); + assertThrows(DatabindException.class, () -> mapper.readJsonApiDocument(doc)); } @Test @@ -580,12 +579,8 @@ public void compareOrder() { private void checkEquality(JsonApiDocument doc1) { JsonApiDocument doc2; - try { - String json = mapper.writeJsonApiDocument(doc1); - doc2 = mapper.readJsonApiDocument(json); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + String json = mapper.writeJsonApiDocument(doc1); + doc2 = mapper.readJsonApiDocument(json); assertEquals(doc1, doc2); assertEquals(doc1.hashCode(), doc2.hashCode()); } diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapperTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapperTest.java index 453f40e10b..9010878734 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapperTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsMapperTest.java @@ -8,13 +8,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.jsonapi.models.JsonApiDocument; import com.yahoo.elide.jsonapi.models.Operations; import com.yahoo.elide.jsonapi.models.Resource; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.json.JsonMapper; /** * Tests for JsonApiAtomicOperationsMapper. @@ -22,8 +22,8 @@ class JsonApiAtomicOperationsMapperTest { @Test - void readDataCollection() throws JsonProcessingException { - JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ObjectMapper()); + void readDataCollection() { + JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ElideMapper(JsonMapper.shared())); String operationsDoc = """ { "atomic:operations": [{ @@ -46,8 +46,8 @@ void readDataCollection() throws JsonProcessingException { } @Test - void readDataSingleId() throws JsonProcessingException { - JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ObjectMapper()); + void readDataSingleId() { + JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ElideMapper(JsonMapper.shared())); String operationsDoc = """ { "atomic:operations": [{ @@ -73,8 +73,8 @@ void readDataSingleId() throws JsonProcessingException { } @Test - void readDataSingleLid() throws JsonProcessingException { - JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ObjectMapper()); + void readDataSingleLid() { + JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ElideMapper(JsonMapper.shared())); String operationsDoc = """ { "atomic:operations": [{ @@ -100,8 +100,8 @@ void readDataSingleLid() throws JsonProcessingException { } @Test - void readDataNull() throws JsonProcessingException { - JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ObjectMapper()); + void readDataNull() { + JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ElideMapper(JsonMapper.shared())); String operationsDoc = """ { "atomic:operations": [{ @@ -121,8 +121,8 @@ void readDataNull() throws JsonProcessingException { } @Test - void readNull() throws JsonProcessingException { - JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ObjectMapper()); + void readNull() { + JsonApiAtomicOperationsMapper mapper = new JsonApiAtomicOperationsMapper(new ElideMapper(JsonMapper.shared())); String operationsDoc = """ { "atomic:operations": [{ diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsTest.java index 7b950330c8..ccb1db24b1 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/extensions/JsonApiAtomicOperationsTest.java @@ -11,6 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.core.datastore.DataStore; import com.yahoo.elide.core.datastore.DataStoreTransaction; @@ -24,9 +25,6 @@ import com.yahoo.elide.jsonapi.JsonApiSettings; import com.yahoo.elide.jsonapi.models.Resource; import com.yahoo.elide.jsonapi.models.Results; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import example.Book; import example.Company; @@ -35,6 +33,10 @@ import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; import java.io.IOException; import java.io.UncheckedIOException; @@ -55,10 +57,11 @@ void setup() { this.dataStore = new HashMapDataStore(Arrays.asList(Book.class, Company.class, Person.class)); EntityDictionary entityDictionary = EntityDictionary.builder().build(); this.dataStore.populateEntityDictionary(entityDictionary); - JsonApiMapper jsonApiMapper = new JsonApiMapper(); + ElideMapper elideMapper = new ElideMapper(JsonMapper.shared()); + JsonApiMapper jsonApiMapper = new JsonApiMapper(elideMapper); JsonApiSettings.JsonApiSettingsBuilder jsonApiSettings = JsonApiSettings.builder().jsonApiMapper(jsonApiMapper); this.settings = ElideSettings.builder().dataStore(this.dataStore).entityDictionary(entityDictionary) - .objectMapper(jsonApiMapper.getObjectMapper()).settings(jsonApiSettings).build(); + .elideMapper(elideMapper).settings(jsonApiSettings).build(); } Supplier> doInTransaction( @@ -138,9 +141,9 @@ void invalidRefShouldThrow() { return JsonApiAtomicOperations.processAtomicOperations(this.dataStore, null, operationsDoc, scope); } catch (JsonApiAtomicOperationsException e) { ObjectNode error = (ObjectNode) e.getErrorResponse().getBody().get(0).get("errors").get(0); - assertEquals("400", error.get("status").asText()); + assertEquals("400", error.get("status").asString()); assertEquals("Bad Request Body'Atomic Operations extension ref must specify the type member.'", - error.get("detail").asText()); + error.get("detail").asString()); return null; } }); @@ -166,9 +169,9 @@ void createResourceShouldNotSpecifyRefShouldThrow() { return JsonApiAtomicOperations.processAtomicOperations(this.dataStore, null, operationsDoc, scope); } catch (JsonApiAtomicOperationsException e) { ObjectNode error = (ObjectNode) e.getErrorResponse().getBody().get(0).get("errors").get(0); - assertEquals("400", error.get("status").asText()); + assertEquals("400", error.get("status").asString()); assertEquals("Bad Request Body'Atomic Operations extension add resource operation may only specify the href member.'", - error.get("detail").asText()); + error.get("detail").asString()); return null; } }); @@ -195,9 +198,9 @@ void bothRefAndHrefShouldThrow() { return JsonApiAtomicOperations.processAtomicOperations(this.dataStore, null, operationsDoc, scope); } catch (JsonApiAtomicOperationsException e) { ObjectNode error = (ObjectNode) e.getErrorResponse().getBody().get(0).get("errors").get(0); - assertEquals("400", error.get("status").asText()); + assertEquals("400", error.get("status").asString()); assertEquals("Bad Request Body'Atomic Operations extension operation cannot contain both ref and href members.'", - error.get("detail").asText()); + error.get("detail").asString()); return null; } }); @@ -224,9 +227,9 @@ void refWithBothIdAndLidShouldThrow() { return JsonApiAtomicOperations.processAtomicOperations(this.dataStore, null, operationsDoc, scope); } catch (JsonApiAtomicOperationsException e) { ObjectNode error = (ObjectNode) e.getErrorResponse().getBody().get(0).get("errors").get(0); - assertEquals("400", error.get("status").asText()); + assertEquals("400", error.get("status").asString()); assertEquals("Bad Request Body'Atomic Operations extension ref cannot contain both id and lid members.'", - error.get("detail").asText()); + error.get("detail").asString()); return null; } }); @@ -247,10 +250,10 @@ void noRefAndHrefShouldThrow() { return JsonApiAtomicOperations.processAtomicOperations(this.dataStore, null, operationsDoc, scope); } catch (JsonApiAtomicOperationsException e) { ObjectNode error = (ObjectNode) e.getErrorResponse().getBody().get(0).get("errors").get(0); - assertEquals("400", error.get("status").asText()); + assertEquals("400", error.get("status").asString()); assertEquals( "Bad Request Body'Atomic Operations extension operation requires either ref or href members to be specified.'", - error.get("detail").asText()); + error.get("detail").asString()); return null; } }); @@ -275,10 +278,10 @@ void removeNoRefAndHrefShouldThrow() { return JsonApiAtomicOperations.processAtomicOperations(this.dataStore, null, operationsDoc, scope); } catch (JsonApiAtomicOperationsException e) { ObjectNode error = (ObjectNode) e.getErrorResponse().getBody().get(0).get("errors").get(0); - assertEquals("400", error.get("status").asText()); + assertEquals("400", error.get("status").asString()); assertEquals( "Bad Request Body'Atomic Operations extension operation requires either ref or href members to be specified.'", - error.get("detail").asText()); + error.get("detail").asString()); return null; } }); @@ -303,8 +306,8 @@ void oneToOneDeleteUnknownCollectionShouldThrow() { return JsonApiAtomicOperations.processAtomicOperations(this.dataStore, null, operationsDoc, scope); } catch (JsonApiAtomicOperationsException e) { JsonNode error = e.getErrorResponse().getBody().get(0).get("errors").get(0); - assertEquals("404", error.get("status").asText()); - assertEquals("Unknown collection author", error.get("detail").asText()); + assertEquals("404", error.get("status").asString()); + assertEquals("Unknown collection author", error.get("detail").asString()); return null; } }); @@ -333,8 +336,8 @@ void addUpdateRemove() throws IOException { assertEquals(200, result.getKey()); JsonNode data = result.getValue().get("atomic:results").get(0).get("data"); - assertEquals("company", data.get("type").asText()); - assertEquals("1", data.get("id").asText()); + assertEquals("company", data.get("type").asString()); + assertEquals("1", data.get("id").asString()); doInTransaction(scope -> { @@ -428,8 +431,8 @@ void addUpdateRemoveHref() throws IOException { assertEquals(200, result.getKey()); JsonNode data = result.getValue().get("atomic:results").get(0).get("data"); - assertEquals("company", data.get("type").asText()); - assertEquals("1", data.get("id").asText()); + assertEquals("company", data.get("type").asString()); + assertEquals("1", data.get("id").asString()); doInTransaction(scope -> { diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorTest.java index 356a70650f..be60ef57ca 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorTest.java @@ -8,12 +8,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; import lombok.Getter; +import tools.jackson.databind.ObjectMapper; import java.util.Map; @@ -24,7 +22,7 @@ class JsonApiErrorTest { private final ObjectMapper objectMapper = new ObjectMapper(); @Test - void getMeta() throws JsonProcessingException { + void getMeta() { JsonApiError error = JsonApiError.builder() .meta(meta -> meta.put("property", "property")) .build(); @@ -33,7 +31,7 @@ void getMeta() throws JsonProcessingException { } @Test - void meta() throws JsonProcessingException { + void meta() { JsonApiError error = JsonApiError.builder() .meta(Map.of("property1", "value1")) .build(); @@ -45,7 +43,7 @@ void meta() throws JsonProcessingException { @Test - void links() throws JsonProcessingException { + void links() { JsonApiError error = JsonApiError.builder() .links(links -> links.about("https://about").type("https://type")) .build(); @@ -56,7 +54,7 @@ void links() throws JsonProcessingException { } @Test - void linksObject() throws JsonProcessingException { + void linksObject() { JsonApiError error = JsonApiError.builder() .links(JsonApiError.Links.builder().about("https://about").type("https://type").build()) .build(); @@ -67,7 +65,7 @@ void linksObject() throws JsonProcessingException { } @Test - void source() throws JsonProcessingException { + void source() { JsonApiError error = JsonApiError.builder() .source(source -> source.header("header").parameter("parameter").pointer("/data/attributes/title")) .build(); @@ -78,7 +76,7 @@ void source() throws JsonProcessingException { } @Test - void sourceObject() throws JsonProcessingException { + void sourceObject() { JsonApiError error = JsonApiError.builder() .source(JsonApiError.Source.builder().header("header").parameter("parameter") .pointer("/data/attributes/title").build()) @@ -95,7 +93,7 @@ public static class MetaObject { } @Test - void metaObject() throws JsonProcessingException { + void metaObject() { JsonApiError error = JsonApiError.builder() .meta(new MetaObject()) .build(); diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorsTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorsTest.java index cf9cf784ba..fdcb7a5851 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorsTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/JsonApiErrorsTest.java @@ -8,10 +8,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; import java.util.Collections; @@ -22,7 +21,7 @@ class JsonApiErrorsTest { private final ObjectMapper objectMapper = new ObjectMapper(); @Test - void basicErrorObject() throws JsonProcessingException { + void basicErrorObject() { JsonApiErrors errors = JsonApiErrors.builder() .error(error -> error.status("422").source(source -> source.pointer("/data/attributes/firstName")) .title("Invalid Attribute").detail("First name must contain at least two characters.")) @@ -34,7 +33,7 @@ void basicErrorObject() throws JsonProcessingException { } @Test - void multipleErrors() throws JsonProcessingException { + void multipleErrors() { JsonApiErrors errors = JsonApiErrors.builder() .error(error -> error.status("403").source(source -> source.pointer("/data/attributes/secretPowers")) .detail("Editing secret powers is not authorized on Sundays.")) @@ -51,7 +50,7 @@ void multipleErrors() throws JsonProcessingException { } @Test - void meta() throws JsonProcessingException { + void meta() { JsonApiErrors errors = JsonApiErrors.builder() .error(error -> error.status("422").meta(meta -> meta.put("property", "property"))) .build(); @@ -68,7 +67,7 @@ void emptyShouldThrow() { } @Test - void errorsConsumer() throws JsonProcessingException { + void errorsConsumer() { JsonApiError error = JsonApiError.builder().detail("First name must contain at least two characters.").build(); JsonApiErrors errorObjects = JsonApiErrors.builder().errors(errors -> errors.add(error)).build(); String actual = objectMapper.writeValueAsString(errorObjects); @@ -78,7 +77,7 @@ void errorsConsumer() throws JsonProcessingException { } @Test - void errors() throws JsonProcessingException { + void errors() { JsonApiError error = JsonApiError.builder().detail("First name must contain at least two characters.").build(); JsonApiErrors errorObjects = JsonApiErrors.builder().errors(Collections.singletonList(error)).build(); String actual = objectMapper.writeValueAsString(errorObjects); diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationTest.java index 43cc4fe3a1..1a5f3b8519 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationTest.java @@ -7,18 +7,19 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.cfg.EnumFeature; +import tools.jackson.databind.json.JsonMapper; + /** * Tests for Operation. */ class OperationTest { @Test - void write() throws JsonProcessingException { + void write() { ObjectMapper objectMapper = new ObjectMapper(); Ref ref = new Ref("articles", "13", null, null); Operation operation = new Operation(Operation.OperationCode.ADD, ref, null, null, null); @@ -29,7 +30,7 @@ void write() throws JsonProcessingException { } @Test - void readSingle() throws JsonProcessingException { + void readSingle() { String json = """ { "op": "update", @@ -50,7 +51,7 @@ void readSingle() throws JsonProcessingException { } @Test - void readSingleReadEnumsUsingToString() throws JsonProcessingException { + void readSingleReadEnumsUsingToString() { String json = """ { "op": "update", @@ -63,7 +64,7 @@ void readSingleReadEnumsUsingToString() throws JsonProcessingException { } } """; - ObjectMapper objectMapper = new ObjectMapper().enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + ObjectMapper objectMapper = JsonMapper.builder().enable(EnumFeature.READ_ENUMS_USING_TO_STRING).build(); Operation operation = objectMapper.readValue(json, Operation.class); assertEquals(Operation.OperationCode.UPDATE, operation.getOperationCode()); Resource resource = objectMapper.treeToValue(operation.getData(), Resource.class); diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationsTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationsTest.java index b6b12a920b..a5f9ba3fdf 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationsTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/OperationsTest.java @@ -7,18 +7,17 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; + /** * Tests for Operations. */ class OperationsTest { @Test - void read() throws JsonProcessingException { + void read() { String json = """ { "atomic:operations": [{ diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/PatchTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/PatchTest.java index b5572fff86..d40d8f8f1e 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/PatchTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/models/PatchTest.java @@ -7,13 +7,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.cfg.EnumFeature; +import tools.jackson.databind.json.JsonMapper; + import java.util.Collections; import java.util.List; @@ -77,7 +78,7 @@ void testListDeserialization() throws Exception { @Test void testDeserializationReadEnumsUsingToString() throws Exception { - ObjectMapper mapper = new ObjectMapper().enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); + ObjectMapper mapper = JsonMapper.builder().enable(EnumFeature.READ_ENUMS_USING_TO_STRING).build(); String input = "{\"op\":\"add\",\"path\":\"/foo/bar\",\"value\":\"stringValue\"}"; Patch patch = mapper.readValue(input, Patch.class); diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializerTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializerTest.java index 9c1e57426f..f601e56f00 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializerTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/JsonApiErrorSerializerTest.java @@ -8,12 +8,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.yahoo.elide.jsonapi.models.JsonApiError; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import java.util.Collections; import java.util.Map; @@ -22,15 +22,15 @@ */ class JsonApiErrorSerializerTest { - private ObjectMapper objectMapper = new ObjectMapper(); + private ObjectMapper objectMapper; @BeforeEach public void setup() { - objectMapper.registerModule(new JsonApiModule()); + objectMapper = JsonMapper.builder().addModule(new JsonApiModule()).build(); } @Test - void idBlank() throws JsonProcessingException { + void idBlank() { JsonApiError jsonApiError = JsonApiError.builder().id(" ").build(); String actual = objectMapper.writeValueAsString(jsonApiError); String expected = """ @@ -39,7 +39,7 @@ void idBlank() throws JsonProcessingException { } @Test - void detailShouldBeEncoded() throws JsonProcessingException { + void detailShouldBeEncoded() { JsonApiError jsonApiError = JsonApiError.builder().detail("").build(); String actual = objectMapper.writeValueAsString(jsonApiError); String expected = """ @@ -48,7 +48,7 @@ void detailShouldBeEncoded() throws JsonProcessingException { } @Test - void detailBlank() throws JsonProcessingException { + void detailBlank() { JsonApiError jsonApiError = JsonApiError.builder().detail(" ").build(); String actual = objectMapper.writeValueAsString(jsonApiError); String expected = """ @@ -57,7 +57,7 @@ void detailBlank() throws JsonProcessingException { } @Test - void meta() throws JsonProcessingException { + void meta() { JsonApiError error = JsonApiError.builder() .meta(Map.of("property1", "value1")) .build(); @@ -72,7 +72,7 @@ public static class Meta { } @Test - void metaObject() throws JsonProcessingException { + void metaObject() { JsonApiError error = JsonApiError.builder() .meta(new Meta()) .build(); @@ -83,7 +83,7 @@ void metaObject() throws JsonProcessingException { } @Test - void metaEmptyMap() throws JsonProcessingException { + void metaEmptyMap() { JsonApiError error = JsonApiError.builder() .meta(Collections.emptyMap()) .build(); @@ -94,7 +94,7 @@ void metaEmptyMap() throws JsonProcessingException { } @Test - void links() throws JsonProcessingException { + void links() { JsonApiError error = JsonApiError.builder() .links(links -> links.about("https://about").type("https://type")) .build(); @@ -105,7 +105,7 @@ void links() throws JsonProcessingException { } @Test - void linksObject() throws JsonProcessingException { + void linksObject() { JsonApiError error = JsonApiError.builder() .links(JsonApiError.Links.builder().about("https://about").type("https://type").build()) .build(); @@ -116,7 +116,7 @@ void linksObject() throws JsonProcessingException { } @Test - void source() throws JsonProcessingException { + void source() { JsonApiError error = JsonApiError.builder() .source(source -> source.header("header").parameter("parameter").pointer("/data/attributes/title")) .build(); @@ -127,7 +127,7 @@ void source() throws JsonProcessingException { } @Test - void sourceObject() throws JsonProcessingException { + void sourceObject() { JsonApiError error = JsonApiError.builder() .source(JsonApiError.Source.builder().header("header").parameter("parameter") .pointer("/data/attributes/title").build()) diff --git a/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializerTest.java b/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializerTest.java index 222c036a37..d00a767baf 100644 --- a/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializerTest.java +++ b/elide-core/src/test/java/com/yahoo/elide/jsonapi/serialization/MetaDeserializerTest.java @@ -9,11 +9,8 @@ import com.yahoo.elide.jsonapi.models.Meta; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; import java.util.List; import java.util.Map; @@ -27,7 +24,7 @@ class MetaDeserializerTest { @SuppressWarnings("rawtypes") @Test - void shouldDeserialize() throws JsonMappingException, JsonProcessingException { + void shouldDeserialize() { String value = """ { "hello": "world", diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/core/Slf4jQueryLogger.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/core/Slf4jQueryLogger.java index e599ab9bd1..98349a5027 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/core/Slf4jQueryLogger.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/core/Slf4jQueryLogger.java @@ -7,12 +7,12 @@ import com.yahoo.elide.core.security.User; import com.yahoo.elide.datastores.aggregation.query.Query; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; import java.util.List; import java.util.Map; diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java index 2b4f313037..ce71ba31dc 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/integration/AggregationDataStoreIntegrationTest.java @@ -9,6 +9,7 @@ import static org.mockito.Mockito.when; import com.yahoo.elide.Elide; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.core.audit.TestAuditLogger; import com.yahoo.elide.core.dictionary.EntityDictionary; @@ -43,6 +44,7 @@ import jakarta.persistence.Persistence; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.core.SecurityContext; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -88,9 +90,10 @@ protected void configure() { dictionary.addRoleCheck(role, new Role.RoleMemberCheck(role)) ); - JsonApiMapper jsonApiMapper = new JsonApiMapper(); + ElideMapper elideMapper = new ElideMapper(JsonMapper.shared()); + JsonApiMapper jsonApiMapper = new JsonApiMapper(elideMapper); Elide elide = new Elide(ElideSettings.builder().dataStore(getDataStore()) - .objectMapper(jsonApiMapper.getObjectMapper()) + .elideMapper(elideMapper) .entityDictionary(dictionary).auditLogger(new TestAuditLogger()).serdes(serdes -> serdes .withISO8601Dates("yyyy-MM-dd'T'HH:mm'Z'", Calendar.getInstance().getTimeZone())) .settings(GraphQLSettingsBuilder.withDefaults(dictionary)) diff --git a/elide-datastore/elide-datastore-jms/pom.xml b/elide-datastore/elide-datastore-jms/pom.xml index 634fb9a3eb..92405dacdb 100644 --- a/elide-datastore/elide-datastore-jms/pom.xml +++ b/elide-datastore/elide-datastore-jms/pom.xml @@ -44,11 +44,11 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - com.fasterxml.jackson.core + tools.jackson.core jackson-core diff --git a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStore.java b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStore.java index 9084681e14..4b7ea8efb9 100644 --- a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStore.java +++ b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStore.java @@ -8,6 +8,7 @@ import static com.yahoo.elide.graphql.subscriptions.SubscriptionModelBuilder.TOPIC_ARGUMENT; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.annotation.Include; import com.yahoo.elide.core.datastore.DataStore; import com.yahoo.elide.core.datastore.DataStoreTransaction; @@ -18,7 +19,6 @@ import com.yahoo.elide.core.utils.ClassScanner; import com.yahoo.elide.graphql.subscriptions.annotations.Subscription; import com.yahoo.elide.graphql.subscriptions.hooks.TopicType; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.jms.ConnectionFactory; import jakarta.jms.JMSContext; @@ -41,21 +41,21 @@ public class JMSDataStore implements DataStore { protected long timeoutInMs = -1; //For serializing Elide models to topics. - protected ObjectMapper objectMapper; + protected ElideMapper elideMapper; /** * Constructor. * @param models The set of models to manage. * @param connectionFactory The JMS connection factory. * @param dictionary The entity dictionary. - * @param objectMapper Object mapper for serializing/deserializing elide models to JMS topics. + * @param elideMapper Object mapper for serializing/deserializing elide models to JMS topics. * @param timeout request timeout in milliseconds. 0 means immediate. null means no timeout. */ public JMSDataStore( Set> models, ConnectionFactory connectionFactory, EntityDictionary dictionary, - ObjectMapper objectMapper, + ElideMapper elideMapper, Duration timeout ) { this.models = models.stream().collect(Collectors.toMap( @@ -70,7 +70,7 @@ public JMSDataStore( this.connectionFactory = connectionFactory; this.dictionary = dictionary; - this.objectMapper = objectMapper; + this.elideMapper = elideMapper; this.timeoutInMs = timeout != null ? timeout.toMillis() : -1; } @@ -79,21 +79,21 @@ public JMSDataStore( * @param scanner to scan for subscription annotations. * @param connectionFactory The JMS connection factory. * @param dictionary The entity dictionary. - * @param objectMapper Object mapper for serializing/deserializing elide models to JMS topics. + * @param elideMapper Object mapper for serializing/deserializing elide models to JMS topics. * @param timeout request timeout in milliseconds. 0 means immediate. null means no timeout. */ public JMSDataStore( ClassScanner scanner, ConnectionFactory connectionFactory, EntityDictionary dictionary, - ObjectMapper objectMapper, + ElideMapper elideMapper, Duration timeout ) { this( scanner.getAnnotatedClasses(Subscription.class, Include.class).stream() .map(ClassType::of) .collect(Collectors.toSet()), - connectionFactory, dictionary, objectMapper, timeout); + connectionFactory, dictionary, elideMapper, timeout); } @Override @@ -119,7 +119,7 @@ public void populateEntityDictionary(EntityDictionary dictionary) { @Override public DataStoreTransaction beginTransaction() { JMSContext context = connectionFactory.createContext(); - return new JMSDataStoreTransaction(context, dictionary, objectMapper, timeoutInMs); + return new JMSDataStoreTransaction(context, dictionary, elideMapper, timeoutInMs); } @Override diff --git a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStoreTransaction.java b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStoreTransaction.java index 1dd7a55273..af5317934f 100644 --- a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStoreTransaction.java +++ b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/JMSDataStoreTransaction.java @@ -8,6 +8,7 @@ import static com.yahoo.elide.graphql.subscriptions.SubscriptionModelBuilder.TOPIC_ARGUMENT; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.core.RequestScope; import com.yahoo.elide.core.datastore.DataStoreIterable; import com.yahoo.elide.core.datastore.DataStoreTransaction; @@ -16,7 +17,6 @@ import com.yahoo.elide.core.request.Argument; import com.yahoo.elide.core.request.EntityProjection; import com.yahoo.elide.graphql.subscriptions.hooks.TopicType; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.jms.Destination; import jakarta.jms.JMSConsumer; @@ -36,7 +36,7 @@ public class JMSDataStoreTransaction implements DataStoreTransaction { private JMSContext context; private EntityDictionary dictionary; - private ObjectMapper objectMapper; + private ElideMapper elideMapper; private long timeoutInMs; private List consumers; @@ -44,14 +44,14 @@ public class JMSDataStoreTransaction implements DataStoreTransaction { * Constructor. * @param context JMS Context * @param dictionary Elide Entity Dictionary - * @param objectMapper serializer to convert Elide models to topic messages. + * @param elideMapper serializer to convert Elide models to topic messages. * @param timeoutInMs request timeout in milliseconds. 0 means immediate. -1 means no timeout. */ - public JMSDataStoreTransaction(JMSContext context, EntityDictionary dictionary, ObjectMapper objectMapper, + public JMSDataStoreTransaction(JMSContext context, EntityDictionary dictionary, ElideMapper elideMapper, long timeoutInMs) { this.context = context; this.dictionary = dictionary; - this.objectMapper = objectMapper; + this.elideMapper = elideMapper; this.timeoutInMs = timeoutInMs; this.consumers = new ArrayList<>(); } @@ -97,7 +97,7 @@ public DataStoreIterable loadObjects(EntityProjection entityProjection, R return new MessageIterable<>( consumer, timeoutInMs, - new MessageDeserializer<>(entityProjection.getType(), objectMapper) + new MessageDeserializer<>(entityProjection.getType(), elideMapper) ); } diff --git a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/MessageDeserializer.java b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/MessageDeserializer.java index 3345ca7b31..e101857f56 100644 --- a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/MessageDeserializer.java +++ b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/MessageDeserializer.java @@ -6,14 +6,14 @@ package com.yahoo.elide.datastores.jms; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.core.exceptions.InternalServerErrorException; import com.yahoo.elide.core.type.Type; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.jms.JMSException; import jakarta.jms.Message; import jakarta.jms.TextMessage; +import tools.jackson.core.JacksonException; import java.util.function.Function; @@ -23,23 +23,24 @@ */ public class MessageDeserializer implements Function { private Type type; - private ObjectMapper objectMapper; + private ElideMapper elideMapper; /** * Constructor. * @param type The type to deserialize to. - * @param objectMapper serializer to convert Elide models to topic messages. + * @param elideMapper serializer to convert Elide models to topic messages. */ - public MessageDeserializer(Type type, ObjectMapper objectMapper) { + public MessageDeserializer(Type type, ElideMapper elideMapper) { this.type = type; - this.objectMapper = objectMapper; + this.elideMapper = elideMapper; } @Override public T apply(Message message) { try { - return (T) objectMapper.readValue(((TextMessage) message).getText(), type.getUnderlyingClass().get()); - } catch (JsonProcessingException | JMSException e) { + return (T) elideMapper.getObjectMapper().readValue(((TextMessage) message).getText(), + type.getUnderlyingClass().get()); + } catch (JacksonException | JMSException e) { throw new InternalServerErrorException(e); } } diff --git a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketConfigurator.java b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketConfigurator.java index 3aebaf1da2..9806f7b2c8 100644 --- a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketConfigurator.java +++ b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketConfigurator.java @@ -9,6 +9,7 @@ import static com.yahoo.elide.graphql.subscriptions.websocket.SubscriptionWebSocket.DEFAULT_USER_FACTORY; import com.yahoo.elide.Elide; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.ElideSettingsBuilderCustomizer; import com.yahoo.elide.core.datastore.DataStore; @@ -21,8 +22,6 @@ import com.yahoo.elide.graphql.serialization.GraphQLModule; import com.yahoo.elide.graphql.subscriptions.websocket.SubscriptionWebSocket; -import com.fasterxml.jackson.databind.ObjectMapper; - import graphql.execution.DataFetcherExceptionHandler; import graphql.execution.SimpleDataFetcherExceptionHandler; import jakarta.jms.ConnectionFactory; @@ -87,10 +86,10 @@ public T getEndpointInstance(Class endpointClass) throws InstantiationExc EntityDictionary dictionary = EntityDictionary.builder().injector(injector).build(); - ObjectMapper objectMapper; + ElideMapper elideMapper; ElideSettings.ElideSettingsBuilder builder = getElideSettingsBuilder(dictionary); - objectMapper = builder.build().getObjectMapper(); - DataStore store = buildDataStore(dictionary, objectMapper); + elideMapper = builder.build().getElideMapper(); + DataStore store = buildDataStore(dictionary, elideMapper); builder.dataStore(store); Elide elide = buildElide(builder); @@ -163,14 +162,15 @@ protected Elide buildElide(ElideSettings.ElideSettingsBuilder builder) { return elide; } - protected DataStore buildDataStore(EntityDictionary dictionary, ObjectMapper objectMapper) { + protected DataStore buildDataStore(EntityDictionary dictionary, ElideMapper elideMapper) { return new JMSDataStore( dictionary.getScanner(), - connectionFactory, dictionary, objectMapper, null); + connectionFactory, dictionary, elideMapper, null); } protected SubscriptionWebSocket buildWebSocket(Elide elide) { - elide.getObjectMapper().registerModule(new GraphQLModule()); + elide.getElideSettings().getElideMapper() + .customizeObjectMapper(builder -> builder.addModule(new GraphQLModule())); return SubscriptionWebSocket.builder() .elide(elide) diff --git a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketTestClient.java b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketTestClient.java index bef3341979..976b3fa2d0 100644 --- a/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketTestClient.java +++ b/elide-datastore/elide-datastore-jms/src/main/java/com/yahoo/elide/datastores/jms/websocket/SubscriptionWebSocketTestClient.java @@ -13,9 +13,6 @@ import com.yahoo.elide.graphql.subscriptions.websocket.protocol.MessageType; import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Next; import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Subscribe; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - import graphql.ExecutionResult; import jakarta.websocket.ClientEndpoint; import jakarta.websocket.CloseReason; @@ -25,6 +22,9 @@ import jakarta.websocket.OnOpen; import jakarta.websocket.Session; import lombok.extern.slf4j.Slf4j; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.util.ArrayList; import java.util.List; @@ -61,11 +61,9 @@ public SubscriptionWebSocketTestClient(int expectedNumberOfMessages, List deserializer = new MessageDeserializer(ClassType.of(Book.class), - new ObjectMapper()); + new ElideMapper(JsonMapper.shared())); Book book = deserializer.apply(message); assertEquals("Foo", book.getTitle()); diff --git a/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/MessageIterableTest.java b/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/MessageIterableTest.java index e1970cf723..6b18ae4ee7 100644 --- a/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/MessageIterableTest.java +++ b/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/MessageIterableTest.java @@ -12,14 +12,16 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.core.type.ClassType; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import jakarta.jms.JMSConsumer; import jakarta.jms.JMSRuntimeException; import jakarta.jms.TextMessage; +import tools.jackson.databind.json.JsonMapper; + import java.util.Iterator; public class MessageIterableTest { @@ -43,7 +45,7 @@ public void testIteratorMultipleItems() throws Exception { Iterator iterator = new MessageIterable( consumer, 1000, - new MessageDeserializer(ClassType.of(String.class), new ObjectMapper())).iterator(); + new MessageDeserializer(ClassType.of(String.class), new ElideMapper(JsonMapper.shared()))).iterator(); assertTrue(iterator.hasNext()); assertEquals("1", iterator.next()); @@ -67,7 +69,7 @@ public void testZeroTimeout() throws Exception { Iterator iterator = new MessageIterable( consumer, 0, - new MessageDeserializer(ClassType.of(String.class), new ObjectMapper())).iterator(); + new MessageDeserializer(ClassType.of(String.class), new ElideMapper(JsonMapper.shared()))).iterator(); assertTrue(iterator.hasNext()); assertEquals("1", iterator.next()); @@ -87,7 +89,7 @@ public void testNegativeTimeout() throws Exception { Iterator iterator = new MessageIterable( consumer, -1, - new MessageDeserializer(ClassType.of(String.class), new ObjectMapper())).iterator(); + new MessageDeserializer(ClassType.of(String.class), new ElideMapper(JsonMapper.shared()))).iterator(); assertTrue(iterator.hasNext()); assertEquals("1", iterator.next()); diff --git a/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/TestBinder.java b/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/TestBinder.java index d4f9250022..a22f65f47a 100644 --- a/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/TestBinder.java +++ b/elide-datastore/elide-datastore-jms/src/test/java/com/yahoo/elide/datastores/jms/TestBinder.java @@ -75,7 +75,7 @@ public Elide provide() { .connectionFactory(connectionFactory) .entityDictionary(elide.getElideSettings().getEntityDictionary()) .scanner(elide.getScanner()) - .objectMapper(elide.getElideSettings().getObjectMapper()) + .elideMapper(elide.getElideSettings().getElideMapper()) .build(); subscriptionScanner.bindLifecycleHooks(); diff --git a/elide-datastore/elide-datastore-jms/src/test/java/example/hooks/ChatBotCreateHook.java b/elide-datastore/elide-datastore-jms/src/test/java/example/hooks/ChatBotCreateHook.java index bdfe362310..12501f889a 100644 --- a/elide-datastore/elide-datastore-jms/src/test/java/example/hooks/ChatBotCreateHook.java +++ b/elide-datastore/elide-datastore-jms/src/test/java/example/hooks/ChatBotCreateHook.java @@ -8,12 +8,12 @@ import static example.Chat.CHAT; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.annotation.LifeCycleHookBinding; import com.yahoo.elide.core.lifecycle.LifeCycleHook; import com.yahoo.elide.core.security.ChangeSpec; import com.yahoo.elide.core.security.RequestScope; import com.yahoo.elide.graphql.subscriptions.hooks.NotifyTopicLifeCycleHook; -import com.fasterxml.jackson.databind.ObjectMapper; import example.Chat; import example.ChatBot; @@ -22,6 +22,8 @@ import jakarta.jms.JMSContext; import lombok.Data; +import tools.jackson.databind.json.JsonMapper; + import java.util.Optional; @Data @@ -40,7 +42,7 @@ public void execute( NotifyTopicLifeCycleHook publisher = new NotifyTopicLifeCycleHook<>( connectionFactory, - new ObjectMapper(), + new ElideMapper(JsonMapper.shared()), JMSContext::createProducer ); diff --git a/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonConverter.java b/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonConverter.java index bc19fb0f67..d64b55a646 100644 --- a/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonConverter.java +++ b/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonConverter.java @@ -7,13 +7,10 @@ package com.yahoo.elide.datastores.jpa.usertypes; import com.yahoo.elide.core.exceptions.InvalidValueException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; - -import java.io.IOException; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; /** * JsonType serializes an object to json string and vice versa. @@ -32,7 +29,7 @@ public JsonConverter(Class objectClass) { public String convertToDatabaseColumn(T value) { try { return MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new InvalidValueException("Unable to serialize", e); } } @@ -41,7 +38,7 @@ public String convertToDatabaseColumn(T value) { public T convertToEntityAttribute(String rawJson) { try { return MAPPER.readValue(rawJson, objectClass); - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidValueException("Unable to deserialize", e); } } diff --git a/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonType.java b/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonType.java index cd75e99bf1..8be2629b72 100644 --- a/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonType.java +++ b/elide-datastore/elide-datastore-jpa/src/test/java/com/yahoo/elide/datastores/jpa/usertypes/JsonType.java @@ -6,14 +6,14 @@ package com.yahoo.elide.datastores.jpa.usertypes; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.ParameterizedType; import org.hibernate.usertype.UserType; -import java.io.IOException; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; + import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -83,7 +83,7 @@ public Object nullSafeGet( try { return MAPPER.readValue(rawJson, this.objectClass); - } catch (IOException e) { + } catch (RuntimeException e) { throw new HibernateException("Could not retrieve an instance of the mapped class from a JDBC resultset."); } } @@ -101,7 +101,7 @@ public void nullSafeSet(PreparedStatement preparedStatement, Object value, int i try { String json = MAPPER.writeValueAsString(value); preparedStatement.setString(i, json); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new HibernateException("Could not write an instance of the mapped class to a prepared statement."); } } diff --git a/elide-datastore/elide-datastore-jpql/pom.xml b/elide-datastore/elide-datastore-jpql/pom.xml index ac78d15d64..e582091dc8 100644 --- a/elide-datastore/elide-datastore-jpql/pom.xml +++ b/elide-datastore/elide-datastore-jpql/pom.xml @@ -44,7 +44,7 @@ elide-core - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/elide-datastore/elide-datastore-jpql/src/main/java/com/yahoo/elide/datastores/jpql/query/JacksonCursorEncoder.java b/elide-datastore/elide-datastore-jpql/src/main/java/com/yahoo/elide/datastores/jpql/query/JacksonCursorEncoder.java index 20c2ee9bb3..15ce641e5f 100644 --- a/elide-datastore/elide-datastore-jpql/src/main/java/com/yahoo/elide/datastores/jpql/query/JacksonCursorEncoder.java +++ b/elide-datastore/elide-datastore-jpql/src/main/java/com/yahoo/elide/datastores/jpql/query/JacksonCursorEncoder.java @@ -7,12 +7,9 @@ import com.yahoo.elide.core.exceptions.InvalidValueException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; -import java.io.IOException; -import java.io.UncheckedIOException; import java.util.Base64; import java.util.Collections; import java.util.LinkedHashMap; @@ -38,12 +35,8 @@ public JacksonCursorEncoder(ObjectMapper objectMapper) { @Override public String encode(Map keys) { - try { - byte[] result = this.objectMapper.writeValueAsBytes(keys); - return Base64.getUrlEncoder().withoutPadding().encodeToString(result); - } catch (JsonProcessingException e) { - throw new UncheckedIOException(e); - } + byte[] result = this.objectMapper.writeValueAsBytes(keys); + return Base64.getUrlEncoder().withoutPadding().encodeToString(result); } @Override @@ -56,7 +49,7 @@ public Map decode(String cursor) { TypeReference> typeRef = new TypeReference>() { }; return this.objectMapper.readValue(result, typeRef); - } catch (IOException | IllegalArgumentException e) { + } catch (IllegalArgumentException e) { throw new InvalidValueException("cursor " + cursor); } } diff --git a/elide-datastore/elide-datastore-jpql/src/test/java/com/yahoo/elide/datastores/hibernate/AbstractHibernateTestService.java b/elide-datastore/elide-datastore-jpql/src/test/java/com/yahoo/elide/datastores/hibernate/AbstractHibernateTestService.java index 6f33d71a91..3fe0cd4766 100644 --- a/elide-datastore/elide-datastore-jpql/src/test/java/com/yahoo/elide/datastores/hibernate/AbstractHibernateTestService.java +++ b/elide-datastore/elide-datastore-jpql/src/test/java/com/yahoo/elide/datastores/hibernate/AbstractHibernateTestService.java @@ -14,8 +14,8 @@ import org.junit.jupiter.api.BeforeAll; import lombok.NoArgsConstructor; +import tools.jackson.core.JacksonException; -import java.io.IOException; import java.util.function.Supplier; @NoArgsConstructor @@ -51,7 +51,7 @@ protected void assertEqualDocuments(String actual, String expected) { JsonApiDocument expectedDoc = jsonApiMapper.readJsonApiDocument(expected); JsonApiDocument actualDoc = jsonApiMapper.readJsonApiDocument(actual); assertEquals(expectedDoc, actualDoc, "\n" + actual + "\n" + expected + "\n"); - } catch (IOException e) { + } catch (JacksonException e) { fail("\n" + actual + "\n" + expected + "\n", e); } } diff --git a/elide-datastore/elide-datastore-multiplex/pom.xml b/elide-datastore/elide-datastore-multiplex/pom.xml index 468e4aff31..467984df8f 100644 --- a/elide-datastore/elide-datastore-multiplex/pom.xml +++ b/elide-datastore/elide-datastore-multiplex/pom.xml @@ -46,7 +46,7 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind test diff --git a/elide-datastore/elide-datastore-noop/pom.xml b/elide-datastore/elide-datastore-noop/pom.xml index e41400e4d6..3c907b0c3a 100644 --- a/elide-datastore/elide-datastore-noop/pom.xml +++ b/elide-datastore/elide-datastore-noop/pom.xml @@ -38,11 +38,11 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - com.fasterxml.jackson.core + tools.jackson.core jackson-core diff --git a/elide-datastore/elide-datastore-noop/src/test/java/com/yahoo/elide/datastores/noop/NoopTransactionTest.java b/elide-datastore/elide-datastore-noop/src/test/java/com/yahoo/elide/datastores/noop/NoopTransactionTest.java index 044df456ef..a28ebb0e4e 100644 --- a/elide-datastore/elide-datastore-noop/src/test/java/com/yahoo/elide/datastores/noop/NoopTransactionTest.java +++ b/elide-datastore/elide-datastore-noop/src/test/java/com/yahoo/elide/datastores/noop/NoopTransactionTest.java @@ -16,11 +16,11 @@ import com.yahoo.elide.core.request.EntityProjection; import com.yahoo.elide.jsonapi.JsonApiMapper; import com.yahoo.elide.jsonapi.JsonApiRequestScope; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.collections4.IterableUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import tools.jackson.databind.ObjectMapper; @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class NoopTransactionTest { diff --git a/elide-datastore/elide-datastore-search/pom.xml b/elide-datastore/elide-datastore-search/pom.xml index 300018cd81..130e29597a 100644 --- a/elide-datastore/elide-datastore-search/pom.xml +++ b/elide-datastore/elide-datastore-search/pom.xml @@ -71,7 +71,7 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind test diff --git a/elide-graphql/pom.xml b/elide-graphql/pom.xml index b6b223a70a..3dd8b6569f 100644 --- a/elide-graphql/pom.xml +++ b/elide-graphql/pom.xml @@ -53,7 +53,7 @@ test - com.fasterxml.jackson.core + tools.jackson.core jackson-databind provided diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandler.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandler.java index 9101b36683..5863526fa8 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandler.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandler.java @@ -18,8 +18,6 @@ import com.yahoo.elide.core.exceptions.InvalidEntityBodyException; import com.yahoo.elide.core.exceptions.TransactionException; import com.yahoo.elide.graphql.models.GraphQLErrors; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; import graphql.GraphQLException; @@ -28,6 +26,9 @@ import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; +import tools.jackson.core.exc.StreamReadException; + import java.io.IOException; import java.io.UncheckedIOException; @@ -47,13 +48,17 @@ public DefaultGraphQLExceptionHandler(ExceptionLogger exceptionLogger, Exception @Override protected ElideResponse handleRuntimeException(RuntimeException exception, GraphQLErrorContext errorContext) { + if (exception instanceof JacksonException) { + return buildResponse(new InvalidEntityBodyException(errorContext.getGraphQLDocument()), errorContext); + } + if (exception instanceof GraphQLException e) { String body = e.getMessage(); return ElideResponse.status(HttpStatus.SC_OK).body(body); } if (exception instanceof InvalidEntityBodyException e) { - if (e.getCause() instanceof JsonParseException) { + if (e.getCause() instanceof StreamReadException) { return buildResponse(e, errorContext); } return buildResponse(HttpStatus.SC_OK, e, errorContext); @@ -92,10 +97,6 @@ protected ElideResponse handleRuntimeException(RuntimeException exception, Gr @Override protected ElideResponse handleNonRuntimeException(Exception exception, GraphQLErrorContext errorContext) { - if (exception instanceof JsonProcessingException) { - return buildResponse(new InvalidEntityBodyException(errorContext.getGraphQLDocument()), errorContext); - } - if (exception instanceof IOException) { return buildResponse(new TransactionException(exception), errorContext); } diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/DeferredId.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/DeferredId.java index 35e75d5728..44a779e0ee 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/DeferredId.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/DeferredId.java @@ -7,14 +7,11 @@ package com.yahoo.elide.graphql; import com.yahoo.elide.core.PersistentResource; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - import lombok.Getter; - -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; +import tools.jackson.databind.annotation.JsonSerialize; /** * The id for any given entity might be populated at transaction commit (as opposed to inline with the data fetch). @@ -33,10 +30,10 @@ public DeferredId(PersistentResource resource) { /** * Serializer for the id value of a {@link DeferredId} object. */ -class SerializeId extends JsonSerializer { +class SerializeId extends ValueSerializer { @Override public void serialize(DeferredId deferredId, JsonGenerator jsonGenerator, - SerializerProvider serializerProvider) throws IOException { - jsonGenerator.writeObject(deferredId.getResource().getId()); + SerializationContext serializerProvider) { + jsonGenerator.writePOJO(deferredId.getResource().getId()); } } diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/GraphQLErrorContext.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/GraphQLErrorContext.java index 32383c909b..bd5548d523 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/GraphQLErrorContext.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/GraphQLErrorContext.java @@ -6,10 +6,10 @@ package com.yahoo.elide.graphql; import com.yahoo.elide.core.exceptions.ErrorContext; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Builder; import lombok.Getter; +import tools.jackson.databind.ObjectMapper; /** * GraphQLErrorContext. diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/QueryRunner.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/QueryRunner.java index aee423add6..ff6f56eb9e 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/QueryRunner.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/QueryRunner.java @@ -17,10 +17,6 @@ import com.yahoo.elide.graphql.parser.GraphQLQuery; import com.yahoo.elide.graphql.parser.QueryParser; import com.yahoo.elide.graphql.serialization.GraphQLModule; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import graphql.ExecutionInput; import graphql.ExecutionResult; @@ -38,9 +34,13 @@ import graphql.validation.ValidationErrorType; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; import java.io.IOException; -import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -98,7 +98,8 @@ public QueryRunner(Elide elide, String apiVersion, DataFetcherExceptionHandler e .queryExecutionStrategy(new AsyncSerialExecutionStrategy(exceptionHandler)) .build(); - elide.getElideSettings().getObjectMapper().registerModule(new GraphQLModule()); + elide.getElideSettings().getElideMapper() + .customizeObjectMapper(mapperBuilder -> mapperBuilder.addModule(new GraphQLModule())); } /** @@ -186,7 +187,7 @@ public ElideResponse run(String baseUrlEndPoint, String graphQLDocument, try { queries = new QueryParser() { }.parseDocument(graphQLDocument, mapper); - } catch (IOException e) { + } catch (JacksonException e) { log.debug("Invalid json body provided to GraphQL", e); return QueryRunner.handleRuntimeException(elide, new InvalidEntityBodyException(graphQLDocument, e)); } @@ -207,8 +208,8 @@ public ElideResponse run(String baseUrlEndPoint, String graphQLDocument, try { String body = mapper.writeValueAsString(response.getBody()); return mapper.readTree(body); - } catch (IOException e) { - log.debug("Caught an IO exception while trying to read response body"); + } catch (RuntimeException e) { + log.debug("Caught a runtime exception while trying to read response body"); return JsonNodeFactory.instance.objectNode(); } }) @@ -224,13 +225,9 @@ private static ElideResponse map(ElideResponse response, ObjectMapper if (response.getBody() instanceof String string) { return ElideResponse.status(response.getStatus()).body(string); } else { - try { - Object body = response.getBody(); - return ElideResponse.status(response.getStatus()) - .body(body != null ? objectMapper.writeValueAsString(body) : null); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + Object body = response.getBody(); + return ElideResponse.status(response.getStatus()) + .body(body != null ? objectMapper.writeValueAsString(body) : null); } } @@ -240,7 +237,7 @@ private static ElideResponse map(ElideResponse response, ObjectMapper * @return query to execute. */ public static String extractQuery(JsonNode jsonDocument) { - return jsonDocument.has(QUERY) ? jsonDocument.get(QUERY).asText() : null; + return jsonDocument.has(QUERY) ? jsonDocument.get(QUERY).asString() : null; } /** @@ -266,7 +263,7 @@ public static Map extractVariables(ObjectMapper mapper, JsonNode */ public static String extractOperation(JsonNode jsonDocument) { if (jsonDocument.has(OPERATION_NAME) && !jsonDocument.get(OPERATION_NAME).isNull()) { - return jsonDocument.get(OPERATION_NAME).asText(); + return jsonDocument.get(OPERATION_NAME).asString(); } return null; diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/models/GraphQLError.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/models/GraphQLError.java index f563a915cc..ad892b07a1 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/models/GraphQLError.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/models/GraphQLError.java @@ -9,11 +9,11 @@ import com.yahoo.elide.graphql.serialization.GraphQLErrorSerializer; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - import graphql.ErrorClassification; import graphql.language.SourceLocation; +import tools.jackson.databind.annotation.JsonSerialize; + import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/parser/QueryParser.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/parser/QueryParser.java index 5691ffb917..f301105990 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/parser/QueryParser.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/parser/QueryParser.java @@ -6,10 +6,9 @@ package com.yahoo.elide.graphql.parser; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -30,9 +29,8 @@ public interface QueryParser { * @param message The document to parse. * @param mapper An object mapper to do JSON parsing. * @return A list of 1 or more parsed GraphQL queries. - * @throws IOException If there is a JSON processing error. */ - default List parseDocument(String message, ObjectMapper mapper) throws IOException { + default List parseDocument(String message, ObjectMapper mapper) { List results = new ArrayList<>(); JsonNode topLevel = mapper.readTree(message); @@ -56,10 +54,9 @@ default List parseDocument(String message, ObjectMapper mapper) th * @param topLevel The query JsonNode to further parse. * @param mapper An object mapper to do JSON parsing. * @return A parsed GraphQL queries. - * @throws IOException If there is a JSON processing error. */ - default GraphQLQuery parseQuery(JsonNode topLevel, ObjectMapper mapper) throws IOException { - String query = topLevel.has(QUERY) ? topLevel.get(QUERY).asText() : null; + default GraphQLQuery parseQuery(JsonNode topLevel, ObjectMapper mapper) { + String query = topLevel.has(QUERY) ? topLevel.get(QUERY).asString() : null; String operationName = ""; Map variables = new HashMap<>(); @@ -68,7 +65,7 @@ default GraphQLQuery parseQuery(JsonNode topLevel, ObjectMapper mapper) throws I } if (topLevel.has(OPERATION_NAME) && !topLevel.get(OPERATION_NAME).isNull()) { - operationName = topLevel.get(OPERATION_NAME).asText(); + operationName = topLevel.get(OPERATION_NAME).asString(); } return new GraphQLQuery(query, operationName, variables); diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultDeserializer.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultDeserializer.java index 5b4241f92f..aad7307f36 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultDeserializer.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultDeserializer.java @@ -6,16 +6,15 @@ package com.yahoo.elide.graphql.serialization; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - import graphql.ExecutionResult; import graphql.ExecutionResultImpl; import graphql.GraphQLError; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.deser.std.StdDeserializer; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -25,15 +24,13 @@ * Deserializes JSON into an Execution Result. */ public class ExecutionResultDeserializer extends StdDeserializer { - private static final long serialVersionUID = 1L; - public ExecutionResultDeserializer() { super(ExecutionResult.class); } @Override - public ExecutionResult deserialize(JsonParser parser, DeserializationContext context) throws IOException { - JsonNode root = parser.getCodec().readTree(parser); + public ExecutionResult deserialize(JsonParser parser, DeserializationContext context) { + JsonNode root = context.readTree(parser); JsonNode dataNode = root.get("data"); JsonNode errorsNode = root.get("errors"); @@ -45,12 +42,12 @@ public ExecutionResult deserialize(JsonParser parser, DeserializationContext con Iterator nodeIterator = errorsNode.iterator(); while (nodeIterator.hasNext()) { JsonNode errorNode = nodeIterator.next(); - errors.add(parser.getCodec().treeToValue(errorNode, GraphQLError.class)); + errors.add(context.readTreeAsValue(errorNode, GraphQLError.class)); } } @SuppressWarnings("unchecked") - Map data = parser.getCodec().treeToValue(dataNode, Map.class); + Map data = context.readTreeAsValue(dataNode, Map.class); return ExecutionResultImpl.newExecutionResult() .errors(errors) diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultSerializer.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultSerializer.java index 9f67c9661d..a49319c36a 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultSerializer.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/ExecutionResultSerializer.java @@ -5,14 +5,13 @@ */ package com.yahoo.elide.graphql.serialization; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import graphql.ExecutionResult; import graphql.GraphQLError; -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ser.std.StdSerializer; + import java.util.List; import java.util.Map; @@ -23,32 +22,33 @@ * optional encoding of the error message by having the {@link GraphQLErrorSerializer} registered on the ObjectMapper. */ public class ExecutionResultSerializer extends StdSerializer { - private static final long serialVersionUID = 1L; - public ExecutionResultSerializer() { super(ExecutionResult.class); } @Override - public void serialize(ExecutionResult value, JsonGenerator gen, SerializerProvider provider) throws IOException { + public void serialize(ExecutionResult value, JsonGenerator gen, SerializationContext provider) { // mimic the ExecutionResult.toSpecification response gen.writeStartObject(); Map spec = value.toSpecification(); if (spec.containsKey("data")) { - gen.writeObjectField("data", spec.get("data")); + gen.writeName("data"); + gen.writePOJO(spec.get("data")); } if (spec.containsKey("errors")) { List errors = value.getErrors(); - gen.writeArrayFieldStart("errors"); + gen.writeName("errors"); + gen.writeStartArray(); for (GraphQLError error : errors) { - gen.writeObject(error); + gen.writePOJO(error); } gen.writeEndArray(); } if (spec.containsKey("extensions")) { - gen.writeObjectField("extensions", spec.get("extensions")); + gen.writeName("extensions"); + gen.writePOJO(spec.get("extensions")); } gen.writeEndObject(); diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorDeserializer.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorDeserializer.java index ae322a1fe3..37026e3886 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorDeserializer.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorDeserializer.java @@ -6,16 +6,15 @@ package com.yahoo.elide.graphql.serialization; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - import graphql.ErrorClassification; import graphql.GraphQLError; import graphql.language.SourceLocation; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.deser.std.StdDeserializer; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -25,8 +24,6 @@ * Deserializes JSON into a GraphQLError. */ public class GraphQLErrorDeserializer extends StdDeserializer { - private static final long serialVersionUID = 1L; - /** * Constructor. */ @@ -36,15 +33,15 @@ public GraphQLErrorDeserializer() { @SuppressWarnings("unchecked") @Override - public GraphQLError deserialize(JsonParser parser, DeserializationContext context) throws IOException { - JsonNode root = parser.getCodec().readTree(parser); + public GraphQLError deserialize(JsonParser parser, DeserializationContext context) { + JsonNode root = context.readTree(parser); JsonNode messageNode = root.get("message"); JsonNode pathNode = root.get("path"); JsonNode sourceLocations = root.get("locations"); JsonNode extensions = root.get("extensions"); Map extensionsMap = extensions == null ? Collections.emptyMap() - : parser.getCodec().treeToValue(extensions, Map.class); + : context.readTreeAsValue(extensions, Map.class); return new GraphQLError() { private static final long serialVersionUID = 1L; @@ -59,7 +56,7 @@ public String toString() { @Override public String getMessage() { - return messageNode == null ? null : messageNode.textValue(); + return messageNode == null ? null : messageNode.stringValue(); } @Override @@ -97,7 +94,7 @@ public List getPath() { if (pathNode != null) { List paths = new ArrayList<>(); pathNode.forEach(path -> - paths.add(path.asText()) + paths.add(path.asString()) ); return paths; } diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorSerializer.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorSerializer.java index 58fb2949fc..cc7deb4120 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorSerializer.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLErrorSerializer.java @@ -5,14 +5,14 @@ */ package com.yahoo.elide.graphql.serialization; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; import org.owasp.encoder.Encode; import graphql.GraphQLError; -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ser.std.StdSerializer; + import java.util.Map; /** @@ -20,9 +20,6 @@ * Supports encoding of the error's message field, making it safe for display in HTML. */ public class GraphQLErrorSerializer extends StdSerializer { - - private static final long serialVersionUID = 1L; - /** * Construct a new GraphQLErrorSerializer, optionally with error encoding enabled. */ @@ -31,25 +28,26 @@ public GraphQLErrorSerializer() { } @Override - public void serialize(GraphQLError value, JsonGenerator gen, SerializerProvider provider) throws IOException { + public void serialize(GraphQLError value, JsonGenerator gen, SerializationContext provider) { Map errorSpec = value.toSpecification(); gen.writeStartObject(); - gen.writeStringField("message", Encode.forHtml((String) errorSpec.get("message"))); + gen.writeName("message"); + gen.writeString(Encode.forHtml((String) errorSpec.get("message"))); if (errorSpec.containsKey("locations")) { - gen.writeFieldName("locations"); - gen.writeObject(errorSpec.get("locations")); + gen.writeName("locations"); + gen.writePOJO(errorSpec.get("locations")); } if (errorSpec.containsKey("path")) { - gen.writeFieldName("path"); - gen.writeObject(errorSpec.get("path")); + gen.writeName("path"); + gen.writePOJO(errorSpec.get("path")); } if (errorSpec.containsKey("extensions")) { - gen.writeFieldName("extensions"); - gen.writeObject(errorSpec.get("extensions")); + gen.writeName("extensions"); + gen.writePOJO(errorSpec.get("extensions")); } gen.writeEndObject(); diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLModule.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLModule.java index 7d03d22fa0..e5a7dd6462 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLModule.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/serialization/GraphQLModule.java @@ -5,12 +5,12 @@ */ package com.yahoo.elide.graphql.serialization; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.databind.module.SimpleModule; - import graphql.ExecutionResult; import graphql.GraphQLError; +import tools.jackson.core.Version; +import tools.jackson.databind.module.SimpleModule; + /** * GraphQL Module. */ diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHook.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHook.java index 162572fb56..b8b077f281 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHook.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHook.java @@ -6,6 +6,7 @@ package com.yahoo.elide.graphql.subscriptions.hooks; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.annotation.LifeCycleHookBinding; import com.yahoo.elide.core.PersistentResource; import com.yahoo.elide.core.lifecycle.CRUDEvent; @@ -13,8 +14,6 @@ import com.yahoo.elide.core.security.ChangeSpec; import com.yahoo.elide.core.security.RequestScope; import com.yahoo.elide.core.type.Type; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.inject.Inject; import jakarta.jms.ConnectionFactory; @@ -23,6 +22,7 @@ import jakarta.jms.JMSProducer; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; import java.util.Optional; import java.util.function.Function; @@ -41,19 +41,19 @@ public class NotifyTopicLifeCycleHook implements LifeCycleHook { private ConnectionFactory connectionFactory; @Inject - private ObjectMapper objectMapper; + private ElideMapper elideMapper; @Inject private Function createProducer; public NotifyTopicLifeCycleHook( ConnectionFactory connectionFactory, - ObjectMapper objectMapper, + ElideMapper elideMapper, Function createProducer ) { this.connectionFactory = connectionFactory; this.createProducer = createProducer; - this.objectMapper = objectMapper; + this.elideMapper = elideMapper; } @Override @@ -93,10 +93,10 @@ public void publish(T object, String topicName) { Destination destination = context.createTopic(topicName); try { - String message = objectMapper.writeValueAsString(object); + String message = elideMapper.getObjectMapper().writeValueAsString(object); log.debug("Serializing {}", message); producer.send(destination, message); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalStateException(e); } } diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScanner.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScanner.java index 2ca231e478..2afde94c02 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScanner.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScanner.java @@ -6,6 +6,7 @@ package com.yahoo.elide.graphql.subscriptions.hooks; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.annotation.LifeCycleHookBinding; import com.yahoo.elide.core.dictionary.EntityDictionary; import com.yahoo.elide.core.type.ClassType; @@ -14,7 +15,6 @@ import com.yahoo.elide.graphql.subscriptions.annotations.Subscription; import com.yahoo.elide.graphql.subscriptions.annotations.SubscriptionField; import com.yahoo.elide.graphql.subscriptions.serialization.GraphQLSubscriptionModule; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Preconditions; import jakarta.jms.ConnectionFactory; @@ -31,7 +31,7 @@ @Builder public class SubscriptionScanner { private ConnectionFactory connectionFactory; - private ObjectMapper objectMapper; + private ElideMapper elideMapper; private EntityDictionary entityDictionary; private ClassScanner scanner; @@ -45,8 +45,10 @@ public class SubscriptionScanner { private int messagePriority = Message.DEFAULT_PRIORITY; public void bindLifecycleHooks() { - - ObjectMapper objectMapper = this.objectMapper.copy().registerModule(new GraphQLSubscriptionModule()); + this.elideMapper = new ElideMapper(this.elideMapper.getObjectMapper()); // Create a copy as the + // GraphQLSubscriptionModule clears + // fields + this.elideMapper.customizeObjectMapper(builder -> builder.addModule(new GraphQLSubscriptionModule())); Function producerFactory = (context) -> { JMSProducer producer = context.createProducer(); @@ -66,7 +68,7 @@ public void bindLifecycleHooks() { for (Subscription.Operation operation : operations) { switch (operation) { case UPDATE: { - addUpdateHooks(ClassType.of(modelType), entityDictionary, producerFactory, objectMapper); + addUpdateHooks(ClassType.of(modelType), entityDictionary, producerFactory, elideMapper); break; } case DELETE: { @@ -74,7 +76,7 @@ public void bindLifecycleHooks() { modelType, LifeCycleHookBinding.Operation.DELETE, LifeCycleHookBinding.TransactionPhase.POSTCOMMIT, - new NotifyTopicLifeCycleHook(connectionFactory, objectMapper, producerFactory), + new NotifyTopicLifeCycleHook(connectionFactory, elideMapper, producerFactory), false ); break; @@ -84,7 +86,7 @@ public void bindLifecycleHooks() { modelType, LifeCycleHookBinding.Operation.CREATE, LifeCycleHookBinding.TransactionPhase.POSTCOMMIT, - new NotifyTopicLifeCycleHook(connectionFactory, objectMapper, producerFactory), + new NotifyTopicLifeCycleHook(connectionFactory, elideMapper, producerFactory), false ); break; @@ -98,7 +100,7 @@ protected void addUpdateHooks( Type model, EntityDictionary dictionary, Function producerFactory, - ObjectMapper objectMapper + ElideMapper elideMapper ) { dictionary.getAllExposedFields(model).stream().forEach(fieldName -> { SubscriptionField subscriptionField = @@ -110,7 +112,7 @@ protected void addUpdateHooks( fieldName, LifeCycleHookBinding.Operation.UPDATE, LifeCycleHookBinding.TransactionPhase.POSTCOMMIT, - new NotifyTopicLifeCycleHook(connectionFactory, objectMapper, producerFactory) + new NotifyTopicLifeCycleHook(connectionFactory, elideMapper, producerFactory) ); } }); diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/GraphQLSubscriptionModule.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/GraphQLSubscriptionModule.java index f470934b32..05811adf01 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/GraphQLSubscriptionModule.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/GraphQLSubscriptionModule.java @@ -5,8 +5,8 @@ */ package com.yahoo.elide.graphql.subscriptions.serialization; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.databind.module.SimpleModule; +import tools.jackson.core.Version; +import tools.jackson.databind.module.SimpleModule; /** * GraphQL Subscription Module. @@ -21,6 +21,6 @@ public GraphQLSubscriptionModule() { @Override public void setupModule(SetupContext context) { super.setupModule(context); - context.addBeanSerializerModifier(new SubscriptionBeanSerializerModifier()); + context.addSerializerModifier(new SubscriptionBeanSerializerModifier()); } } diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifier.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifier.java index 4f0847f827..32f58abd80 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifier.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifier.java @@ -8,23 +8,25 @@ import com.yahoo.elide.core.dictionary.EntityBinding; import com.yahoo.elide.graphql.subscriptions.annotations.SubscriptionField; -import com.fasterxml.jackson.databind.BeanDescription; -import com.fasterxml.jackson.databind.SerializationConfig; -import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; -import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; +import tools.jackson.databind.BeanDescription; +import tools.jackson.databind.SerializationConfig; +import tools.jackson.databind.ser.BeanPropertyWriter; +import tools.jackson.databind.ser.ValueSerializerModifier; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; /** - * {@link BeanSerializerModifier} that only serializes ID fields and fields annotated + * {@link ValueSerializerModifier} that only serializes ID fields and fields annotated * with SubscriptionField. */ -public class SubscriptionBeanSerializerModifier extends BeanSerializerModifier { +public class SubscriptionBeanSerializerModifier extends ValueSerializerModifier { + + private static final long serialVersionUID = 1L; @Override - public List changeProperties(SerializationConfig config, BeanDescription beanDesc, + public List changeProperties(SerializationConfig config, BeanDescription.Supplier beanDesc, List beanProperties) { List result = new ArrayList<>(); for (BeanPropertyWriter beanProperty : beanProperties) { diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/RequestHandler.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/RequestHandler.java index bbd51da29b..82f10b509a 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/RequestHandler.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/RequestHandler.java @@ -21,8 +21,6 @@ import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Next; import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Ping; import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Subscribe; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; @@ -34,6 +32,8 @@ import graphql.GraphQLError; import graphql.language.SourceLocation; import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import java.io.Closeable; import java.io.IOException; @@ -121,7 +121,7 @@ public void handleRequest(Subscribe subscribeRequest) { try { responseBody = elide.getObjectMapper().writeValueAsString(response.getBody()); safeSendError(responseBody); - } catch (JsonProcessingException e1) { + } catch (JacksonException e1) { safeSendError(e1.toString()); } safeClose(); @@ -194,12 +194,12 @@ protected void sendMessage(String message) { } protected void safeSendPing() { - ObjectMapper mapper = elide.getElideSettings().getObjectMapper(); + ObjectMapper mapper = elide.getElideSettings().getElideMapper().getObjectMapper(); Ping ping = new Ping(); try { sendMessage(mapper.writeValueAsString(ping)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error("UNEXPECTED Json Serialization Error {}", e.getMessage()); safeClose(); } @@ -207,14 +207,14 @@ protected void safeSendPing() { protected void safeSendNext(ExecutionResult result) { log.debug("Sending Next {}", result); - ObjectMapper mapper = elide.getElideSettings().getObjectMapper(); + ObjectMapper mapper = elide.getElideSettings().getElideMapper().getObjectMapper(); Next next = Next.builder() .result(result) .id(protocolID) .build(); try { sendMessage(mapper.writeValueAsString(next)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error("UNEXPECTED Json Serialization Error {}", e.getMessage()); safeClose(); } @@ -222,13 +222,13 @@ protected void safeSendNext(ExecutionResult result) { protected void safeSendComplete() { log.debug("Sending Complete"); - ObjectMapper mapper = elide.getElideSettings().getObjectMapper(); + ObjectMapper mapper = elide.getElideSettings().getElideMapper().getObjectMapper(); Complete complete = Complete.builder() .id(protocolID) .build(); try { sendMessage(mapper.writeValueAsString(complete)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error("UNEXPECTED Json Serialization Error {}", e.getMessage()); safeClose(); } @@ -236,14 +236,14 @@ protected void safeSendComplete() { protected void safeSendError(GraphQLError[] errors) { log.debug("Sending Error {}", errors); - ObjectMapper mapper = elide.getElideSettings().getObjectMapper(); + ObjectMapper mapper = elide.getElideSettings().getElideMapper().getObjectMapper(); Error error = Error.builder() .id(protocolID) .payload(errors) .build(); try { sendMessage(mapper.writeValueAsString(error)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error("UNEXPECTED Json Serialization Error {}", e.getMessage()); safeClose(); } @@ -252,6 +252,8 @@ protected void safeSendError(GraphQLError[] errors) { protected void safeSendError(String message) { GraphQLError error = new GraphQLError() { + private static final long serialVersionUID = 1L; + @Override public String getMessage() { return message; diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/SessionHandler.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/SessionHandler.java index dae07f6318..f0faaea27e 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/SessionHandler.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/SessionHandler.java @@ -22,15 +22,15 @@ import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Pong; import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Subscribe; import com.yahoo.elide.graphql.subscriptions.websocket.protocol.WebSocketCloseReasons; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Preconditions; import graphql.GraphQL; import jakarta.websocket.CloseReason; import jakarta.websocket.Session; import lombok.extern.slf4j.Slf4j; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import java.io.IOException; import java.time.Duration; @@ -149,7 +149,7 @@ public void handleRequest(String message) { MessageType messageType; try { - messageType = MessageType.valueOf(type.textValue().toUpperCase(Locale.ROOT)); + messageType = MessageType.valueOf(type.stringValue().toUpperCase(Locale.ROOT)); } catch (IllegalArgumentException e) { safeClose(INVALID_MESSAGE); return; @@ -182,7 +182,7 @@ public void handleRequest(String message) { return; } } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { safeClose(INVALID_MESSAGE); } } @@ -248,24 +248,24 @@ protected void handleComplete(Complete complete) { } protected void safeSendConnectionAck() { - ObjectMapper mapper = elide.getElideSettings().getObjectMapper(); + ObjectMapper mapper = elide.getElideSettings().getElideMapper().getObjectMapper(); ConnectionAck ack = new ConnectionAck(); try { sendMessage(mapper.writeValueAsString(ack)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error("UNEXPECTED Json Serialization Error {}", e.getMessage()); safeClose(INTERNAL_ERROR); } } protected void safeSendPong() { - ObjectMapper mapper = elide.getElideSettings().getObjectMapper(); + ObjectMapper mapper = elide.getElideSettings().getElideMapper().getObjectMapper(); Pong pong = new Pong(); try { sendMessage(mapper.writeValueAsString(pong)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error("UNEXPECTED Json Serialization Error {}", e.getMessage()); safeClose(INTERNAL_ERROR); } diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Error.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Error.java index 5b9407c934..9ad81477b9 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Error.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Error.java @@ -10,13 +10,14 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import graphql.GraphQLError; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Value; +import tools.jackson.databind.annotation.JsonDeserialize; + /** * Error occurred during setup of the subscription (server to client). */ diff --git a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Next.java b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Next.java index 451dd06114..6462bc6729 100644 --- a/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Next.java +++ b/elide-graphql/src/main/java/com/yahoo/elide/graphql/subscriptions/websocket/protocol/Next.java @@ -11,13 +11,13 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import graphql.ExecutionResult; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Value; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; /** * Next subscription message (server to client). diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLErrorMapperTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLErrorMapperTest.java index d4dc47d479..e1249f2107 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLErrorMapperTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLErrorMapperTest.java @@ -12,15 +12,15 @@ import com.yahoo.elide.graphql.models.SourceLocationBuilder; import com.yahoo.elide.graphql.serialization.GraphQLModule; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import graphql.GraphQLError; import graphql.execution.ResultPath; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import java.util.List; import java.util.Map; @@ -29,16 +29,16 @@ */ class DefaultGraphQLErrorMapperTest { - private ObjectMapper objectMapper = new ObjectMapper(); + private ObjectMapper objectMapper; private GraphQLErrorMapper mapper = new DefaultGraphQLErrorMapper(); @BeforeEach public void setup() { - objectMapper.registerModule(new GraphQLModule()); + objectMapper = JsonMapper.builder().addModule(new GraphQLModule()).build(); } @Test - void toGraphQLError() throws JsonProcessingException { + void toGraphQLError() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("") @@ -54,7 +54,7 @@ void toGraphQLError() throws JsonProcessingException { } @Test - void toGraphQLErrorExtensions() throws JsonProcessingException { + void toGraphQLErrorExtensions() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("message") @@ -67,7 +67,7 @@ void toGraphQLErrorExtensions() throws JsonProcessingException { } @Test - void toGraphQLErrorLinks() throws JsonProcessingException { + void toGraphQLErrorLinks() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("message") @@ -80,7 +80,7 @@ void toGraphQLErrorLinks() throws JsonProcessingException { } @Test - void toGraphQLErrorSource() throws JsonProcessingException { + void toGraphQLErrorSource() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("message") @@ -93,7 +93,7 @@ void toGraphQLErrorSource() throws JsonProcessingException { } @Test - void toGraphQLErrorClassification() throws JsonProcessingException { + void toGraphQLErrorClassification() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("message") @@ -106,7 +106,7 @@ void toGraphQLErrorClassification() throws JsonProcessingException { } @Test - void toGraphQLErrorPath() throws JsonProcessingException { + void toGraphQLErrorPath() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("message") @@ -119,7 +119,7 @@ void toGraphQLErrorPath() throws JsonProcessingException { } @Test - void toGraphQLErrorResultPath() throws JsonProcessingException { + void toGraphQLErrorResultPath() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("message") @@ -132,7 +132,7 @@ void toGraphQLErrorResultPath() throws JsonProcessingException { } @Test - void toGraphQLErrorLocations() throws JsonProcessingException { + void toGraphQLErrorLocations() { GraphQLError graphqlError = mapper .toGraphQLError(ElideError.builder() .message("message") diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandlerTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandlerTest.java index fa07ac97c7..42515aef38 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandlerTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/DefaultGraphQLExceptionHandlerTest.java @@ -16,10 +16,6 @@ import com.yahoo.elide.core.exceptions.InvalidEntityBodyException; import com.yahoo.elide.core.exceptions.Slf4jExceptionLogger; import com.yahoo.elide.graphql.models.GraphQLErrors; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.JsonMappingException; - import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -37,6 +33,10 @@ import jakarta.validation.constraints.NotNull; import jakarta.ws.rs.WebApplicationException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.exc.StreamReadException; +import tools.jackson.databind.DatabindException; + import java.io.IOException; import java.util.List; import java.util.Set; @@ -54,8 +54,8 @@ enum ExceptionStatusInput { INVALID_API(new InvalidApiVersionException(""), GraphQLErrorContext.builder().build(), 400), INVALID_ENTITY_BODY(new InvalidEntityBodyException(""), GraphQLErrorContext.builder().build(), 200), INVALID_CONSTRAINT(new InvalidConstraintException(""), GraphQLErrorContext.builder().build(), 200), - INVALID_ENTITY_BODY_JSON_PARSE(new InvalidEntityBodyException("", new JsonParseException("")), GraphQLErrorContext.builder().build(), 400), - JSON_PROCESSING(JsonMappingException.from((JsonParser) null, ""), GraphQLErrorContext.builder().build(), 400), + INVALID_ENTITY_BODY_JSON_PARSE(new InvalidEntityBodyException("", new StreamReadException("")), GraphQLErrorContext.builder().build(), 400), + JSON_PROCESSING(DatabindException.from((JsonParser) null, ""), GraphQLErrorContext.builder().build(), 400), IO(new IOException(""), GraphQLErrorContext.builder().build(), 423), ; diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/ExecutionResultDeserializerTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/ExecutionResultDeserializerTest.java index 7ad9050770..caf9ebd7f4 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/ExecutionResultDeserializerTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/ExecutionResultDeserializerTest.java @@ -13,9 +13,6 @@ import com.yahoo.elide.graphql.serialization.ExecutionResultDeserializer; import com.yahoo.elide.graphql.serialization.GraphQLErrorDeserializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -24,6 +21,10 @@ import graphql.GraphQLError; import graphql.language.SourceLocation; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; + import java.util.Map; @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -32,16 +33,15 @@ public class ExecutionResultDeserializerTest { @BeforeAll public void init() { - mapper = new ObjectMapper(); - mapper.registerModule(new SimpleModule("ExecutionResult") + mapper = JsonMapper.builder().addModule(new SimpleModule("ExecutionResult") .addDeserializer(GraphQLError.class, new GraphQLErrorDeserializer()) .addDeserializer(ExecutionResult.class, new ExecutionResultDeserializer()) - ); + ).build(); } @Test public void testDeserialization() throws Exception { - String resultText = "{\"data\":{\"book\":{\"id\":\"1\",\"title\":null}},\"errors\":[{\"message\":\"Exception while fetching data (/book/title) : Bad Request\",\"locations\":[{\"line\":1,\"column\":38}],\"path\":[\"book\",\"title\"],\"extensions\":{\"classification\":\"DataFetchingException\"}}]}}"; + String resultText = "{\"data\":{\"book\":{\"id\":\"1\",\"title\":null}},\"errors\":[{\"message\":\"Exception while fetching data (/book/title) : Bad Request\",\"locations\":[{\"line\":1,\"column\":38}],\"path\":[\"book\",\"title\"],\"extensions\":{\"classification\":\"DataFetchingException\"}}]}"; ExecutionResult result = mapper.readValue(resultText, ExecutionResult.class); @@ -63,7 +63,7 @@ public void testDeserialization() throws Exception { @Test public void testDeserializationWithMissingData() throws Exception { - String resultText = "{\"errors\":[{\"message\":\"Exception while fetching data (/book/title) : Bad Request\",\"locations\":[{\"line\":1,\"column\":38}],\"path\":[\"book\",\"title\"],\"extensions\":{\"classification\":\"DataFetchingException\"}}]}}"; + String resultText = "{\"errors\":[{\"message\":\"Exception while fetching data (/book/title) : Bad Request\",\"locations\":[{\"line\":1,\"column\":38}],\"path\":[\"book\",\"title\"],\"extensions\":{\"classification\":\"DataFetchingException\"}}]}"; ExecutionResult result = mapper.readValue(resultText, ExecutionResult.class); diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLEndpointTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLEndpointTest.java index 125ef1e3a7..a0a241ebfe 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLEndpointTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLEndpointTest.java @@ -36,10 +36,6 @@ import com.yahoo.elide.core.security.checks.Check; import com.yahoo.elide.core.utils.DefaultClassScanner; import com.yahoo.elide.graphql.GraphQLSettings.GraphQLSettingsBuilder; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.Sets; import example.models.versioned.BookV2; import org.json.JSONException; @@ -65,6 +61,11 @@ import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.UriInfo; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; + import java.io.IOException; import java.net.URI; import java.security.Principal; @@ -401,9 +402,9 @@ void testCrypticErrorOnUpsert() throws IOException, JSONException { Response response = endpoint.post("", uriInfo, requestHeaders, user2, graphQLRequestToJSON(graphQLRequest)); JsonNode node = extract200Response(response); - Iterator errors = node.get("errors").elements(); + Iterator errors = node.get("errors").iterator(); assertTrue(errors.hasNext()); - assertTrue(errors.next().get("message").asText().contains("No id provided, cannot persist incidents")); + assertTrue(errors.next().get("message").asString().contains("No id provided, cannot persist incidents")); verify(exceptionMappers).toErrorResponse(any(), any()); } @@ -1246,7 +1247,7 @@ private static void assert200EqualBody(Response response, String expected) throw private static void assert200DataEqual(Response response, String expected) throws IOException, JSONException { JsonNode actualNode = extract200Response(response); - Iterator> iterator = actualNode.fields(); + Iterator> iterator = actualNode.properties().iterator(); // get json node that has "data" key String actual = null; @@ -1262,6 +1263,6 @@ private static void assert200DataEqual(Response response, String expected) throw private static void assertHasErrors(Response response) throws IOException { JsonNode node = extract200Response(response); - assertTrue(node.get("errors").elements().hasNext()); + assertTrue(node.get("errors").iterator().hasNext()); } } diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLErrorDeserializerTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLErrorDeserializerTest.java index f446672fe5..4078943894 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLErrorDeserializerTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/GraphQLErrorDeserializerTest.java @@ -12,9 +12,6 @@ import com.yahoo.elide.graphql.serialization.GraphQLErrorDeserializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -22,15 +19,18 @@ import graphql.GraphQLError; import graphql.language.SourceLocation; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; + @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class GraphQLErrorDeserializerTest { private ObjectMapper mapper; @BeforeAll public void init() { - mapper = new ObjectMapper(); - mapper.registerModule(new SimpleModule("GraphQLError") - .addDeserializer(GraphQLError.class, new GraphQLErrorDeserializer())); + mapper = JsonMapper.builder().addModule(new SimpleModule("GraphQLError") + .addDeserializer(GraphQLError.class, new GraphQLErrorDeserializer())).build(); } diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/PersistentResourceFetcherTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/PersistentResourceFetcherTest.java index d4b8a06124..6401317091 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/PersistentResourceFetcherTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/PersistentResourceFetcherTest.java @@ -25,11 +25,6 @@ import com.yahoo.elide.core.utils.coerce.CoerceUtil; import com.yahoo.elide.graphql.parser.GraphQLEntityProjectionMaker; import com.yahoo.elide.jsonapi.JsonApiSettings; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import example.Author; import example.Book; import example.Price; @@ -46,6 +41,10 @@ import graphql.GraphQLError; import graphql.execution.DataFetcherExceptionHandler; import graphql.execution.SimpleDataFetcherExceptionHandler; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; import java.io.IOException; import java.io.InputStream; @@ -310,7 +309,7 @@ protected interface EvaluationFunction { void evaluate(String graphQLRequest, String graphQLResponse) throws Exception; } - protected String getBody(ElideResponse response) throws JsonProcessingException { + protected String getBody(ElideResponse response) { if (response.getBody() instanceof String value) { return value; } diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/QueryRunnerTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/QueryRunnerTest.java index f7e9f03b2c..46539394cb 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/QueryRunnerTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/QueryRunnerTest.java @@ -29,8 +29,6 @@ import com.yahoo.elide.core.type.ClassType; import com.yahoo.elide.graphql.models.GraphQLErrors; import com.yahoo.elide.graphql.serialization.GraphQLErrorDeserializer; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.databind.module.SimpleModule; import example.Book; @@ -50,6 +48,9 @@ import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; +import tools.jackson.core.Version; +import tools.jackson.databind.module.SimpleModule; + import java.util.Map; import java.util.Set; @@ -165,7 +166,7 @@ void constraintViolationException() throws Exception { ElideResponse response = queryRunner.run("", body, null); SimpleModule module = new SimpleModule("GraphQLDeserializer", Version.unknownVersion()); module.addDeserializer(GraphQLError.class, new GraphQLErrorDeserializer()); - elide.getObjectMapper().registerModule(module); + elide.getElideSettings().getElideMapper().customizeObjectMapper(builder -> builder.addModule(module)); GraphQLErrors errorObjects = elide.getObjectMapper().readValue(response.getBody(), GraphQLErrors.class); assertEquals(3, errorObjects.getErrors().size()); for (GraphQLError errorObject : errorObjects.getErrors()) { diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorTest.java index 9c698a37e3..bcd4a3e4bb 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorTest.java @@ -7,13 +7,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import graphql.language.SourceLocation; +import tools.jackson.databind.ObjectMapper; import java.util.Arrays; import java.util.Map; @@ -24,7 +23,7 @@ class GraphQLErrorTest { private final ObjectMapper objectMapper = new ObjectMapper(); @Test - void extensionsConsumer() throws JsonProcessingException { + void extensionsConsumer() { graphql.GraphQLError error = GraphQLError.builder() .message("Name for character with ID 1002 could not be fetched.").extensions(extensions -> { extensions.put("code", "CAN_NOT_FETCH_BY_ID"); @@ -38,7 +37,7 @@ void extensionsConsumer() throws JsonProcessingException { } @Test - void extensions() throws JsonProcessingException { + void extensions() { graphql.GraphQLError error = GraphQLError.builder() .message("Name for character with ID 1002 could not be fetched.") .extensions(Map.of("code", "CAN_NOT_FETCH_BY_ID")).build(); @@ -50,7 +49,7 @@ void extensions() throws JsonProcessingException { } @Test - void locationsConsumer() throws JsonProcessingException { + void locationsConsumer() { SourceLocation location = new SourceLocationBuilder().line(6).column(7).build(); graphql.GraphQLError error = GraphQLError.builder() .message("Name for character with ID 1002 could not be fetched.") @@ -62,7 +61,7 @@ void locationsConsumer() throws JsonProcessingException { } @Test - void locationsConsumerMultiple() throws JsonProcessingException { + void locationsConsumerMultiple() { graphql.GraphQLError error = GraphQLError.builder() .message("Name for character with ID 1002 could not be fetched.") .location(location -> location.line(1).column(2)).location(location -> location.line(3).column(4)) @@ -74,7 +73,7 @@ void locationsConsumerMultiple() throws JsonProcessingException { } @Test - void locations() throws JsonProcessingException { + void locations() { SourceLocation location = new SourceLocationBuilder().line(6).column(7).build(); graphql.GraphQLError error = GraphQLError.builder() .message("Name for character with ID 1002 could not be fetched.").locations(Arrays.asList(location)) diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorsTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorsTest.java index fa24537c1f..374b9002ac 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorsTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/models/GraphQLErrorsTest.java @@ -7,10 +7,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; /** * Test for GraphqlErrors. @@ -19,7 +18,7 @@ class GraphQLErrorsTest { private final ObjectMapper objectMapper = new ObjectMapper(); @Test - void basicErrorResult() throws JsonProcessingException { + void basicErrorResult() { GraphQLErrors errors = GraphQLErrors.builder() .error(error -> error.message("Name for character with ID 1002 could not be fetched.") .location(location -> location.line(6).column(7)).path("hero", "heroFriends", 1, "name") diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/serialization/GraphQLModuleTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/serialization/GraphQLModuleTest.java index 125dee81a8..8a9733d5f7 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/serialization/GraphQLModuleTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/serialization/GraphQLModuleTest.java @@ -8,35 +8,33 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import graphql.ExecutionResult; import graphql.GraphQLError; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import java.util.List; import java.util.Map; class GraphQLModuleTest { - private ObjectMapper objectMapper = new ObjectMapper(); + private ObjectMapper objectMapper; @BeforeEach public void setup() { - objectMapper.registerModule(new GraphQLModule()); + this.objectMapper = JsonMapper.builder().addModule(new GraphQLModule()).build(); } /** * Checks that the execution result error messages should be HTML encoded. * This is as the GraphQLModule has registered the GraphQLErrorSerializer. - * - * @throws JsonProcessingException the exception */ @Test - void executionResultErrorMessageShouldBeHtmlEncoded() throws JsonProcessingException { + void executionResultErrorMessageShouldBeHtmlEncoded() { ExecutionResult executionResult = ExecutionResult.newExecutionResult() .errors(List.of(GraphQLError.newError().message("").build())) .extensions(Map.of("timestamp", "Fri Feb 9 14:33:09 UTC 2018")) diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionDataFetcherTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionDataFetcherTest.java index 5b247e6e07..ad0b99e6cc 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionDataFetcherTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionDataFetcherTest.java @@ -34,8 +34,6 @@ import com.yahoo.elide.graphql.parser.SubscriptionEntityProjectionMaker; import com.yahoo.elide.graphql.subscriptions.hooks.TopicType; import com.yahoo.elide.jsonapi.JsonApiSettings.JsonApiSettingsBuilder; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import example.Address; import example.Author; import example.Book; @@ -54,6 +52,8 @@ import graphql.execution.AsyncSerialExecutionStrategy; import graphql.execution.SubscriptionExecutionStrategy; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -338,7 +338,7 @@ protected void assertSubscriptionEquals( ); assertTrue(actualResponse.getErrors().toString().contains(expectedError)); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { fail("JSON parsing exception", e); } } diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionWebSocketTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionWebSocketTest.java index fd2d778f56..f8ba86a430 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionWebSocketTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/SubscriptionWebSocketTest.java @@ -39,7 +39,6 @@ import com.yahoo.elide.graphql.subscriptions.websocket.protocol.ConnectionInit; import com.yahoo.elide.graphql.subscriptions.websocket.protocol.Subscribe; import com.yahoo.elide.jsonapi.JsonApiSettings.JsonApiSettingsBuilder; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.MoreExecutors; import example.Author; import example.Book; @@ -56,6 +55,8 @@ import jakarta.websocket.Session; import lombok.extern.slf4j.Slf4j; +import tools.jackson.databind.ObjectMapper; + import java.io.IOException; import java.net.URI; import java.time.Duration; @@ -115,7 +116,8 @@ public SubscriptionWebSocketTest() { elide = new Elide(settings); - elide.getObjectMapper().registerModule(new GraphQLModule()); + elide.getElideSettings().getElideMapper() + .customizeObjectMapper(builder -> builder.addModule(new GraphQLModule())); } @BeforeEach diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHookTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHookTest.java index 5bdac99fbe..71554a419c 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHookTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/NotifyTopicLifeCycleHookTest.java @@ -15,12 +15,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.annotation.LifeCycleHookBinding; import com.yahoo.elide.core.PersistentResource; import com.yahoo.elide.core.RequestScope; import com.yahoo.elide.core.dictionary.EntityDictionary; import com.yahoo.elide.core.lifecycle.CRUDEvent; -import com.fasterxml.jackson.databind.ObjectMapper; import example.Book; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,6 +31,7 @@ import jakarta.jms.JMSContext; import jakarta.jms.JMSProducer; import jakarta.jms.Topic; +import tools.jackson.databind.json.JsonMapper; import java.util.Optional; @@ -62,7 +63,7 @@ public void testManagedModelNotification() { NotifyTopicLifeCycleHook bookHook = new NotifyTopicLifeCycleHook( connectionFactory, - new ObjectMapper(), JMSContext::createProducer); + new ElideMapper(JsonMapper.shared()), JMSContext::createProducer); Book book = new Book(); PersistentResource resource = new PersistentResource<>(book, "123", scope); diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScannerTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScannerTest.java index 8c784d212b..8a54c8f7eb 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScannerTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/hooks/SubscriptionScannerTest.java @@ -10,17 +10,18 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.annotation.LifeCycleHookBinding; import com.yahoo.elide.core.dictionary.EntityDictionary; import com.yahoo.elide.core.type.ClassType; import com.yahoo.elide.core.utils.ClassScanner; import com.yahoo.elide.core.utils.DefaultClassScanner; -import com.fasterxml.jackson.databind.ObjectMapper; import example.Author; import example.Book; import org.junit.jupiter.api.Test; import jakarta.jms.ConnectionFactory; +import tools.jackson.databind.json.JsonMapper; public class SubscriptionScannerTest { @@ -34,7 +35,7 @@ public void testLifeCycleHookBindings() { .connectionFactory(connectionFactory) .entityDictionary(dictionary) .scanner(classScanner) - .objectMapper(new ObjectMapper()) + .elideMapper(new ElideMapper(JsonMapper.shared())) .build(); subscriptionScanner.bindLifecycleHooks(); diff --git a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifierTest.java b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifierTest.java index 0dac947d01..2ca9ef67db 100644 --- a/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifierTest.java +++ b/elide-graphql/src/test/java/com/yahoo/elide/graphql/subscriptions/serialization/SubscriptionBeanSerializerModifierTest.java @@ -8,14 +8,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.yahoo.elide.graphql.subscriptions.annotations.SubscriptionField; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; import org.junit.jupiter.api.Test; import jakarta.persistence.Id; import lombok.Data; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; class SubscriptionBeanSerializerModifierTest { @Data @@ -64,13 +64,14 @@ public void setIgnore(String ignore) { } @Test - void serializeFields() throws JsonProcessingException { + void serializeFields() { FieldsModel model = new FieldsModel(); model.setId("id"); model.setField("field"); model.setIgnore("ignore"); ObjectMapper objectMapper = JsonMapper.builder() + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) .addModule(new GraphQLSubscriptionModule()).build(); String actual = objectMapper.writeValueAsString(model); String expected = """ @@ -79,13 +80,14 @@ void serializeFields() throws JsonProcessingException { } @Test - void serializeProperties() throws JsonProcessingException { + void serializeProperties() { PropertiesModel model = new PropertiesModel(); model.setId("id"); model.setField("field"); model.setIgnore("ignore"); ObjectMapper objectMapper = JsonMapper.builder() + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) .addModule(new GraphQLSubscriptionModule()).build(); String actual = objectMapper.writeValueAsString(model); String expected = """ diff --git a/elide-graphql/src/test/java/example/Price.java b/elide-graphql/src/test/java/example/Price.java index d7f67ca89a..541d60a67c 100644 --- a/elide-graphql/src/test/java/example/Price.java +++ b/elide-graphql/src/test/java/example/Price.java @@ -6,17 +6,16 @@ package example; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.deser.std.StdDeserializer; + import java.math.BigDecimal; import java.util.Currency; @@ -35,8 +34,8 @@ public PriceDeserializer() { @Override - public Price deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException { - JsonNode node = parser.getCodec().readTree(parser); + public Price deserialize(JsonParser parser, DeserializationContext ctxt) { + JsonNode node = ctxt.readTree(parser); if (node == null) { return null; } @@ -53,7 +52,7 @@ public Price deserialize(JsonParser parser, DeserializationContext ctxt) throws return new Price(new BigDecimal(unitNode.asDouble()), null); } - Currency currency = Currency.getInstance(node.get("currency").get("currencyCode").asText("")); + Currency currency = Currency.getInstance(node.get("currency").get("currencyCode").asString("")); return new Price(new BigDecimal(unitNode.asDouble()), currency); } diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncApiIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncApiIT.java index 25b28370a9..35312ba7ba 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncApiIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncApiIT.java @@ -23,14 +23,14 @@ import com.yahoo.elide.jsonapi.JsonApi; import com.yahoo.elide.jsonapi.resources.JsonApiEndpoint; import com.yahoo.elide.test.jsonapi.elements.Resource; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.BeforeEach; import io.restassured.response.Response; import jakarta.ws.rs.core.MediaType; import lombok.Getter; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; import java.util.Map; import java.util.concurrent.Executors; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncIT.java index 7a72e1a322..6510bc2760 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/AsyncIT.java @@ -42,8 +42,6 @@ import com.yahoo.elide.jsonapi.JsonApiSettings.JsonApiSettingsBuilder; import com.yahoo.elide.jsonapi.resources.SecurityContextUser; import com.yahoo.elide.test.graphql.EnumFieldSerializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -52,6 +50,9 @@ import jakarta.ws.rs.core.SecurityContext; import lombok.Data; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.annotation.JsonSerialize; + import java.io.IOException; import java.security.Principal; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/TableExportIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/TableExportIT.java index 24e0ddf5b3..44a09bc089 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/TableExportIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/async/integration/tests/TableExportIT.java @@ -46,8 +46,6 @@ import com.yahoo.elide.jsonapi.resources.SecurityContextUser; import com.yahoo.elide.test.graphql.EnumFieldSerializer; import com.yahoo.elide.test.jsonapi.elements.Resource; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.eclipse.jetty.ee10.servlet.ServletHolder; import org.glassfish.jersey.servlet.ServletContainer; import org.junit.jupiter.api.Test; @@ -58,6 +56,9 @@ import jakarta.ws.rs.core.SecurityContext; import lombok.Data; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.annotation.JsonSerialize; + import java.io.IOException; import java.nio.file.Files; import java.security.Principal; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/core/utils/JsonParser.java b/elide-integration-tests/src/test/java/com/yahoo/elide/core/utils/JsonParser.java index 827bae2803..49715b2791 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/core/utils/JsonParser.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/core/utils/JsonParser.java @@ -7,8 +7,9 @@ import static org.junit.jupiter.api.Assertions.fail; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import java.io.IOException; import java.io.InputStream; @@ -34,7 +35,7 @@ public JsonParser(ObjectMapper objectMapper) { public JsonNode toJsonNode(String jsonString) { try { return objectMapper.readTree(jsonString); - } catch (IOException e) { + } catch (JacksonException e) { fail("Unable to parse JSON\n" + jsonString, e); throw new IllegalStateException(); // should not reach here } diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/EncodedErrorObjectsIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/EncodedErrorObjectsIT.java index 2b35d69329..a9b254b3cc 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/EncodedErrorObjectsIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/EncodedErrorObjectsIT.java @@ -48,6 +48,9 @@ public void invalidCollectionException() { .body(equalTo(expected)); } + /** + * This now requires enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) in Jackson 3 to pass. + */ @Test public void invalidEntityBodyException() { String request = jsonParser.getJson("/EncodedErrorResponsesIT/invalidEntityBodyException.req.json"); @@ -92,6 +95,9 @@ public void invalidValueException() { .body(equalTo(expected)); } + /** + * This now requires enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) in Jackson 3 to pass. + */ @Test public void jsonPatchExtensionException() { String request = jsonParser.getJson("/EncodedErrorResponsesIT/jsonPatchExtensionException.req.json"); diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/VerboseEncodedErrorResponsesIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/VerboseEncodedErrorResponsesIT.java index e0a76171dd..bbf9e21a9b 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/VerboseEncodedErrorResponsesIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/errorEncodingTests/VerboseEncodedErrorResponsesIT.java @@ -18,6 +18,7 @@ import com.yahoo.elide.jsonapi.JsonApi; import com.yahoo.elide.jsonapi.resources.JsonApiEndpoint; import com.yahoo.elide.test.jsonapi.elements.Resource; + import org.apache.http.HttpStatus; import org.junit.jupiter.api.Test; @@ -59,6 +60,9 @@ public void invalidCollectionException() { .body(equalTo(expected)); } + /** + * This now requires enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) in Jackson 3 to pass. + */ @Test public void invalidEntityBodyException() { String request = jsonParser.getJson("/EncodedErrorResponsesIT/invalidEntityBodyException.req.json"); @@ -103,6 +107,9 @@ public void invalidValueException() { .body(equalTo(expected)); } + /** + * This now requires enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) in Jackson 3 to pass. + */ @Test public void jsonPatchExtensionException() { String request = jsonParser.getJson("/EncodedErrorResponsesIT/jsonPatchExtensionException.req.json"); diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/errorObjectsTests/ErrorObjectsIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/errorObjectsTests/ErrorObjectsIT.java index 939b9cefbe..f7b8acf3fe 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/errorObjectsTests/ErrorObjectsIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/errorObjectsTests/ErrorObjectsIT.java @@ -14,13 +14,13 @@ import com.yahoo.elide.initialization.IntegrationTest; import com.yahoo.elide.jsonapi.JsonApi; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpStatus; import org.junit.jupiter.api.Test; import jakarta.ws.rs.core.MediaType; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import java.io.IOException; public class ErrorObjectsIT extends IntegrationTest { diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/GraphQLIntegrationTest.java b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/GraphQLIntegrationTest.java index 2cbe238777..22f9302404 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/GraphQLIntegrationTest.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/GraphQLIntegrationTest.java @@ -11,10 +11,6 @@ import static org.junit.jupiter.api.Assertions.fail; import com.yahoo.elide.core.exceptions.HttpStatus; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.glassfish.jersey.server.ResourceConfig; import org.json.JSONException; import org.junit.jupiter.api.TestInstance; @@ -23,6 +19,10 @@ import io.restassured.response.ValidatableResponse; import jakarta.ws.rs.core.MediaType; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IntegrationTest.java b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IntegrationTest.java index 81219ea02f..a65918ce03 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IntegrationTest.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/IntegrationTest.java @@ -16,9 +16,6 @@ import com.yahoo.elide.jsonapi.models.JsonApiDocument; import com.yahoo.elide.jsonapi.resources.JsonApiEndpoint; import com.yahoo.elide.test.jsonapi.elements.Data; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.eclipse.jetty.ee10.servlet.ServletContextHandler; import org.eclipse.jetty.ee10.servlet.ServletHolder; @@ -36,7 +33,9 @@ import io.restassured.RestAssured; import lombok.extern.slf4j.Slf4j; -import java.io.IOException; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import java.lang.reflect.InvocationTargetException; /** @@ -149,11 +148,11 @@ protected final Server setUpServer() throws Exception { return server; } - protected JsonNode getAsNode(String url) throws JsonProcessingException { + protected JsonNode getAsNode(String url) { return getAsNode(url, HttpStatus.SC_OK); } - protected JsonNode getAsNode(String url, int httpStatus) throws JsonProcessingException { + protected JsonNode getAsNode(String url, int httpStatus) { return mapper.readTree(get(url) .then() .statusCode(httpStatus) @@ -176,7 +175,7 @@ protected void assertEqualDocuments(final String actual, final String expected) JsonApiDocument expectedDoc = jsonApiMapper.readJsonApiDocument(expected); JsonApiDocument actualDoc = jsonApiMapper.readJsonApiDocument(actual); assertEquals(expectedDoc, actualDoc, "\n" + actual + "\n" + expected + "\n"); - } catch (IOException e) { + } catch (JacksonException e) { fail("\n" + actual + "\n" + expected + "\n", e); } } diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/StandardTestBinder.java b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/StandardTestBinder.java index ce0c30108b..d9eeb6303f 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/StandardTestBinder.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/StandardTestBinder.java @@ -8,6 +8,7 @@ import static org.mockito.Mockito.mock; import com.yahoo.elide.Elide; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.async.AsyncSettings; import com.yahoo.elide.async.AsyncSettings.AsyncSettingsBuilder; @@ -17,14 +18,20 @@ import com.yahoo.elide.core.filter.dialect.jsonapi.DefaultFilterDialect; import com.yahoo.elide.core.filter.dialect.jsonapi.MultipleFilterDialect; import com.yahoo.elide.graphql.GraphQLSettings.GraphQLSettingsBuilder; +import com.yahoo.elide.jsonapi.JsonApiMapper; import com.yahoo.elide.jsonapi.JsonApiSettings.JsonApiSettingsBuilder; import example.TestCheckMappings; import example.models.triggers.services.BillingService; + import org.glassfish.hk2.api.Factory; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.utilities.binding.AbstractBinder; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.json.JsonMapper; + import java.util.Arrays; import java.util.Calendar; @@ -62,8 +69,12 @@ public Elide provide() { Arrays.asList(rsqlFilterStrategy, defaultFilterStrategy), Arrays.asList(rsqlFilterStrategy, defaultFilterStrategy) ); - + ElideMapper elideMapper = new ElideMapper( + JsonMapper.builder().disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build()); + JsonApiMapper jsonApiMapper = new JsonApiMapper(elideMapper); JsonApiSettingsBuilder jsonApiSettings = JsonApiSettingsBuilder.withDefaults(dictionary) + .jsonApiMapper(jsonApiMapper) .joinFilterDialect(multipleFilterStrategy) .subqueryFilterDialect(multipleFilterStrategy); @@ -72,6 +83,7 @@ public Elide provide() { AsyncSettingsBuilder asyncSettings = AsyncSettings.builder(); Elide elide = new Elide(ElideSettings.builder().dataStore(IntegrationTest.getDataStore()) + .elideMapper(elideMapper) .auditLogger(auditLogger) .entityDictionary(dictionary) .serdes(serdes -> serdes.withISO8601Dates("yyyy-MM-dd'T'HH:mm'Z'", Calendar.getInstance().getTimeZone())) diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/VerboseErrorResponsesTestBinder.java b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/VerboseErrorResponsesTestBinder.java index c3bd52b312..215acab1fd 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/VerboseErrorResponsesTestBinder.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/initialization/VerboseErrorResponsesTestBinder.java @@ -8,6 +8,7 @@ import static com.yahoo.elide.initialization.IntegrationTest.getDataStore; import com.yahoo.elide.Elide; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.async.AsyncSettings; import com.yahoo.elide.async.AsyncSettings.AsyncSettingsBuilder; @@ -17,6 +18,7 @@ import com.yahoo.elide.core.filter.dialect.jsonapi.DefaultFilterDialect; import com.yahoo.elide.core.filter.dialect.jsonapi.MultipleFilterDialect; import com.yahoo.elide.graphql.GraphQLSettings.GraphQLSettingsBuilder; +import com.yahoo.elide.jsonapi.JsonApiMapper; import com.yahoo.elide.jsonapi.JsonApiSettings.JsonApiSettingsBuilder; import example.TestCheckMappings; @@ -26,6 +28,10 @@ import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.utilities.binding.AbstractBinder; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.json.JsonMapper; + import java.util.Arrays; /** @@ -60,8 +66,12 @@ public Elide provide() { Arrays.asList(rsqlFilterStrategy, defaultFilterStrategy), Arrays.asList(rsqlFilterStrategy, defaultFilterStrategy) ); - + ElideMapper elideMapper = new ElideMapper( + JsonMapper.builder().disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build()); + JsonApiMapper jsonApiMapper = new JsonApiMapper(elideMapper); JsonApiSettingsBuilder jsonApiSettings = JsonApiSettingsBuilder.withDefaults(dictionary) + .jsonApiMapper(jsonApiMapper) .joinFilterDialect(multipleFilterStrategy) .subqueryFilterDialect(multipleFilterStrategy); @@ -70,6 +80,7 @@ public Elide provide() { AsyncSettingsBuilder asyncSettings = AsyncSettings.builder(); Elide elide = new Elide(ElideSettings.builder().dataStore(getDataStore()) + .elideMapper(elideMapper) .auditLogger(auditLogger) .settings(jsonApiSettings, graphqlSettings, asyncSettings) .entityDictionary(dictionary) diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/BookAuthorIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/BookAuthorIT.java index 7d4ebfb896..88fe179d23 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/BookAuthorIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/BookAuthorIT.java @@ -21,9 +21,9 @@ import com.yahoo.elide.initialization.IntegrationTest; import com.yahoo.elide.jsonapi.JsonApi; import com.yahoo.elide.test.jsonapi.elements.Resource; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; public class BookAuthorIT extends IntegrationTest { diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/DataStoreIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/DataStoreIT.java index 6596240e8f..2dad7f6a08 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/DataStoreIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/DataStoreIT.java @@ -25,8 +25,6 @@ import com.yahoo.elide.jsonapi.JsonApi; import com.yahoo.elide.jsonapi.JsonApiSettings.JsonApiSettingsBuilder; import com.yahoo.elide.test.jsonapi.elements.Data; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import example.Author; import example.Book; import example.Chapter; @@ -36,6 +34,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.Arrays; @@ -150,9 +150,9 @@ public void testRootEntityFormulaFetch() throws Exception { JsonNode result = mapper.readTree(response.getBody()); assertEquals(ALL_BOOKS_COUNT, result.get(DATA).size()); - assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(STORM_OF_SWORDS, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asText()); + assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(STORM_OF_SWORDS, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asString()); assertEquals(ICE_AND_FIRE_CHAPTER_COUNT, result.get(DATA).get(0).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); assertEquals(CLASH_OF_KINGS_CHAPTER_COUNT, result.get(DATA).get(1).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); @@ -170,9 +170,9 @@ public void testSubcollectionEntityFormulaFetch() throws Exception { JsonNode result = mapper.readTree(response.getBody()); assertEquals(ALL_BOOKS_COUNT, result.get(DATA).size()); - assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(STORM_OF_SWORDS, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asText()); + assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(STORM_OF_SWORDS, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asString()); assertEquals(ICE_AND_FIRE_CHAPTER_COUNT, result.get(DATA).get(0).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); assertEquals(CLASH_OF_KINGS_CHAPTER_COUNT, result.get(DATA).get(1).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); @@ -191,7 +191,7 @@ public void testRootEntityFormulaWithFilter() throws Exception { JsonNode result = mapper.readTree(response.getBody()); assertEquals(1, result.get(DATA).size()); - assertEquals(CLASH_OF_KINGS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asText()); + assertEquals(CLASH_OF_KINGS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asString()); assertEquals(CLASH_OF_KINGS_CHAPTER_COUNT, result.get(DATA).get(0).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); } @@ -208,7 +208,7 @@ public void testSubCollectionEntityFormulaWithFilter() throws Exception { JsonNode result = mapper.readTree(response.getBody()); assertEquals(1, result.get(DATA).size()); - assertEquals(CLASH_OF_KINGS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asText()); + assertEquals(CLASH_OF_KINGS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asString()); assertEquals(CLASH_OF_KINGS_CHAPTER_COUNT, result.get(DATA).get(0).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); } @@ -225,9 +225,9 @@ public void testRootEntityFormulaWithSorting() throws Exception { JsonNode result = mapper.readTree(response.getBody()); assertEquals(ALL_BOOKS_COUNT, result.get(DATA).size()); - assertEquals(STORM_OF_SWORDS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asText()); + assertEquals(STORM_OF_SWORDS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asString()); assertEquals(STORM_OF_SWORDS_CHAPTER_COUNT, result.get(DATA).get(0).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); assertEquals(CLASH_OF_KINGS_CHAPTER_COUNT, result.get(DATA).get(1).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); @@ -246,9 +246,9 @@ public void testSubcollectionEntityFormulaWithSorting() throws Exception { JsonNode result = mapper.readTree(response.getBody()); assertEquals(ALL_BOOKS_COUNT, result.get(DATA).size()); - assertEquals(STORM_OF_SWORDS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asText()); - assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asText()); + assertEquals(STORM_OF_SWORDS, result.get(DATA).get(0).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(CLASH_OF_KINGS, result.get(DATA).get(1).get(ATTRIBUTES).get(TITLE).asString()); + assertEquals(SONG_OF_ICE_AND_FIRE, result.get(DATA).get(2).get(ATTRIBUTES).get(TITLE).asString()); assertEquals(STORM_OF_SWORDS_CHAPTER_COUNT, result.get(DATA).get(0).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); assertEquals(CLASH_OF_KINGS_CHAPTER_COUNT, result.get(DATA).get(1).get(ATTRIBUTES).get(CHAPTER_COUNT).asInt()); diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/FilterIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/FilterIT.java index 56aff1defb..884e153262 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/FilterIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/FilterIT.java @@ -21,14 +21,14 @@ import com.yahoo.elide.core.utils.JsonParser; import com.yahoo.elide.initialization.IntegrationTest; import com.yahoo.elide.jsonapi.JsonApi; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; import org.apache.commons.collections4.CollectionUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; + import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; @@ -54,15 +54,15 @@ public class FilterIT extends IntegrationTest { private Set authorIds = new HashSet<>(); private String getAuthorId(JsonNode author, String name) { - if (author.get("attributes").get("name").asText().equals(name)) { - return author.get("id").asText(); + if (author.get("attributes").get("name").asString().equals(name)) { + return author.get("id").asString(); } return null; } @BeforeEach - void setup() throws JsonProcessingException { + void setup() { given() .contentType(JsonApi.JsonPatch.MEDIA_TYPE) @@ -254,10 +254,10 @@ void testRootNestedComplexAttribute() throws Exception { } @Test - void testRootFilterImplicitSingle() throws JsonProcessingException { + void testRootFilterImplicitSingle() { int scienceFictionBookCount = 0; for (JsonNode node : books.get("data")) { - if (node.get("attributes").get("genre").asText().equalsIgnoreCase("Science Fiction")) { + if (node.get("attributes").get("genre").asString().equalsIgnoreCase("Science Fiction")) { scienceFictionBookCount += 1; } } @@ -281,10 +281,10 @@ void testRootFilterImplicitSingle() throws JsonProcessingException { } @Test - void testRootFilterInSingle() throws JsonProcessingException { + void testRootFilterInSingle() { int literaryFictionBookCount = 0; for (JsonNode node : books.get("data")) { - if (node.get("attributes").get("genre").asText().equalsIgnoreCase("Literary Fiction")) { + if (node.get("attributes").get("genre").asString().equalsIgnoreCase("Literary Fiction")) { literaryFictionBookCount += 1; } } @@ -313,11 +313,11 @@ void testRootFilterInSingle() throws JsonProcessingException { @Test @Tag("skipInMemory") - void testRootFilterNotInSingle() throws JsonProcessingException { + void testRootFilterNotInSingle() { int nonLiteraryFictionBookCount = 0; for (JsonNode node : books.get("data")) { if (!node.get("attributes").get("genre").isNull() - && !node.get("attributes").get("genre").asText().equalsIgnoreCase("Literary Fiction")) { + && !node.get("attributes").get("genre").asString().equalsIgnoreCase("Literary Fiction")) { nonLiteraryFictionBookCount += 1; } } @@ -342,12 +342,12 @@ void testRootFilterNotInSingle() throws JsonProcessingException { @Test @Tag("skipInMemory") - void testRootFilterNotInMultiple() throws JsonProcessingException { + void testRootFilterNotInMultiple() { int nonFictionBookCount = 0; for (JsonNode node : books.get("data")) { if (!node.get("attributes").get("genre").isNull() - && !node.get("attributes").get("genre").asText().equalsIgnoreCase("Literary Fiction") - && !node.get("attributes").get("genre").asText().equalsIgnoreCase("Science Fiction")) { + && !node.get("attributes").get("genre").asString().equalsIgnoreCase("Literary Fiction") + && !node.get("attributes").get("genre").asString().equalsIgnoreCase("Science Fiction")) { nonFictionBookCount += 1; } } @@ -371,11 +371,11 @@ void testRootFilterNotInMultiple() throws JsonProcessingException { } @Test - void testRootFilterInMultipleSingle() throws JsonProcessingException { + void testRootFilterInMultipleSingle() { int literaryAndScienceFictionBookCount = 0; for (JsonNode node : books.get("data")) { - if (node.get("attributes").get("genre").asText().equalsIgnoreCase("Literary Fiction") - || node.get("attributes").get("genre").asText().equalsIgnoreCase("Science Fiction")) { + if (node.get("attributes").get("genre").asString().equalsIgnoreCase("Literary Fiction") + || node.get("attributes").get("genre").asString().equalsIgnoreCase("Science Fiction")) { literaryAndScienceFictionBookCount += 1; } } @@ -421,10 +421,10 @@ void testNonRootEntityError() { } @Test - void testRootFilterPostfix() throws JsonProcessingException { + void testRootFilterPostfix() { int genreEndsWithFictionBookCount = 0; for (JsonNode node : books.get("data")) { - if (node.get("attributes").get("genre").asText().toLowerCase(Locale.ENGLISH).endsWith("fiction")) { + if (node.get("attributes").get("genre").asString().toLowerCase(Locale.ENGLISH).endsWith("fiction")) { genreEndsWithFictionBookCount += 1; } } @@ -448,10 +448,10 @@ void testRootFilterPostfix() throws JsonProcessingException { } @Test - void testRootFilterPrefix() throws JsonProcessingException { + void testRootFilterPrefix() { int titleStartsWithTheBookCount = 0; for (JsonNode node : books.get("data")) { - if (node.get("attributes").get("title").asText().toLowerCase(Locale.ENGLISH).startsWith("the")) { + if (node.get("attributes").get("title").asString().toLowerCase(Locale.ENGLISH).startsWith("the")) { titleStartsWithTheBookCount += 1; } } @@ -476,10 +476,10 @@ void testRootFilterPrefix() throws JsonProcessingException { @Test @Tag("skipInMemory") - void testRootFilterPrefixWithSpecialChars() throws JsonProcessingException { + void testRootFilterPrefixWithSpecialChars() { int titleStartsWithTheBookCount = 0; for (JsonNode node : books.get("data")) { - if (node.get("attributes").get("title").asText().toLowerCase(Locale.ENGLISH).startsWith("i'm")) { + if (node.get("attributes").get("title").asString().toLowerCase(Locale.ENGLISH).startsWith("i'm")) { titleStartsWithTheBookCount += 1; } } @@ -504,10 +504,10 @@ void testRootFilterPrefixWithSpecialChars() throws JsonProcessingException { @Test @Tag("skipInMemory") - void testRootFilterInfix() throws JsonProcessingException { + void testRootFilterInfix() { int titleContainsTheBookCount = 0; for (JsonNode node : books.get("data")) { - if (node.get("attributes").get("title").asText().toLowerCase(Locale.ENGLISH).contains("the")) { + if (node.get("attributes").get("title").asString().toLowerCase(Locale.ENGLISH).contains("the")) { titleContainsTheBookCount += 1; } } @@ -535,13 +535,13 @@ void testRootFilterInfix() throws JsonProcessingException { } @Test - void testRootFilterWithInclude() throws JsonProcessingException { + void testRootFilterWithInclude() { Set authorIdsOfLiteraryFiction = new HashSet<>(); for (JsonNode book : books.get("data")) { - if (book.get("attributes").get("genre").asText().equals("Literary Fiction")) { + if (book.get("attributes").get("genre").asString().equals("Literary Fiction")) { for (JsonNode author : book.get("relationships").get("authors").get("data")) { - authorIdsOfLiteraryFiction.add(author.get("id").asText()); + authorIdsOfLiteraryFiction.add(author.get("id").asString()); } } } @@ -552,26 +552,26 @@ void testRootFilterWithInclude() throws JsonProcessingException { JsonNode result = getAsNode("/book?include=authors&filter[book.genre]=Literary Fiction"); for (JsonNode author : result.get("included")) { - assertTrue(authorIdsOfLiteraryFiction.contains(author.get("id").asText())); + assertTrue(authorIdsOfLiteraryFiction.contains(author.get("id").asString())); } /* Test RSQL Typed */ result = getAsNode("/book?include=authors&filter[book]=genre=='Literary Fiction'"); for (JsonNode author : result.get("included")) { - assertTrue(authorIdsOfLiteraryFiction.contains(author.get("id").asText())); + assertTrue(authorIdsOfLiteraryFiction.contains(author.get("id").asString())); } /* Test RSQL Global */ result = getAsNode("/book?include=authors&filter=genre=='Literary Fiction'"); for (JsonNode author : result.get("included")) { - assertTrue(authorIdsOfLiteraryFiction.contains(author.get("id").asText())); + assertTrue(authorIdsOfLiteraryFiction.contains(author.get("id").asString())); } } @Test - void testRootFilterIsNull() throws JsonProcessingException { + void testRootFilterIsNull() { Set bookIdsWithNullGenre = new HashSet<>(); for (JsonNode book : books.get("data")) { @@ -636,7 +636,7 @@ void testRootFilterIsNull() throws JsonProcessingException { } @Test - void testRootFilterIsNotNull() throws JsonProcessingException { + void testRootFilterIsNotNull() { Set bookIdsWithNonNullGenre = new HashSet<>(); for (JsonNode book : books.get("data")) { @@ -701,10 +701,10 @@ void testRootFilterIsNotNull() throws JsonProcessingException { } @Test - void testNonRootFilterImplicitSingle() throws JsonProcessingException { + void testNonRootFilterImplicitSingle() { int asimovScienceFictionBookCount = 0; for (JsonNode node : asimovBooks.get("data")) { - if (node.get("attributes").get("genre").asText().equals("Science Fiction")) { + if (node.get("attributes").get("genre").asString().equals("Science Fiction")) { asimovScienceFictionBookCount += 1; } } @@ -723,10 +723,10 @@ void testNonRootFilterImplicitSingle() throws JsonProcessingException { } @Test - void testNonRootFilterInSingle() throws JsonProcessingException { + void testNonRootFilterInSingle() { int asimovHistoryBookCount = 0; for (JsonNode node : asimovBooks.get("data")) { - if (node.get("attributes").get("genre").asText().equals("History")) { + if (node.get("attributes").get("genre").asString().equals("History")) { asimovHistoryBookCount += 1; } } @@ -745,11 +745,11 @@ void testNonRootFilterInSingle() throws JsonProcessingException { } @Test - void testNonRootFilterNotInSingle() throws JsonProcessingException { + void testNonRootFilterNotInSingle() { int nonHistoryBookCount = 0; for (JsonNode node : asimovBooks.get("data")) { if (!node.get("attributes").get("genre").isNull() - && !node.get("attributes").get("genre").asText().equals("History")) { + && !node.get("attributes").get("genre").asString().equals("History")) { nonHistoryBookCount += 1; } } @@ -768,10 +768,10 @@ void testNonRootFilterNotInSingle() throws JsonProcessingException { } @Test - void testNonRootFilterPostfix() throws JsonProcessingException { + void testNonRootFilterPostfix() { int genreEndsWithFictionBookCount = 0; for (JsonNode node : asimovBooks.get("data")) { - if (node.get("attributes").get("genre").asText().endsWith("Fiction")) { + if (node.get("attributes").get("genre").asString().endsWith("Fiction")) { genreEndsWithFictionBookCount += 1; } } @@ -790,10 +790,10 @@ void testNonRootFilterPostfix() throws JsonProcessingException { } @Test - void testNonRootFilterPostfixInsensitive() throws JsonProcessingException { + void testNonRootFilterPostfixInsensitive() { int editorEdBooks = 0; for (JsonNode node : nullNedBooks.get("data")) { - if (node.get("attributes").get("editorName").asText().endsWith("d")) { + if (node.get("attributes").get("editorName").asString().endsWith("d")) { editorEdBooks += 1; } } @@ -820,10 +820,10 @@ void testNonRootFilterPostfixInsensitive() throws JsonProcessingException { } @Test - void testNonRootFilterPrefixInsensitive() throws JsonProcessingException { + void testNonRootFilterPrefixInsensitive() { int editorEdBooks = 0; for (JsonNode node : nullNedBooks.get("data")) { - if (node.get("attributes").get("editorName").asText().startsWith("E")) { + if (node.get("attributes").get("editorName").asString().startsWith("E")) { editorEdBooks += 1; } } @@ -851,10 +851,10 @@ void testNonRootFilterPrefixInsensitive() throws JsonProcessingException { } @Test - void testNonRootFilterInfixInsensitive() throws JsonProcessingException { + void testNonRootFilterInfixInsensitive() { int editorEditBooks = 0; for (JsonNode node : nullNedBooks.get("data")) { - if (node.get("attributes").get("editorName").asText().contains("Ed")) { + if (node.get("attributes").get("editorName").asString().contains("Ed")) { editorEditBooks += 1; } } @@ -881,10 +881,10 @@ void testNonRootFilterInfixInsensitive() throws JsonProcessingException { } @Test - void testNonRootFilterPrefix() throws JsonProcessingException { + void testNonRootFilterPrefix() { int titleStartsWithTheBookCount = 0; for (JsonNode node : asimovBooks.get("data")) { - if (node.get("attributes").get("title").asText().startsWith("The")) { + if (node.get("attributes").get("title").asString().startsWith("The")) { titleStartsWithTheBookCount += 1; } } @@ -903,10 +903,10 @@ void testNonRootFilterPrefix() throws JsonProcessingException { } @Test - void testNonRootFilterPrefixWithSpecialChars() throws JsonProcessingException { + void testNonRootFilterPrefixWithSpecialChars() { int titleStartsWithTheBookCount = 0; for (JsonNode node : thomasHarrisBooks.get("data")) { - if (node.get("attributes").get("title").asText().startsWith("I'm")) { + if (node.get("attributes").get("title").asString().startsWith("I'm")) { titleStartsWithTheBookCount += 1; } } @@ -926,10 +926,10 @@ void testNonRootFilterPrefixWithSpecialChars() throws JsonProcessingException { @Test @Tag("skipInMemory") - void testNonRootFilterInfix() throws JsonProcessingException { + void testNonRootFilterInfix() { int titleContainsTheBookCount = 0; for (JsonNode node : asimovBooks.get("data")) { - if (node.get("attributes").get("title").asText().toLowerCase(Locale.ENGLISH).contains("the")) { + if (node.get("attributes").get("title").asString().toLowerCase(Locale.ENGLISH).contains("the")) { titleContainsTheBookCount += 1; } } @@ -948,13 +948,13 @@ void testNonRootFilterInfix() throws JsonProcessingException { } @Test - void testNonRootFilterWithInclude() throws JsonProcessingException { + void testNonRootFilterWithInclude() { Set authorIdsOfScienceFiction = new HashSet<>(); for (JsonNode book : asimovBooks.get("data")) { - if (book.get("attributes").get("genre").asText().equals("Science Fiction")) { + if (book.get("attributes").get("genre").asString().equals("Science Fiction")) { for (JsonNode author : book.get("relationships").get("authors").get("data")) { - authorIdsOfScienceFiction.add(author.get("id").asText()); + authorIdsOfScienceFiction.add(author.get("id").asString()); } } } @@ -965,19 +965,19 @@ void testNonRootFilterWithInclude() throws JsonProcessingException { JsonNode result = getAsNode(String.format("/author/%s/books?include=authors&filter[book.genre]=Science Fiction", asimovId)); for (JsonNode author : result.get("included")) { - assertTrue(authorIdsOfScienceFiction.contains(author.get("id").asText())); + assertTrue(authorIdsOfScienceFiction.contains(author.get("id").asString())); } /* Test RSQL Typed */ result = getAsNode(String.format("/author/%s/books?include=authors&filter[book]=genre=='Science Fiction'", asimovId)); for (JsonNode author : result.get("included")) { - assertTrue(authorIdsOfScienceFiction.contains(author.get("id").asText())); + assertTrue(authorIdsOfScienceFiction.contains(author.get("id").asString())); } } @Test - void testNonRootFilterIsNull() throws JsonProcessingException { + void testNonRootFilterIsNull() { Set bookIdsWithNullGenre = new HashSet<>(); for (JsonNode book : nullNedBooks.get("data")) { @@ -1021,7 +1021,7 @@ void testNonRootFilterIsNull() throws JsonProcessingException { } @Test - void testNonRootFilterIsNotNull() throws JsonProcessingException { + void testNonRootFilterIsNotNull() { Set bookIdsWithNonNullGenre = new HashSet<>(); for (JsonNode book : nullNedBooks.get("data")) { @@ -1065,7 +1065,7 @@ void testNonRootFilterIsNotNull() throws JsonProcessingException { } @Test - void testPublishDateGreaterThanFilter() throws JsonProcessingException { + void testPublishDateGreaterThanFilter() { Set bookIdsWithNonNullGenre = new HashSet<>(); long publishDate; @@ -1099,7 +1099,7 @@ void testPublishDateGreaterThanFilter() throws JsonProcessingException { } @Test - void testPublishDateEqualsFilter() throws JsonProcessingException { + void testPublishDateEqualsFilter() { /* Test Default */ JsonNode result = getAsNode("/book?filter[book.publishDate][in]=0,1454638927412"); @@ -1112,7 +1112,7 @@ void testPublishDateEqualsFilter() throws JsonProcessingException { } @Test - void testPublishDatePrefixFilter() throws JsonProcessingException { + void testPublishDatePrefixFilter() { /* Test Default */ /* publish date = 1454638927412 */ JsonNode result = getAsNode("/book?filter[book.publishDate][prefix]=1"); @@ -1127,7 +1127,7 @@ void testPublishDatePrefixFilter() throws JsonProcessingException { } @Test - void testPublishDateInfixFilter() throws JsonProcessingException { + void testPublishDateInfixFilter() { /* Test Default */ /* publish date = 1454638927412 */ JsonNode result = getAsNode("/book?filter[book.publishDate][infix]=389"); @@ -1142,7 +1142,7 @@ void testPublishDateInfixFilter() throws JsonProcessingException { } @Test - void testPublishDatePostfixFilter() throws JsonProcessingException { + void testPublishDatePostfixFilter() { /* Test Default */ /* publish date = 1454638927412 */ JsonNode result = getAsNode("/book?filter[book.publishDate][postfix]=412"); @@ -1157,7 +1157,7 @@ void testPublishDatePostfixFilter() throws JsonProcessingException { } @Test - void testPublishDateGreaterThanFilterSubRecord() throws JsonProcessingException { + void testPublishDateGreaterThanFilterSubRecord() { long publishDate; /* Test Default */ @@ -1182,7 +1182,7 @@ void testPublishDateGreaterThanFilterSubRecord() throws JsonProcessingException } @Test - void testPublishDateLessThanOrEqualsFilterSubRecord() throws JsonProcessingException { + void testPublishDateLessThanOrEqualsFilterSubRecord() { long publishDate; /* Test Default */ @@ -1207,7 +1207,7 @@ void testPublishDateLessThanOrEqualsFilterSubRecord() throws JsonProcessingExcep } @Test - void testPublishDateLessThanOrEqual() throws JsonProcessingException { + void testPublishDateLessThanOrEqual() { long publishDate; /* Test Default */ @@ -1242,7 +1242,7 @@ void testPublishDateLessThanOrEqual() throws JsonProcessingException { } @Test - void testPublishDateLessThanFilter() throws JsonProcessingException { + void testPublishDateLessThanFilter() { long publishDate; /* Test Default */ @@ -1280,7 +1280,7 @@ void testPublishDateLessThanFilter() throws JsonProcessingException { * Verifies that issue 508 is closed. */ @Test - void testIssue508() throws JsonProcessingException { + void testIssue508() { JsonNode result = getAsNode("book?filter=(authors.name=='Thomas Harris',publisher.name=='Default publisher')&page[totals]"); assertEquals(2, result.get("data").size()); @@ -1305,19 +1305,19 @@ void testIssue508() throws JsonProcessingException { } @Test - void testGetBadRelationshipNameWithNestedFieldFilter() throws JsonProcessingException { + void testGetBadRelationshipNameWithNestedFieldFilter() { /* Test Default */ JsonNode result = getAsNode( "book?filter[book.author12.name]=Null Ned", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Unknown field in filter: author12\n" + "Invalid query parameter: filter[book.author12.name]"); /* Test RSQL Global */ result = getAsNode("book?filter=author12.name=='Null Ned'", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Invalid filter format: filter\n" + "No such association author12 for type book\n" + "Invalid filter format: filter\n" @@ -1325,14 +1325,14 @@ void testGetBadRelationshipNameWithNestedFieldFilter() throws JsonProcessingExce } @Test - void testGetBooksFilteredByAuthors() throws JsonProcessingException { + void testGetBooksFilteredByAuthors() { /* Test Default */ JsonNode result = getAsNode("book?filter[book.authors.name]=Null Ned"); assertEquals(result.get("data").size(), nullNedBooks.get("data").size()); for (JsonNode book : result.get("data")) { - String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asText(); + String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asString(); assertEquals(authorId, nullNedId); } @@ -1342,13 +1342,13 @@ void testGetBooksFilteredByAuthors() throws JsonProcessingException { assertEquals(result.get("data").size(), nullNedBooks.get("data").size()); for (JsonNode book : result.get("data")) { - String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asText(); + String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asString(); assertEquals(authorId, nullNedId); } } @Test - void testGetBooksFilteredByAuthorsId() throws JsonProcessingException { + void testGetBooksFilteredByAuthorsId() { String nullNedIdStr = String.valueOf(nullNedId); /* Test Default */ JsonNode result = getAsNode("book?filter[book.authors.id]=" + nullNedIdStr); @@ -1356,7 +1356,7 @@ void testGetBooksFilteredByAuthorsId() throws JsonProcessingException { assertEquals(result.get("data").size(), nullNedBooks.get("data").size()); for (JsonNode book : result.get("data")) { - String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asText(); + String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asString(); assertEquals(authorId, nullNedId); } @@ -1366,41 +1366,41 @@ void testGetBooksFilteredByAuthorsId() throws JsonProcessingException { assertEquals(result.get("data").size(), nullNedBooks.get("data").size()); for (JsonNode book : result.get("data")) { - String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asText(); + String authorId = book.get("relationships").get("authors").get("data").get(0).get("id").asString(); assertEquals(authorId, nullNedId); } } @Test - void testGetBooksFilteredByAuthorAndTitle() throws JsonProcessingException { + void testGetBooksFilteredByAuthorAndTitle() { /* Test Default */ JsonNode result = getAsNode("book?filter[book.authors.name]=Null Ned&filter[book.title]=Life with Null Ned"); assertEquals(result.get("data").size(), 1); - assertEquals(result.get("data").get(0).get("attributes").get("title").asText(), "Life with Null Ned"); + assertEquals(result.get("data").get(0).get("attributes").get("title").asString(), "Life with Null Ned"); assertEquals( - result.get("data").get(0).get("relationships").get("authors").get("data").get(0).get("id").asText(), + result.get("data").get(0).get("relationships").get("authors").get("data").get(0).get("id").asString(), nullNedId); /* Test RSQL Global */ result = getAsNode("book?filter=authors.name=='Null Ned';title=='Life with Null Ned'"); assertEquals(result.get("data").size(), 1); - assertEquals(result.get("data").get(0).get("attributes").get("title").asText(), "Life with Null Ned"); + assertEquals(result.get("data").get(0).get("attributes").get("title").asString(), "Life with Null Ned"); assertEquals( - result.get("data").get(0).get("relationships").get("authors").get("data").get(0).get("id").asText(), + result.get("data").get(0).get("relationships").get("authors").get("data").get(0).get("id").asString(), nullNedId); } @Test - void testFilterAuthorsByBookChapterTitle() throws JsonProcessingException { + void testFilterAuthorsByBookChapterTitle() { /* Test Default */ JsonNode result = getAsNode("/author?sort=-name&filter[author.books.chapters.title][in]=Viva la Roma!,Mamma mia I wantz some pizza!"); assertEquals(result.get("data").size(), 2); for (JsonNode author : result.get("data")) { - String name = author.get("attributes").get("name").asText(); + String name = author.get("attributes").get("name").asString(); assertTrue(name.equals("Isaac Asimov") || name.equals("Null Ned")); } @@ -1410,20 +1410,20 @@ void testFilterAuthorsByBookChapterTitle() throws JsonProcessingException { assertEquals(result.get("data").size(), 2); for (JsonNode author : result.get("data")) { - String name = author.get("attributes").get("name").asText(); + String name = author.get("attributes").get("name").asString(); assertTrue(name.equals("Isaac Asimov") || name.equals("Null Ned")); } } @Test - void testFilterAuthorBookByPublisher() throws JsonProcessingException { + void testFilterAuthorBookByPublisher() { /* Test default */ JsonNode result = getAsNode(String.format("/author/%s/books?filter[book.publisher.name]=Default publisher", hemingwayId)); JsonNode data = result.get("data"); assertEquals(data.size(), 1); for (JsonNode book : data) { - String name = book.get("attributes").get("title").asText(); + String name = book.get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", name); } @@ -1434,7 +1434,7 @@ void testFilterAuthorBookByPublisher() throws JsonProcessingException { assertEquals(data.size(), 1); for (JsonNode book : data) { - String name = book.get("attributes").get("title").asText(); + String name = book.get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", name); } } @@ -1512,7 +1512,7 @@ void testFilterByAuthorBookByChapter() { } @Test - void testFilterBookByAuthorAddress() throws JsonProcessingException { + void testFilterBookByAuthorAddress() { /* Test default */ JsonNode result = getAsNode("book?filter[book.authors.homeAddress]=main&include=authors"); JsonNode data = result.get("data"); @@ -1526,12 +1526,12 @@ void testFilterBookByAuthorAddress() throws JsonProcessingException { @Test - void testGetBadRelationshipRoot() throws JsonProcessingException { + void testGetBadRelationshipRoot() { /* Test Default */ JsonNode result = getAsNode( "/author?filter[idontexist.books.title][in]=Viva la Roma!,Mamma mia I wantz some pizza!", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Unknown entity in filter: idontexist\n" + "Invalid query parameter: filter[idontexist.books.title][in]"); @@ -1539,7 +1539,7 @@ void testGetBadRelationshipRoot() throws JsonProcessingException { result = getAsNode( "/author?filter=idontexist.books.title=in=('Viva la Roma!','Mamma mia I wantz some pizza!')", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Invalid filter format: filter\n" + "No such association idontexist for type author\n" + "Invalid filter format: filter\n" @@ -1547,12 +1547,12 @@ void testGetBadRelationshipRoot() throws JsonProcessingException { } @Test - void testGetBadRelationshipIntermediate() throws JsonProcessingException { + void testGetBadRelationshipIntermediate() { /* Test Default */ JsonNode result = getAsNode( "/author?filter[author.idontexist.title][in]=Viva la Roma!,Mamma mia I wantz some pizza!", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Unknown field in filter: idontexist\n" + "Invalid query parameter: filter[author.idontexist.title][in]"); @@ -1560,7 +1560,7 @@ void testGetBadRelationshipIntermediate() throws JsonProcessingException { result = getAsNode( "/author?filter=idontexist.title=in=('Viva la Roma!','Mamma mia I wantz some pizza!')", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Invalid filter format: filter\n" + "No such association idontexist for type author\n" + "Invalid filter format: filter\n" @@ -1568,12 +1568,12 @@ void testGetBadRelationshipIntermediate() throws JsonProcessingException { } @Test - void testGetBadRelationshipLeaf() throws JsonProcessingException { + void testGetBadRelationshipLeaf() { /* Test Default */ JsonNode result = getAsNode( "/author?filter[author.books.idontexist][in]=Viva la Roma!,Mamma mia I wantz some pizza!", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Unknown field in filter: idontexist\n" + "Invalid query parameter: filter[author.books.idontexist][in]"); @@ -1581,7 +1581,7 @@ void testGetBadRelationshipLeaf() throws JsonProcessingException { result = getAsNode( "/author?filter=books.idontexist=in=('Viva la Roma!','Mamma mia I wantz some pizza!')", HttpStatus.SC_BAD_REQUEST); - assertEquals(result.get("errors").get(0).get("detail").asText(), + assertEquals(result.get("errors").get(0).get("detail").asString(), "Invalid filter format: filter\n" + "No such association idontexist for type book\n" + "Invalid filter format: filter\n" @@ -1592,14 +1592,14 @@ void testGetBadRelationshipLeaf() throws JsonProcessingException { * Verify that a combination of filters and order by generate working SQL. */ @Test - void testFilterWithSort() throws JsonProcessingException { + void testFilterWithSort() { JsonNode result = getAsNode(String.format("/author/%s/books?filter[book.title][notnull]=true&sort=title", asimovId)); JsonNode data = result.get("data"); assertEquals(data.size(), 2); } @Test - void testBetweenOperatorOnRoot() throws JsonProcessingException { + void testBetweenOperatorOnRoot() { JsonNode result = getAsNode("/book?filter[book.id][between]=2,4"); JsonNode data = result.get("data"); assertEquals(3, data.size()); @@ -1616,7 +1616,7 @@ void testBetweenOperatorOnRoot() throws JsonProcessingException { } @Test - void testBetweenOperatorOnNonRoot() throws JsonProcessingException { + void testBetweenOperatorOnNonRoot() { JsonNode result = getAsNode(String.format("/author/%s/books?filter[book.id][notbetween]=6,7", nullNedId)); JsonNode data = result.get("data"); assertEquals(1, data.size()); @@ -1634,7 +1634,7 @@ void testBetweenOperatorOnNonRoot() throws JsonProcessingException { @Test - void testIsEmptyRelationshipOnRoot() throws JsonProcessingException { + void testIsEmptyRelationshipOnRoot() { //Book has ToMany relationship with chapter Set bookIdsWithEmptyChapters = new HashSet<>(); JsonNode result; @@ -1683,7 +1683,7 @@ void testIsEmptyRelationshipOnRoot() throws JsonProcessingException { } @Test - void testNotEmptyRelationshipOnNonRoot() throws JsonProcessingException { + void testNotEmptyRelationshipOnNonRoot() { //Book has ToMany relationship with chapter Set bookIdsWithNonEmptyChapters = new HashSet<>(); JsonNode result; @@ -1733,7 +1733,7 @@ void testNotEmptyRelationshipOnNonRoot() throws JsonProcessingException { @Tag("excludeOnHibernate3") @Tag("excludeOnHibernate5") @Tag("excludeOnJPA") - void testNotEmptyAttributeOnRoot() throws JsonProcessingException { + void testNotEmptyAttributeOnRoot() { Set bookIdsWithNonEmptyAwards = new HashSet<>(); JsonNode result; @@ -1785,7 +1785,7 @@ void testNotEmptyAttributeOnRoot() throws JsonProcessingException { @Tag("excludeOnHibernate3") @Tag("excludeOnHibernate5") @Tag("excludeOnJPA") - void testIsEmptyAttributesOnNonRoot() throws JsonProcessingException { + void testIsEmptyAttributesOnNonRoot() { Set bookIdsWithEmptyAwards = new HashSet<>(); JsonNode result; for (JsonNode book : nullNedBooks.get("data")) { @@ -1831,7 +1831,7 @@ void testIsEmptyAttributesOnNonRoot() throws JsonProcessingException { } @Test - void testExceptionOnEmptyOperator() throws JsonProcessingException { + void testExceptionOnEmptyOperator() { JsonNode result; // Typed Expression result = getAsNode(String.format("/author/%s/books?filter[book.authors.name][notempty]", nullNedId), HttpStatus.SC_BAD_REQUEST); @@ -1840,7 +1840,7 @@ void testExceptionOnEmptyOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book.authors.name][notempty]\n" + "Invalid toMany join. toMany association has to be the target collection.book.authors.name NOTEMPTY []\n" + "Invalid query parameter: filter[book.authors.name][notempty]", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); //RSQL @@ -1850,7 +1850,7 @@ void testExceptionOnEmptyOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid association authors.name. toMany association has to be the target collection.", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); } @@ -1864,10 +1864,10 @@ void testMemberOfOnAttributes() { // * Filter On Root Entity * for (JsonNode book : books.get("data")) { - Iterator awards = book.get("attributes").get("awards").elements(); + Iterator awards = book.get("attributes").get("awards").iterator(); while (awards.hasNext()) { - if (awards.next().asText().equals(filterString)) { - awardBook.add(book.get("id").asText()); + if (awards.next().asString().equals(filterString)) { + awardBook.add(book.get("id").asString()); break; } } @@ -1892,10 +1892,10 @@ void testMemberOfOnAttributes() { // * Filter On Non Root Entity * for (JsonNode book : nullNedBooks.get("data")) { - Iterator awards = book.get("attributes").get("awards").elements(); + Iterator awards = book.get("attributes").get("awards").iterator(); while (awards.hasNext()) { - if (awards.next().asText().equals(filterString)) { - nullNedAwardBook.add(book.get("id").asText()); + if (awards.next().asString().equals(filterString)) { + nullNedAwardBook.add(book.get("id").asString()); break; } } @@ -1928,7 +1928,7 @@ void testMembertoOneRelationships() { for (JsonNode book : books.get("data")) { int publisherId = book.get("relationships").get("publisher").get("data").get("id").asInt(); if (publisherId == 1) { - publisherBook.add(book.get("id").asText()); + publisherBook.add(book.get("id").asString()); break; } } @@ -2074,7 +2074,7 @@ void testSubcollectionMemberOfToManyRelationshipConjunction() { @Test @Tag("excludeOnHibernate3") - void testExceptionOnMemberOfOperator() throws JsonProcessingException { + void testExceptionOnMemberOfOperator() { JsonNode result; // Typed Expression result = getAsNode(String.format("/author/%s/books?filter[book.authors][hasmember]", nullNedId), HttpStatus.SC_BAD_REQUEST); @@ -2083,7 +2083,7 @@ void testExceptionOnMemberOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book.authors][hasmember]\n" + "Invalid Path: Last Path Element cannot be a collection type\n" + "Invalid query parameter: filter[book.authors][hasmember]", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); //RSQL @@ -2093,7 +2093,7 @@ void testExceptionOnMemberOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element cannot be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); @@ -2104,7 +2104,7 @@ void testExceptionOnMemberOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element has to be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); result = getAsNode(String.format("/book?filter[book]=title=hasnomember=\"%s\"", "*The*"), HttpStatus.SC_BAD_REQUEST); assertEquals( @@ -2112,13 +2112,13 @@ void testExceptionOnMemberOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element has to be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); result = getAsNode(String.format("/book?filter[book.title][hasmember]=\"%s\"", "*The*"), HttpStatus.SC_BAD_REQUEST); assertEquals( "Invalid Path: Last Path Element has to be a collection type\n" + "Invalid query parameter: filter[book.title][hasmember]", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); } @@ -2133,11 +2133,11 @@ void testSubsetOfOnAttributes() { // * Filter On Root Entity * for (JsonNode book : books.get("data")) { - Iterator awards = book.get("attributes").get("awards").elements(); + Iterator awards = book.get("attributes").get("awards").iterator(); while (awards.hasNext()) { - allAwards.add(awards.next().asText()); + allAwards.add(awards.next().asString()); } - awardBook.add(book.get("id").asText()); + awardBook.add(book.get("id").asString()); } filterString = allAwards.stream().collect(Collectors.joining(",")); @@ -2165,11 +2165,11 @@ void testSubsetOfOnAttributes() { // * Filter On Non Root Entity * for (JsonNode book : nullNedBooks.get("data")) { - Iterator awards = book.get("attributes").get("awards").elements(); + Iterator awards = book.get("attributes").get("awards").iterator(); while (awards.hasNext()) { - allAwards.add(awards.next().asText()); + allAwards.add(awards.next().asString()); } - nullNedAwardBook.add(book.get("id").asText()); + nullNedAwardBook.add(book.get("id").asString()); } filterString = allAwards.stream().collect(Collectors.joining(",")); @@ -2203,7 +2203,7 @@ void testSubsetOfToOneRelationships() { // * Filter On Root Entity * for (JsonNode book : books.get("data")) { - publisherBook.add(book.get("id").asText()); + publisherBook.add(book.get("id").asString()); } // Test Default filter type on Root Entity when() @@ -2331,7 +2331,7 @@ void testSubcollectionSubsetOfToManyRelationshipConjunction() { @Test @Tag("excludeOnHibernate3") - void testExceptionOnSubsetOfOperator() throws JsonProcessingException { + void testExceptionOnSubsetOfOperator() { JsonNode result; // Typed Expression result = getAsNode(String.format("/author/%s/books?filter[book.authors][subsetof]", nullNedId), HttpStatus.SC_BAD_REQUEST); @@ -2340,7 +2340,7 @@ void testExceptionOnSubsetOfOperator() throws JsonProcessingException { Invalid query parameter: filter[book.authors][subsetof] Invalid Path: Last Path Element cannot be a collection type Invalid query parameter: filter[book.authors][subsetof]""", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); //RSQL @@ -2350,7 +2350,7 @@ void testExceptionOnSubsetOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element cannot be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); @@ -2361,7 +2361,7 @@ void testExceptionOnSubsetOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element has to be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); result = getAsNode(String.format("/book?filter[book]=title=notsubsetof=\"%s\"", "*The*"), HttpStatus.SC_BAD_REQUEST); assertEquals( @@ -2369,13 +2369,13 @@ void testExceptionOnSubsetOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element has to be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); result = getAsNode(String.format("/book?filter[book.title][subsetof]=\"%s\"", "*The*"), HttpStatus.SC_BAD_REQUEST); assertEquals( "Invalid Path: Last Path Element has to be a collection type\n" + "Invalid query parameter: filter[book.title][subsetof]", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); } @@ -2389,10 +2389,10 @@ void testSupersetOfOnAttributes() { // * Filter On Root Entity * for (JsonNode book : books.get("data")) { - Iterator awards = book.get("attributes").get("awards").elements(); + Iterator awards = book.get("attributes").get("awards").iterator(); while (awards.hasNext()) { - if (awards.next().asText().equals(filterString)) { - awardBook.add(book.get("id").asText()); + if (awards.next().asString().equals(filterString)) { + awardBook.add(book.get("id").asString()); break; } } @@ -2417,10 +2417,10 @@ void testSupersetOfOnAttributes() { // * Filter On Non Root Entity * for (JsonNode book : nullNedBooks.get("data")) { - Iterator awards = book.get("attributes").get("awards").elements(); + Iterator awards = book.get("attributes").get("awards").iterator(); while (awards.hasNext()) { - if (awards.next().asText().equals(filterString)) { - nullNedAwardBook.add(book.get("id").asText()); + if (awards.next().asString().equals(filterString)) { + nullNedAwardBook.add(book.get("id").asString()); break; } } @@ -2453,7 +2453,7 @@ void testSupersetOfToOneRelationships() { for (JsonNode book : books.get("data")) { int publisherId = book.get("relationships").get("publisher").get("data").get("id").asInt(); if (publisherId == 1) { - publisherBook.add(book.get("id").asText()); + publisherBook.add(book.get("id").asString()); break; } } @@ -2584,7 +2584,7 @@ void testSubcollectionSupersetOfToManyRelationshipConjunction() { @Test @Tag("excludeOnHibernate3") - void testExceptionOnSupersetOfOperator() throws JsonProcessingException { + void testExceptionOnSupersetOfOperator() { JsonNode result; // Typed Expression result = getAsNode(String.format("/author/%s/books?filter[book.authors][supersetof]", nullNedId), HttpStatus.SC_BAD_REQUEST); @@ -2593,7 +2593,7 @@ void testExceptionOnSupersetOfOperator() throws JsonProcessingException { Invalid query parameter: filter[book.authors][supersetof] Invalid Path: Last Path Element cannot be a collection type Invalid query parameter: filter[book.authors][supersetof]""", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); //RSQL @@ -2603,7 +2603,7 @@ void testExceptionOnSupersetOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element cannot be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); @@ -2614,7 +2614,7 @@ void testExceptionOnSupersetOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element has to be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); result = getAsNode(String.format("/book?filter[book]=title=notsupersetof=\"%s\"", "*The*"), HttpStatus.SC_BAD_REQUEST); assertEquals( @@ -2622,13 +2622,13 @@ void testExceptionOnSupersetOfOperator() throws JsonProcessingException { + "Invalid query parameter: filter[book]\n" + "Invalid filter format: filter[book]\n" + "Invalid Path: Last Path Element has to be a collection type", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); result = getAsNode(String.format("/book?filter[book.title][supersetof]=\"%s\"", "*The*"), HttpStatus.SC_BAD_REQUEST); assertEquals( "Invalid Path: Last Path Element has to be a collection type\n" + "Invalid query parameter: filter[book.title][supersetof]", - result.get("errors").get(0).get("detail").asText() + result.get("errors").get(0).get("detail").asString() ); } diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/GraphQLIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/GraphQLIT.java index 4a0485518c..d9efff7cfd 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/GraphQLIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/GraphQLIT.java @@ -24,10 +24,6 @@ import com.yahoo.elide.core.exceptions.HttpStatus; import com.yahoo.elide.initialization.GraphQLIntegrationTest; import com.yahoo.elide.test.graphql.VariableFieldSerializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import example.Currency; import example.Price; import org.junit.jupiter.api.BeforeEach; @@ -40,6 +36,11 @@ import lombok.Getter; import lombok.Setter; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; + import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/ResourceIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/ResourceIT.java index a3333860dd..a91a9d22bb 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/ResourceIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/ResourceIT.java @@ -973,7 +973,9 @@ public void testMissingTypeInJsonBody() { @Test public void testInvalidJson() { - String detail = "Unexpected close marker ']': expected '}' (for Object starting at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1])"; + // Either StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION is enabled to have the line and column numbers and source otherwise no line and column number + // Unexpected close marker ']': expected '}' (for Object starting at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]) + String detail = "Unexpected close marker ']': expected '}' (for Object starting at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); byte offset: #UNKNOWN])"; given() .contentType(JsonApi.MEDIA_TYPE) diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/SortingIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/SortingIT.java index ae726a97d6..fe56d50a88 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/SortingIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/SortingIT.java @@ -16,11 +16,12 @@ import com.yahoo.elide.core.utils.JsonParser; import com.yahoo.elide.initialization.IntegrationTest; import com.yahoo.elide.jsonapi.JsonApi; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; + import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -66,10 +67,10 @@ public void testSortingRootCollectionByRelationshipProperty() throws IOException assertEquals(8, size); JsonNode books = result.get("data"); - String firstBookName = books.get(0).get("attributes").get("title").asText(); + String firstBookName = books.get(0).get("attributes").get("title").asString(); assertEquals("For Whom the Bell Tolls", firstBookName); - String secondBookName = books.get(1).get("attributes").get("title").asText(); + String secondBookName = books.get(1).get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", secondBookName); result = getAsNode("/book?sort=publisher.name"); @@ -77,10 +78,10 @@ public void testSortingRootCollectionByRelationshipProperty() throws IOException assertEquals(8, size); books = result.get("data"); - firstBookName = books.get(size - 2).get("attributes").get("title").asText(); + firstBookName = books.get(size - 2).get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", firstBookName); - secondBookName = books.get(size - 1).get("attributes").get("title").asText(); + secondBookName = books.get(size - 1).get("attributes").get("title").asString(); assertEquals("For Whom the Bell Tolls", secondBookName); } @@ -91,10 +92,10 @@ public void testSortingSubcollectionByRelationshipProperty() throws IOException assertEquals(2, result.get("data").size()); JsonNode books = result.get("data"); - String firstBookName = books.get(0).get("attributes").get("title").asText(); + String firstBookName = books.get(0).get("attributes").get("title").asString(); assertEquals("For Whom the Bell Tolls", firstBookName); - String secondBookName = books.get(1).get("attributes").get("title").asText(); + String secondBookName = books.get(1).get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", secondBookName); result = getAsNode("/author/1/books?sort=publisher.name"); @@ -102,10 +103,10 @@ public void testSortingSubcollectionByRelationshipProperty() throws IOException assertEquals(2, result.get("data").size()); books = result.get("data"); - firstBookName = books.get(0).get("attributes").get("title").asText(); + firstBookName = books.get(0).get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", firstBookName); - secondBookName = books.get(1).get("attributes").get("title").asText(); + secondBookName = books.get(1).get("attributes").get("title").asString(); assertEquals("For Whom the Bell Tolls", secondBookName); } @@ -124,20 +125,20 @@ public void testSortingByRelationshipId() throws IOException { assertEquals(8, result.get("data").size()); JsonNode books = result.get("data"); - String firstBookName = books.get(0).get("attributes").get("title").asText(); + String firstBookName = books.get(0).get("attributes").get("title").asString(); assertEquals("For Whom the Bell Tolls", firstBookName); - String secondBookName = books.get(1).get("attributes").get("title").asText(); + String secondBookName = books.get(1).get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", secondBookName); result = getAsNode("/book?sort=publisher.id"); assertEquals(8, result.get("data").size()); books = result.get("data"); - firstBookName = books.get(6).get("attributes").get("title").asText(); + firstBookName = books.get(6).get("attributes").get("title").asString(); assertEquals("The Old Man and the Sea", firstBookName); - secondBookName = books.get(7).get("attributes").get("title").asText(); + secondBookName = books.get(7).get("attributes").get("title").asString(); assertEquals("For Whom the Bell Tolls", secondBookName); } @@ -166,7 +167,7 @@ public void testSortingByNestedComplexAttribute() throws IOException { JsonNode books = result.get("data"); for (int idx = 0; idx < isoCodes.size(); idx++) { String expectedCode = isoCodes.get(idx); - String actualCode = books.get(idx).get("attributes").get("price").get("currency").get("isoCode").asText(); + String actualCode = books.get(idx).get("attributes").get("price").get("currency").get("isoCode").asString(); assertEquals(expectedCode, actualCode); } } @@ -181,7 +182,7 @@ public void testSortingSubcollectionByNestedComplexAttribute() throws IOExceptio JsonNode books = result.get("data"); for (int idx = 0; idx < isoCodes.size(); idx++) { String expectedCode = isoCodes.get(idx); - String actualCode = books.get(idx).get("attributes").get("price").get("currency").get("isoCode").asText(); + String actualCode = books.get(idx).get("attributes").get("price").get("currency").get("isoCode").asString(); assertEquals(expectedCode, actualCode); } } @@ -205,7 +206,7 @@ public void testSortingById() throws IOException { JsonNode books = result.get("data"); for (int idx = 0; idx < bookTitles.size(); idx++) { String expectedTitle = bookTitles.get(idx); - String actualTitle = books.get(idx).get("attributes").get("title").asText(); + String actualTitle = books.get(idx).get("attributes").get("title").asString(); assertEquals(expectedTitle, actualTitle); } } diff --git a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/TransferableIT.java b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/TransferableIT.java index 629f883e93..23ace6a75a 100644 --- a/elide-integration-tests/src/test/java/com/yahoo/elide/tests/TransferableIT.java +++ b/elide-integration-tests/src/test/java/com/yahoo/elide/tests/TransferableIT.java @@ -22,14 +22,15 @@ import com.yahoo.elide.core.exceptions.HttpStatus; import com.yahoo.elide.initialization.IntegrationTest; import com.yahoo.elide.jsonapi.JsonApi; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; import example.Left; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import io.restassured.response.Response; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; + /** * Tests @NonTransferable annotation integration tests. */ @@ -395,9 +396,9 @@ public void testCreateContainerAndNonTransferable() throws Exception { // Should have 3 results, 1st is container, 2nd and 3rd are untransferables assertEquals(3, patchJson.size()); - assertEquals("container", patchJson.get(0).get("data").get("type").asText()); - assertEquals("untransferable", patchJson.get(1).get("data").get("type").asText()); - assertEquals("untransferable", patchJson.get(2).get("data").get("type").asText()); + assertEquals("container", patchJson.get(0).get("data").get("type").asString()); + assertEquals("untransferable", patchJson.get(1).get("data").get("type").asString()); + assertEquals("untransferable", patchJson.get(2).get("data").get("type").asString()); // Container should have 2 untransferables assertEquals(2, patchJson.get(0).get("data").get("relationships").get("untransferables").get("data").size()); @@ -457,9 +458,9 @@ public void testCreateContainerAndTransferables() throws Exception { // Should have 3 results, 1st is container, 2nd and 3rd are transferables assertEquals(3, patchJson.size()); - assertEquals("container", patchJson.get(0).get("data").get("type").asText()); - assertEquals("transferable", patchJson.get(1).get("data").get("type").asText()); - assertEquals("transferable", patchJson.get(2).get("data").get("type").asText()); + assertEquals("container", patchJson.get(0).get("data").get("type").asString()); + assertEquals("transferable", patchJson.get(1).get("data").get("type").asString()); + assertEquals("transferable", patchJson.get(2).get("data").get("type").asString()); // Container should have 2 transferables assertEquals(2, patchJson.get(0).get("data").get("relationships").get("transferables").get("data").size()); diff --git a/elide-integration-tests/src/test/java/example/Address.java b/elide-integration-tests/src/test/java/example/Address.java index 02755f537f..70b3fc3a7b 100644 --- a/elide-integration-tests/src/test/java/example/Address.java +++ b/elide-integration-tests/src/test/java/example/Address.java @@ -5,17 +5,15 @@ */ package example; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - import jakarta.persistence.AttributeConverter; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Embeddable; import lombok.Data; -import java.io.IOException; +import tools.jackson.core.JacksonException; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; @@ -37,21 +35,16 @@ public static class MapConverter implements AttributeConverter attribute) { try { return mapper.writeValueAsString(attribute); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalStateException(e); } } @Override public Map convertToEntityAttribute(String dbData) { - try { - TypeReference> typeRef = new TypeReference<>() { - }; - - return mapper.readValue(dbData, typeRef); - } catch (IOException e) { - throw new IllegalStateException(e); - } + TypeReference> typeRef = new TypeReference<>() { + }; + return mapper.readValue(dbData, typeRef); } } } diff --git a/elide-integration-tests/src/test/java/example/models/targetEntity/Manager.java b/elide-integration-tests/src/test/java/example/models/targetEntity/Manager.java index faf6512a48..b64421b442 100644 --- a/elide-integration-tests/src/test/java/example/models/targetEntity/Manager.java +++ b/elide-integration-tests/src/test/java/example/models/targetEntity/Manager.java @@ -31,5 +31,5 @@ public class Manager implements Employee { @OneToMany(targetEntity = SWE.class, mappedBy = "boss") @EqualsAndHashCode.Exclude - Set reports; + Set reports; } diff --git a/elide-model-config/pom.xml b/elide-model-config/pom.xml index d9b2f6debd..2ad0616215 100644 --- a/elide-model-config/pom.xml +++ b/elide-model-config/pom.xml @@ -48,7 +48,7 @@ 7.1.18-SNAPSHOT - com.fasterxml.jackson.core + tools.jackson.core jackson-databind @@ -56,7 +56,7 @@ jackson-annotations - com.fasterxml.jackson.core + tools.jackson.core jackson-core diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigHelpers.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigHelpers.java index 5910f2b516..bd35737203 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigHelpers.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/DynamicConfigHelpers.java @@ -10,10 +10,6 @@ import com.yahoo.elide.modelconfig.model.ElideSecurityConfig; import com.yahoo.elide.modelconfig.model.ElideTableConfig; import com.yahoo.elide.modelconfig.parser.handlebars.HandlebarsHydrator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; import org.apache.commons.lang3.StringUtils; import org.hjson.JsonValue; @@ -21,6 +17,9 @@ import lombok.extern.slf4j.Slf4j; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -189,7 +188,7 @@ private static ObjectMapper getInstance() { } } - private static T getModelPojo(String jsonConfig, final Class configPojo) throws JsonProcessingException { + private static T getModelPojo(String jsonConfig, final Class configPojo) { return DynamicConfigObjectMapper.getInstance().readValue(jsonConfig, configPojo); } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Argument.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Argument.java index 35f9a6510c..7d50ce4ec3 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Argument.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Argument.java @@ -8,13 +8,14 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; import java.util.LinkedHashSet; import java.util.Set; @@ -36,6 +37,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = Argument.ArgumentBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class Argument implements Named { private static final long serialVersionUID = -6628282044575311784L; @@ -50,6 +53,7 @@ public class Argument implements Named { @JsonProperty("values") @JsonDeserialize(as = LinkedHashSet.class) + @Builder.Default private Set values = new LinkedHashSet<>(); @JsonProperty("tableSource") @@ -66,4 +70,7 @@ public class Argument implements Named { public String getDescription() { return (this.description == null ? getName() : this.description); } + + public static class ArgumentBuilder { + } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/DBConfig.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/DBConfig.java index 52bb54e75e..bdb9380a7e 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/DBConfig.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/DBConfig.java @@ -8,12 +8,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; import java.util.Map; @@ -36,6 +36,8 @@ @NoArgsConstructor public class DBConfig implements Named { + private static final long serialVersionUID = 1L; + @JsonProperty("name") private String name; diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Dimension.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Dimension.java index 082392b257..d8171ccfcc 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Dimension.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Dimension.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Builder; @@ -16,6 +15,8 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.Singular; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -49,6 +50,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = Dimension.DimensionBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class Dimension implements Named { private static final long serialVersionUID = 7886036651874169795L; @@ -87,6 +90,7 @@ public class Dimension implements Named { @JsonProperty("tags") @JsonDeserialize(as = LinkedHashSet.class) + @Builder.Default private Set tags = new LinkedHashSet<>(); @JsonProperty("arguments") @@ -95,6 +99,7 @@ public class Dimension implements Named { @JsonProperty("values") @JsonDeserialize(as = LinkedHashSet.class) + @Builder.Default private Set values = new LinkedHashSet<>(); @JsonProperty("tableSource") @@ -120,4 +125,7 @@ public String getDescription() { public boolean hasArgument(String argName) { return hasName(this.arguments, argName); } + + public static class DimensionBuilder { + } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideDBConfig.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideDBConfig.java index 70a6e3e5ea..a7ca466bc0 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideDBConfig.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideDBConfig.java @@ -8,12 +8,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; import java.util.LinkedHashSet; import java.util.Set; diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideNamespaceConfig.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideNamespaceConfig.java index e42d92f621..320d4d2fe3 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideNamespaceConfig.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideNamespaceConfig.java @@ -10,12 +10,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; import java.util.LinkedHashSet; import java.util.Locale; diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideSecurityConfig.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideSecurityConfig.java index 5eeaabcb90..7a94fc2842 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideSecurityConfig.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideSecurityConfig.java @@ -8,12 +8,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; import java.util.LinkedHashSet; import java.util.Set; diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideTableConfig.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideTableConfig.java index f9f659595e..5ab5a23841 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideTableConfig.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/ElideTableConfig.java @@ -8,12 +8,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; import java.util.LinkedHashSet; import java.util.Set; diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Grain.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Grain.java index f6449702c8..53084618af 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Grain.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Grain.java @@ -14,6 +14,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; import java.io.Serializable; @@ -31,6 +33,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = Grain.GrainBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class Grain implements Serializable { private static final long serialVersionUID = -6253818551445562327L; @@ -63,4 +67,7 @@ public String toString() { return this.value; } } + + public static class GrainBuilder { + } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Join.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Join.java index a7168a27b8..0bb5748cad 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Join.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Join.java @@ -16,6 +16,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; /** * Joins describe the SQL expression necessary to join two physical tables. @@ -35,6 +37,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = Join.JoinBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class Join implements Named { private static final long serialVersionUID = -1416294756711914111L; @@ -42,6 +46,7 @@ public class Join implements Named { private String name; @JsonProperty("namespace") + @Builder.Default private String namespace = DEFAULT; @JsonProperty("to") @@ -51,6 +56,7 @@ public class Join implements Named { private Join.Type type; @JsonProperty("kind") + @Builder.Default private Join.Kind kind = Join.Kind.TOONE; @JsonProperty("definition") @@ -103,4 +109,7 @@ public String toString() { return this.value; } } + + public static class JoinBuilder { + } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Measure.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Measure.java index f3a843c49a..90206d655e 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Measure.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Measure.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Builder; @@ -16,6 +15,8 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.Singular; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -45,6 +46,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = Measure.MeasureBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class Measure implements Named { private static final long serialVersionUID = 4404642046984907827L; @@ -79,6 +82,7 @@ public class Measure implements Named { @JsonProperty("tags") @JsonDeserialize(as = LinkedHashSet.class) + @Builder.Default private Set tags = new LinkedHashSet<>(); @JsonProperty("arguments") @@ -105,4 +109,7 @@ public String getDescription() { public boolean hasArgument(String argName) { return hasName(this.arguments, argName); } + + public static class MeasureBuilder { + } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/NamespaceConfig.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/NamespaceConfig.java index 2410aa7b2c..be6ecf0f6a 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/NamespaceConfig.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/NamespaceConfig.java @@ -15,6 +15,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; /** * Namespace Config JSON. @@ -32,6 +34,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = NamespaceConfig.NamespaceConfigBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class NamespaceConfig implements Named { private static final long serialVersionUID = 279959092479649876L; @@ -62,4 +66,7 @@ public class NamespaceConfig implements Named { public String getDescription() { return (this.description == null ? getName() : this.description); } + + public static class NamespaceConfigBuilder { + } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Table.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Table.java index 8ae897320b..7658acf448 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Table.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/Table.java @@ -10,7 +10,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.google.common.collect.Streams; import org.apache.commons.lang3.StringUtils; @@ -20,6 +19,8 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.Singular; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -58,6 +59,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = Table.TableBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class Table implements Named { private static final long serialVersionUID = -7537337382856372741L; @@ -244,4 +247,7 @@ public static String getModelName(String tableName, String namespace) { return namespace + "_" + tableName; } + + public static class TableBuilder { + } } diff --git a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/TableSource.java b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/TableSource.java index 9c54a1b2a2..e0dde7c907 100644 --- a/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/TableSource.java +++ b/elide-model-config/src/main/java/com/yahoo/elide/modelconfig/model/TableSource.java @@ -10,13 +10,14 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; import java.io.Serializable; import java.util.LinkedHashSet; @@ -38,6 +39,8 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@JsonDeserialize(builder = TableSource.TableSourceBuilder.class) +@JsonPOJOBuilder(withPrefix = "") public class TableSource implements Serializable { private static final long serialVersionUID = 5721654374755116755L; @@ -45,6 +48,7 @@ public class TableSource implements Serializable { private String table; @JsonProperty("namespace") + @Builder.Default private String namespace = DEFAULT; @JsonProperty("column") @@ -52,5 +56,9 @@ public class TableSource implements Serializable { @JsonProperty("suggestionColumns") @JsonDeserialize(as = LinkedHashSet.class) + @Builder.Default private Set suggestionColumns = new LinkedHashSet<>(); + + public static class TableSourceBuilder { + } } diff --git a/elide-model-config/src/test/java/com/yahoo/elide/modelconfig/validator/DynamicConfigValidatorTest.java b/elide-model-config/src/test/java/com/yahoo/elide/modelconfig/validator/DynamicConfigValidatorTest.java index 875838c9e5..bd076a72e2 100644 --- a/elide-model-config/src/test/java/com/yahoo/elide/modelconfig/validator/DynamicConfigValidatorTest.java +++ b/elide-model-config/src/test/java/com/yahoo/elide/modelconfig/validator/DynamicConfigValidatorTest.java @@ -20,6 +20,8 @@ import com.yahoo.elide.modelconfig.store.models.ConfigFile; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; import java.util.Map; public class DynamicConfigValidatorTest { @@ -410,7 +412,9 @@ public void testDuplicateArgumentName() throws Exception { // PlayerStats table already has argument 'countryCode' with type 'TEXT'. // Adding another argument 'countryCode' with type 'INTEGER'. - playerStatsTable.getArguments().add(Argument.builder().name("countryCode").type(Type.INTEGER).build()); + List arguments = new ArrayList<>(playerStatsTable.getArguments()); + arguments.add(Argument.builder().name("countryCode").type(Type.INTEGER).build()); + playerStatsTable.setArguments(arguments); Exception e = assertThrows(IllegalStateException.class, () -> testClass.validateConfigs()); assertEquals("Multiple Arguments found with the same name: countryCode", e.getMessage()); } @@ -433,7 +437,9 @@ public void testDuplicateArgumentNameInTableFilter() throws Exception { Table playerStatsTable = testClass.getElideTableConfig().getTable("PlayerNamespace_PlayerStats"); // PlayerStats table already has a filter argument 'code' with type 'TEXT'. - playerStatsTable.getArguments().add(Argument.builder().name("code").type(Type.TEXT).build()); + List arguments = new ArrayList<>(playerStatsTable.getArguments()); + arguments.add(Argument.builder().name("code").type(Type.TEXT).build()); + playerStatsTable.setArguments(arguments); Exception e = assertThrows(IllegalStateException.class, () -> testClass.validateConfigs()); assertEquals("Multiple Arguments found with the same name: code", e.getMessage()); } @@ -446,7 +452,9 @@ public void testDuplicateArgumentNameInComplexTableFilter() throws Exception { Table playerStatsTable = testClass.getElideTableConfig().getTable("PlayerNamespace_PlayerStats"); // PlayerStats table already has a filter argument 'code' with type 'TEXT'. - playerStatsTable.getArguments().add(Argument.builder().name("code").type(Type.TEXT).build()); + List arguments = new ArrayList<>(playerStatsTable.getArguments()); + arguments.add(Argument.builder().name("code").type(Type.TEXT).build()); + playerStatsTable.setArguments(arguments); playerStatsTable.setFilterTemplate("foo=={{bar}};blah=={{code}}"); Exception e = assertThrows(IllegalStateException.class, () -> testClass.validateConfigs()); assertEquals("Multiple Arguments found with the same name: code", e.getMessage()); diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java index c2363739fd..d90033241f 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideAutoConfiguration.java @@ -119,7 +119,7 @@ import com.yahoo.elide.swagger.OpenApiBuilder; import com.yahoo.elide.utils.HeaderProcessor; import com.yahoo.elide.utils.Headers; -import com.fasterxml.jackson.databind.ObjectMapper; + import org.apache.commons.lang3.StringUtils; import org.springdoc.core.customizers.OpenApiCustomizer; import org.springdoc.core.models.GroupedOpenApi; @@ -140,7 +140,6 @@ import org.springframework.context.annotation.Scope; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.util.function.SingletonSupplier; @@ -158,6 +157,8 @@ import jakarta.persistence.EntityManagerFactory; import lombok.extern.slf4j.Slf4j; +import tools.jackson.databind.json.JsonMapper; + import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -218,7 +219,7 @@ public ElideSettingsBuilder elideSettingsBuilder(ElideConfigProperties settings, SerdesBuilder serdesBuilder, ObjectProvider settingsProvider, ObjectProvider customizerProvider) { return ElideSettingsBuilderCustomizers.buildElideSettingsBuilder(builder -> { - builder.dataStore(dataStore).entityDictionary(entityDictionary).objectMapper(elideMapper.getObjectMapper()) + builder.dataStore(dataStore).entityDictionary(entityDictionary).elideMapper(elideMapper) .maxPageSize(settings.getMaxPageSize()) .defaultPageSize(settings.getDefaultPageSize()).auditLogger(auditLogger) .baseUrl(settings.getBaseUrl()) @@ -584,12 +585,12 @@ public ExceptionLogger exceptionLogger() { @Bean @ConditionalOnMissingBean @Scope(SCOPE_PROTOTYPE) - public ObjectMapperBuilder objectMapperBuilder( - Optional optionalJackson2ObjectMapperBuilder) { - if (optionalJackson2ObjectMapperBuilder.isPresent()) { - return optionalJackson2ObjectMapperBuilder.get()::build; + ObjectMapperBuilder objectMapperBuilder( + Optional optionalJsonMapperBuilder) { + if (optionalJsonMapperBuilder.isPresent()) { + return optionalJsonMapperBuilder.get()::build; } - return ObjectMapper::new; + return JsonMapper::shared; } @Bean @@ -938,7 +939,7 @@ public JsonApiSettingsBuilder jsonApiSettingsBuilder(ElideConfigProperties setti @Bean @ConditionalOnMissingBean public JsonApiMapper jsonApiMapper(ElideMapper elideMapper) { - return new JsonApiMapper(elideMapper.getObjectMapper()); + return new JsonApiMapper(elideMapper); } } diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionConfiguration.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionConfiguration.java index 9ac8e5b41b..2e7d9c698b 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionConfiguration.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionConfiguration.java @@ -124,7 +124,7 @@ SubscriptionWebSocketConfiguratorBuilder subscriptionWebSocketConfiguratorBuilde serdesBuilder.build().entrySet().stream().forEach(entry -> { entries.put(entry.getKey(), entry.getValue()); }); - })).objectMapper(elideMapper.getObjectMapper()).auditLogger(auditLogger) + })).elideMapper(elideMapper).auditLogger(auditLogger) .verboseErrors(config.isVerboseErrors()) .maxPageSize(config.getMaxPageSize()) .defaultPageSize(config.getDefaultPageSize()); diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfiguration.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfiguration.java index b3f270ccae..c4974eaaf5 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfiguration.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/config/ElideSubscriptionScanningConfiguration.java @@ -58,7 +58,7 @@ public void onStartOrRefresh(ApplicationEvent event) { .scanner(elide.getScanner()) .entityDictionary(elide.getElideSettings().getEntityDictionary()) .connectionFactory(connectionFactory) - .objectMapper(elide.getElideSettings().getObjectMapper()) + .elideMapper(elide.getElideSettings().getElideMapper()) .build(); scanner.bindLifecycleHooks(); diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/jackson/ObjectMapperBuilder.java b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/jackson/ObjectMapperBuilder.java index 27c71eb203..11f4592106 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/jackson/ObjectMapperBuilder.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/jackson/ObjectMapperBuilder.java @@ -5,12 +5,12 @@ */ package com.yahoo.elide.spring.jackson; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; /** * Used to build an ObjectMapper. * - * @see com.fasterxml.jackson.databind.ObjectMapper + * @see tools.jackson.databind.ObjectMapper */ @FunctionalInterface public interface ObjectMapperBuilder { diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonConverter.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonConverter.java index 75e6f448d7..81ca16f075 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonConverter.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonConverter.java @@ -7,13 +7,12 @@ package example.models.jpa.usertypes; import com.yahoo.elide.core.exceptions.InvalidValueException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; -import java.io.IOException; /** * JsonType serializes an object to json string and vice versa. @@ -32,7 +31,7 @@ public JsonConverter(Class objectClass) { public String convertToDatabaseColumn(T value) { try { return MAPPER.writeValueAsString(value); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new InvalidValueException("Unable to serialize", e); } } @@ -41,7 +40,7 @@ public String convertToDatabaseColumn(T value) { public T convertToEntityAttribute(String rawJson) { try { return MAPPER.readValue(rawJson, objectClass); - } catch (IOException e) { + } catch (JacksonException e) { throw new InvalidValueException("Unable to deserialize", e); } } diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonType.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonType.java index d192083e61..10c36315ce 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonType.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/models/jpa/usertypes/JsonType.java @@ -6,14 +6,14 @@ package example.models.jpa.usertypes; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.ParameterizedType; import org.hibernate.usertype.UserType; -import java.io.IOException; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; + import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -83,7 +83,7 @@ public Object nullSafeGet( try { return MAPPER.readValue(rawJson, this.objectClass); - } catch (IOException e) { + } catch (RuntimeException e) { throw new HibernateException("Could not retrieve an instance of the mapped class from a JDBC resultset."); } } @@ -101,7 +101,7 @@ public void nullSafeSet(PreparedStatement preparedStatement, Object value, int i try { String json = MAPPER.writeValueAsString(value); preparedStatement.setString(i, json); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new HibernateException("Could not write an instance of the mapped class to a prepared statement."); } } diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/ControllerTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/ControllerTest.java index 48c0fb7524..aa1763a047 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/ControllerTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/ControllerTest.java @@ -47,12 +47,6 @@ import com.yahoo.elide.jsonapi.JsonApi; import com.yahoo.elide.test.graphql.GraphQLDSL; import com.yahoo.elide.test.jsonapi.elements.AtomicOperationCode; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; @@ -65,6 +59,9 @@ import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.dataformat.yaml.YAMLFactory; import java.util.Map; /** @@ -1114,7 +1111,7 @@ public void apiDocsDocumentTest() { } @Test - public void apiDocsDocumentTestYaml() throws JsonMappingException, JsonProcessingException { + public void apiDocsDocumentTestYaml() { ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); String response = given() .accept("application/yaml") diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/IntegrationTestSetup.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/IntegrationTestSetup.java index 1c4f374363..3a6004853d 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/IntegrationTestSetup.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/IntegrationTestSetup.java @@ -8,6 +8,7 @@ import static org.mockito.Mockito.spy; import com.yahoo.elide.Elide; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.RefreshableElide; import com.yahoo.elide.async.AsyncSettings; @@ -46,12 +47,13 @@ public RefreshableElide initializeElide(EntityDictionary dictionary, DataStore dataStore, ElideConfigProperties settings, HeaderProcessor headerProcessor, + ElideMapper elideMapper, JsonApiMapper mapper, ExceptionMappersBuilder exceptionMappersBuilder) { ElideSettings.ElideSettingsBuilder builder = ElideSettings.builder().dataStore(dataStore) .entityDictionary(dictionary) - .objectMapper(mapper.getObjectMapper()) + .elideMapper(elideMapper) .maxPageSize(settings.getMaxPageSize()) .defaultPageSize(settings.getDefaultPageSize()) .auditLogger(new Slf4jLogger()) diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java index 780fb10225..e5d9b37b38 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/SubscriptionTest.java @@ -30,13 +30,11 @@ import com.yahoo.elide.datastores.jms.websocket.SubscriptionWebSocketTestClient; import com.yahoo.elide.graphql.GraphQLExceptionHandler; import com.yahoo.elide.jsonapi.JsonApi; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.apache.http.HttpStatus; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import graphql.ExecutionResult; @@ -59,12 +57,6 @@ SerdesBuilderCustomizer serdesBuilderCustomzer() { serdesBuilder.entry(OffsetDateTime.class, serde); }; } - - @Bean - Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() { - Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json().modules(new JavaTimeModule()); - return builder; - } } @SuppressWarnings("unchecked") diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/Update200StatusTestSetup.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/Update200StatusTestSetup.java index 48122c8416..7b9034e6f4 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/Update200StatusTestSetup.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/example/tests/Update200StatusTestSetup.java @@ -6,6 +6,7 @@ package example.tests; import com.yahoo.elide.Elide; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.RefreshableElide; import com.yahoo.elide.core.TransactionRegistry; @@ -39,6 +40,7 @@ public RefreshableElide getRefreshableElide(EntityDictionary dictionary, HeaderProcessor headerProcessor, TransactionRegistry transactionRegistry, ElideConfigProperties settings, + ElideMapper elideMapper, JsonApiMapper mapper, ExceptionMappersBuilder exceptionMappersBuilder) { ExceptionMappers exceptionMappers = exceptionMappersBuilder.build(); @@ -56,7 +58,7 @@ public RefreshableElide getRefreshableElide(EntityDictionary dictionary, new DefaultGraphQLErrorMapper())); ElideSettings.ElideSettingsBuilder builder = ElideSettings.builder().dataStore(dataStore) .entityDictionary(dictionary) - .objectMapper(mapper.getObjectMapper()) + .elideMapper(elideMapper) .maxPageSize(settings.getMaxPageSize()) .defaultPageSize(settings.getDefaultPageSize()) .auditLogger(new Slf4jLogger()) diff --git a/elide-standalone/pom.xml b/elide-standalone/pom.xml index d2f7ae0643..72f13ee5ee 100644 --- a/elide-standalone/pom.xml +++ b/elide-standalone/pom.xml @@ -44,7 +44,7 @@ - 4.2.38 + 5.0.6 utf-8 @@ -53,7 +53,7 @@ - io.dropwizard.metrics + io.dropwizard.metrics5 metrics-bom ${metrics.version} pom @@ -164,22 +164,22 @@ - io.dropwizard.metrics + io.dropwizard.metrics5 metrics-core - io.dropwizard.metrics + io.dropwizard.metrics5 metrics-jakarta-servlet - io.dropwizard.metrics + io.dropwizard.metrics5 metrics-jakarta-servlets - io.dropwizard.metrics + io.dropwizard.metrics5 metrics-jetty12-ee10 diff --git a/elide-standalone/src/main/java/com/yahoo/elide/standalone/ElideStandalone.java b/elide-standalone/src/main/java/com/yahoo/elide/standalone/ElideStandalone.java index c68477ca5e..789e3aedda 100644 --- a/elide-standalone/src/main/java/com/yahoo/elide/standalone/ElideStandalone.java +++ b/elide-standalone/src/main/java/com/yahoo/elide/standalone/ElideStandalone.java @@ -21,10 +21,10 @@ import org.eclipse.jetty.server.Server; import org.glassfish.jersey.servlet.ServletContainer; -import io.dropwizard.metrics.servlet.InstrumentedFilter; -import io.dropwizard.metrics.servlets.AdminServlet; -import io.dropwizard.metrics.servlets.HealthCheckServlet; -import io.dropwizard.metrics.servlets.MetricsServlet; +import io.dropwizard.metrics5.servlet.InstrumentedFilter; +import io.dropwizard.metrics5.servlets.AdminServlet; +import io.dropwizard.metrics5.servlets.HealthCheckServlet; +import io.dropwizard.metrics5.servlets.MetricsServlet; import jakarta.servlet.DispatcherType; import lombok.extern.slf4j.Slf4j; diff --git a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java index 8531c01666..e3f1c3eb94 100644 --- a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java +++ b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideResourceConfig.java @@ -43,14 +43,15 @@ import com.yahoo.elide.standalone.Util; import com.yahoo.elide.swagger.resources.ApiDocsEndpoint; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.health.HealthCheckRegistry; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.api.TypeLiteral; import org.glassfish.jersey.inject.hk2.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import graphql.execution.DataFetcherExceptionHandler; +import io.dropwizard.metrics5.MetricRegistry; +import io.dropwizard.metrics5.health.HealthCheckRegistry; + import jakarta.inject.Inject; import jakarta.persistence.EntityManagerFactory; import jakarta.servlet.ServletContext; @@ -139,7 +140,7 @@ public T instantiate(Class cls) { } ElideSettings elideSettings = settings.getElideSettings(dictionary, dataStore, - settings.getJsonApiMapper()); + settings.getElideMapper(), settings.getJsonApiMapper()); Elide elide = new Elide(elideSettings, new TransactionRegistry(), elideSettings.getEntityDictionary().getScanner(), false); diff --git a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSettings.java b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSettings.java index 0710d5405a..3e199354f5 100644 --- a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSettings.java +++ b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSettings.java @@ -7,6 +7,7 @@ import static com.yahoo.elide.datastores.jpa.JpaDataStore.DEFAULT_LOGGER; +import com.yahoo.elide.ElideMapper; import com.yahoo.elide.ElideSettings; import com.yahoo.elide.ElideSettings.ElideSettingsBuilder; import com.yahoo.elide.Serdes; @@ -70,8 +71,6 @@ import com.yahoo.elide.swagger.OpenApiBuilder; import com.yahoo.elide.swagger.resources.ApiDocsEndpoint; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.apache.commons.lang3.StringUtils; import org.eclipse.jetty.ee10.servlet.ServletContextHandler; import org.glassfish.hk2.api.ServiceLocator; @@ -88,6 +87,7 @@ import io.swagger.v3.oas.models.servers.Server; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; +import tools.jackson.databind.json.JsonMapper; import java.io.IOException; import java.util.ArrayList; @@ -108,7 +108,7 @@ * Interface for configuring an ElideStandalone application. */ public interface ElideStandaloneSettings { - public static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper(); + public static final ElideMapper DEFAULT_ELIDE_MAPPER = new ElideMapper(JsonMapper.shared()); /** * The OpenAPI Specification Version. @@ -224,6 +224,7 @@ default AsyncSettingsBuilder getAsyncSettingsBuilder() { * * @param dictionary the dictionary * @param dataStore the data store + * @param elideMapper the elideMapper * @param mapper the mapper * @return the ElideSettingsBuilder * @@ -232,11 +233,11 @@ default AsyncSettingsBuilder getAsyncSettingsBuilder() { * @see #getAsyncSettingsBuilder() */ default ElideSettingsBuilder getElideSettingsBuilder(EntityDictionary dictionary, DataStore dataStore, - JsonApiMapper mapper) { + ElideMapper elideMapper, JsonApiMapper mapper) { ElideSettingsBuilder builder = ElideSettings.builder().dataStore(dataStore) .entityDictionary(dictionary) .baseUrl(getBaseUrl()) - .objectMapper(mapper.getObjectMapper()) + .elideMapper(elideMapper) .auditLogger(getAuditLogger()) .maxPageSize(getMaxPageSize()) .defaultPageSize(getDefaultPageSize()); @@ -291,13 +292,15 @@ default SerdesBuilder getSerdesBuilder() { * * @param dictionary EntityDictionary object. * @param dataStore DataStore object + * @param elideMapper Object elideMapper * @param mapper Object mapper * @return Configured ElideSettings object. * - * @see #getElideSettingsBuilder(EntityDictionary, DataStore, JsonApiMapper) + * @see #getElideSettingsBuilder(EntityDictionary, DataStore, ElideMapper, JsonApiMapper) */ - default ElideSettings getElideSettings(EntityDictionary dictionary, DataStore dataStore, JsonApiMapper mapper) { - ElideSettingsBuilder builder = getElideSettingsBuilder(dictionary, dataStore, mapper); + default ElideSettings getElideSettings(EntityDictionary dictionary, DataStore dataStore, ElideMapper elideMapper, + JsonApiMapper mapper) { + ElideSettingsBuilder builder = getElideSettingsBuilder(dictionary, dataStore, elideMapper, mapper); return builder.build(); } @@ -817,7 +820,7 @@ default ExceptionLogger getExceptionLogger() { * @return object mapper. */ default JsonApiMapper getJsonApiMapper() { - return new JsonApiMapper(getObjectMapper()); + return new JsonApiMapper(getElideMapper()); } /** @@ -825,8 +828,8 @@ default JsonApiMapper getJsonApiMapper() { * * @return object mapper. */ - default ObjectMapper getObjectMapper() { - return DEFAULT_OBJECT_MAPPER; + default ElideMapper getElideMapper() { + return DEFAULT_ELIDE_MAPPER; } /** diff --git a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSubscriptionSettings.java b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSubscriptionSettings.java index d4bf61d4d5..e0cd43f5b6 100644 --- a/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSubscriptionSettings.java +++ b/elide-standalone/src/main/java/com/yahoo/elide/standalone/config/ElideStandaloneSubscriptionSettings.java @@ -135,7 +135,7 @@ default SubscriptionScanner subscriptionScanner(Elide elide, ConnectionFactory c .scanner(elide.getScanner()) .entityDictionary(elide.getElideSettings().getEntityDictionary()) .connectionFactory(connectionFactory) - .objectMapper(elide.getElideSettings().getObjectMapper()) + .elideMapper(elide.getElideSettings().getElideMapper()) .build(); scanner.bindLifecycleHooks(); @@ -187,7 +187,7 @@ default ElideSettingsBuilderCustomizer getElideSettingsBuilderCustomizer(ElideSt elideSettingsBuilder .maxPageSize(settings.getMaxPageSize()) .defaultPageSize(settings.getDefaultPageSize()) - .objectMapper(settings.getObjectMapper()) + .elideMapper(settings.getElideMapper()) .auditLogger(settings.getAuditLogger()) .verboseErrors(settings.verboseErrors()); elideSettingsBuilder.getSettings(GraphQLSettingsBuilder.class) diff --git a/elide-standalone/src/test/java/example/ElideStandaloneTest.java b/elide-standalone/src/test/java/example/ElideStandaloneTest.java index b17611c179..aea00a0053 100644 --- a/elide-standalone/src/test/java/example/ElideStandaloneTest.java +++ b/elide-standalone/src/test/java/example/ElideStandaloneTest.java @@ -227,7 +227,7 @@ public void testMetricsServlet() throws Exception { .get("/stats/metrics") .then() .statusCode(200) - .body("meters", hasKey("io.dropwizard.metrics.servlet.InstrumentedFilter.responseCodes.ok")); + .body("meters", hasKey("io.dropwizard.metrics5.servlet.InstrumentedFilter.responseCodes.ok")); } @Test diff --git a/elide-swagger/pom.xml b/elide-swagger/pom.xml index 2e98082083..6eccebf597 100644 --- a/elide-swagger/pom.xml +++ b/elide-swagger/pom.xml @@ -79,9 +79,14 @@ provided - com.fasterxml.jackson.core + tools.jackson.core jackson-databind provided + + + tools.jackson.dataformat + jackson-dataformat-yaml + provided io.swagger.core.v3 diff --git a/elide-swagger/src/main/java/com/yahoo/elide/swagger/converter/JsonApiModelResolver.java b/elide-swagger/src/main/java/com/yahoo/elide/swagger/converter/JsonApiModelResolver.java index 42bfaaec94..ed4253f2db 100644 --- a/elide-swagger/src/main/java/com/yahoo/elide/swagger/converter/JsonApiModelResolver.java +++ b/elide-swagger/src/main/java/com/yahoo/elide/swagger/converter/JsonApiModelResolver.java @@ -16,7 +16,7 @@ import com.yahoo.elide.core.utils.coerce.converters.Serde; import com.yahoo.elide.swagger.models.media.Relationship; import com.yahoo.elide.swagger.models.media.Resource; -import com.fasterxml.jackson.databind.type.SimpleType; +import com.fasterxml.jackson.databind.type.SimpleType; // swagger still using Jackson 2 import com.google.common.base.Preconditions; import org.apache.commons.lang3.StringUtils; @@ -30,6 +30,7 @@ import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import io.swagger.v3.oas.models.media.Schema; + import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; diff --git a/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiBuilderTest.java b/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiBuilderTest.java index 7be379deea..78e5450234 100644 --- a/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiBuilderTest.java +++ b/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiBuilderTest.java @@ -30,8 +30,6 @@ import com.yahoo.elide.swagger.models.media.Data; import com.yahoo.elide.swagger.models.media.Datum; import com.yahoo.elide.swagger.models.media.Relationship; -import com.fasterxml.jackson.databind.JsonNode; - import example.models.Agent; import example.models.Author; import example.models.Book; @@ -65,6 +63,9 @@ import jakarta.persistence.OneToMany; import lombok.Getter; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; + import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Date; @@ -1051,13 +1052,13 @@ void testAtomicOperationsOpenApi30() throws Exception { dictionary.bindEntity(Book.class); OpenApiBuilder builder = new OpenApiBuilder(dictionary).apiVersion(info.getVersion()); OpenAPI openApi = builder.build(); - JsonNode jsonNode = Json.mapper().readTree(Json.pretty(openApi)); + JsonNode jsonNode = JsonMapper.shared().readTree(Json.mapper().readTree(Json.pretty(openApi)).toString()); JsonNode operations = jsonNode.at("/paths/~1operations"); JsonNode schema = operations.at("/post/requestBody/content/application~1vnd.api+json; ext=\"https:~1~1jsonapi.org~1ext~1atomic\"/schema"); JsonNode dataSchema = schema.at("/properties/atomic:operations/items/properties/data"); JsonNode typeSchema = dataSchema.at("/anyOf/1/type"); - assertTrue(typeSchema.isTextual()); // OpenAPI 3.0 doesn't support type: null - assertEquals("object", typeSchema.asText()); + assertTrue(typeSchema.isString()); // OpenAPI 3.0 doesn't support type: null + assertEquals("object", typeSchema.asString()); JsonNode nullableSchema = dataSchema.at("/anyOf/1/nullable"); assertTrue(nullableSchema.isBoolean()); // OpenaAPI 3.0 supports nullable assertTrue(nullableSchema.booleanValue()); @@ -1071,13 +1072,13 @@ void testAtomicOperationsOpenApi31() throws Exception { OpenApiBuilder builder = new OpenApiBuilder(dictionary, openApi -> openApi.specVersion(SpecVersion.V31).openapi("3.1.0")).apiVersion(info.getVersion()); OpenAPI openApi = builder.build(); - JsonNode jsonNode = Json31.mapper().readTree(Json31.pretty(openApi)); + JsonNode jsonNode = JsonMapper.shared().readTree(Json31.mapper().readTree(Json31.pretty(openApi)).toString()); JsonNode operations = jsonNode.at("/paths/~1operations"); JsonNode schema = operations.at("/post/requestBody/content/application~1vnd.api+json; ext=\"https:~1~1jsonapi.org~1ext~1atomic\"/schema"); JsonNode dataSchema = schema.at("/properties/atomic:operations/items/properties/data"); JsonNode typeSchema = dataSchema.at("/anyOf/1/type"); assertTrue(typeSchema.isArray()); - assertEquals("null", typeSchema.get(1).asText()); // OpenAPI 3.1 supports type: null + assertEquals("null", typeSchema.get(1).asString()); // OpenAPI 3.1 supports type: null JsonNode nullableSchema = dataSchema.at("/anyOf/1/nullable"); assertTrue(nullableSchema.isMissingNode()); // OpenAPI 3.1 does not support nullable } diff --git a/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiIT.java b/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiIT.java index 808cd442e1..824b3ba5b9 100644 --- a/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiIT.java +++ b/elide-swagger/src/test/java/com/yahoo/elide/swagger/OpenApiIT.java @@ -14,12 +14,12 @@ import com.yahoo.elide.swagger.OpenApiDocument.MediaType; import com.yahoo.elide.swagger.resources.ApiDocsEndpoint; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; - import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.dataformat.yaml.YAMLFactory; + class OpenApiIT extends AbstractApiResourceInitializer { public OpenApiIT() { super(ApiDocsResourceConfig.class, ApiDocsEndpoint.class.getPackage().getName()); diff --git a/elide-swagger/src/test/java/com/yahoo/elide/swagger/models/media/AtomicOperationTest.java b/elide-swagger/src/test/java/com/yahoo/elide/swagger/models/media/AtomicOperationTest.java index 90abafbc34..b172e8b2c3 100644 --- a/elide-swagger/src/test/java/com/yahoo/elide/swagger/models/media/AtomicOperationTest.java +++ b/elide-swagger/src/test/java/com/yahoo/elide/swagger/models/media/AtomicOperationTest.java @@ -7,16 +7,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; import io.swagger.v3.core.util.Json; import io.swagger.v3.core.util.Json31; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; + /** * Test for AtomicOperation. */ @@ -25,12 +23,9 @@ class AtomicOperationTest { /** * For OpenAPI 3.1 the nullable keyword is not allowed. - * - * @throws JsonMappingException exception - * @throws JsonProcessingException exception */ @Test - void openApi31() throws JsonMappingException, JsonProcessingException { + void openApi31() { AtomicOperation atomicOperation = new AtomicOperation(); String result = Json31.pretty(atomicOperation); JsonNode jsonNode = objectMapper.readTree(result); @@ -43,19 +38,16 @@ void openApi31() throws JsonMappingException, JsonProcessingException { /** * For OpenAPI 3.0 the null type is not allowed. - * - * @throws JsonMappingException exception - * @throws JsonProcessingException exception */ @Test - void openApi30() throws JsonMappingException, JsonProcessingException { + void openApi30() { AtomicOperation atomicOperation = new AtomicOperation(); String result = Json.pretty(atomicOperation); JsonNode jsonNode = objectMapper.readTree(result); JsonNode data = jsonNode.at("/properties/data/anyOf/1"); JsonNode type = data.at("/type"); JsonNode nullable = data.at("/nullable"); - assertTrue(type.isTextual()); + assertTrue(type.isString()); assertTrue(nullable.isBoolean()); } } diff --git a/elide-test/pom.xml b/elide-test/pom.xml index 51efefdceb..f3c09d0755 100644 --- a/elide-test/pom.xml +++ b/elide-test/pom.xml @@ -48,7 +48,7 @@ graphql-java - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/elide-test/src/main/java/com/yahoo/elide/test/graphql/EnumFieldSerializer.java b/elide-test/src/main/java/com/yahoo/elide/test/graphql/EnumFieldSerializer.java index 555a5f4386..9ec97e08cd 100644 --- a/elide-test/src/main/java/com/yahoo/elide/test/graphql/EnumFieldSerializer.java +++ b/elide-test/src/main/java/com/yahoo/elide/test/graphql/EnumFieldSerializer.java @@ -5,19 +5,17 @@ */ package com.yahoo.elide.test.graphql; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; /** * A Jackson serializer for String entity field. */ -public class EnumFieldSerializer extends JsonSerializer { +public class EnumFieldSerializer extends ValueSerializer { @Override - public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(String value, JsonGenerator gen, SerializationContext serializationContext) { gen.writeRawValue(value); } } diff --git a/elide-test/src/main/java/com/yahoo/elide/test/graphql/GraphQLDSL.java b/elide-test/src/main/java/com/yahoo/elide/test/graphql/GraphQLDSL.java index 3b3b5646ea..fb8192a4ea 100644 --- a/elide-test/src/main/java/com/yahoo/elide/test/graphql/GraphQLDSL.java +++ b/elide-test/src/main/java/com/yahoo/elide/test/graphql/GraphQLDSL.java @@ -19,11 +19,15 @@ import com.yahoo.elide.test.graphql.elements.VariableDefinition; import com.yahoo.elide.test.graphql.elements.VariableDefinitions; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.google.common.collect.ImmutableList; +import tools.jackson.core.JacksonException; +import tools.jackson.core.json.JsonWriteFeature; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; @@ -197,10 +201,19 @@ public final class GraphQLDSL { /** * Jackson-serializes objects. */ - private static final ObjectMapper BASE_MAPPER = new ObjectMapper() - .setSerializationInclusion(JsonInclude.Include.NON_NULL) - .setSerializationInclusion(JsonInclude.Include.NON_DEFAULT) - .setSerializationInclusion(JsonInclude.Include.NON_EMPTY); + private static final ObjectMapper BASE_MAPPER = JsonMapper.builder() + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .changeDefaultPropertyInclusion(c -> JsonInclude.Value.construct(Include.NON_EMPTY, Include.NON_EMPTY) + .withValueInclusion(Include.NON_DEFAULT)) + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .build(); + + private static final ObjectMapper ARGUMENT_MAPPER = JsonMapper.builder() + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .changeDefaultPropertyInclusion(c -> JsonInclude.Value.construct(Include.NON_EMPTY, Include.NON_EMPTY) + .withValueInclusion(Include.NON_DEFAULT)) + .disable(JsonWriteFeature.QUOTE_PROPERTY_NAMES) + .build(); /** * Returns the JSON representation of an object. @@ -212,11 +225,7 @@ public final class GraphQLDSL { * @throws IllegalStateException */ public static String toJson(Object object) { - try { - return BASE_MAPPER.writer().writeValueAsString(object); - } catch (JsonProcessingException exception) { - throw new IllegalArgumentException(exception); - } + return BASE_MAPPER.writer().writeValueAsString(object); } /** @@ -515,15 +524,10 @@ public static Argument argument(String name, Object value, boolean quoted) { try { return new Argument( name, - BASE_MAPPER - .configure( - // GraphQL argument name is unquoted; hence quoted field is disabled. - JsonGenerator.Feature.QUOTE_FIELD_NAMES, - false - ) + ARGUMENT_MAPPER .writeValueAsString(value) ); - } catch (JsonProcessingException exception) { + } catch (JacksonException exception) { throw new IllegalStateException(String.format("Cannot serialize %s", value), exception); } } diff --git a/elide-test/src/main/java/com/yahoo/elide/test/graphql/VariableFieldSerializer.java b/elide-test/src/main/java/com/yahoo/elide/test/graphql/VariableFieldSerializer.java index 4700c6dc81..995cf6ff58 100644 --- a/elide-test/src/main/java/com/yahoo/elide/test/graphql/VariableFieldSerializer.java +++ b/elide-test/src/main/java/com/yahoo/elide/test/graphql/VariableFieldSerializer.java @@ -5,11 +5,9 @@ */ package com.yahoo.elide.test.graphql; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; /** * A Jackson serializer for String entity field. @@ -47,13 +45,13 @@ * * @see Variables */ -public class VariableFieldSerializer extends JsonSerializer { +public class VariableFieldSerializer extends ValueSerializer { private static final String VARIABLE_SIGN = "$"; private static final String ENUM_SIGN = "#"; @Override - public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(String value, JsonGenerator gen, SerializationContext serializers) { if (value.startsWith(VARIABLE_SIGN)) { // this is a variable diff --git a/pom.xml b/pom.xml index f16e26e344..f843a997d6 100644 --- a/pom.xml +++ b/pom.xml @@ -99,16 +99,16 @@ 25.0.2 33.5.0-jre 4.5.0 - 7.2.6.Final + 7.3.0.Final 9.1.0.Final - 8.2.2.Final + 8.3.0.Final 3.1.0 5.6 5.0.4 2.13.2 2.4.240 7.0.2 - 2.21.1 + 3.1.0 2.0.1 3.1.0 3.2.0 @@ -131,7 +131,7 @@ 2025.0.4 2.1.0 2.0.17 - 4.0.3 + 4.0.5 7.0.5 5.0.1 3.0.2 @@ -543,7 +543,7 @@ test - com.fasterxml.jackson + tools.jackson jackson-bom ${jackson-bom.version} pom From 8084454081e9e54b73c57fe2b5c4ffb6dd8e9cbb Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Fri, 24 Apr 2026 22:04:38 +0800 Subject: [PATCH 10/12] Upgrade to Atomikos Spring Boot 4 Starter --- elide-spring/elide-spring-boot-autoconfigure/pom.xml | 2 +- .../spring/config/ElideAutoConfigurationTransactionTest.java | 3 --- pom.xml | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/elide-spring/elide-spring-boot-autoconfigure/pom.xml b/elide-spring/elide-spring-boot-autoconfigure/pom.xml index c588b0fec1..1655ebe188 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/pom.xml +++ b/elide-spring/elide-spring-boot-autoconfigure/pom.xml @@ -264,7 +264,7 @@ com.atomikos - transactions-spring-boot3-starter + transactions-spring-boot4-starter test diff --git a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java index d48f41443d..1ebf5a85d5 100644 --- a/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java +++ b/elide-spring/elide-spring-boot-autoconfigure/src/test/java/com/yahoo/elide/spring/config/ElideAutoConfigurationTransactionTest.java @@ -31,7 +31,6 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -491,7 +490,6 @@ public LocalContainerEntityManagerFactoryBean entityManagerFactoryV3(EntityManag } @Test - @Disabled // Disabled as no Spring Boot 4 compatible atomikos starter void multiplexDataStoreJtaTransaction() { contextRunner .withPropertyValues("spring.cloud.refresh.enabled=false", @@ -558,7 +556,6 @@ void multiplexDataStoreJtaTransaction() { } @Test - @Disabled // Disabled as no Spring Boot 4 compatible atomikos starter void multipleDataStoreJtaTransaction() { contextRunner.withPropertyValues("spring.cloud.refresh.enabled=false", "atomikos.properties.max-timeout=0") .withConfiguration(AutoConfigurations.of(AtomikosAutoConfiguration.class)) diff --git a/pom.xml b/pom.xml index f843a997d6..9cd6484998 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 4.13.2 2.52.0 - 6.0.0 + 6.0.1 1.41.0 3.2.3 4.8.184 @@ -200,7 +200,7 @@ com.atomikos - transactions-spring-boot3-starter + transactions-spring-boot4-starter ${atomikos.version} From 813ec8e508953186e216835092de42346b06a4eb Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Sat, 25 Apr 2026 09:35:18 +0800 Subject: [PATCH 11/12] Update dependencies --- checkstyle-style.xml | 2 +- elide-quarkus/pom.xml | 2 +- pom.xml | 44 +++++++++++++++++++++---------------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/checkstyle-style.xml b/checkstyle-style.xml index 4bf2726962..f201269d78 100644 --- a/checkstyle-style.xml +++ b/checkstyle-style.xml @@ -137,7 +137,7 @@ - + diff --git a/elide-quarkus/pom.xml b/elide-quarkus/pom.xml index 5cc2b702e8..d8e2503433 100644 --- a/elide-quarkus/pom.xml +++ b/elide-quarkus/pom.xml @@ -49,7 +49,7 @@ 11 UTF-8 UTF-8 - 3.32.3 + 3.35.0 7.1.18-SNAPSHOT 3.5.5 ${project.basedir}/../.. diff --git a/pom.xml b/pom.xml index 9cd6484998..0b37a12ac3 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 4.13.2 - 2.52.0 + 2.53.0 6.0.1 1.41.0 3.2.3 @@ -96,19 +96,19 @@ 6.0.0 25.0 24.0 - 25.0.2 - 33.5.0-jre + 25.0.3 + 33.6.0-jre 4.5.0 - 7.3.0.Final + 7.3.2.Final 9.1.0.Final 8.3.0.Final 3.1.0 - 5.6 - 5.0.4 - 2.13.2 + 5.6.1 + 5.0.5 + 2.14.0 2.4.240 7.0.2 - 3.1.0 + 3.1.2 2.0.1 3.1.0 3.2.0 @@ -116,33 +116,33 @@ 2.2.0 4.0.0 3.1.1 - 2.4.2 + 2.4.3 4.0.2 - 12.1.7 - 7.4.0 + 12.1.8 + 7.5.0 1.5.3 3.0.0 - 3.0.1 - 6.0.2 + 3.0.2 + 6.0.3 1.5.32 - 1.18.44 + 1.18.46 5.5.1 6.0.0 - 2025.0.4 + 2025.0.5 2.1.0 2.0.17 - 4.0.5 - 7.0.5 + 4.0.6 + 7.0.7 5.0.1 - 3.0.2 - 2.2.45 + 3.0.3 + 2.2.49 1.2.1 - 11.0.18 + 11.0.21 5.23.0 3.6.1 4.3.0 - 10.21.4 - 12.2.0 + 12.3.1 + 12.2.1 0.8.14 2.3.1 3.6.0 From 911a856ee517d2e5882908012fd8d19116100f84 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Thu, 30 Apr 2026 12:29:08 +0800 Subject: [PATCH 12/12] Clean quarkus --- elide-quarkus/deployment/pom.xml | 1 - .../deployment/ElideExtensionProcessor.java | 63 ++++++++++--------- elide-quarkus/pom.xml | 26 +++----- elide-quarkus/runtime/pom.xml | 2 +- 4 files changed, 43 insertions(+), 49 deletions(-) diff --git a/elide-quarkus/deployment/pom.xml b/elide-quarkus/deployment/pom.xml index d57d173174..639b974f5c 100644 --- a/elide-quarkus/deployment/pom.xml +++ b/elide-quarkus/deployment/pom.xml @@ -121,7 +121,6 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.10.0 attach-javadocs diff --git a/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java b/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java index e12e39bb46..6888faf28b 100644 --- a/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java +++ b/elide-quarkus/deployment/src/main/java/com/yahoo/elide/extension/deployment/ElideExtensionProcessor.java @@ -26,7 +26,12 @@ import com.yahoo.elide.extension.runtime.ElideRecorder; import com.yahoo.elide.graphql.DeferredId; import com.yahoo.elide.graphql.GraphQLEndpoint; -import com.yahoo.elide.jsonapi.models.*; +import com.yahoo.elide.jsonapi.models.Data; +import com.yahoo.elide.jsonapi.models.JsonApiDocument; +import com.yahoo.elide.jsonapi.models.Meta; +import com.yahoo.elide.jsonapi.models.Relationship; +import com.yahoo.elide.jsonapi.models.Resource; +import com.yahoo.elide.jsonapi.models.ResourceIdentifier; import com.yahoo.elide.jsonapi.resources.JsonApiEndpoint; import com.yahoo.elide.jsonapi.serialization.DataDeserializer; import com.yahoo.elide.jsonapi.serialization.DataSerializer; @@ -69,8 +74,10 @@ import jakarta.inject.Named; import jakarta.inject.Singleton; import jakarta.ws.rs.Path; - -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; /** * Quarkus extension processor for Elide. @@ -203,9 +210,9 @@ public void configureElideModels( index.getIndex().getKnownClasses().forEach(classInfo -> { boolean found = false; - for (Class annotationClass : ElideRecorder.ANNOTATIONS) { + for (Class annotationClass : ElideRecorder.ANNOTATIONS) { AnnotationInstance instance = - classInfo.classAnnotation(DotName.createSimple(annotationClass.getCanonicalName())); + classInfo.declaredAnnotation(DotName.createSimple(annotationClass.getCanonicalName())); if (instance != null) { found = true; @@ -218,9 +225,8 @@ public void configureElideModels( Class beanClass = Class.forName(classInfo.name().toString(), false, Thread.currentThread().getContextClassLoader()); - reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder() - .type(convertToType(beanClass)) - .build()); + reflectionHierarchiesBuildItems + .produce(ReflectiveHierarchyBuildItem.builder(convertToType(beanClass)).build()); elideClasses.add(beanClass); } catch (ClassNotFoundException e) { LOG.error("Unable to load class from Jandex Index: " + classInfo.name()); @@ -235,34 +241,35 @@ public void configureElideModels( .addQualifier(Default.class) .done()); - reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder() - .type(convertToType(JsonApiDocument.class)) - .build()); - reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder() - .type(convertToType(OpenApiDocument.class)) - .build()); - reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder() - .type(convertToType(GraphQLSchema.class)) - .build()); + reflectionHierarchiesBuildItems + .produce(ReflectiveHierarchyBuildItem.builder(convertToType(JsonApiDocument.class)).build()); + reflectionHierarchiesBuildItems + .produce(ReflectiveHierarchyBuildItem.builder(convertToType(OpenApiDocument.class)).build()); + reflectionHierarchiesBuildItems + .produce(ReflectiveHierarchyBuildItem.builder(convertToType(GraphQLSchema.class)).build()); //JSON-API Serialization Classes: - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DataSerializer.class)); - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DataDeserializer.class)); - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, MetaDeserializer.class)); - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, KeySerializer.class)); + reflectionBuildItems.produce(ReflectiveClassBuildItem.builder(DataSerializer.class).methods().fields().build()); + reflectionBuildItems + .produce(ReflectiveClassBuildItem.builder(DataDeserializer.class).methods().fields().build()); + reflectionBuildItems + .produce(ReflectiveClassBuildItem.builder(MetaDeserializer.class).methods().fields().build()); + reflectionBuildItems.produce(ReflectiveClassBuildItem.builder(KeySerializer.class).methods().fields().build()); //Prefabbed Checks: - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, Collections.AppendOnly.class)); - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, Collections.RemoveOnly.class)); + reflectionBuildItems + .produce(ReflectiveClassBuildItem.builder(Collections.AppendOnly.class).methods().fields().build()); + reflectionBuildItems + .produce(ReflectiveClassBuildItem.builder(Collections.RemoveOnly.class).methods().fields().build()); //GraphQL Schema: - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DeferredId.class)); + reflectionBuildItems.produce(ReflectiveClassBuildItem.builder(DeferredId.class).methods().fields().build()); // reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DeferredId.SerializeId.class)); //Needed by elide dependency coerce utils which pulls in commons logging. // reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, JBossLogFactory.class)); - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, LogFactory.class)); - reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, SimpleLog.class)); + reflectionBuildItems.produce(ReflectiveClassBuildItem.builder(LogFactory.class).methods().fields().build()); + reflectionBuildItems.produce(ReflectiveClassBuildItem.builder(SimpleLog.class).methods().fields().build()); } private org.jboss.jandex.Type convertToType(Class cls) { @@ -283,9 +290,9 @@ private org.jboss.jandex.Type convertToType(Class cls) { */ private void generateEndpointClass( BuildProducer generatedJaxRsResourceBuildItemBuildProducer, - String endpointStyle, Class endpointClass, String customPath, Param... params) { + String endpointStyle, Class endpointClass, String customPath, Param... params) { // Deconstruct Param instances - Class[] paramClasses = new Class[params.length]; + Class[] paramClasses = new Class[params.length]; io.quarkus.gizmo.Type[] paramTypes = new io.quarkus.gizmo.Type[params.length]; String[] paramNames = new String[params.length]; for (int i = 0; i < params.length; i++) { diff --git a/elide-quarkus/pom.xml b/elide-quarkus/pom.xml index d8e2503433..5c3687dff2 100644 --- a/elide-quarkus/pom.xml +++ b/elide-quarkus/pom.xml @@ -42,16 +42,7 @@ runtime - 3.13.0 - 3.5.5 - true - 11 - 11 - UTF-8 - UTF-8 3.35.0 - 7.1.18-SNAPSHOT - 3.5.5 ${project.basedir}/../.. @@ -66,37 +57,37 @@ com.yahoo.elide elide-core - ${elide.version} + ${project.version} com.yahoo.elide elide-graphql - ${elide.version} + ${project.version} com.yahoo.elide elide-datastore-aggregation - ${elide.version} + ${project.version} com.yahoo.elide elide-datastore-jpa - ${elide.version} + ${project.version} com.yahoo.elide elide-datastore-multiplex - ${elide.version} + ${project.version} com.yahoo.elide elide-swagger - ${elide.version} + ${project.version} com.yahoo.elide elide-test-helpers - ${elide.version} + ${project.version} @@ -109,7 +100,6 @@ maven-surefire-plugin - ${surefire-plugin.version} org.jboss.logmanager.LogManager @@ -120,7 +110,6 @@ maven-failsafe-plugin - ${failsafe-plugin.version} org.jboss.logmanager.LogManager @@ -138,7 +127,6 @@ maven-compiler-plugin - ${compiler-plugin.version} diff --git a/elide-quarkus/runtime/pom.xml b/elide-quarkus/runtime/pom.xml index ddaeb89d0b..cb2daaddb2 100644 --- a/elide-quarkus/runtime/pom.xml +++ b/elide-quarkus/runtime/pom.xml @@ -85,7 +85,7 @@ io.quarkus quarkus-extension-maven-plugin - 3.0.0.Beta1 + ${quarkus.version} compile