View Javadoc
1   package net.technearts.rip;
2   
3   import static java.util.Optional.ofNullable;
4   import static spark.Service.ignite;
5   
6   import java.net.URISyntaxException;
7   import java.nio.file.Path;
8   import java.nio.file.Paths;
9   import java.util.HashMap;
10  import java.util.Map;
11  import java.util.Objects;
12  
13  import org.slf4j.Logger;
14  import org.slf4j.LoggerFactory;
15  
16  import com.google.common.collect.ComparisonChain;
17  
18  import spark.Service;
19  
20  /**
21   * Servidor Rip rodando em um Jetty, para criação de serviços rest (ou qualquer
22   * requisição http) a serem usados para mocks de serviços reais. Os serviços
23   * respondem com base apenas no conteúdo do body da requisição.
24   */
25  public class RipServer implements Comparable<RipServer>, AutoCloseable {
26    private static final Logger logger = LoggerFactory.getLogger(RipServer.class);
27    private static final Map<Integer, RipServer> instance = new HashMap<>();
28  
29    /**
30     * Cria um RipServer na porta padrão (7777)
31     *
32     * @return Um RipRoute para criação das rotas
33     */
34    public static RipRoute localhost() {
35      return localhost(7777);
36    }
37  
38    /**
39     * Cria um RipServer na porta <code>port</code>
40     *
41     * @param port a porta do servidor
42     * @return Um RipRoute para criação das rotas
43     */
44    public static RipRoute localhost(final int port) {
45      return localhost(port, "/");
46    }
47  
48    /**
49     * Cria um RipServer na porta <code>port</code>
50     *
51     * @param port     a porta do servidor
52     * @param location o local dos arquivos
53     * @return Um RipRoute para criação das rotas
54     */
55    public static RipRoute localhost(final int port, final String location) {
56      if (!instance.containsKey(port)) {
57        logger.debug("Criando servidor local na porta {}", port);
58        instance.put(port, new RipServer(port, location));
59      }
60      return new RipRoute(instance.get(port));
61    }
62  
63    /**
64     * Para o servidor na porta <code>port</code>
65     *
66     * @param port a porta do servidor
67     */
68    public static void stop(final int port) {
69      if (instance.containsKey(port)) {
70        instance.get(port).service.stop();
71      }
72    }
73  
74    /**
75     * Transforma um caminho de arquivo informado em um objeto <code>Path</code>
76     *
77     * @param fileName o caminho/nome do arquivo, com raiz em src/main/resources
78     * @return Um <code>Path</code> para o arquivo
79     */
80    public static Path withFile(final String fileName) {
81      try {
82        return Paths.get(RipServer.class.getResource(fileName).toURI());
83      } catch (final URISyntaxException e) {
84        return null;
85      }
86    }
87  
88    private final int port;
89    private final String location;
90    Service service;
91  
92    private RipServer(final int port, final String location) {
93      this.port = port;
94      this.location = location;
95      service = ignite();
96      service.port(port);
97      service.staticFiles.location(location);
98    }
99  
100   @Override
101   public void close() throws Exception {
102     instance.values().stream().parallel()
103         .forEach(server -> server.service.stop());
104     instance.clear();
105 
106   }
107 
108   @Override
109   public int compareTo(final RipServer that) {
110     return ComparisonChain.start().compare(port, that.port).result();
111   }
112 
113   @Override
114   public boolean equals(final Object object) {
115     if (object instanceof RipServer) {
116       final RipServer that = (RipServer) object;
117       return port == that.port;
118     }
119     return false;
120   }
121 
122   @Override
123   public int hashCode() {
124     return Objects.hashCode(port);
125   }
126 
127   void reset() {
128     logger.info("Apagando rotas no servidor local na porta {}", port);
129     ofNullable(instance.remove(port))
130         .ifPresent(server -> server.service.stop());
131     logger.info("Recriando servidor local na porta {} sem rotas", port);
132     instance.put(port, new RipServer(port, location));
133   }
134 
135   @Override
136   public String toString() {
137     return String.format("RipServer %s", port);
138   }
139 }