From 11358b03af48d4b439bb13fa97506af719404f2f Mon Sep 17 00:00:00 2001 From: Fabrizzio Araya <37148755+fabrizzio-dotCMS@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:32:55 -0600 Subject: [PATCH] feat(CDI) Refs: #29552 (#29678) ### Proposed Changes * In this PR we are upgrading to jersey 2.28 * We are changing DotRestApplication to use package discovery to load Resources and Providers * We're making some adjustments on some Mappers to preserve the present behavior * We're introducing CDI through Weld container --------- Co-authored-by: spbolton --- bom/application/pom.xml | 54 +- build.xml | 1141 ----------------- dotCMS/pom.xml | 42 +- .../main/java/com/dotcms/cdi/CDIUtils.java | 35 + .../dotcms/rest/annotation/HeaderFilter.java | 2 + .../java/com/dotcms/rest/api/CorsFilter.java | 2 + .../dotcms/rest/config/ContainerReloader.java | 12 +- .../rest/config/DotRestApplication.java | 313 +---- .../JerseyApplicationEventListener.java | 39 + .../DefaultDotBadRequestExceptionMapper.java | 2 + .../mapper/DoesNotExistExceptionMapper.java | 2 + .../mapper/DotBadRequestExceptionMapper.java | 2 +- .../exception/mapper/DotExceptionMapper.java | 4 +- .../ElasticsearchStatusExceptionMapper.java | 2 + .../mapper/JsonMappingExceptionMapper.java | 22 +- .../mapper/NotAllowedExceptionMapper.java | 2 + .../mapper/NotFoundInDbExceptionMapper.java | 2 + .../AlreadyExistsExceptionMapper.java | 11 + .../badrequest/DotStateExceptionMapper.java | 10 + .../IllegalArgumentExceptionMapper.java | 10 + .../InvalidFolderNameExceptionMapper.java | 11 + .../JsonProcessingExceptionMapper.java | 11 + .../NumberFormatExceptionMapper.java | 11 + .../servlet/ReloadableServletContainer.java | 135 -- .../com/dotmarketing/plugin/PluginLoader.java | 178 --- .../dotmarketing/servlets/InitServlet.java | 65 +- .../util/jasper/DotJasperTask.java | 50 - dotCMS/src/main/webapp/WEB-INF/beans.xml | 9 + dotCMS/src/main/webapp/WEB-INF/web.xml | 17 +- .../test/java/com/dotcms/UnitTestBase.java | 27 +- .../filters/NormalizationFilterTest.java | 2 +- .../dotmarketing/plugin/PluginMergerTest.java | 80 -- dotCMS/src/test/resources/META-INF/beans.xml | 9 + dotcms-integration/pom.xml | 17 + .../java/com/dotcms/IntegrationTestBase.java | 19 +- .../java/com/dotcms/cdi/GreetingBean.java | 17 + .../com/dotcms/cdi/MessageServiceBean.java | 12 + .../com/dotcms/cdi/SimpleInjectionIT.java | 31 + .../util/IntegrationTestInitService.java | 9 + .../src/test/resources/META-INF/beans.xml | 9 + 40 files changed, 472 insertions(+), 1956 deletions(-) delete mode 100644 build.xml create mode 100644 dotCMS/src/main/java/com/dotcms/cdi/CDIUtils.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/config/JerseyApplicationEventListener.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/AlreadyExistsExceptionMapper.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/DotStateExceptionMapper.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/IllegalArgumentExceptionMapper.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/InvalidFolderNameExceptionMapper.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/JsonProcessingExceptionMapper.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/NumberFormatExceptionMapper.java delete mode 100644 dotCMS/src/main/java/com/dotcms/rest/servlet/ReloadableServletContainer.java delete mode 100644 dotCMS/src/main/java/com/dotmarketing/plugin/PluginLoader.java delete mode 100644 dotCMS/src/main/java/com/dotmarketing/util/jasper/DotJasperTask.java create mode 100644 dotCMS/src/main/webapp/WEB-INF/beans.xml delete mode 100644 dotCMS/src/test/java/com/dotmarketing/plugin/PluginMergerTest.java create mode 100644 dotCMS/src/test/resources/META-INF/beans.xml create mode 100644 dotcms-integration/src/test/java/com/dotcms/cdi/GreetingBean.java create mode 100644 dotcms-integration/src/test/java/com/dotcms/cdi/MessageServiceBean.java create mode 100644 dotcms-integration/src/test/java/com/dotcms/cdi/SimpleInjectionIT.java create mode 100644 dotcms-integration/src/test/resources/META-INF/beans.xml diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 1eae80e3ca5f..de35ba06259b 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -24,7 +24,7 @@ 4.33.0 0.14.1 2.17.2 - 2.22.1 + 2.28 22.3.3 @@ -84,11 +84,6 @@ ***************************** --> - - com.dotcms - ant-tooling - 1.3.2 - com.dotcms.lib dot.aopalliance-repackaged @@ -1137,7 +1132,7 @@ javax.ws.rs javax.ws.rs-api - 2.0.1 + 2.1.1 @@ -1152,6 +1147,51 @@ ${swagger.version} + + + + org.jboss.weld.servlet + weld-servlet-shaded + 3.1.9.Final + + + + org.glassfish.hk2.external + bean-validator + 2.5.0-b06 + + + + org.glassfish.hk2 + hk2-locator + 2.5.0 + + + + org.jboss.weld + weld-junit5 + 2.0.2.Final + test + + + org.jboss.weld.se + weld-se-core + + + + + + org.jboss.weld.se + weld-se-shaded + 3.1.9.Final + test + + + + io.smallrye + jandex + 3.0.5 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${javadoc.title} - - - ${javadoc.bottom} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Deploying plugins to: ${plugin.root.dir} | ${plugin.jar.deploy.dir} - - - - - Copying plugins to: ${plugin.root.dir} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Deploying plugins from: ${plugin.root.dir} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Undeploying plugins from: ${plugin.root.dir} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dotCMS/pom.xml b/dotCMS/pom.xml index bc5557037e7f..c5aa707ecbb2 100644 --- a/dotCMS/pom.xml +++ b/dotCMS/pom.xml @@ -106,10 +106,6 @@ ***************************** --> - - com.dotcms - ant-tooling - com.dotcms.lib dot.aopalliance-repackaged @@ -1199,12 +1195,11 @@ jersey-common - + org.glassfish.jersey.core jersey-server @@ -1412,6 +1407,39 @@ + + + + org.jboss.weld.servlet + weld-servlet-shaded + 3.1.9.Final + + + + org.glassfish.hk2.external + bean-validator + 2.5.0-b06 + + + + org.glassfish.hk2 + hk2-locator + + + + org.jboss.weld.se + weld-se-shaded + test + + + + + + io.smallrye + jandex + 3.0.5 + + org.apache.tomcat tomcat-catalina diff --git a/dotCMS/src/main/java/com/dotcms/cdi/CDIUtils.java b/dotCMS/src/main/java/com/dotcms/cdi/CDIUtils.java new file mode 100644 index 000000000000..296b09eeab28 --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/cdi/CDIUtils.java @@ -0,0 +1,35 @@ +package com.dotcms.cdi; + +import com.dotmarketing.util.Logger; +import java.util.Optional; +import javax.enterprise.inject.spi.CDI; + +/** + * Utility class to get beans from CDI container + */ +public class CDIUtils { + + /** + * Private constructor to avoid instantiation + */ + private CDIUtils() { + } + + /** + * Get a bean from CDI container + * @param clazz the class of the bean + * @return an Optional with the bean if found, empty otherwise + */ + public static Optional getBean(Class clazz) { + try { + return Optional.of(CDI.current().select(clazz).get()); + } catch (Exception e) { + Logger.error(CDIUtils.class, + String.format("Unable to find bean of class [%s] [%s]", clazz, e.getMessage()) + ); + } + return Optional.empty(); + } + + +} diff --git a/dotCMS/src/main/java/com/dotcms/rest/annotation/HeaderFilter.java b/dotCMS/src/main/java/com/dotcms/rest/annotation/HeaderFilter.java index b6c2825188d2..4209dea526e6 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/annotation/HeaderFilter.java +++ b/dotCMS/src/main/java/com/dotcms/rest/annotation/HeaderFilter.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.Map; import java.util.Optional; +import javax.ws.rs.ext.Provider; /** * This decorator reads the annotations on the resources and includes header based on it based on them. @@ -31,6 +32,7 @@ */ @Singleton @Priority(Priorities.HEADER_DECORATOR) +@Provider public class HeaderFilter implements ContainerResponseFilter { private final PermissionsUtil permissionsUtil = PermissionsUtil.getInstance(); diff --git a/dotCMS/src/main/java/com/dotcms/rest/api/CorsFilter.java b/dotCMS/src/main/java/com/dotcms/rest/api/CorsFilter.java index f2b6bcca1e90..c55045fe7f3c 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/api/CorsFilter.java +++ b/dotCMS/src/main/java/com/dotcms/rest/api/CorsFilter.java @@ -16,11 +16,13 @@ import com.dotmarketing.util.Logger; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import javax.ws.rs.ext.Provider; /** * @author Geoff M. Granum */ +@Provider public class CorsFilter implements ContainerResponseFilter { diff --git a/dotCMS/src/main/java/com/dotcms/rest/config/ContainerReloader.java b/dotCMS/src/main/java/com/dotcms/rest/config/ContainerReloader.java index d0c116e64053..969420976ad0 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/config/ContainerReloader.java +++ b/dotCMS/src/main/java/com/dotcms/rest/config/ContainerReloader.java @@ -2,6 +2,8 @@ import com.dotmarketing.util.Logger; import java.util.concurrent.atomic.AtomicReference; +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.ext.Provider; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.spi.AbstractContainerLifecycleListener; import org.glassfish.jersey.server.spi.Container; @@ -9,16 +11,12 @@ /** * A new Reloader will get created on each reload there can only be one container at a time */ -class ContainerReloader extends AbstractContainerLifecycleListener { - - private static final ContainerReloader INSTANCE = new ContainerReloader(); +@Provider +@ApplicationScoped +public class ContainerReloader extends AbstractContainerLifecycleListener { private static final AtomicReference containerRef = new AtomicReference<>(); - public static ContainerReloader getInstance() { - return INSTANCE; - } - @Override public void onStartup(Container container) { Logger.debug(ContainerReloader.class, "Jersey Container started"); diff --git a/dotCMS/src/main/java/com/dotcms/rest/config/DotRestApplication.java b/dotCMS/src/main/java/com/dotcms/rest/config/DotRestApplication.java index 8ace717c0a88..77a4d860275c 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/config/DotRestApplication.java +++ b/dotCMS/src/main/java/com/dotcms/rest/config/DotRestApplication.java @@ -1,136 +1,19 @@ package com.dotcms.rest.config; -import com.dotcms.ai.rest.*; -import com.dotcms.contenttype.model.field.FieldTypeResource; -import com.dotcms.rendering.js.JsResource; -import com.dotcms.rest.AuditPublishingResource; -import com.dotcms.rest.BundlePublisherResource; -import com.dotcms.rest.BundleResource; -import com.dotcms.rest.CMSConfigResource; -import com.dotcms.rest.ClusterResource; -import com.dotcms.rest.EnvironmentResource; -import com.dotcms.rest.IntegrityResource; -import com.dotcms.rest.JSPPortlet; -import com.dotcms.rest.LicenseResource; -import com.dotcms.rest.OSGIResource; -import com.dotcms.rest.PublishQueueResource; -import com.dotcms.rest.RestExamplePortlet; -import com.dotcms.rest.RulesEnginePortlet; -import com.dotcms.rest.StructureResource; -import com.dotcms.rest.TagResource; -import com.dotcms.rest.WidgetResource; -import com.dotcms.rest.annotation.HeaderFilter; -import com.dotcms.rest.annotation.RequestFilter; -import com.dotcms.rest.api.CorsFilter; -import com.dotcms.rest.api.MyObjectMapperProvider; -import com.dotcms.rest.api.v1.announcements.AnnouncementsResource; -import com.dotcms.rest.api.v1.apps.AppsResource; -import com.dotcms.rest.api.v1.asset.WebAssetResource; -import com.dotcms.rest.api.v1.authentication.ApiTokenResource; -import com.dotcms.rest.api.v1.authentication.AuthenticationResource; -import com.dotcms.rest.api.v1.authentication.CreateJsonWebTokenResource; -import com.dotcms.rest.api.v1.authentication.ForgotPasswordResource; -import com.dotcms.rest.api.v1.authentication.LoginFormResource; -import com.dotcms.rest.api.v1.authentication.LogoutResource; -import com.dotcms.rest.api.v1.authentication.ResetPasswordResource; -import com.dotcms.rest.api.v1.browser.BrowserResource; -import com.dotcms.rest.api.v1.browsertree.BrowserTreeResource; -import com.dotcms.rest.api.v1.categories.CategoriesResource; -import com.dotcms.rest.api.v1.container.ContainerResource; -import com.dotcms.rest.api.v1.content.ContentRelationshipsResource; -import com.dotcms.rest.api.v1.content.ContentReportResource; -import com.dotcms.rest.api.v1.content.ContentResource; -import com.dotcms.rest.api.v1.content.ContentVersionResource; -import com.dotcms.rest.api.v1.content.ResourceLinkResource; -import com.dotcms.rest.api.v1.contenttype.ContentTypeResource; -import com.dotcms.rest.api.v1.contenttype.FieldResource; -import com.dotcms.rest.api.v1.contenttype.FieldVariableResource; -import com.dotcms.rest.api.v1.ema.EMAResource; -import com.dotcms.rest.api.v1.event.EventsResource; -import com.dotcms.rest.api.v1.experiments.ExperimentsResource; -import com.dotcms.rest.api.v1.fileasset.FileAssetsResource; -import com.dotcms.rest.api.v1.folder.FolderResource; -import com.dotcms.rest.api.v1.form.FormResource; -import com.dotcms.rest.api.v1.index.ESIndexResource; -import com.dotcms.rest.api.v1.languages.LanguagesResource; -import com.dotcms.rest.api.v1.maintenance.JVMInfoResource; -import com.dotcms.rest.api.v1.maintenance.MaintenanceResource; -import com.dotcms.rest.api.v1.menu.MenuResource; -import com.dotcms.rest.api.v1.notification.NotificationResource; -import com.dotcms.rest.api.v1.page.NavResource; -import com.dotcms.rest.api.v1.page.PageResource; -import com.dotcms.rest.api.v1.personalization.PersonalizationResource; -import com.dotcms.rest.api.v1.personas.PersonaResource; -import com.dotcms.rest.api.v1.portlet.PortletResource; -import com.dotcms.rest.api.v1.portlet.ToolGroupResource; -import com.dotcms.rest.api.v1.pushpublish.PushPublishFilterResource; -import com.dotcms.rest.api.v1.relationships.RelationshipsResource; -import com.dotcms.rest.api.v1.site.SiteResource; -import com.dotcms.rest.api.v1.sites.ruleengine.rules.RuleResource; -import com.dotcms.rest.api.v1.sites.ruleengine.rules.actions.ActionResource; -import com.dotcms.rest.api.v1.sites.ruleengine.rules.conditions.ConditionGroupResource; -import com.dotcms.rest.api.v1.sites.ruleengine.rules.conditions.ConditionResource; -import com.dotcms.rest.api.v1.sites.ruleengine.rules.conditions.ConditionValueResource; -import com.dotcms.rest.api.v1.system.AppContextInitResource; -import com.dotcms.rest.api.v1.system.ConfigurationResource; -import com.dotcms.rest.api.v1.system.SystemTableResource; -import com.dotcms.rest.api.v1.system.UpgradeTaskResource; -import com.dotcms.rest.api.v1.system.cache.CacheResource; -import com.dotcms.rest.api.v1.system.i18n.I18NResource; -import com.dotcms.rest.api.v1.system.logger.LoggerResource; -import com.dotcms.rest.api.v1.system.monitor.MonitorResource; -import com.dotcms.rest.api.v1.system.permission.PermissionResource; -import com.dotcms.rest.api.v1.system.role.RoleResource; -import com.dotcms.rest.api.v1.system.ruleengine.actionlets.ActionletsResource; -import com.dotcms.rest.api.v1.system.ruleengine.conditionlets.ConditionletsResource; -import com.dotcms.rest.api.v1.system.storage.StorageResource; -import com.dotcms.rest.api.v1.taillog.TailLogResource; -import com.dotcms.rest.api.v1.temp.TempFileResource; -import com.dotcms.rest.api.v1.template.TemplateResource; -import com.dotcms.rest.api.v1.theme.ThemeResource; -import com.dotcms.rest.api.v1.user.UserResource; -import com.dotcms.rest.api.v1.variants.VariantResource; -import com.dotcms.rest.api.v1.versionable.VersionableResource; -import com.dotcms.rest.api.v1.vtl.VTLResource; -import com.dotcms.rest.api.v1.workflow.WorkflowResource; -import com.dotcms.rest.elasticsearch.ESContentResourcePortlet; -import com.dotcms.rest.exception.mapper.DefaultDotBadRequestExceptionMapper; -import com.dotcms.rest.exception.mapper.DoesNotExistExceptionMapper; -import com.dotcms.rest.exception.mapper.DotBadRequestExceptionMapper; -import com.dotcms.rest.exception.mapper.DotDataExceptionMapper; -import com.dotcms.rest.exception.mapper.DotSecurityExceptionMapper; -import com.dotcms.rest.exception.mapper.ElasticsearchStatusExceptionMapper; -import com.dotcms.rest.exception.mapper.HttpStatusCodeExceptionMapper; -import com.dotcms.rest.exception.mapper.InvalidFormatExceptionMapper; -import com.dotcms.rest.exception.mapper.InvalidLicenseExceptionMapper; -import com.dotcms.rest.exception.mapper.JsonMappingExceptionMapper; -import com.dotcms.rest.exception.mapper.JsonParseExceptionMapper; -import com.dotcms.rest.exception.mapper.NotAllowedExceptionMapper; -import com.dotcms.rest.exception.mapper.NotFoundInDbExceptionMapper; -import com.dotcms.rest.exception.mapper.ParamExceptionMapper; -import com.dotcms.rest.exception.mapper.ResourceNotFoundExceptionMapper; -import com.dotcms.rest.exception.mapper.RuntimeExceptionMapper; -import com.dotcms.rest.exception.mapper.UnrecognizedPropertyExceptionMapper; -import com.dotcms.rest.exception.mapper.WorkflowPortletAccessExceptionMapper; -import com.dotcms.rest.personas.PersonasResourcePortlet; -import com.dotmarketing.business.DotStateException; -import com.dotmarketing.exception.AlreadyExistException; -import com.dotmarketing.portlets.folders.exception.InvalidFolderNameException; -import com.fasterxml.jackson.core.JsonProcessingException; +import com.dotcms.cdi.CDIUtils; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; -import com.google.common.collect.ImmutableSet; import io.swagger.v3.jaxrs2.integration.resources.AcceptHeaderOpenApiResource; import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.servers.Server; import io.swagger.v3.oas.annotations.tags.Tag; -import org.glassfish.jersey.media.multipart.MultiPartFeature; - -import javax.ws.rs.core.Application; import java.util.Map; -import java.util.Set; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import javax.ws.rs.ApplicationPath; +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.glassfish.jersey.server.ResourceConfig; /** * This class provides the list of all the REST end-points in dotCMS. Every new @@ -160,151 +43,24 @@ @Tag(name = "Content Report") } ) -public class DotRestApplication extends Application { - /** - * these are system resources and should never change - */ - private static final Set> INTERNAL_CLASSES = ImmutableSet.>builder() - .add(MultiPartFeature.class) - .add(ESIndexResource.class) - .add(com.dotcms.rest.RoleResource.class) - .add(BundleResource.class) - .add(StructureResource.class) - .add(com.dotcms.rest.ContentResource.class) - .add(BundlePublisherResource.class) - .add(JSPPortlet.class) - .add(AuditPublishingResource.class) - .add(WidgetResource.class) - .add(CMSConfigResource.class) - .add(OSGIResource.class) - .add(com.dotcms.rest.api.v1.osgi.OSGIResource.class) - .add(com.dotcms.rest.UserResource.class) - .add(ClusterResource.class) - .add(EnvironmentResource.class) - .add(NotificationResource.class) - .add(IntegrityResource.class) - .add(LicenseResource.class) - .add(RestExamplePortlet.class) - .add(ESContentResourcePortlet.class) - .add(PersonaResource.class) - .add(UserResource.class) - .add(TagResource.class) - .add(RulesEnginePortlet.class) - .add(RuleResource.class) - .add(ConditionGroupResource.class) - .add(ConditionResource.class) - .add(ConditionValueResource.class) - .add(PersonasResourcePortlet.class) - .add(ConditionletsResource.class) - .add(MonitorResource.class) - .add(ActionResource.class) - .add(ActionletsResource.class) - .add(I18NResource.class) - .add(LanguagesResource.class) - .add(com.dotcms.rest.api.v2.languages.LanguagesResource.class) - .add(MenuResource.class) - .add(AuthenticationResource.class) - .add(LogoutResource.class) - .add(LoginFormResource.class) - .add(ForgotPasswordResource.class) - .add(ConfigurationResource.class) - .add(AppContextInitResource.class) - .add(SiteResource.class) - .add(ContentTypeResource.class) - .add(FieldResource.class) - .add(com.dotcms.rest.api.v2.contenttype.FieldResource.class) - .add(com.dotcms.rest.api.v3.contenttype.FieldResource.class) - .add(FieldTypeResource.class) - .add(FieldVariableResource.class) - .add(ResetPasswordResource.class) - .add(RoleResource.class) - .add(CreateJsonWebTokenResource.class) - .add(ApiTokenResource.class) - .add(PortletResource.class) - .add(EventsResource.class) - .add(FolderResource.class) - .add(BrowserTreeResource.class) - .add(CategoriesResource.class) - .add(PageResource.class) - .add(ContentRelationshipsResource.class) - .add(WorkflowResource.class) - .add(ContainerResource.class) - .add(ThemeResource.class) - .add(NavResource.class) - .add(RelationshipsResource.class) - .add(VTLResource.class) - .add(JsResource.class) - .add(ContentVersionResource.class) - .add(FileAssetsResource.class) - .add(PersonalizationResource.class) - .add(TempFileResource.class) - .add(UpgradeTaskResource.class) - .add(AppsResource.class) - .add(EMAResource.class) - .add(BrowserResource.class) - .add(ResourceLinkResource.class) - .add(PushPublishFilterResource.class) - .add(LoggerResource.class) - .add(TemplateResource.class) - .add(MaintenanceResource.class) - .add(PublishQueueResource.class) - .add(ToolGroupResource.class) - .add(VersionableResource.class) - .add(PermissionResource.class) - .add(ContentResource.class) - .add(CacheResource.class) - .add(JVMInfoResource.class) - .add(FormResource.class) - .add(OpenApiResource.class) - .add(AcceptHeaderOpenApiResource.class) - .add(ExperimentsResource.class) - .add(TailLogResource.class) - .add(VariantResource.class) - .add(WebAssetResource.class) - .add(SystemTableResource.class) - .add(StorageResource.class) - .add(com.dotcms.rest.api.v2.tags.TagResource.class) - .add(AnnouncementsResource.class) - .add(CompletionsResource.class) - .add(EmbeddingsResource.class) - .add(ImageResource.class) - .add(SearchResource.class) - .add(TextResource.class) - .add(ContentReportResource.class) - .build(); +@ApplicationPath("/api") +public class DotRestApplication extends ResourceConfig { + + public DotRestApplication() { - private static final Set> PROVIDER_CLASSES = ImmutableSet.>builder() - .add(ContainerReloader.class) - .add(RequestFilter.class) - .add(HeaderFilter.class) - .add(CorsFilter.class) - .add(MyObjectMapperProvider.class) - .add(JacksonJaxbJsonProvider.class) - .add(HttpStatusCodeExceptionMapper.class) - .add(ResourceNotFoundExceptionMapper.class) - .add(InvalidFormatExceptionMapper.class) - .add(JsonParseExceptionMapper.class) - .add(ParamExceptionMapper.class) - .add(JsonMappingExceptionMapper.class) - .add(UnrecognizedPropertyExceptionMapper.class) - .add(InvalidLicenseExceptionMapper.class) - .add(WorkflowPortletAccessExceptionMapper.class) - .add(NotFoundInDbExceptionMapper.class) - .add(DoesNotExistExceptionMapper.class) - .add((new DotBadRequestExceptionMapper(){}).getClass()) - .add((new DotBadRequestExceptionMapper(){}).getClass()) - .add((new DotBadRequestExceptionMapper(){}).getClass()) - .add(DefaultDotBadRequestExceptionMapper.class) - .add((new DotBadRequestExceptionMapper(){}).getClass()) - .add((new DotBadRequestExceptionMapper(){}).getClass()) - .add(DotSecurityExceptionMapper.class) - .add(DotDataExceptionMapper.class) - .add(ElasticsearchStatusExceptionMapper.class) - .add((new DotBadRequestExceptionMapper(){}).getClass()) - .add(NotAllowedExceptionMapper.class) - .add(RuntimeExceptionMapper.class) - .build(); + register(MultiPartFeature.class). + register(JacksonJaxbJsonProvider.class). + register(OpenApiResource.class). + register(AcceptHeaderOpenApiResource.class). + registerClasses(customClasses.keySet()). + packages( + "com.dotcms.rest", + "com.dotcms.contenttype.model.field", + "com.dotcms.rendering.js", + "com.dotcms.ai.rest" + ); + } /** * This is the cheap way to create a concurrent set of user provided classes @@ -316,10 +72,12 @@ public class DotRestApplication extends Application { * @param clazz the class ot add */ public static synchronized void addClass(Class clazz) { - if(clazz==null)return; - if (Boolean.TRUE.equals(customClasses.computeIfAbsent(clazz,c -> true))) - { - ContainerReloader.getInstance().reload(); + if(clazz==null){ + return; + } + if (Boolean.TRUE.equals(customClasses.computeIfAbsent(clazz,c -> true))) { + final Optional reloader = CDIUtils.getBean(ContainerReloader.class); + reloader.ifPresent(ContainerReloader::reload); } } @@ -328,20 +86,13 @@ public static synchronized void addClass(Class clazz) { * @param clazz */ public static synchronized void removeClass(Class clazz) { - if(clazz==null)return; + if(clazz==null){ + return; + } if(customClasses.remove(clazz) != null){ - ContainerReloader.getInstance().reload(); + final Optional reloader = CDIUtils.getBean(ContainerReloader.class); + reloader.ifPresent(ContainerReloader::reload); } } - @Override - public Set> getClasses() { - return ImmutableSet.>builder() - .addAll(customClasses.keySet()) - .addAll(INTERNAL_CLASSES) - .addAll(PROVIDER_CLASSES) - .build(); - - } - } diff --git a/dotCMS/src/main/java/com/dotcms/rest/config/JerseyApplicationEventListener.java b/dotCMS/src/main/java/com/dotcms/rest/config/JerseyApplicationEventListener.java new file mode 100644 index 000000000000..0f0970bed5ab --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/config/JerseyApplicationEventListener.java @@ -0,0 +1,39 @@ +package com.dotcms.rest.config; + +import com.dotmarketing.util.Logger; +import java.util.Objects; +import java.util.Set; +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.ext.Provider; +import org.glassfish.jersey.server.monitoring.ApplicationEvent; +import org.glassfish.jersey.server.monitoring.ApplicationEvent.Type; +import org.glassfish.jersey.server.monitoring.ApplicationEventListener; +import org.glassfish.jersey.server.monitoring.RequestEvent; +import org.glassfish.jersey.server.monitoring.RequestEventListener; + +@Provider +@ApplicationScoped +public class JerseyApplicationEventListener implements ApplicationEventListener { + + @Override + public void onEvent(ApplicationEvent event) { + if (Objects.requireNonNull(event.getType()) == Type.INITIALIZATION_FINISHED) { + logLoadedClasses(event); + } + } + + private void logLoadedClasses(ApplicationEvent event) { + Set> resourceClasses = event.getResourceConfig().getClasses(); + Logger.info(JerseyApplicationEventListener.class,"Loaded resource classes:"); + resourceClasses.forEach(clazz -> Logger.info(JerseyApplicationEventListener.class,clazz.getName())); + + Set providerClasses = event.getResourceConfig().getInstances(); + Logger.info(JerseyApplicationEventListener.class,"Loaded provider classes:"); + providerClasses.forEach(instance -> Logger.info(JerseyApplicationEventListener.class,instance.getClass().getName())); + } + + @Override + public RequestEventListener onRequest(RequestEvent requestEvent) { + return null; // No specific request events handling + } +} \ No newline at end of file diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DefaultDotBadRequestExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DefaultDotBadRequestExceptionMapper.java index f172b5d7ccf5..1288de086e04 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DefaultDotBadRequestExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DefaultDotBadRequestExceptionMapper.java @@ -1,6 +1,8 @@ package com.dotcms.rest.exception.mapper; import com.dotcms.rest.exception.BadRequestException; +import javax.ws.rs.ext.Provider; +@Provider public class DefaultDotBadRequestExceptionMapper extends DotBadRequestExceptionMapper { } diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DoesNotExistExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DoesNotExistExceptionMapper.java index 9239480f7519..b60d4818c97c 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DoesNotExistExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DoesNotExistExceptionMapper.java @@ -3,10 +3,12 @@ import com.dotmarketing.exception.DoesNotExistException; import com.dotmarketing.util.SecurityLogger; import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; /** * Mapper for {@link DoesNotExistException} */ +@Provider public class DoesNotExistExceptionMapper implements javax.ws.rs.ext.ExceptionMapper { diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotBadRequestExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotBadRequestExceptionMapper.java index a36f889dae9b..7cbfabba65b7 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotBadRequestExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotBadRequestExceptionMapper.java @@ -14,7 +14,7 @@ * * @param Exception class to mapper */ -public class DotBadRequestExceptionMapper extends DotExceptionMapper { +public abstract class DotBadRequestExceptionMapper extends DotExceptionMapper { @Override public Response toResponse(final T exception) { diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotExceptionMapper.java index 68897c1b3d21..73e6da92c858 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/DotExceptionMapper.java @@ -11,11 +11,13 @@ public abstract class DotExceptionMapper implements javax.ws.rs.ext.ExceptionMapper { + protected DotExceptionMapper() {} + @Override public Response toResponse(final T exception) { SecurityLogger.logInfo(DotSecurityExceptionMapper.class, exception.getMessage()); - return ExceptionMapperUtil.createResponse(exception, this.getErrorKey(), Response.Status.FORBIDDEN); + return ExceptionMapperUtil.createResponse(exception, this.getErrorKey(), this.getErrorStatus()); } protected abstract String getErrorKey(); diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/ElasticsearchStatusExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/ElasticsearchStatusExceptionMapper.java index e9f7fb9521df..85193ab752a6 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/ElasticsearchStatusExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/ElasticsearchStatusExceptionMapper.java @@ -3,9 +3,11 @@ import com.dotmarketing.util.Logger; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.Provider; import org.elasticsearch.ElasticsearchStatusException; import javax.ws.rs.ext.ExceptionMapper; +@Provider public class ElasticsearchStatusExceptionMapper implements ExceptionMapper { diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/JsonMappingExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/JsonMappingExceptionMapper.java index 7d9643a8e8d7..b7b1d4fb268a 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/JsonMappingExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/JsonMappingExceptionMapper.java @@ -1,32 +1,30 @@ package com.dotcms.rest.exception.mapper; import com.dotcms.exception.ExceptionUtil; -import com.fasterxml.jackson.databind.JsonMappingException; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.ExceptionMapper; -import javax.ws.rs.ext.Provider; import com.dotcms.rest.exception.BadRequestException; import com.dotcms.rest.exception.HttpStatusCodeException; import com.dotcms.rest.exception.ValidationException; import com.dotmarketing.util.Logger; -import com.google.common.collect.ImmutableSet; - +import com.fasterxml.jackson.databind.exc.ValueInstantiationException; import java.util.Optional; import java.util.Set; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; /** * Handles error on the Jackson mapping * @author jsanca */ @Provider -public class JsonMappingExceptionMapper implements ExceptionMapper { +public class JsonMappingExceptionMapper implements ExceptionMapper { - private final static Set> EXCEPTIONS = - ImmutableSet.of(WebApplicationException.class, ValidationException.class, BadRequestException.class, HttpStatusCodeException.class); + private static final Set> EXCEPTIONS = + Set.of(WebApplicationException.class, ValidationException.class, BadRequestException.class, HttpStatusCodeException.class); @Override - public Response toResponse(final JsonMappingException exception) + public Response toResponse(final ValueInstantiationException exception) { //Log into our logs first. Logger.warn(this.getClass(), exception.getMessage(), exception); @@ -34,7 +32,7 @@ public Response toResponse(final JsonMappingException exception) final Optional throwable = ExceptionUtil.getCause(exception, EXCEPTIONS); //Return 4xx message to the client. return throwable.isPresent()? - WebApplicationException.class.cast(throwable.get()).getResponse(): + ((WebApplicationException) throwable.get()).getResponse(): ExceptionMapperUtil.createResponse(ExceptionMapperUtil.getJsonErrorAsString(exception.getMessage()), exception.getMessage()); } } diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotAllowedExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotAllowedExceptionMapper.java index dddd3433517f..bd11951dcc52 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotAllowedExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotAllowedExceptionMapper.java @@ -4,10 +4,12 @@ import com.dotmarketing.util.SecurityLogger; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.Provider; /** * Mapper for {@link NotAllowedException} */ +@Provider public class NotAllowedExceptionMapper implements javax.ws.rs.ext.ExceptionMapper { diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotFoundInDbExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotFoundInDbExceptionMapper.java index 3bc6935979a4..db1ff375e767 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotFoundInDbExceptionMapper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/NotFoundInDbExceptionMapper.java @@ -3,10 +3,12 @@ import com.dotcms.contenttype.exception.NotFoundInDbException; import javax.ws.rs.core.Response; import com.dotmarketing.util.SecurityLogger; +import javax.ws.rs.ext.Provider; /** * Mapper for {@link NotFoundInDbException} */ +@Provider public class NotFoundInDbExceptionMapper implements javax.ws.rs.ext.ExceptionMapper { diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/AlreadyExistsExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/AlreadyExistsExceptionMapper.java new file mode 100644 index 000000000000..419e53d71f09 --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/AlreadyExistsExceptionMapper.java @@ -0,0 +1,11 @@ +package com.dotcms.rest.exception.mapper.badrequest; + +import com.amazonaws.services.kms.model.AlreadyExistsException; +import com.dotcms.rest.exception.mapper.DotBadRequestExceptionMapper; +import javax.ws.rs.ext.Provider; + +@Provider +public class AlreadyExistsExceptionMapper + extends DotBadRequestExceptionMapper { + +} diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/DotStateExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/DotStateExceptionMapper.java new file mode 100644 index 000000000000..37c526f3851b --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/DotStateExceptionMapper.java @@ -0,0 +1,10 @@ +package com.dotcms.rest.exception.mapper.badrequest; +import com.dotcms.rest.exception.mapper.DotBadRequestExceptionMapper; +import com.dotmarketing.business.DotStateException; +import javax.ws.rs.ext.Provider; + +@Provider +public class DotStateExceptionMapper + extends DotBadRequestExceptionMapper { + +} \ No newline at end of file diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/IllegalArgumentExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/IllegalArgumentExceptionMapper.java new file mode 100644 index 000000000000..037a0086b1cf --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/IllegalArgumentExceptionMapper.java @@ -0,0 +1,10 @@ +package com.dotcms.rest.exception.mapper.badrequest; + +import com.dotcms.rest.exception.mapper.DotBadRequestExceptionMapper; +import javax.ws.rs.ext.Provider; + +@Provider +public class IllegalArgumentExceptionMapper + extends DotBadRequestExceptionMapper { + +} \ No newline at end of file diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/InvalidFolderNameExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/InvalidFolderNameExceptionMapper.java new file mode 100644 index 000000000000..c133ee8f7f78 --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/InvalidFolderNameExceptionMapper.java @@ -0,0 +1,11 @@ +package com.dotcms.rest.exception.mapper.badrequest; + +import com.dotcms.rest.exception.mapper.DotBadRequestExceptionMapper; +import com.dotmarketing.portlets.folders.exception.InvalidFolderNameException; +import javax.ws.rs.ext.Provider; + +@Provider +public class InvalidFolderNameExceptionMapper + extends DotBadRequestExceptionMapper { + +} \ No newline at end of file diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/JsonProcessingExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/JsonProcessingExceptionMapper.java new file mode 100644 index 000000000000..18f8040a8a83 --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/JsonProcessingExceptionMapper.java @@ -0,0 +1,11 @@ +package com.dotcms.rest.exception.mapper.badrequest; + +import com.dotcms.rest.exception.mapper.DotBadRequestExceptionMapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import javax.ws.rs.ext.Provider; + +@Provider +public class JsonProcessingExceptionMapper + extends DotBadRequestExceptionMapper { + +} diff --git a/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/NumberFormatExceptionMapper.java b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/NumberFormatExceptionMapper.java new file mode 100644 index 000000000000..3fbd0fbb1306 --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/exception/mapper/badrequest/NumberFormatExceptionMapper.java @@ -0,0 +1,11 @@ + +package com.dotcms.rest.exception.mapper.badrequest; + +import com.dotcms.rest.exception.mapper.DotBadRequestExceptionMapper; +import javax.ws.rs.ext.Provider; + +@Provider +public class NumberFormatExceptionMapper + extends DotBadRequestExceptionMapper { + +} \ No newline at end of file diff --git a/dotCMS/src/main/java/com/dotcms/rest/servlet/ReloadableServletContainer.java b/dotCMS/src/main/java/com/dotcms/rest/servlet/ReloadableServletContainer.java deleted file mode 100644 index 947b41293d55..000000000000 --- a/dotCMS/src/main/java/com/dotcms/rest/servlet/ReloadableServletContainer.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * http://glassfish.java.net/public/CDDL+GPL_1_1.html - * or packager/legal/LICENSE.txt. See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at packager/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * Oracle designates this particular file as subject to the "Classpath" - * exception as provided by Oracle in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ - -package com.dotcms.rest.servlet; - -import com.dotcms.rest.config.DotRestApplication; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Map; -import javax.servlet.FilterConfig; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import org.glassfish.jersey.servlet.ServletContainer; -import org.glassfish.jersey.servlet.WebConfig; -import org.glassfish.jersey.servlet.WebServletConfig; - -/** - * This class is a wrapper around the Jersey ServletContainer that prevents needing - * to reconfigure the web.xml file. The base DotRestApplication now handles the - * servlet reloading. This class is only needed to add the additional init parameters - * - */ -public class ReloadableServletContainer extends ServletContainer { - - /** - * - */ - private static final long serialVersionUID = 1L; - - private static final Map ADDITIONAL_INIT_PARAMS = Map.of("javax.ws.rs.Application", DotRestApplication.class.getName()); - - public ReloadableServletContainer() { - } - - @Override - public void init() throws ServletException { - // Cannot extend WebServletConfig because it is final so we will decorate it to modify - // the init parameters - init(new WebServletConfigDecorator(new WebServletConfig(this))); - } - - - private class WebServletConfigDecorator implements WebConfig { - - private final WebServletConfig webServletConfig; - - public WebServletConfigDecorator(WebServletConfig webServletConfig) { - this.webServletConfig = webServletConfig; - } - - @Override - public ConfigType getConfigType() { - return webServletConfig.getConfigType(); - } - - @Override - public ServletConfig getServletConfig() { - return webServletConfig.getServletConfig(); - } - - @Override - public FilterConfig getFilterConfig() { - return webServletConfig.getFilterConfig(); - } - - @Override - public String getName() { - return webServletConfig.getName(); - } - - @Override - public String getInitParameter(String name) { - if (ADDITIONAL_INIT_PARAMS.containsKey(name)) { - return ADDITIONAL_INIT_PARAMS.get(name); - } - return webServletConfig.getInitParameter(name); - } - - @Override - public Enumeration getInitParameterNames() { - // Add the "javax.ws.rs.Application" init parameter to the list of init parameters - // so that the Jersey application can be configured via web.xml - - @SuppressWarnings("unchecked") - HashSet paramNamesSet = new HashSet(Collections.list(webServletConfig.getInitParameterNames())); - - paramNamesSet.addAll(ADDITIONAL_INIT_PARAMS.keySet()); - return Collections.enumeration(paramNamesSet); - } - - @Override - public ServletContext getServletContext() { - return webServletConfig.getServletContext(); - } - } -} diff --git a/dotCMS/src/main/java/com/dotmarketing/plugin/PluginLoader.java b/dotCMS/src/main/java/com/dotmarketing/plugin/PluginLoader.java deleted file mode 100644 index eda8a1df1d46..000000000000 --- a/dotCMS/src/main/java/com/dotmarketing/plugin/PluginLoader.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.dotmarketing.plugin; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.jar.Manifest; - -import com.dotmarketing.business.APILocator; -import com.dotmarketing.business.Interceptor; -import com.dotmarketing.exception.DotDataException; -import com.dotmarketing.plugin.business.PluginAPI; -import com.dotmarketing.plugin.model.Plugin; -import com.dotmarketing.plugin.util.PluginUtil; -import com.dotmarketing.util.Logger; -import com.dotmarketing.util.UtilMethods; - -public class PluginLoader { - - private PluginAPI pluginAPI; - - public PluginLoader() { - pluginAPI = APILocator.getPluginAPI(); - } - - public void loadPlugins(String rootPath, String pluginPath) { - List pluginJars = PluginUtil.getPluginJars(rootPath, pluginPath); - List pluginIds = new ArrayList<>(); - - //initialize the pluginAPI - PluginAPI pluginAPI = APILocator.getPluginAPI(); - pluginAPI.setDeployedPluginOrder(pluginIds); - try { - pluginAPI.setPluginJarDir(new File(pluginPath)); - } catch (IOException e) { - Logger.fatal(this, "ERROR : while initializing pluginAPI", e); - return; - } - - List plugins = null; - try { - plugins = pluginAPI.findPlugins(); - } catch (DotDataException e) { - Logger.fatal(this, "ERROR : when loading the installed plugins", e); - return; - } - - for (File f : pluginJars) { - String id = f.getName(); - try{ - id = PluginUtil.getPluginNameFromJar(f.getName()); - Plugin plugin = null; - - if (plugins != null) { - for (Plugin tempPlugin: plugins) { - if (tempPlugin.getId().equals(id)) { - plugin = tempPlugin; - break; - } - } - } - - boolean newPlugin = false; - JarFile jar; - Manifest mf; - try { - jar = new JarFile(f.getPath()); - mf=jar.getManifest(); - } catch (IOException e1) { - Logger.fatal(this, "Method loadPlugins : Error deploying plugin id:" + id, e1); - continue; - } - Attributes attrs=mf.getMainAttributes(); - if(plugin == null || !UtilMethods.isSet(plugin.getId())){ - plugin = new Plugin(); - newPlugin = true; - plugin.setFirstDeployedDate(Calendar.getInstance().getTime()); - plugin.setId(id); - } - String version = attrs.getValue("Plugin-Version"); - if(!UtilMethods.isSet(version)){ - Logger.fatal(this, "Method loadPlugins : Error deploying plugin id:" + id); - continue; - } - if(!newPlugin){ - if(plugin.getPluginVersion().equalsIgnoreCase(version)){ - setUpHooks(id); - loadPluginProperties(jar, plugin.getId()); - pluginIds.add(id); - pluginAPI.setDeployedPluginOrder(pluginIds); - continue; - } - } - - plugin.setPluginVersion(version); - String oldVersion = plugin.getPluginVersion(); - plugin.setLastDeployedDate(Calendar.getInstance().getTime()); - String pluginName = attrs.getValue("Plugin-Name") == null ? "":attrs.getValue("Plugin-Name"); - String author = attrs.getValue("Author") == null ? "":attrs.getValue("Author"); - plugin.setAuthor(author); - plugin.setPluginName(pluginName); - try{ - pluginAPI.save(plugin); - } catch (DotDataException e2) { - Logger.fatal(this, "Method loadPlugins : Error deploying plugin id:" + id, e2); - continue; - } - loadPluginProperties(jar, plugin.getId()); - String deployClass = attrs.getValue("Deploy-Class"); - PluginDeployer deployer=null; - if (deployClass!=null && deployClass.length()>0) { - try { - deployClass = deployClass.trim(); - Object o=Class.forName(deployClass).newInstance(); - if (o instanceof PluginDeployer) { - deployer=(PluginDeployer)o; - if(newPlugin) - deployer.deploy(); - else - deployer.redeploy(oldVersion); - } - } catch (InstantiationException e) { - Logger.debug(PluginLoader.class,"InstantiationException: " + id + " " + e.getMessage(),e); - continue; - } catch (IllegalAccessException e) { - Logger.debug(PluginLoader.class,"IllegalAccessException: " + id + " " + e.getMessage(),e); - continue; - } catch (ClassNotFoundException e) { - Logger.debug(PluginLoader.class,"ClassNotFoundException: " + id + " " + e.getMessage(),e); - continue; - } - } - setUpHooks(id); - pluginIds.add(id); - pluginAPI.setDeployedPluginOrder(pluginIds); - pluginAPI.loadBackEndFiles(plugin.getId()); - - }catch (Exception e) { - Logger.fatal(this, "ERROR DEPLOYING A PLUGIN : " + id, e); - } - } - } - - private void setUpHooks(String pluginId) throws InstantiationException, IllegalAccessException, ClassNotFoundException, DotDataException{ - - PluginAPI pluginAPI = APILocator.getPluginAPI(); - Interceptor conI = (Interceptor)APILocator.getContentletAPIntercepter(); - String conPreHooks = pluginAPI.loadPluginConfigProperty(pluginId, "contentletapi.prehooks"); - String conPostHooks = pluginAPI.loadPluginConfigProperty(pluginId, "contentletapi.posthooks"); - if(UtilMethods.isSet(conPreHooks)){ - String[] pres = conPreHooks.split(","); - for (String string : pres) { - conI.addPreHook(string); - } - } - if(UtilMethods.isSet(conPostHooks)){ - String[] post = conPostHooks.split(","); - for (String string : post) { - conI.addPostHook(string); - } - } - } - - private void loadPluginProperties(JarFile jar, String pluginId) throws IOException, DotDataException{ - Map props = PluginUtil.loadPropertiesFromFile(jar); - String reload = props.get("reload.force"); - if(!UtilMethods.isSet(reload) || Boolean.valueOf(reload)){ - pluginAPI.deletePluginProperties(pluginId); - for (String key : props.keySet()) { - pluginAPI.saveProperty(pluginId, key, props.get(key)); - } - } - } -} diff --git a/dotCMS/src/main/java/com/dotmarketing/servlets/InitServlet.java b/dotCMS/src/main/java/com/dotmarketing/servlets/InitServlet.java index fd58f6d5bf0e..d974640ceb15 100644 --- a/dotCMS/src/main/java/com/dotmarketing/servlets/InitServlet.java +++ b/dotCMS/src/main/java/com/dotmarketing/servlets/InitServlet.java @@ -1,42 +1,11 @@ package com.dotmarketing.servlets; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.URL; -import java.net.URLEncoder; -import java.net.UnknownHostException; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.List; -import javax.management.InstanceAlreadyExistsException; -import javax.management.MBeanRegistrationException; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; - -import org.apache.commons.lang.SystemUtils; -import org.apache.felix.framework.OSGISystem; -import org.apache.felix.framework.OSGIUtil; -import org.apache.lucene.search.BooleanQuery; -import org.quartz.SchedulerException; import com.dotcms.business.CloseDBIfOpened; import com.dotcms.enterprise.LicenseUtil; import com.dotcms.rest.api.v1.maintenance.ClusterManagementTopic; -import com.maxmind.geoip2.exception.GeoIp2Exception; - import com.dotcms.util.GeoIp2CityDbUtil; import com.dotmarketing.beans.Host; import com.dotmarketing.business.APILocator; -import com.dotmarketing.business.CacheLocator; import com.dotmarketing.business.PermissionAPI; import com.dotmarketing.common.reindex.ReindexThread; import com.dotmarketing.db.HibernateUtil; @@ -46,20 +15,44 @@ import com.dotmarketing.exception.DotSecurityException; import com.dotmarketing.init.DotInitScheduler; import com.dotmarketing.loggers.mbeans.Log4jConfig; -import com.dotmarketing.menubuilders.RefreshMenus; -import com.dotmarketing.plugin.PluginLoader; import com.dotmarketing.portlets.contentlet.action.ImportAuditUtil; import com.dotmarketing.portlets.contentlet.business.HostAPI; import com.dotmarketing.portlets.languagesmanager.business.LanguageAPI; import com.dotmarketing.portlets.languagesmanager.model.Language; import com.dotmarketing.quartz.job.ShutdownHookThread; import com.dotmarketing.util.Config; -import com.dotmarketing.util.ConfigUtils; import com.dotmarketing.util.Logger; import com.dotmarketing.util.UtilMethods; import com.dotmarketing.util.VelocityUtil; import com.dotmarketing.util.WebKeys; import com.liferay.portal.util.ReleaseInfo; +import com.maxmind.geoip2.exception.GeoIp2Exception; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.URL; +import java.net.URLEncoder; +import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; +import javax.management.InstanceAlreadyExistsException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import org.apache.commons.lang.SystemUtils; +import org.apache.felix.framework.OSGISystem; +import org.apache.felix.framework.OSGIUtil; +import org.apache.lucene.search.BooleanQuery; /** * Initialization servlet for specific dotCMS components and features. @@ -112,10 +105,6 @@ public void init(ServletConfig config) throws ServletException { Logger.info(this, ""); - String classPath = config.getServletContext().getRealPath("/WEB-INF/lib"); - - new PluginLoader().loadPlugins(config.getServletContext().getRealPath("/"),classPath); - int mc = Config.getIntProperty("lucene_max_clause_count", 4096); BooleanQuery.setMaxClauseCount(mc); diff --git a/dotCMS/src/main/java/com/dotmarketing/util/jasper/DotJasperTask.java b/dotCMS/src/main/java/com/dotmarketing/util/jasper/DotJasperTask.java deleted file mode 100644 index 7b353e9725f4..000000000000 --- a/dotCMS/src/main/java/com/dotmarketing/util/jasper/DotJasperTask.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.dotmarketing.util.jasper; - -import com.dotmarketing.loggers.Log4jUtil; -import org.apache.jasper.JasperException; -import org.apache.jasper.JspC; - -import java.util.HashSet; -import java.util.Set; - -public class DotJasperTask extends JspC { - - @Override - protected void processFile(String arg0) throws JasperException { - - //Create and add a new ConsoleAppender to the log4j configuration - Log4jUtil.createAndAddConsoleAppender(); - - if ( ((!arg0.endsWith("_inc.jsp")) && (!arg0.startsWith("/html/plugins/"))) || includeJSP(arg0)) { - super.processFile(arg0); - } else { - //System.err.println("Skipping: " + arg0); - - } - } - - private static Set includeList = null; - private static final Integer mutex = Integer.valueOf(0); - - private static void buildIncludeList() { - synchronized (mutex) { - if (includeList != null) - return; - Set set = new HashSet<>(); - // Load some defaults - set.add("contentlet_versions_inc.jsp"); - set.add("view_contentlet_popup_inc.jsp"); - includeList = set; - } - } - - public static boolean includeJSP(String jsp) { - if (includeList == null) - buildIncludeList(); - for (String str : includeList) { - if (jsp.endsWith(str)) - return true; - } - return false; - } -} diff --git a/dotCMS/src/main/webapp/WEB-INF/beans.xml b/dotCMS/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 000000000000..1675ad7ab74c --- /dev/null +++ b/dotCMS/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/dotCMS/src/main/webapp/WEB-INF/web.xml b/dotCMS/src/main/webapp/WEB-INF/web.xml index 5b0174fb06fb..e96d9c8fcdec 100644 --- a/dotCMS/src/main/webapp/WEB-INF/web.xml +++ b/dotCMS/src/main/webapp/WEB-INF/web.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> - dotCMS + dotCMS UTF-8 UTF-8 @@ -194,6 +194,9 @@ + + org.jboss.weld.environment.servlet.Listener + com.dotmarketing.listeners.ContextLifecycleListener @@ -361,11 +364,9 @@ com.dotcms.csspreproc.SassPreProcessServlet - + RESTAPI - - com.dotcms.rest.servlet.ReloadableServletContainer - + org.glassfish.jersey.servlet.ServletContainer jersey.config.server.mediaTypeMappings txt : text/plain, xml : application/xml, json : application/json, js : application/javascript @@ -508,11 +509,7 @@ DotGraphQLHttpServlet /api/v1/graphql - - RESTAPI - /api/* - - + diff --git a/dotCMS/src/test/java/com/dotcms/UnitTestBase.java b/dotCMS/src/test/java/com/dotcms/UnitTestBase.java index 63af236708be..e994d0f1f97a 100644 --- a/dotCMS/src/test/java/com/dotcms/UnitTestBase.java +++ b/dotCMS/src/test/java/com/dotcms/UnitTestBase.java @@ -1,21 +1,22 @@ package com.dotcms; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import com.dotcms.company.CompanyAPI; -import com.liferay.portal.model.Company; -import com.liferay.portal.model.User; -import org.junit.BeforeClass; - import com.dotcms.contenttype.business.ContentTypeAPI; import com.dotmarketing.business.APILocator; import com.dotmarketing.exception.DotDataException; import com.dotmarketing.exception.DotSecurityException; import com.dotmarketing.util.BaseMessageResources; import com.dotmarketing.util.Config; - +import com.liferay.portal.model.Company; +import com.liferay.portal.model.User; import java.util.TimeZone; +import org.jboss.weld.bootstrap.api.helpers.RegistrySingletonProvider; +import org.jboss.weld.environment.se.Weld; +import org.jboss.weld.environment.se.WeldContainer; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.mockito.Mockito; public abstract class UnitTestBase extends BaseMessageResources { @@ -23,6 +24,8 @@ public abstract class UnitTestBase extends BaseMessageResources { protected static final ContentTypeAPI contentTypeAPI = mock(ContentTypeAPI.class); protected static final CompanyAPI companyAPI = mock(CompanyAPI.class); + private static WeldContainer weld; + public static class MyAPILocator extends APILocator { static { @@ -44,6 +47,11 @@ protected CompanyAPI getCompanyAPIImpl() { @BeforeClass public static void prepare () throws DotDataException, DotSecurityException, Exception { + weld = new Weld().containerId(RegistrySingletonProvider.STATIC_INSTANCE) + .initialize(); + + System.out.println("Weld :: " + weld); + Config.initializeConfig(); Config.setProperty("API_LOCATOR_IMPLEMENTATION", MyAPILocator.class.getName()); Config.setProperty("SYSTEM_EXIT_ON_STARTUP_FAILURE", false); @@ -55,4 +63,11 @@ public static void prepare () throws DotDataException, DotSecurityException, Exc Mockito.lenient().when(company.getTimeZone()).thenReturn(TimeZone.getDefault()); Mockito.lenient().when(companyAPI.getDefaultCompany()).thenReturn(company); } + + @AfterClass + public static void cleanup() { + if( null != weld && weld.isRunning() ){ + weld.shutdown(); + } + } } diff --git a/dotCMS/src/test/java/com/dotcms/filters/NormalizationFilterTest.java b/dotCMS/src/test/java/com/dotcms/filters/NormalizationFilterTest.java index b32aed403de0..f241d3fbf1f6 100644 --- a/dotCMS/src/test/java/com/dotcms/filters/NormalizationFilterTest.java +++ b/dotCMS/src/test/java/com/dotcms/filters/NormalizationFilterTest.java @@ -18,7 +18,7 @@ public class NormalizationFilterTest extends UnitTestBase { - private final static NormalizationFilter normalizationFilter = new NormalizationFilter(); + private static final NormalizationFilter normalizationFilter = new NormalizationFilter(); private static HttpServletResponse mockResponse; private static HttpServletRequest mockRequest; private static FilterChain chain; diff --git a/dotCMS/src/test/java/com/dotmarketing/plugin/PluginMergerTest.java b/dotCMS/src/test/java/com/dotmarketing/plugin/PluginMergerTest.java deleted file mode 100644 index 0e8a61974924..000000000000 --- a/dotCMS/src/test/java/com/dotmarketing/plugin/PluginMergerTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.dotmarketing.plugin; - -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import com.dotcms.UnitTestBase; -import com.dotmarketing.plugin.util.PluginFileMerger; - -public class PluginMergerTest extends UnitTestBase { - - @Test - @Ignore - public void testMergeByAttribute() throws IOException { - PluginFileMerger fileMerger = new PluginFileMerger(); - - String name = "override-test"; - - StringBuilder sb = new StringBuilder(); - String newline = "\n"; - - sb.append(""); - sb.append(newline).append(""); - sb.append(newline).append(""); - - String dwr = sb.toString(); - - Map overrideMap = new HashMap<>(); - overrideMap.put("create", "javascript"); - - sb = new StringBuilder(""); - sb.append(""); - sb.append(""); - sb.append(""); - sb.append(newline); - sb.append(""); - sb.append(newline); - sb.append(""); - sb.append(""); - sb.append(""); - sb.append(""); - sb.append(""); - sb.append(""); - - InputStream input = new ByteArrayInputStream(sb.toString().getBytes()); - - String fileContent = fileMerger.mergeByAttribute(input, "", - "", "", "", dwr, - overrideMap, "", ""); - - String commentedPart = sb.toString(); - - sb = new StringBuilder(""); - sb.append(newline).append(""); - sb.append(newline).append(""); - sb.append(newline).append(""); - sb.append(newline).append(""); - - String newPart = sb.toString(); - - assertTrue(fileContent.toString().contains(commentedPart)); - assertTrue(fileContent.toString().contains(newPart)); - - - } - -} diff --git a/dotCMS/src/test/resources/META-INF/beans.xml b/dotCMS/src/test/resources/META-INF/beans.xml new file mode 100644 index 000000000000..1675ad7ab74c --- /dev/null +++ b/dotCMS/src/test/resources/META-INF/beans.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/dotcms-integration/pom.xml b/dotcms-integration/pom.xml index 20b6010ed32a..e00fba1d4e6e 100644 --- a/dotcms-integration/pom.xml +++ b/dotcms-integration/pom.xml @@ -223,6 +223,23 @@ jackson-annotations test + + org.jboss.weld + weld-junit5 + test + + + org.jboss.weld.se + weld-se-core + + + + + + org.jboss.weld.se + weld-se-shaded + test + diff --git a/dotcms-integration/src/test/java/com/dotcms/IntegrationTestBase.java b/dotcms-integration/src/test/java/com/dotcms/IntegrationTestBase.java index 72d7559084fb..01fc89e82008 100644 --- a/dotcms-integration/src/test/java/com/dotcms/IntegrationTestBase.java +++ b/dotcms-integration/src/test/java/com/dotcms/IntegrationTestBase.java @@ -31,7 +31,10 @@ import java.io.UnsupportedEncodingException; import java.util.List; import org.apache.commons.io.FileUtils; +import org.jboss.weld.environment.se.Weld; +import org.jboss.weld.environment.se.WeldContainer; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; @@ -53,6 +56,8 @@ public abstract class IntegrationTestBase extends BaseMessageResources { private final static PrintStream stdout = System.out; private final static ByteArrayOutputStream output = new ByteArrayOutputStream(); + private static WeldContainer weld; + @Rule public TestName name = new TestName(); @@ -256,7 +261,7 @@ public void cleanCategories(List categoriesToDelete) { protected void initConnection() { if (DbConnectionFactory.connectionExists()) { - DbConnectionFactory.closeSilently(); // start always we a new one + DbConnectionFactory.closeSilently(); // start always with a new one } } @@ -275,4 +280,16 @@ protected T wrapOnReadOnlyConn(final ReturnableDelegate supplier) throw DbConnectionFactory.closeSilently(); } } + + @BeforeClass + public static void initWeld() { + weld = new Weld().containerId("IntegrationTestBase").initialize(); + } + + @AfterClass + public static void cleanupWeld() { + if( null != weld && weld.isRunning() ){ + weld.shutdown(); + } + } } diff --git a/dotcms-integration/src/test/java/com/dotcms/cdi/GreetingBean.java b/dotcms-integration/src/test/java/com/dotcms/cdi/GreetingBean.java new file mode 100644 index 000000000000..3c56a1696ac5 --- /dev/null +++ b/dotcms-integration/src/test/java/com/dotcms/cdi/GreetingBean.java @@ -0,0 +1,17 @@ +package com.dotcms.cdi; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + + +@ApplicationScoped +public class GreetingBean { + + @Inject + MessageServiceBean injectedTestBean; + + public String greet() { + return injectedTestBean.getMessage(); + } + +} diff --git a/dotcms-integration/src/test/java/com/dotcms/cdi/MessageServiceBean.java b/dotcms-integration/src/test/java/com/dotcms/cdi/MessageServiceBean.java new file mode 100644 index 000000000000..100ce23fa143 --- /dev/null +++ b/dotcms-integration/src/test/java/com/dotcms/cdi/MessageServiceBean.java @@ -0,0 +1,12 @@ +package com.dotcms.cdi; + +import javax.enterprise.context.Dependent; + +@Dependent +public class MessageServiceBean { + + public String getMessage() { + return "Hello World"; + } + +} diff --git a/dotcms-integration/src/test/java/com/dotcms/cdi/SimpleInjectionIT.java b/dotcms-integration/src/test/java/com/dotcms/cdi/SimpleInjectionIT.java new file mode 100644 index 000000000000..30e3112da561 --- /dev/null +++ b/dotcms-integration/src/test/java/com/dotcms/cdi/SimpleInjectionIT.java @@ -0,0 +1,31 @@ +package com.dotcms.cdi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.dotcms.IntegrationTestBase; +import java.util.Optional; +import org.junit.Test; + +/** + * Integration test for simple CDI injection + */ +public class SimpleInjectionIT extends IntegrationTestBase { + + /** + * Test CDI injection + * Given scenario: An annotated bean is injected + * Expected result: the bean is injected + */ + @Test + public void testInjection() { + + Optional optional = CDIUtils.getBean(GreetingBean.class); + assertTrue(optional.isPresent()); + final GreetingBean greetingBean = optional.get(); + assertEquals("Hello World", greetingBean.greet()); + + } + +} diff --git a/dotcms-integration/src/test/java/com/dotcms/util/IntegrationTestInitService.java b/dotcms-integration/src/test/java/com/dotcms/util/IntegrationTestInitService.java index e94f6a935605..2ea04111cde2 100644 --- a/dotcms-integration/src/test/java/com/dotcms/util/IntegrationTestInitService.java +++ b/dotcms-integration/src/test/java/com/dotcms/util/IntegrationTestInitService.java @@ -13,6 +13,9 @@ import com.dotmarketing.util.Logger; import com.liferay.util.SystemProperties; import org.awaitility.Awaitility; +import org.jboss.weld.bootstrap.api.helpers.RegistrySingletonProvider; +import org.jboss.weld.environment.se.Weld; +import org.jboss.weld.environment.se.WeldContainer; import org.mockito.Mockito; import java.time.Duration; @@ -29,6 +32,8 @@ public class IntegrationTestInitService { private static final AtomicBoolean initCompleted = new AtomicBoolean(false); + private static WeldContainer weld; + static { SystemProperties.getProperties(); } @@ -44,6 +49,10 @@ public static IntegrationTestInitService getInstance() { public void init() throws Exception { try { if (initCompleted.compareAndSet(false, true)) { + + weld = new Weld().containerId(RegistrySingletonProvider.STATIC_INSTANCE) + .initialize(); + System.setProperty(TestUtil.DOTCMS_INTEGRATION_TEST, TestUtil.DOTCMS_INTEGRATION_TEST); Awaitility.setDefaultPollInterval(10, TimeUnit.MILLISECONDS); diff --git a/dotcms-integration/src/test/resources/META-INF/beans.xml b/dotcms-integration/src/test/resources/META-INF/beans.xml new file mode 100644 index 000000000000..1675ad7ab74c --- /dev/null +++ b/dotcms-integration/src/test/resources/META-INF/beans.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file