From 42b5e814a57b8d2b4a6d73e38fe794f3c664c667 Mon Sep 17 00:00:00 2001 From: ZaidM Date: Fri, 12 Dec 2014 15:00:52 +0000 Subject: [PATCH] added NginxConfigFileGenerator to pass in custom server.conf templates to NginxController --- .../proxy/nginx/NginxConfigFileGenerator.java | 250 +---------------- .../entity/proxy/nginx/NginxController.java | 8 +- .../proxy/nginx/NginxControllerImpl.java | 13 +- .../nginx/NginxDefaultConfigGenerator.java | 256 ++++++++++++++++++ ...java => NginxTemplateConfigGenerator.java} | 21 +- 5 files changed, 285 insertions(+), 263 deletions(-) create mode 100644 software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java rename software/webapp/src/main/java/brooklyn/entity/proxy/nginx/{NginxConfigTemplate.java => NginxTemplateConfigGenerator.java} (81%) diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java index fa74e5900a..1da0ed8dff 100644 --- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java +++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigFileGenerator.java @@ -18,248 +18,16 @@ */ package brooklyn.entity.proxy.nginx; -import static java.lang.String.format; - -import java.util.Collection; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.proxy.ProxySslConfig; -import brooklyn.util.text.Strings; - -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimap; - /** - * Generates a configuration file for {@link NginxController}. + * Generates a {@code server.conf} configuration file for an {@link NginxController}. */ -public class NginxConfigFileGenerator { - - private static final Logger LOG = LoggerFactory.getLogger(NginxConfigFileGenerator.class); - - private NginxDriver driver; - private NginxController nginx; - - public static NginxConfigFileGenerator generator(NginxDriver driver) { - return new NginxConfigFileGenerator(driver); - } - - private NginxConfigFileGenerator(NginxDriver driver) { - this.driver = driver; - this.nginx = (NginxController) driver.getEntity(); - } - - public String configFile() { - StringBuilder config = new StringBuilder(); - config.append("\n"); - config.append(format("pid %s;\n", driver.getPidFile())); - config.append("events {\n"); - config.append(" worker_connections 8196;\n"); - config.append("}\n"); - config.append("http {\n"); - - ProxySslConfig globalSslConfig = nginx.getSslConfig(); - - if (nginx.isSsl()) { - verifyConfig(globalSslConfig); - appendSslConfig("global", config, " ", globalSslConfig, true, true); - } - - // If no servers, then defaults to returning 404 - // TODO Give nicer page back - if (nginx.getDomain()!=null || nginx.getServerPoolAddresses() == null || nginx.getServerPoolAddresses().isEmpty()) { - config.append(" server {\n"); - config.append(getCodeForServerConfig()); - config.append(" listen "+nginx.getPort()+";\n"); - config.append(getCodeFor404()); - config.append(" }\n"); - } - - // For basic round-robin across the server-pool - if (nginx.getServerPoolAddresses() != null && nginx.getServerPoolAddresses().size() > 0) { - config.append(format(" upstream "+nginx.getId()+" {\n")); - if (nginx.isSticky()){ - config.append(" sticky;\n"); - } - for (String address : nginx.getServerPoolAddresses()) { - config.append(" server "+address+";\n"); - } - config.append(" }\n"); - config.append(" server {\n"); - config.append(getCodeForServerConfig()); - config.append(" listen "+nginx.getPort()+";\n"); - if (nginx.getDomain()!=null) - config.append(" server_name "+nginx.getDomain()+";\n"); - config.append(" location / {\n"); - config.append(" proxy_pass "+(globalSslConfig != null && globalSslConfig.getTargetIsSsl() ? "https" : "http")+"://"+nginx.getId()+";\n"); - config.append(" }\n"); - config.append(" }\n"); - } - - // For mapping by URL - Iterable mappings = nginx.getUrlMappings(); - Multimap mappingsByDomain = LinkedHashMultimap.create(); - for (UrlMapping mapping : mappings) { - Collection addrs = mapping.getAttribute(UrlMapping.TARGET_ADDRESSES); - if (addrs != null && addrs.size() > 0) { - mappingsByDomain.put(mapping.getDomain(), mapping); - } - } - - for (UrlMapping um : mappings) { - Collection addrs = um.getAttribute(UrlMapping.TARGET_ADDRESSES); - if (addrs != null && addrs.size() > 0) { - config.append(format(" upstream "+um.getUniqueLabel()+" {\n")); - if (nginx.isSticky()){ - config.append(" sticky;\n"); - } - for (String address: addrs) { - config.append(" server "+address+";\n"); - } - config.append(" }\n"); - } - } - - for (String domain : mappingsByDomain.keySet()) { - config.append(" server {\n"); - config.append(getCodeForServerConfig()); - config.append(" listen "+nginx.getPort()+";\n"); - config.append(" server_name "+domain+";\n"); - boolean hasRoot = false; - - // set up SSL - ProxySslConfig localSslConfig = null; - for (UrlMapping mappingInDomain : mappingsByDomain.get(domain)) { - ProxySslConfig sslConfig = mappingInDomain.getConfig(UrlMapping.SSL_CONFIG); - if (sslConfig!=null) { - verifyConfig(sslConfig); - if (localSslConfig!=null) { - if (localSslConfig.equals(sslConfig)) { - //ignore identical config specified on multiple mappings - } else { - LOG.warn("{} mapping {} provides SSL config for {} when a different config had already been provided by another mapping, ignoring this one", - new Object[] {this, mappingInDomain, domain}); - } - } else if (globalSslConfig!=null) { - if (globalSslConfig.equals(sslConfig)) { - //ignore identical config specified on multiple mappings - } else { - LOG.warn("{} mapping {} provides SSL config for {} when a different config had been provided at root nginx scope, ignoring this one", - new Object[] {this, mappingInDomain, domain}); - } - } else { - //new config, is okay - localSslConfig = sslConfig; - } - } - } - if (localSslConfig != null) { - appendSslConfig(domain, config, " ", localSslConfig, true, true); - } - - for (UrlMapping mappingInDomain : mappingsByDomain.get(domain)) { - // TODO Currently only supports "~" for regex. Could add support for other options, - // such as "~*", "^~", literals, etc. - boolean isRoot = mappingInDomain.getPath()==null || mappingInDomain.getPath().length()==0 || mappingInDomain.getPath().equals("/"); - if (isRoot && hasRoot) { - LOG.warn(""+this+" mapping "+mappingInDomain+" provides a duplicate / proxy, ignoring"); - } else { - hasRoot |= isRoot; - String location = isRoot ? "/" : "~ " + mappingInDomain.getPath(); - config.append(" location "+location+" {\n"); - Collection rewrites = mappingInDomain.getConfig(UrlMapping.REWRITES); - if (rewrites != null && rewrites.size() > 0) { - for (UrlRewriteRule rule: rewrites) { - config.append(" rewrite \"^"+rule.getFrom()+"$\" \""+rule.getTo()+"\""); - if (rule.isBreak()) config.append(" break"); - config.append(" ;\n"); - } - } - config.append(" proxy_pass "+ - (localSslConfig != null && localSslConfig.getTargetIsSsl() ? "https" : - (localSslConfig == null && globalSslConfig != null && globalSslConfig.getTargetIsSsl()) ? "https" : - "http")+ - "://"+mappingInDomain.getUniqueLabel()+" ;\n"); - config.append(" }\n"); - } - } - if (!hasRoot) { - //provide a root block giving 404 if there isn't one for this server - config.append(" location / { \n"+getCodeFor404()+" }\n"); - } - config.append(" }\n"); - } - - config.append("}\n"); - - return config.toString(); - } - - protected String getCodeForServerConfig() { - // See http://wiki.nginx.org/HttpProxyModule - return ""+ - // this prevents nginx from reporting version number on error pages - " server_tokens off;\n"+ - - // this prevents nginx from using the internal proxy_pass codename as Host header passed upstream. - // Not using $host, as that causes integration test to fail with a "connection refused" testing - // url-mappings, at URL "http://localhost:${port}/atC0" (with a trailing slash it does work). - " proxy_set_header Host $http_host;\n"+ - - // following added, as recommended for wordpress in: - // http://zeroturnaround.com/labs/wordpress-protips-go-with-a-clustered-approach/#!/ - " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"+ - " proxy_set_header X-Real-IP $remote_addr;\n"; - } - - protected String getCodeFor404() { - return " return 404;\n"; - } - - protected void verifyConfig(ProxySslConfig proxySslConfig) { - if(Strings.isEmpty(proxySslConfig.getCertificateDestination()) && Strings.isEmpty(proxySslConfig.getCertificateSourceUrl())){ - throw new IllegalStateException("ProxySslConfig can't have a null certificateDestination and null certificateSourceUrl. One or both need to be set"); - } - } - - protected boolean appendSslConfig(String id, StringBuilder out, String prefix, ProxySslConfig ssl, - boolean sslBlock, boolean certificateBlock) { - if (ssl == null) return false; - if (sslBlock) { - out.append(prefix); - out.append("ssl on;\n"); - } - if (ssl.getReuseSessions()) { - out.append(prefix); - out.append(""); - } - if (certificateBlock) { - String cert; - if (Strings.isEmpty(ssl.getCertificateDestination())) { - cert = "" + id + ".crt"; - } else { - cert = ssl.getCertificateDestination(); - } - - out.append(prefix); - out.append("ssl_certificate " + cert + ";\n"); - - String key; - if (!Strings.isEmpty(ssl.getKeyDestination())) { - key = ssl.getKeyDestination(); - } else if (!Strings.isEmpty(ssl.getKeySourceUrl())) { - key = "" + id + ".key"; - } else { - key = null; - } - - if (key != null) { - out.append(prefix); - out.append("ssl_certificate_key " + key + ";\n"); - } - } - return true; - } +public interface NginxConfigFileGenerator { + + /** + * Entry point for the generator. + * + * @return The contents of the {@code server.conf} file + */ + String generateConfigFile(NginxDriver driver, NginxController entity); } diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java index 88d1bb9fba..c645dd2a6b 100644 --- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java +++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxController.java @@ -37,6 +37,7 @@ import brooklyn.util.flags.SetFromFlag; import com.google.common.collect.ImmutableMap; +import com.google.common.reflect.TypeToken; /** * An entity that represents an Nginx proxy (e.g. for routing requests to servers in a cluster). @@ -104,9 +105,12 @@ public interface NginxController extends AbstractController, HasShortName { ConfigKey WITH_CC_OPT = ConfigKeys.newStringConfigKey( "nginx.install.withCcOpt", "String to pass in with --with-cc-opt=\"\"", "-I /usr/local/include"); + @SetFromFlag("configGenerator") + ConfigKey SERVER_CONF_GENERATOR = ConfigKeys.newConfigKey(NginxConfigFileGenerator.class, + "nginx.config.generator", "The server.conf generator class", new NginxDefaultConfigGenerator()); + @SetFromFlag("configTemplate") - ConfigKey SERVER_CONF_TEMPLATE_URL = ConfigKeys.newStringConfigKey( - "nginx.config.templateUrl", "The server.conf configuration file URL (FreeMarker template)"); + ConfigKey SERVER_CONF_TEMPLATE_URL = NginxTemplateConfigGenerator.SERVER_CONF_TEMPLATE_URL; @SetFromFlag("staticContentArchive") ConfigKey STATIC_CONTENT_ARCHIVE_URL = ConfigKeys.newStringConfigKey( diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java index 74727fb243..041b8f6eb6 100644 --- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java +++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java @@ -262,18 +262,13 @@ public void installSslKeys(String id, ProxySslConfig ssl) { public String getConfigFile() { NginxSshDriver driver = (NginxSshDriver) getDriver(); if (driver==null) { - if (LOG.isDebugEnabled()) - LOG.debug("No driver for {}, so not generating config file (is entity stopping? state={})", - this, getAttribute(NginxController.SERVICE_STATE_ACTUAL)); + LOG.debug("No driver for {}, so not generating config file (is entity stopping? state={})", + this, getAttribute(NginxController.SERVICE_STATE_ACTUAL)); return null; } - String templateUrl = getConfig(NginxController.SERVER_CONF_TEMPLATE_URL); - if (templateUrl != null) { - return NginxConfigTemplate.generator(driver).configFile(); - } else { - return NginxConfigFileGenerator.generator(driver).configFile(); - } + NginxConfigFileGenerator templateGenerator = getConfig(NginxController.SERVER_CONF_GENERATOR); + return templateGenerator.generateConfigFile(driver, this); } @Override diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java new file mode 100644 index 0000000000..7ba069e645 --- /dev/null +++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java @@ -0,0 +1,256 @@ +/* + * 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 brooklyn.entity.proxy.nginx; + +import static java.lang.String.format; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; + +import brooklyn.entity.proxy.ProxySslConfig; +import brooklyn.util.text.Strings; + +/** + * Generates the {@code server.conf} configuration file using sensors on an {@link NginxController}. + */ +public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator { + + private static final Logger LOG = LoggerFactory.getLogger(NginxDefaultConfigGenerator.class); + + public NginxDefaultConfigGenerator() { } + + @Override + public String generateConfigFile(NginxDriver driver, NginxController nginx) { + StringBuilder config = new StringBuilder(); + config.append("\n"); + config.append(format("pid %s;\n", driver.getPidFile())); + config.append("events {\n"); + config.append(" worker_connections 8196;\n"); + config.append("}\n"); + config.append("http {\n"); + + ProxySslConfig globalSslConfig = nginx.getSslConfig(); + + if (nginx.isSsl()) { + verifyConfig(globalSslConfig); + appendSslConfig("global", config, " ", globalSslConfig, true, true); + } + + // If no servers, then defaults to returning 404 + // TODO Give nicer page back + if (nginx.getDomain()!=null || nginx.getServerPoolAddresses() == null || nginx.getServerPoolAddresses().isEmpty()) { + config.append(" server {\n"); + config.append(getCodeForServerConfig()); + config.append(" listen "+nginx.getPort()+";\n"); + config.append(getCodeFor404()); + config.append(" }\n"); + } + + // For basic round-robin across the server-pool + if (nginx.getServerPoolAddresses() != null && nginx.getServerPoolAddresses().size() > 0) { + config.append(format(" upstream "+nginx.getId()+" {\n")); + if (nginx.isSticky()){ + config.append(" sticky;\n"); + } + for (String address : nginx.getServerPoolAddresses()) { + config.append(" server "+address+";\n"); + } + config.append(" }\n"); + config.append(" server {\n"); + config.append(getCodeForServerConfig()); + config.append(" listen "+nginx.getPort()+";\n"); + if (nginx.getDomain()!=null) + config.append(" server_name "+nginx.getDomain()+";\n"); + config.append(" location / {\n"); + config.append(" proxy_pass "+(globalSslConfig != null && globalSslConfig.getTargetIsSsl() ? "https" : "http")+"://"+nginx.getId()+";\n"); + config.append(" }\n"); + config.append(" }\n"); + } + + // For mapping by URL + Iterable mappings = nginx.getUrlMappings(); + Multimap mappingsByDomain = LinkedHashMultimap.create(); + for (UrlMapping mapping : mappings) { + Collection addrs = mapping.getAttribute(UrlMapping.TARGET_ADDRESSES); + if (addrs != null && addrs.size() > 0) { + mappingsByDomain.put(mapping.getDomain(), mapping); + } + } + + for (UrlMapping um : mappings) { + Collection addrs = um.getAttribute(UrlMapping.TARGET_ADDRESSES); + if (addrs != null && addrs.size() > 0) { + config.append(format(" upstream "+um.getUniqueLabel()+" {\n")); + if (nginx.isSticky()){ + config.append(" sticky;\n"); + } + for (String address: addrs) { + config.append(" server "+address+";\n"); + } + config.append(" }\n"); + } + } + + for (String domain : mappingsByDomain.keySet()) { + config.append(" server {\n"); + config.append(getCodeForServerConfig()); + config.append(" listen "+nginx.getPort()+";\n"); + config.append(" server_name "+domain+";\n"); + boolean hasRoot = false; + + // set up SSL + ProxySslConfig localSslConfig = null; + for (UrlMapping mappingInDomain : mappingsByDomain.get(domain)) { + ProxySslConfig sslConfig = mappingInDomain.getConfig(UrlMapping.SSL_CONFIG); + if (sslConfig!=null) { + verifyConfig(sslConfig); + if (localSslConfig!=null) { + if (localSslConfig.equals(sslConfig)) { + //ignore identical config specified on multiple mappings + } else { + LOG.warn("{} mapping {} provides SSL config for {} when a different config had already been provided by another mapping, ignoring this one", + new Object[] {this, mappingInDomain, domain}); + } + } else if (globalSslConfig!=null) { + if (globalSslConfig.equals(sslConfig)) { + //ignore identical config specified on multiple mappings + } else { + LOG.warn("{} mapping {} provides SSL config for {} when a different config had been provided at root nginx scope, ignoring this one", + new Object[] {this, mappingInDomain, domain}); + } + } else { + //new config, is okay + localSslConfig = sslConfig; + } + } + } + if (localSslConfig != null) { + appendSslConfig(domain, config, " ", localSslConfig, true, true); + } + + for (UrlMapping mappingInDomain : mappingsByDomain.get(domain)) { + // TODO Currently only supports "~" for regex. Could add support for other options, + // such as "~*", "^~", literals, etc. + boolean isRoot = mappingInDomain.getPath()==null || mappingInDomain.getPath().length()==0 || mappingInDomain.getPath().equals("/"); + if (isRoot && hasRoot) { + LOG.warn(""+this+" mapping "+mappingInDomain+" provides a duplicate / proxy, ignoring"); + } else { + hasRoot |= isRoot; + String location = isRoot ? "/" : "~ " + mappingInDomain.getPath(); + config.append(" location "+location+" {\n"); + Collection rewrites = mappingInDomain.getConfig(UrlMapping.REWRITES); + if (rewrites != null && rewrites.size() > 0) { + for (UrlRewriteRule rule: rewrites) { + config.append(" rewrite \"^"+rule.getFrom()+"$\" \""+rule.getTo()+"\""); + if (rule.isBreak()) config.append(" break"); + config.append(" ;\n"); + } + } + config.append(" proxy_pass "+ + (localSslConfig != null && localSslConfig.getTargetIsSsl() ? "https" : + (localSslConfig == null && globalSslConfig != null && globalSslConfig.getTargetIsSsl()) ? "https" : + "http")+ + "://"+mappingInDomain.getUniqueLabel()+" ;\n"); + config.append(" }\n"); + } + } + if (!hasRoot) { + //provide a root block giving 404 if there isn't one for this server + config.append(" location / { \n"+getCodeFor404()+" }\n"); + } + config.append(" }\n"); + } + + config.append("}\n"); + + return config.toString(); + } + + protected String getCodeForServerConfig() { + // See http://wiki.nginx.org/HttpProxyModule + return ""+ + // this prevents nginx from reporting version number on error pages + " server_tokens off;\n"+ + + // this prevents nginx from using the internal proxy_pass codename as Host header passed upstream. + // Not using $host, as that causes integration test to fail with a "connection refused" testing + // url-mappings, at URL "http://localhost:${port}/atC0" (with a trailing slash it does work). + " proxy_set_header Host $http_host;\n"+ + + // following added, as recommended for wordpress in: + // http://zeroturnaround.com/labs/wordpress-protips-go-with-a-clustered-approach/#!/ + " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"+ + " proxy_set_header X-Real-IP $remote_addr;\n"; + } + + protected String getCodeFor404() { + return " return 404;\n"; + } + + protected void verifyConfig(ProxySslConfig proxySslConfig) { + if(Strings.isEmpty(proxySslConfig.getCertificateDestination()) && Strings.isEmpty(proxySslConfig.getCertificateSourceUrl())){ + throw new IllegalStateException("ProxySslConfig can't have a null certificateDestination and null certificateSourceUrl. One or both need to be set"); + } + } + + protected boolean appendSslConfig(String id, StringBuilder out, String prefix, ProxySslConfig ssl, + boolean sslBlock, boolean certificateBlock) { + if (ssl == null) return false; + if (sslBlock) { + out.append(prefix); + out.append("ssl on;\n"); + } + if (ssl.getReuseSessions()) { + out.append(prefix); + out.append(""); + } + if (certificateBlock) { + String cert; + if (Strings.isEmpty(ssl.getCertificateDestination())) { + cert = "" + id + ".crt"; + } else { + cert = ssl.getCertificateDestination(); + } + + out.append(prefix); + out.append("ssl_certificate " + cert + ";\n"); + + String key; + if (!Strings.isEmpty(ssl.getKeyDestination())) { + key = ssl.getKeyDestination(); + } else if (!Strings.isEmpty(ssl.getKeySourceUrl())) { + key = "" + id + ".key"; + } else { + key = null; + } + + if (key != null) { + out.append(prefix); + out.append("ssl_certificate_key " + key + ";\n"); + } + } + return true; + } + +} diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigTemplate.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxTemplateConfigGenerator.java similarity index 81% rename from software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigTemplate.java rename to software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxTemplateConfigGenerator.java index 4c360423ca..d141ecf1ab 100644 --- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxConfigTemplate.java +++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxTemplateConfigGenerator.java @@ -21,9 +21,12 @@ import java.util.Collection; import java.util.Map; +import brooklyn.config.ConfigKey; +import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.proxy.ProxySslConfig; import brooklyn.util.ResourceUtils; import brooklyn.util.collections.MutableMap; +import brooklyn.util.flags.SetFromFlag; import brooklyn.util.text.Strings; import brooklyn.util.text.TemplateProcessor; @@ -31,21 +34,17 @@ import com.google.common.collect.Multimap; /** - * Processes a FreeMarker template for an {@link NginxController} configuration file. + * Processes a FreeMarker template to generate the {@code server.conf} configuration file for an {@link NginxController}. */ -public class NginxConfigTemplate { +public class NginxTemplateConfigGenerator implements NginxConfigFileGenerator { - private NginxDriver driver; + public static final ConfigKey SERVER_CONF_TEMPLATE_URL = ConfigKeys.newStringConfigKey( + "nginx.config.templateUrl", "The server.conf configuration file URL (FreeMarker template)"); - public static NginxConfigTemplate generator(NginxDriver driver) { - return new NginxConfigTemplate(driver); - } - - private NginxConfigTemplate(NginxDriver driver) { - this.driver = driver; - } + public NginxTemplateConfigGenerator() { } - public String configFile() { + @Override + public String generateConfigFile(NginxDriver driver, NginxController nginx) { // Check template URL exists String templateUrl = driver.getEntity().getConfig(NginxController.SERVER_CONF_TEMPLATE_URL); ResourceUtils.create(this).checkUrlExists(templateUrl);