blob: 170c76b2ca589c85ac010321d59a1bbb82d9c80f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.knox.gateway.deploy;
import org.apache.knox.gateway.GatewayMessages;
import org.apache.knox.gateway.GatewayServlet;
import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.deploy.impl.ApplicationDeploymentContributor;
import org.apache.knox.gateway.descriptor.GatewayDescriptor;
import org.apache.knox.gateway.descriptor.GatewayDescriptorFactory;
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.registry.ServiceRegistry;
import org.apache.knox.gateway.topology.Application;
import org.apache.knox.gateway.topology.Provider;
import org.apache.knox.gateway.topology.Service;
import org.apache.knox.gateway.topology.Topology;
import org.apache.knox.gateway.topology.Version;
import org.apache.knox.gateway.util.ServiceDefinitionsLoader;
import org.apache.knox.gateway.util.Urls;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.descriptor.api.Descriptors;
import org.jboss.shrinkwrap.descriptor.api.webapp30.WebAppDescriptor;
import org.jboss.shrinkwrap.descriptor.api.webcommon30.FilterType;
import org.jboss.shrinkwrap.descriptor.api.webcommon30.ServletType;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.beans.Statement;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.TreeMap;
public abstract class DeploymentFactory {
private static final JAXBContext jaxbContext = getJAXBContext();
private static final String SERVLET_NAME_SUFFIX = "-knox-gateway-servlet";
private static final String FILTER_NAME_SUFFIX = "-knox-gateway-filter";
private static final GatewayMessages log = MessagesFactory.get( GatewayMessages.class );
private static GatewayServices gatewayServices;
private static Map<String,Map<String,Map<Version, ServiceDeploymentContributor>>> SERVICE_CONTRIBUTOR_MAP;
static {
loadServiceContributors();
}
private static Set<ProviderDeploymentContributor> PROVIDER_CONTRIBUTORS;
private static Map<String,Map<String,ProviderDeploymentContributor>> PROVIDER_CONTRIBUTOR_MAP;
static {
loadProviderContributors();
}
private static JAXBContext getJAXBContext() {
Map<String,String> properties = new HashMap<>(2);
properties.put( "eclipselink-oxm-xml", "org/apache/knox/gateway/topology/topology_binding-xml.xml");
properties.put( "eclipselink.media-type", "application/xml" );
try {
return JAXBContext.newInstance(Topology.class.getPackage().getName(), Topology.class.getClassLoader(), properties);
} catch (JAXBException e) {
throw new IllegalStateException(e);
}
}
public static void setGatewayServices(GatewayServices services) {
DeploymentFactory.gatewayServices = services;
}
static List<Application> findApplicationsByUrl( Topology topology, String url ) {
List<Application> foundApps = new ArrayList<>();
if( topology != null ) {
url = Urls.trimLeadingAndTrailingSlash( url );
Collection<Application> searchApps = topology.getApplications();
if( searchApps != null ) {
for( Application searchApp : searchApps ) {
List<String> searchUrls = searchApp.getUrls();
if( searchUrls == null || searchUrls.isEmpty() ) {
searchUrls = new ArrayList<>(1);
searchUrls.add( searchApp.getName() );
}
for( String searchUrl : searchUrls ) {
if( url.equalsIgnoreCase( Urls.trimLeadingAndTrailingSlash( searchUrl ) ) ) {
foundApps.add( searchApp );
break;
}
}
}
}
}
return foundApps;
}
// Verify that there are no two apps with duplicate urls.
static void validateNoAppsWithDuplicateUrlsInTopology( Topology topology ) {
if( topology != null ) {
Collection<Application> apps = topology.getApplications();
if( apps != null ) {
for( Application app : apps ) {
List<String> urls = app.getUrls();
if( urls == null || urls.isEmpty() ) {
urls = new ArrayList<>(1);
urls.add( app.getName() );
}
for( String url : urls ) {
List<Application> dups = findApplicationsByUrl( topology, url );
for( Application dup : dups ) {
if( dup != app ) { //NOPMD - check for exact same object
throw new DeploymentException( "Topology " + topology.getName() + " contains applications " + app.getName() + " and " + dup.getName() + " with the same url: " + url );
}
}
}
}
}
}
}
// Verify that if there are services that there are no applications with a root url.
static void validateNoAppsWithRootUrlsInServicesTopology( Topology topology ) {
if( topology != null ) {
Collection<Service> services = topology.getServices();
if( services != null && !services.isEmpty() ) {
List<Application> dups = findApplicationsByUrl( topology, "/" );
if(!dups.isEmpty()) {
throw new DeploymentException( "Topology " + topology.getName() + " contains both services and an application " + dups.get( 0 ).getName() + " with a root url." );
}
}
}
}
static void validateTopology( Topology topology ) {
validateNoAppsWithRootUrlsInServicesTopology( topology );
validateNoAppsWithDuplicateUrlsInTopology( topology );
}
public static EnterpriseArchive createDeployment( GatewayConfig config, Topology topology ) {
validateTopology( topology );
loadStacksServiceContributors( config );
Map<String,List<ProviderDeploymentContributor>> providers = selectContextProviders( topology );
Map<String,List<ServiceDeploymentContributor>> services = selectContextServices( topology );
Map<String,ServiceDeploymentContributor> applications = selectContextApplications( config, topology );
EnterpriseArchive ear = ShrinkWrap.create( EnterpriseArchive.class, topology.getName() );
ear.addAsResource( toStringAsset( topology ), "topology.xml" );
if( !services.isEmpty() ) {
WebArchive war = createServicesDeployment( config, topology, providers, services );
ear.addAsModule( war );
}
if( !applications.isEmpty() ) {
for( Map.Entry<String, ServiceDeploymentContributor> application : applications.entrySet() ) {
WebArchive war = createApplicationDeployment( config, topology, providers, application );
ear.addAsModule( war );
}
}
return ear;
}
private static WebArchive createServicesDeployment(
GatewayConfig config,
Topology topology,
Map<String,List<ProviderDeploymentContributor>> providers,
Map<String,List<ServiceDeploymentContributor>> services ) {
DeploymentContext context = createDeploymentContext( config, "/", topology, providers );
initialize( context, providers, services, null );
contribute( context, providers, services, null );
finish( context, providers, services, null );
return context.getWebArchive();
}
public static WebArchive createApplicationDeployment(
GatewayConfig config,
Topology topology,
Map<String,List<ProviderDeploymentContributor>> providers,
Map.Entry<String,ServiceDeploymentContributor> application ) {
String appPath = "/" + Urls.trimLeadingAndTrailingSlash( application.getKey() );
DeploymentContext context = createDeploymentContext( config, appPath, topology, providers );
initialize( context, providers, null, application );
contribute( context, providers, null, application );
finish( context, providers, null, application );
return context.getWebArchive();
}
private static Asset toStringAsset( Topology topology ) {
StringWriter writer = new StringWriter();
String xml;
try {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
marshaller.marshal( topology, writer );
xml = writer.toString();
} catch (JAXBException e) {
throw new DeploymentException( "Failed to marshall topology.", e );
}
return new StringAsset( xml );
}
private static DeploymentContext createDeploymentContext(
GatewayConfig config,
String archivePath,
Topology topology,
Map<String,List<ProviderDeploymentContributor>> providers ) {
archivePath = Urls.encode( archivePath );
WebArchive webArchive = ShrinkWrap.create( WebArchive.class, archivePath );
WebAppDescriptor webAppDesc = Descriptors.create( WebAppDescriptor.class );
GatewayDescriptor gateway = GatewayDescriptorFactory.create();
return new DeploymentContextImpl(
config, topology, gateway, webArchive, webAppDesc, providers );
}
// Scan through the providers in the topology. Collect any named providers in their roles list.
// Scan through all of the loaded providers. For each that doesn't have an existing provider in the role
// list add it.
private static Map<String,List<ProviderDeploymentContributor>> selectContextProviders( Topology topology ) {
Map<String,List<ProviderDeploymentContributor>> providers = new LinkedHashMap<>();
addMissingDefaultProviders(topology);
collectTopologyProviders( topology, providers );
collectDefaultProviders( providers );
return providers;
}
private static void addMissingDefaultProviders(Topology topology) {
Collection<Provider> providers = topology.getProviders();
HashMap<String, String> providerMap = new HashMap<>();
for (Provider provider : providers) {
providerMap.put(provider.getRole(), provider.getName());
}
// first make sure that the required provider is available from the serviceloaders
// for some tests the number of providers are limited to the classpath of the module
// and exceptions will be thrown as topologies are deployed even though they will
// work fine at actual server runtime.
if (PROVIDER_CONTRIBUTOR_MAP.get("identity-assertion") != null) {
// check for required providers and add the defaults if missing
if (!providerMap.containsKey("identity-assertion")) {
Provider idassertion = new Provider();
idassertion.setRole("identity-assertion");
idassertion.setName("Default");
idassertion.setEnabled(true);
providers.add(idassertion);
}
}
}
private static void collectTopologyProviders(
Topology topology, Map<String, List<ProviderDeploymentContributor>> defaults ) {
for( Provider provider : topology.getProviders() ) {
String name = provider.getName();
if( name != null ) {
String role = provider.getRole();
Map<String,ProviderDeploymentContributor> nameMap = PROVIDER_CONTRIBUTOR_MAP.get( role );
if( nameMap != null ) {
ProviderDeploymentContributor contributor = nameMap.get( name );
// If there isn't a contributor with this role/name try to find a "*" contributor.
if( contributor == null ) {
nameMap = PROVIDER_CONTRIBUTOR_MAP.get( "*" );
if( nameMap != null ) {
contributor = nameMap.get( name );
}
}
if( contributor != null ) {
List list = defaults.get( role );
if( list == null ) {
list = new ArrayList( 1 );
defaults.put( role, list );
}
if( !list.contains( contributor ) ) {
list.add( contributor );
}
}
}
}
}
}
private static void collectDefaultProviders( Map<String,List<ProviderDeploymentContributor>> defaults ) {
for( ProviderDeploymentContributor contributor : PROVIDER_CONTRIBUTORS ) {
String role = contributor.getRole();
List<ProviderDeploymentContributor> list = defaults.computeIfAbsent(role, k -> new ArrayList<>());
if( list.isEmpty() ) {
list.add( contributor );
}
}
}
// Scan through the services in the topology.
// For each that we find add it to the list of service roles included in the topology.
private static Map<String,List<ServiceDeploymentContributor>> selectContextServices( Topology topology ) {
Map<String,List<ServiceDeploymentContributor>> defaults
= new HashMap<>();
for( Service service : topology.getServices() ) {
String role = service.getRole();
ServiceDeploymentContributor contributor = getServiceContributor( role, service.getName(), service.getVersion() );
if( contributor != null ) {
List<ServiceDeploymentContributor> list = defaults.computeIfAbsent(role, k -> new ArrayList<>(1));
if( !list.contains( contributor ) ) {
list.add( contributor );
}
}
}
return defaults;
}
private static Map<String,ServiceDeploymentContributor> selectContextApplications(
GatewayConfig config, Topology topology ) {
Map<String,ServiceDeploymentContributor> contributors = new HashMap<>();
if( topology != null ) {
for( Application application : topology.getApplications() ) {
String name = application.getName();
if( name == null || name.isEmpty() ) {
throw new DeploymentException( "Topologies cannot contain an application without a name." );
}
ApplicationDeploymentContributor contributor = new ApplicationDeploymentContributor( config, application );
List<String> urls = application.getUrls();
if( urls == null || urls.isEmpty() ) {
urls = new ArrayList<>( 1 );
urls.add( "/" + name );
}
for( String url : urls ) {
if( url == null || url.isEmpty() || "/".equals(url) ) {
if( !topology.getServices().isEmpty() ) {
throw new DeploymentException( String.format(Locale.ROOT,
"Topologies with services cannot contain an application (%s) with a root url.", name ) );
}
}
contributors.put( url, contributor );
}
}
}
return contributors;
}
private static void initialize(
DeploymentContext context,
Map<String,List<ProviderDeploymentContributor>> providers,
Map<String,List<ServiceDeploymentContributor>> services,
Map.Entry<String,ServiceDeploymentContributor> applications ) {
WebAppDescriptor wad = context.getWebAppDescriptor();
String topoName = context.getTopology().getName();
if( applications == null ) {
String servletName = topoName + SERVLET_NAME_SUFFIX;
wad.createServlet().servletName( servletName ).servletClass( GatewayServlet.class.getName() );
wad.createServletMapping().servletName( servletName ).urlPattern( "/*" );
} else {
String filterName = topoName + FILTER_NAME_SUFFIX;
wad.createFilter().filterName( filterName ).filterClass( GatewayServlet.class.getName() );
wad.createFilterMapping().filterName( filterName ).urlPattern( "/*" );
}
if (gatewayServices != null) {
gatewayServices.initializeContribution(context);
} else {
log.gatewayServicesNotInitialized();
}
initializeProviders( context, providers );
initializeServices( context, services );
initializeApplications( context, applications );
}
private static void initializeProviders(
DeploymentContext context,
Map<String,List<ProviderDeploymentContributor>> providers ) {
if( providers != null ) {
for( Entry<String, List<ProviderDeploymentContributor>> entry : providers.entrySet() ) {
for( ProviderDeploymentContributor contributor : entry.getValue() ) {
try {
injectServices( contributor );
log.initializeProvider( contributor.getName(), contributor.getRole() );
contributor.initializeContribution( context );
} catch( Exception e ) {
log.failedToInitializeContribution( e );
throw new DeploymentException( "Failed to initialize contribution.", e );
}
}
}
}
}
private static void initializeServices( DeploymentContext context, Map<String, List<ServiceDeploymentContributor>> services ) {
if( services != null ) {
for( Entry<String, List<ServiceDeploymentContributor>> entry : services.entrySet() ) {
for( ServiceDeploymentContributor contributor : entry.getValue() ) {
try {
injectServices( contributor );
log.initializeService( contributor.getName(), contributor.getRole() );
contributor.initializeContribution( context );
} catch( Exception e ) {
log.failedToInitializeContribution( e );
throw new DeploymentException( "Failed to initialize contribution.", e );
}
}
}
}
}
private static void initializeApplications( DeploymentContext context, Map.Entry<String, ServiceDeploymentContributor> application ) {
if( application != null ) {
ServiceDeploymentContributor contributor = application.getValue();
if( contributor != null ) {
try {
injectServices( contributor );
log.initializeApplication( contributor.getName() );
contributor.initializeContribution( context );
} catch( Exception e ) {
log.failedToInitializeContribution( e );
throw new DeploymentException( "Failed to initialize application contribution.", e );
}
}
}
}
private static void injectServices(Object contributor) {
if (gatewayServices != null) {
Statement stmt;
for(ServiceType serviceType : gatewayServices.getServiceTypes()) {
try {
// TODO: this is just a temporary injection solution
// TODO: test for the existence of the setter before attempting it
// TODO: avoid exception throwing when there is no setter
stmt = new Statement(contributor, "set" + serviceType.getServiceTypeName(), new Object[]{gatewayServices.getService(serviceType)});
stmt.execute();
} catch (NoSuchMethodException e) {
// TODO: eliminate the possibility of this being thrown up front
} catch (Exception e) {
// Maybe it makes sense to throw exception
log.failedToInjectService( serviceType.getServiceTypeName(), e );
throw new DeploymentException("Failed to inject service.", e);
}
}
}
}
private static void contribute(
DeploymentContext context,
Map<String,List<ProviderDeploymentContributor>> providers,
Map<String,List<ServiceDeploymentContributor>> services,
Map.Entry<String,ServiceDeploymentContributor> applications ) {
Topology topology = context.getTopology();
contributeProviders( context, topology, providers );
contributeServices( context, topology, services );
contributeApplications( context, topology, applications );
}
private static void contributeProviders( DeploymentContext context, Topology topology, Map<String, List<ProviderDeploymentContributor>> providers ) {
for( Provider provider : topology.getProviders() ) {
ProviderDeploymentContributor contributor = getProviderContributor( providers, provider.getRole(), provider.getName() );
if( contributor != null && provider.isEnabled() ) {
try {
log.contributeProvider( provider.getName(), provider.getRole() );
contributor.contributeProvider( context, provider );
} catch( Exception e ) {
// Maybe it makes sense to throw exception
log.failedToContributeProvider( provider.getName(), provider.getRole(), e );
throw new DeploymentException("Failed to contribute provider.", e);
}
}
}
}
private static void contributeServices( DeploymentContext context, Topology topology, Map<String, List<ServiceDeploymentContributor>> services ) {
if( services != null ) {
for( Service service : topology.getServices() ) {
ServiceDeploymentContributor contributor = getServiceContributor( service.getRole(), service.getName(), service.getVersion() );
if( contributor != null ) {
try {
log.contributeService( service.getName(), service.getRole() );
contributor.contributeService( context, service );
if( gatewayServices != null ) {
ServiceRegistry sr = gatewayServices.getService( ServiceType.SERVICE_REGISTRY_SERVICE );
if( sr != null ) {
String regCode = sr.getRegistrationCode( topology.getName() );
sr.registerService( regCode, topology.getName(), service.getRole(), service.getUrls() );
}
}
} catch( Exception e ) {
// Maybe it makes sense to throw exception
log.failedToContributeService( service.getName(), service.getRole(), e );
throw new DeploymentException( "Failed to contribute service.", e );
}
}
}
}
}
private static void contributeApplications( DeploymentContext context, Topology topology, Map.Entry<String, ServiceDeploymentContributor> applications ) {
if( applications != null ) {
ServiceDeploymentContributor contributor = applications.getValue();
if( contributor != null ) {
try {
log.contributeApplication( contributor.getName() );
Application applicationDesc = topology.getApplication( applications.getKey() );
contributor.contributeService( context, applicationDesc );
} catch( Exception e ) {
log.failedToInitializeContribution( e );
throw new DeploymentException( "Failed to contribution application.", e );
}
}
}
}
public static ProviderDeploymentContributor getProviderContributor( String role, String name ) {
ProviderDeploymentContributor contributor = null;
Map<String,ProviderDeploymentContributor> nameMap = PROVIDER_CONTRIBUTOR_MAP.get( role );
if( nameMap != null ) {
if( name != null ) {
contributor = nameMap.get( name );
} else if ( !nameMap.isEmpty() ) {
contributor = nameMap.values().iterator().next();
}
}
return contributor;
}
public static ServiceDeploymentContributor getServiceContributor( String role, String name, Version version ) {
ServiceDeploymentContributor contributor = null;
Map<String,Map<Version, ServiceDeploymentContributor>> nameMap = SERVICE_CONTRIBUTOR_MAP.get( role );
if( nameMap != null && !nameMap.isEmpty()) {
Map<Version, ServiceDeploymentContributor> versionMap;
if ( name == null ) {
versionMap = nameMap.values().iterator().next();
} else {
versionMap = nameMap.get( name );
}
if ( versionMap != null && !versionMap.isEmpty()) {
if( version == null ) {
contributor = ((TreeMap<Version, ServiceDeploymentContributor>) versionMap).lastEntry().getValue();
} else {
contributor = versionMap.get( version );
}
}
}
return contributor;
}
private static void finish(
DeploymentContext context,
Map<String,List<ProviderDeploymentContributor>> providers,
Map<String,List<ServiceDeploymentContributor>> services,
Map.Entry<String,ServiceDeploymentContributor> application ) {
try {
// Write the gateway descriptor (gateway.xml) into the war.
StringWriter writer = new StringWriter();
GatewayDescriptorFactory.store( context.getGatewayDescriptor(), "xml", writer );
context.getWebArchive().addAsWebInfResource(
new StringAsset( writer.toString() ),
GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
// Set the location of the gateway descriptor as a servlet init param.
if( application == null ) {
String servletName = context.getTopology().getName() + SERVLET_NAME_SUFFIX;
ServletType<WebAppDescriptor> servlet = findServlet( context, servletName );
// Coverity CID 1352314
if( servlet == null ) {
throw new DeploymentException( "Missing servlet " + servletName );
} else {
servlet.createInitParam()
.paramName( GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_PARAM )
.paramValue( "/WEB-INF/" + GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
}
} else {
String servletName = context.getTopology().getName() + FILTER_NAME_SUFFIX;
FilterType<WebAppDescriptor> filter = findFilter( context, servletName );
// Coverity CID 1352313
if( filter == null ) {
throw new DeploymentException( "Missing filter " + servletName );
} else {
filter.createInitParam()
.paramName( GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_PARAM )
.paramValue( "/WEB-INF/" + GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
}
}
if (gatewayServices != null) {
gatewayServices.finalizeContribution(context);
}
finalizeProviders( context, providers );
finalizeServices( context, services );
finalizeApplications( context, application );
writeDeploymentDescriptor( context, application != null );
} catch ( IOException e ) {
throw new RuntimeException( e );
}
}
private static void finalizeProviders( DeploymentContext context, Map<String, List<ProviderDeploymentContributor>> providers ) {
if( providers != null ) {
for( Entry<String, List<ProviderDeploymentContributor>> entry : providers.entrySet() ) {
for( ProviderDeploymentContributor contributor : entry.getValue() ) {
try {
log.finalizeProvider( contributor.getName(), contributor.getRole() );
contributor.finalizeContribution( context );
} catch( Exception e ) {
// Maybe it makes sense to throw exception
log.failedToFinalizeContribution( e );
throw new DeploymentException( "Failed to finish contribution.", e );
}
}
}
}
}
private static void finalizeServices( DeploymentContext context, Map<String, List<ServiceDeploymentContributor>> services ) {
if( services != null ) {
for( Entry<String, List<ServiceDeploymentContributor>> entry : services.entrySet() ) {
for( ServiceDeploymentContributor contributor : entry.getValue() ) {
try {
log.finalizeService( contributor.getName(), contributor.getRole() );
contributor.finalizeContribution( context );
} catch( Exception e ) {
// Maybe it makes sense to throw exception
log.failedToFinalizeContribution( e );
throw new DeploymentException( "Failed to finish contribution.", e );
}
}
}
}
}
private static void finalizeApplications( DeploymentContext context, Map.Entry<String, ServiceDeploymentContributor> application ) {
if( application != null ) {
ServiceDeploymentContributor contributor = application.getValue();
if( contributor != null ) {
try {
log.finalizeApplication( contributor.getName() );
contributor.finalizeContribution( context );
} catch( Exception e ) {
log.failedToInitializeContribution( e );
throw new DeploymentException( "Failed to contribution application.", e );
}
}
}
}
private static void writeDeploymentDescriptor( DeploymentContext context, boolean override ) {
// Write the web.xml into the war.
Asset webXmlAsset = new StringAsset( context.getWebAppDescriptor().exportAsString() );
if( override ) {
context.getWebArchive().addAsWebInfResource( webXmlAsset, "override-web.xml" );
} else {
context.getWebArchive().setWebXML( webXmlAsset );
}
}
public static ServletType<WebAppDescriptor> findServlet( DeploymentContext context, String name ) {
List<ServletType<WebAppDescriptor>> servlets = context.getWebAppDescriptor().getAllServlet();
for( ServletType<WebAppDescriptor> servlet : servlets ) {
if( name.equals( servlet.getServletName() ) ) {
return servlet;
}
}
return null;
}
public static FilterType<WebAppDescriptor> findFilter( DeploymentContext context, String name ) {
List<FilterType<WebAppDescriptor>> filters = context.getWebAppDescriptor().getAllFilter();
for( FilterType<WebAppDescriptor> filter : filters ) {
if( name.equals( filter.getFilterName() ) ) {
return filter;
}
}
return null;
}
private static void loadStacksServiceContributors( GatewayConfig config ) {
String stacks = config.getGatewayServicesDir();
log.usingServicesDirectory(stacks);
File stacksDir = new File(stacks);
Set<ServiceDeploymentContributor> deploymentContributors = ServiceDefinitionsLoader.loadServiceDefinitionDeploymentContributors(stacksDir);
addServiceDeploymentContributors(deploymentContributors.iterator());
}
private static void loadServiceContributors() {
SERVICE_CONTRIBUTOR_MAP = new HashMap<>();
ServiceLoader<ServiceDeploymentContributor> loader = ServiceLoader.load( ServiceDeploymentContributor.class );
Iterator<ServiceDeploymentContributor> contributors = loader.iterator();
addServiceDeploymentContributors(contributors);
}
private static void addServiceDeploymentContributors(Iterator<ServiceDeploymentContributor> contributors) {
while( contributors.hasNext() ) {
ServiceDeploymentContributor contributor = contributors.next();
if( contributor.getName() == null ) {
log.ignoringServiceContributorWithMissingName( contributor.getClass().getName() );
continue;
}
if( contributor.getRole() == null ) {
log.ignoringServiceContributorWithMissingRole( contributor.getClass().getName() );
continue;
}
if( contributor.getVersion() == null ) {
log.ignoringServiceContributorWithMissingVersion(contributor.getClass().getName());
continue;
}
Map<String,Map<Version, ServiceDeploymentContributor>> nameMap = SERVICE_CONTRIBUTOR_MAP.get( contributor.getRole() );
if( nameMap == null ) {
nameMap = new HashMap<>();
SERVICE_CONTRIBUTOR_MAP.put( contributor.getRole(), nameMap );
}
Map<Version, ServiceDeploymentContributor> versionMap = nameMap.get(contributor.getName());
if (versionMap == null) {
versionMap = new TreeMap<>();
nameMap.put(contributor.getName(), versionMap);
}
versionMap.put( contributor.getVersion(), contributor );
}
}
private static void loadProviderContributors() {
Set<ProviderDeploymentContributor> set = new HashSet<>();
Map<String,Map<String,ProviderDeploymentContributor>> roleMap
= new HashMap<>();
ServiceLoader<ProviderDeploymentContributor> loader = ServiceLoader.load( ProviderDeploymentContributor.class );
for (ProviderDeploymentContributor contributor : loader) {
if (contributor.getName() == null) {
log.ignoringProviderContributorWithMissingName(contributor.getClass().getName());
continue;
}
if (contributor.getRole() == null) {
log.ignoringProviderContributorWithMissingRole(contributor.getClass().getName());
continue;
}
set.add(contributor);
Map nameMap = roleMap.get(contributor.getRole());
if (nameMap == null) {
nameMap = new HashMap<>();
roleMap.put(contributor.getRole(), nameMap);
}
nameMap.put(contributor.getName(), contributor);
}
PROVIDER_CONTRIBUTORS = set;
PROVIDER_CONTRIBUTOR_MAP = roleMap;
}
static ProviderDeploymentContributor getProviderContributor(
Map<String,List<ProviderDeploymentContributor>> providers, String role, String name ) {
ProviderDeploymentContributor contributor = null;
if( name == null ) {
List<ProviderDeploymentContributor> list = providers.get( role );
if( list != null && !list.isEmpty() ) {
contributor = list.get( 0 );
}
} else {
contributor = getProviderContributor( role, name );
// Explicit configuration that is wrong should just fail
// rather than randomly select a provider. Implicit default
// providers can be selected when no name is provided.
if (contributor == null || !contributor.getRole().equals(role) ||
!contributor.getName().equals(name)) {
throw new DeploymentException(
"Failed to contribute provider. Role: " +
role + " Name: " + name + ". Please check the topology for" +
" errors in name and role and that the provider is " +
"on the classpath.");
}
}
return contributor;
}
}