View Javadoc
1   package de.juplo.httpresources;
2   
3   
4   import java.nio.file.Files;
5   import java.nio.file.Path;
6   import java.nio.file.Paths;
7   import java.util.LinkedHashMap;
8   import java.util.LinkedList;
9   import java.util.List;
10  import java.util.Map;
11  import org.slf4j.Logger;
12  import org.slf4j.LoggerFactory;
13  import org.testcontainers.containers.BindMode;
14  import org.testcontainers.containers.NginxContainer;
15  
16  
17  /**
18   * A configurable subclass of the {@link NginxContainer}.
19   * @author Kai Moritz
20   */
21  public class ConfigurableNginxContainer extends NginxContainer
22  {
23    private final static Logger LOG =
24        LoggerFactory.getLogger(ConfigurableNginxContainer.class);
25  
26  
27    public final static int DEFAULT_NGINX_PORT = 80;
28  
29    private final Map<String, String> directives;
30  
31  
32    /**
33     * Creates an instance with a default-configuration, that matches the
34     * static configuration of the base-class {@link NginxContainer}
35     */
36    public ConfigurableNginxContainer()
37    {
38      directives = new LinkedHashMap<>();
39      directives.put("daemon", "off");
40    }
41  
42  
43    /**
44     * Adds a global directive to the configuration-map.
45     * <p>
46     * This method can only be used to add <em>global</em> directives.
47     * Global directives are all directives, that are marked with the context
48     * <code>Main</code> in the {@link http://nginx.org/en/docs/ngx_core_module.html
49     * Nginx-documentation}, for example <code>daemon</code>, <code>user</code>
50     * and <code>env</code>.
51     * <p>
52     * If you need to modify contexts, like <code>server</code> or
53     * <code>http</code>, you have to
54     * {@link #withConfiguration(String) pass in a complete configuration}.
55     * @param key The key of the directive
56     * @param value The value of the directive (the <code>;</code> is added automatically)
57     * @return <code>this</code> instance, to enable a fluid API.
58     */
59    public ConfigurableNginxContainer withGlobalDirective(String key, String value)
60    {
61      directives.put(key, value);
62      return this;
63    }
64  
65    public Map<String, String> getGlobalDirectives()
66    {
67      return directives;
68    }
69  
70    public ConfigurableNginxContainer withConfiguration(String path)
71    {
72      Path config = Paths.get(path);
73  
74      if (Files.isRegularFile(config))
75      {
76        LOG.info("Binding file {} as /etc/nginx/nginx.conf", config.toAbsolutePath());
77        addFileSystemBind(path, "/etc/nginx/nginx.conf", BindMode.READ_ONLY);
78        return this;
79      }
80  
81      if (Files.isDirectory(config))
82      {
83        LOG.info("Binding directory {} as /etc/nginx/", config.toAbsolutePath());
84        addFileSystemBind(path, "/etc/nginx/nginx.conf", BindMode.READ_ONLY);
85        return this;
86      }
87  
88      throw new IllegalArgumentException(
89            config.toAbsolutePath() +
90            " has to represent either a directory, or a regular file!");
91    }
92  
93    @Override
94    protected void configure()
95    {
96      addExposedPort(DEFAULT_NGINX_PORT);
97      List<String> commands = new LinkedList<>();
98      commands.add("nginx");
99      directives.entrySet().forEach((directive) ->
100     {
101       commands.add("-g");
102       commands.add(directive.getKey() + " " + directive.getValue() + ";");
103     });
104     LOG.info("CMD: {}", commands);
105     setCommand(commands.toArray(new String[commands.size()]));
106   }
107 }