ConsulRepository implements EntryPointRepository, PortRepository, HaproxyRepository { @Override public Integer newPort(String key) { int newPort = -1; try { boolean failToPutNewPort = true; while (failToPutNewPort) { HttpGet getPortById = new HttpGet("http: Optional<ConsulItem<Map<String, Integer>>> portsByEntrypoint = client.execute(getPortById, httpResponse -> consulReader.parseHttpResponse(httpResponse, consulReader::parsePortsByHaproxyFromHttpEntity)); HttpPut putPortById; if (portsByEntrypoint.isPresent()) { Map<String, Integer> rawPortsByEntrypoint = portsByEntrypoint.get().value(mapper); if (rawPortsByEntrypoint.containsKey(key)) { throw new IllegalStateException("Port for key " + key + " is already set. It's port " + rawPortsByEntrypoint.get(key)); } if (rawPortsByEntrypoint.size() >= (maxGeneratedPort - minGeneratedPort)) { throw new IllegalStateException("Can't create new port, all port are used between " + minGeneratedPort + " and " + maxGeneratedPort); } boolean portAlreadyUsed = true; while (portAlreadyUsed) { newPort = random.nextInt(maxGeneratedPort - minGeneratedPort) + minGeneratedPort; portAlreadyUsed = rawPortsByEntrypoint.values().contains(newPort); } rawPortsByEntrypoint.put(key, newPort); putPortById = new HttpPut("http: String encodedJson = encodeJson(rawPortsByEntrypoint); putPortById.setEntity(new StringEntity(encodedJson)); } else { newPort = random.nextInt(maxGeneratedPort - minGeneratedPort) + minGeneratedPort; Map<String, Integer> rawPortsByEntrypoint = new HashMap<>(); rawPortsByEntrypoint.put(key, newPort); putPortById = new HttpPut("http: String encodedJson = encodeJson(rawPortsByEntrypoint); putPortById.setEntity(new StringEntity(encodedJson)); } failToPutNewPort = !client.execute(putPortById, httpResponse -> consulReader.parseHttpResponse(httpResponse, consulReader::parseBooleanFromHttpEntity)) .orElseThrow((Supplier<RuntimeException>) () -> new IllegalStateException("can't parse boolean value")); } } catch (IOException e) { throw new RuntimeException(e); } return newPort; } ConsulRepository(String host, int port, int minGeneratedPort, int maxGeneratedPort);   ConsulRepository(String host, int port, int minGeneratedPort, int maxGeneratedPort, ObjectMapper mapper, ConsulReader consulReader, CloseableHttpClient client); @Override boolean lock(EntryPointKey entryPointKey); @Override boolean isAutoreloaded(EntryPointKey entryPointKey); @Override void release(EntryPointKey key); @Override Optional<EntryPoint> getCurrentConfiguration(EntryPointKey key); @Override Set<String> getEntryPointsId(); @Override Optional<EntryPoint> getPendingConfiguration(EntryPointKey key); @Override Optional<EntryPoint> getCommittingConfiguration(EntryPointKey key); @Override void setPendingConfiguration(EntryPointKey key, EntryPoint configuration); @Override void removePendingConfiguration(EntryPointKey key); @Override boolean setCommittingConfiguration(String correlationId, EntryPointKey entryPointKey, EntryPoint configuration, int ttl); @Override void removeCommittingConfiguration(EntryPointKey key); @Override Optional<Boolean> removeEntrypoint(EntryPointKey entryPointKey); @Override void setCurrentConfiguration(EntryPointKey key, EntryPoint configuration); @Override void init(); @Override Optional<Map<String, Integer>> getPorts(); @Override Optional<Integer> getPort(String key); @Override Integer newPort(String key); @Override Optional<Map<String, String>> getHaproxyProperties(String haproxyId); @Override Optional<Map<String, String>> getHaproxyPropertiesAndAccepting404(String haproxyId); @Override Set<String> getHaproxyVersions(); @Override void addVersion(String haproxyVersion); @Override List<Map<String, String>> getHaproxyProperties(); @Override boolean isAutoreload(String haproxyId); @Override Set<String> getHaproxyIds(); @Override void setHaproxyProperty(String haproxyId, String key, String value); @Override Optional<String> getHaproxyProperty(String haproxyId, String key); @Override Optional<String> getCommitCorrelationId(EntryPointKey key); @Override void setAutoreload(EntryPointKey entryPointKey, Boolean autoreload); void shutdown();  }
@Test(expected = IllegalStateException.class) public void should_throw_exception_if_all_port_used() throws IOException { ConsulReader consulReader = mock(ConsulReader.class); CloseableHttpClient closeableHttpClient = mock(CloseableHttpClient.class); try { ConsulRepository consulRepository = new ConsulRepository("localhost", 50080, 32_000, 32_003, new ObjectMapper(), consulReader, closeableHttpClient); ConsulItem<Map<String, Integer>> consulItem = new ConsulItem<>(1, "/key", 1L, new BASE64Encoder().encode("{\"ep1\":\"1\",\"ep2\":\"2\",\"ep3\":\"3\",\"ep4\":\"4\"}".getBytes()), 1L, 1L); when(closeableHttpClient.execute(any(HttpRequestBase.class), any(ResponseHandler.class))).thenReturn(Optional.of(consulItem), Optional.empty(), Optional.empty()); consulRepository.newPort("test"); } finally { verify(closeableHttpClient, times(1)).execute(any(HttpRequestBase.class), any(ResponseHandler.class)); } }