/* * JBoss, Home of Professional Open Source. * Copyright 2017, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.wildfly.extension.undertow.deployment; import io.undertow.server.handlers.builder.PredicatedHandler; import io.undertow.server.handlers.builder.PredicatedHandlersParser; import org.jboss.as.server.deployment.AttachmentKey; import org.jboss.as.server.deployment.Attachments; import org.jboss.as.server.deployment.DeploymentPhaseContext; import org.jboss.as.server.deployment.DeploymentUnit; import org.jboss.as.server.deployment.DeploymentUnitProcessingException; import org.jboss.as.server.deployment.DeploymentUnitProcessor; import org.jboss.as.server.deployment.module.ResourceRoot; import org.jboss.as.web.common.WarMetaData; import org.jboss.metadata.javaee.spec.ParamValueMetaData; import org.jboss.metadata.web.jboss.HttpHandlerMetaData; import org.jboss.metadata.web.jboss.JBossWebMetaData; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.vfs.VirtualFile; import org.wildfly.extension.undertow.logging.UndertowLogger; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; /** * DUP that handles undertow-handlers.conf, and handlers definded in jboss-web.xml * * @author Stuart Douglas */ public class UndertowHandlersDeploymentProcessor implements DeploymentUnitProcessor { private static final String WEB_INF = "WEB-INF/undertow-handlers.conf"; private static final String META_INF = "META-INF/undertow-handlers.conf"; public static final AttachmentKey<List<PredicatedHandler>> PREDICATED_HANDLERS = AttachmentKey.create(List.class); @Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); final Module module = deploymentUnit.getAttachment(Attachments.MODULE); if (module == null) { return; } handleInfoFile(deploymentUnit, module); handleJbossWebXml(deploymentUnit, module); } private void handleJbossWebXml(DeploymentUnit deploymentUnit, Module module) throws DeploymentUnitProcessingException { WarMetaData warMetadata = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); if (warMetadata == null) { return; } JBossWebMetaData merged = warMetadata.getMergedJBossWebMetaData(); if (merged == null) { return; } List<HttpHandlerMetaData> handlers = merged.getHandlers(); if (handlers == null) { return; } for (HttpHandlerMetaData hander : handlers) { try { ClassLoader cl = module.getClassLoader(); if (hander.getModule() != null) { Module handlerModule = deploymentUnit.getAttachment(Attachments.SERVICE_MODULE_LOADER).loadModule(ModuleIdentifier.fromString(hander.getModule())); cl = handlerModule.getClassLoader(); } Class<?> handlerClass = cl.loadClass(hander.getHandlerClass()); Map<String, String> params = new HashMap<>(); if(hander.getParams() != null) { for(ParamValueMetaData param : hander.getParams()) { params.put(param.getParamName(), param.getParamValue()); } } deploymentUnit.addToAttachmentList(UndertowAttachments.UNDERTOW_OUTER_HANDLER_CHAIN_WRAPPERS, new ConfiguredHandlerWrapper(handlerClass, params)); } catch (Exception e) { throw UndertowLogger.ROOT_LOGGER.failedToConfigureHandlerClass(hander.getHandlerClass(), e); } } } private void handleInfoFile(DeploymentUnit deploymentUnit, Module module) { final List<PredicatedHandler> handlerWrappers = new ArrayList<>(); ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); try { ResourceRoot root = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT); VirtualFile config = root.getRoot().getChild(WEB_INF); try { if (config.exists()) { handlerWrappers.addAll(PredicatedHandlersParser.parse(config.openStream(), module.getClassLoader())); } Enumeration<URL> paths = module.getClassLoader().getResources(META_INF); while (paths.hasMoreElements()) { URL path = paths.nextElement(); handlerWrappers.addAll(PredicatedHandlersParser.parse(path.openStream(), module.getClassLoader())); } } catch (IOException e) { throw new RuntimeException(e); } if (!handlerWrappers.isEmpty()) { deploymentUnit.putAttachment(PREDICATED_HANDLERS, handlerWrappers); } } finally { Thread.currentThread().setContextClassLoader(oldCl); } } @Override public void undeploy(DeploymentUnit context) { } }