diff options
Diffstat (limited to 'sdnr/wt/common/src')
11 files changed, 734 insertions, 410 deletions
diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.java index 0998e301e..1ece24161 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/HtAssert.java @@ -22,9 +22,14 @@ package org.onap.ccsdk.features.sdnr.wt.common; import java.util.Arrays; - +/** + * + * @author Michael Dürre + * + */ public class HtAssert { + public static class HtNullable<T> { } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java index 1ed74a1eb..2aee0f8e6 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/Resources.java @@ -31,66 +31,76 @@ import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * + * @author Michael Dürre + * + * class to get access to internal jar resources + */ public class Resources { - private static final Logger LOG = LoggerFactory.getLogger(Resources.class); + // constants + private static final Logger LOG = LoggerFactory.getLogger(Resources.class); + // end of constants - private static URL getFileURL(Class<?> cls,String resFile) { - Bundle b = FrameworkUtil.getBundle(cls); - URL u = null; - LOG.debug("try to get file {}", resFile); - if (b == null) { - LOG.info("Load resource as file: {}", resFile); - u = getUrlForRessource(cls,resFile); - } else { - LOG.info("Load resource from bundle: {}", resFile); - u = b.getEntry(resFile); - } - return u; - } + // static methods + private static URL getFileURL(Class<?> cls, String resFile) { + Bundle b = FrameworkUtil.getBundle(cls); + URL u = null; + LOG.debug("try to get file {}", resFile); + if (b == null) { + LOG.info("Load resource as file: {}", resFile); + u = getUrlForRessource(cls, resFile); + } else { + LOG.info("Load resource from bundle: {}", resFile); + u = b.getEntry(resFile); + } + return u; + } - private static String readFile(final URL u) throws IOException { - return readFile(u.openStream()); - } + private static String readFile(final URL u) throws IOException { + return readFile(u.openStream()); + } - private static String readFile(final InputStream s) throws IOException { - // read file - final String LR = "\n"; - BufferedReader in = new BufferedReader(new InputStreamReader(s)); - StringBuilder sb = new StringBuilder(); - String inputLine; - while ((inputLine = in.readLine()) != null) { - sb.append(inputLine+LR); - } - in.close(); - s.close(); - return sb.toString(); - } + private static String readFile(final InputStream s) throws IOException { + // read file + final String LR = "\n"; + BufferedReader in = new BufferedReader(new InputStreamReader(s)); + StringBuilder sb = new StringBuilder(); + String inputLine; + while ((inputLine = in.readLine()) != null) { + sb.append(inputLine + LR); + } + in.close(); + s.close(); + return sb.toString(); + } - public static String getFileContent( Class<?> cls, String resFile) { - LOG.debug("loading file {} from res", resFile); - URL u = getFileURL(cls,resFile); - String s=null; - if (u == null) { - LOG.warn("cannot find resfile: {}", resFile); - return null; - } - try { - s=readFile(u); - } catch (Exception e) { - LOG.warn("problem reading file: {}", e.getMessage()); - } - return s; + public static String getFileContent(Class<?> cls, String resFile) { + LOG.debug("loading file {} from res", resFile); + URL u = getFileURL(cls, resFile); + String s = null; + if (u == null) { + LOG.warn("cannot find resfile: {}", resFile); + return null; + } + try { + s = readFile(u); + } catch (Exception e) { + LOG.warn("problem reading file: {}", e.getMessage()); + } + return s; - } + } - public static URL getUrlForRessource(Class<?> cls,String fileOrDirectory) { - //ClassLoader loader = Thread.currentThread().getContextClassLoader(); - ClassLoader loader = cls.getClassLoader(); - URL url = loader.getResource(fileOrDirectory); - if(url==null && fileOrDirectory.startsWith("/")) { - url = loader.getResource(fileOrDirectory.substring(1)); - } - return url; - } + public static URL getUrlForRessource(Class<?> cls, String fileOrDirectory) { + //ClassLoader loader = Thread.currentThread().getContextClassLoader(); + ClassLoader loader = cls.getClassLoader(); + URL url = loader.getResource(fileOrDirectory); + if (url == null && fileOrDirectory.startsWith("/")) { + url = loader.getResource(fileOrDirectory.substring(1)); + } + return url; + } + // end of static methods } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/ConfigurationFileRepresentation.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/ConfigurationFileRepresentation.java index 0a432cb18..18a69f004 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/ConfigurationFileRepresentation.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/ConfigurationFileRepresentation.java @@ -43,20 +43,25 @@ import org.slf4j.LoggerFactory; */ public class ConfigurationFileRepresentation implements IConfigChangedListener { + // constants private static final Logger LOG = LoggerFactory.getLogger(ConfigurationFileRepresentation.class); private static final long FILE_POLL_INTERVAL_MS = 1000; private static final String SECTIONNAME_ROOT = ""; private static final String LR = "\n"; private static final String EMPTY = ""; + // end of constants + // variables /** Related configuration file **/ private final File mFile; /** Monitor changes of file **/ private final ConfigFileObserver fileObserver; /** List of sections **/ private final HashMap<String, Section> sections; + // end of variables + // constructors public ConfigurationFileRepresentation(File f) { this.mFile = f; @@ -80,11 +85,67 @@ public class ConfigurationFileRepresentation implements IConfigChangedListener { public ConfigurationFileRepresentation(String configurationfile) { this(new File(configurationfile)); } + // end of constructors + // getters and setters public synchronized Optional<Section> getSection(String name) { return Optional.ofNullable(sections.get(name)); } + // end of getters and setters + // private methods + private synchronized void reLoad() { + sections.clear(); + addSection(SECTIONNAME_ROOT); + load(); + } + + private synchronized void load() { + LOG.debug("loading file {}", getMFileName()); + String curSectionName = SECTIONNAME_ROOT; + Optional<Section> sectionOptional = this.getSection(curSectionName); + Section curSection = sectionOptional.isPresent() ? sectionOptional.get() : this.addSection(curSectionName); + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(this.mFile)); + for (String line; (line = br.readLine()) != null;) { + line = line.trim(); + if (line.isEmpty()) { + continue; + } + if (line.startsWith("[") && line.endsWith("]")) { + curSectionName = line.substring(1, line.length() - 1); + curSection = this.addSection(curSectionName); + } else { + curSection.addLine(line); + } + } + + } catch (Exception e) { + LOG.info("Problem loading configuration file. {} {}", getMFileName(), e); + } finally { + try { + if (br != null) { + br.close(); + } + } catch (IOException e) { + } + } + LOG.debug("finished loading file"); + LOG.debug("start parsing sections"); + for (Section section : this.sections.values()) { + section.parseLines(); + } + LOG.debug("finished parsing " + this.sections.size() + " sections"); + } + + private String getMFileName() { + return mFile.getAbsolutePath(); + } + + // end of private methods + + // public methods public synchronized Section addSection(String name) { if (this.sections.containsKey(name)) { return this.sections.get(name); @@ -94,12 +155,6 @@ public class ConfigurationFileRepresentation implements IConfigChangedListener { return s; } - private synchronized void reLoad() { - sections.clear(); - addSection(SECTIONNAME_ROOT); - load(); - } - public synchronized void save() { LOG.debug("Write configuration to {}", getMFileName()); try (BufferedWriter bw = new BufferedWriter(new FileWriter(this.mFile, false))) { @@ -188,50 +243,6 @@ public class ConfigurationFileRepresentation implements IConfigChangedListener { public synchronized boolean getPropertyBoolean(String section, String propertyKey) { return getProperty(section, propertyKey).equalsIgnoreCase("true"); } + // end of public methods - /* - * Private - */ - private synchronized void load() { - LOG.debug("loading file {}", getMFileName()); - String curSectionName = SECTIONNAME_ROOT; - Optional<Section> sectionOptional = this.getSection(curSectionName); - Section curSection = sectionOptional.isPresent() ? sectionOptional.get() : this.addSection(curSectionName); - BufferedReader br = null; - try { - br = new BufferedReader(new FileReader(this.mFile)); - for (String line; (line = br.readLine()) != null;) { - line = line.trim(); - if (line.isEmpty()) { - continue; - } - if (line.startsWith("[") && line.endsWith("]")) { - curSectionName = line.substring(1, line.length() - 1); - curSection = this.addSection(curSectionName); - } else { - curSection.addLine(line); - } - } - - } catch (Exception e) { - LOG.info("Problem loading configuration file. {} {}", getMFileName(), e); - } finally { - try { - if (br != null) { - br.close(); - } - } catch (IOException e) { - } - } - LOG.debug("finished loading file"); - LOG.debug("start parsing sections"); - for (Section section : this.sections.values()) { - section.parseLines(); - } - LOG.debug("finished parsing " + this.sections.size() + " sections"); - } - - private String getMFileName() { - return mFile.getAbsolutePath(); - } } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java index fd1e404a1..b6d277f76 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/Section.java @@ -32,24 +32,53 @@ import java.util.regex.Pattern; import org.onap.ccsdk.features.sdnr.wt.common.configuration.exception.ConversionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +/** + * + * @author Michael Dürre, Herbert Eiselt + * + * subset of configuration identified by its name + */ public class Section { + // constants private static final Logger LOG = LoggerFactory.getLogger(Section.class); private static final String DELIMITER = "="; private static final String COMMENTCHARS[] = {"#", ";"}; - + // end of constants + + // variables private final String name; private final List<String> rawLines; private final LinkedHashMap<String, SectionValue> values; - + // end of variables + + // constructors public Section(String name) { LOG.debug("new section created: '{}'", name); this.name = name; this.rawLines = new ArrayList<>(); this.values = new LinkedHashMap<>(); } + //end of constructors + + // getters and setters + public String getName() { + return name; + } + // end of getters and setters + // private methods + private boolean isCommentLine(String line) { + for (String c : COMMENTCHARS) { + if (line.startsWith(c)) { + return true; + } + } + return false; + } + // end of private methods + + // public methods public void addLine(String line) { LOG.trace("adding raw line:" + line); this.rawLines.add(line); @@ -90,9 +119,7 @@ public class Section { return value; } - public String getName() { - return name; - } + public void setProperty(String key, String value) { boolean isuncommented = this.isCommentLine(key); @@ -143,14 +170,7 @@ public class Section { } } - private boolean isCommentLine(String line) { - for (String c : COMMENTCHARS) { - if (line.startsWith(c)) { - return true; - } - } - return false; - } + public String[] toLines() { List<String> lines = new ArrayList<>(); @@ -222,5 +242,6 @@ public class Section { public String toString() { return "Section [name=" + name + ", rawLines=" + rawLines + ", values=" + values + "]"; } + // end of public methods } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/SectionValue.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/SectionValue.java index 5e3b533c0..3aacf9a40 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/SectionValue.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/configuration/subtypes/SectionValue.java @@ -23,13 +23,20 @@ package org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes; import java.util.ArrayList; import java.util.List; - +/** + * + * @author Michael Dürre, Herbert Eiselt + * + */ class SectionValue { + // variables private String value; private final List<String> comments; private boolean isUncommented; + // end of variables + // constructors public SectionValue(String value, List<String> commentsForValue, boolean isuncommented) { this.comments = commentsForValue; this.value = value; @@ -43,9 +50,9 @@ class SectionValue { public SectionValue(String value, boolean isUncommented) { this(value, new ArrayList<String>(), isUncommented); } - - /* Getter / Setter */ - + // end of constructors + + // getters and setters public String getValue() { return value; } @@ -67,11 +74,14 @@ class SectionValue { public List<String> getComments() { return comments; } - + // end of getters and setters + + // public methods @Override public String toString() { return "SectionValue [value=" + value + ", comments=" + comments + ", isUncommented=" + isUncommented + "]"; } + // end of public methods } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java index c10c4a65d..70b81990e 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java @@ -30,20 +30,19 @@ import java.security.cert.CertificateException; import java.security.spec.InvalidKeySpecException; import java.text.ParseException; -import javax.net.ssl.SSLContext; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.config.RequestConfig.Builder; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; import org.elasticsearch.client.Response; import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback; -import org.elasticsearch.client.RestClientBuilder.RequestConfigCallback; import org.json.JSONException; import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo; import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo.Protocol; @@ -66,7 +65,6 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.requests.RefreshIndexRequ import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; import org.onap.ccsdk.features.sdnr.wt.common.database.requests.UpdateByQueryRequest; import org.onap.ccsdk.features.sdnr.wt.common.database.requests.UpdateRequest; -import org.onap.ccsdk.features.sdnr.wt.common.database.responses.AcknowledgedResponse; import org.onap.ccsdk.features.sdnr.wt.common.database.responses.ClusterHealthResponse; import org.onap.ccsdk.features.sdnr.wt.common.database.responses.ClusterSettingsResponse; import org.onap.ccsdk.features.sdnr.wt.common.database.responses.CreateAliasResponse; @@ -91,272 +89,281 @@ import org.slf4j.LoggerFactory; public class ExtRestClient { - private static final Logger LOG = LoggerFactory.getLogger(ExtRestClient.class); - - private class BasicAuthHttpClientConfigCallback implements HttpClientConfigCallback { - - private final String basicAuthUsername; - private final String basicAuthPassword; - private final boolean trustAll; - - BasicAuthHttpClientConfigCallback(String username, String password, boolean trustAll) { - this.basicAuthUsername = username; - this.basicAuthPassword = password; - this.trustAll = trustAll; - } - - @Override - public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { - HttpAsyncClientBuilder httpAsyncClientBuilder = null; - try { - httpAsyncClientBuilder = httpClientBuilder.setSSLContext(BaseHTTPClient.setupSsl(this.trustAll)); - } catch (NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | CertificateException | KeyStoreException | InvalidKeySpecException | IOException e) { - LOG.warn("unable to init ssl context for db client: {}",e.getMessage()); - } - if (basicAuthPassword == null || basicAuthUsername == null) { - return httpAsyncClientBuilder; - } - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(AuthScope.ANY, - new UsernamePasswordCredentials(basicAuthUsername, basicAuthPassword)); - - return httpAsyncClientBuilder == null ? httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider) - : httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider); - } - - } - // private class SSLCercAuthHttpClientConfigCallback implements HttpClientConfigCallback { - // - // private final String certFilename; - // - // SSLCercAuthHttpClientConfigCallback(String certfile) { - // this.certFilename = certfile; - // } - // - // @Override - // public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { - // if (this.certFilename == null) { - // return httpClientBuilder; - // } - // - // char[] keystorePass = "MY PASSWORD".toCharArray(); - // - // FileInputStream fis = null; - // - // // Loading KEYSTORE in JKS format - // KeyStore keyStorePci = null; - // try { - // keyStorePci = KeyStore.getInstance(KeyStore.getDefaultType()); - // } catch (KeyStoreException e1) { - // LOG.warn("unable to load keystore: {}",e1); - // } - // if (keyStorePci != null) { - // try { - // fis = new FileInputStream(this.certFilename); - // keyStorePci.load(fis, keystorePass); - // } catch (Exception e) { - // LOG.error("Error loading keystore: " + this.certFilename); - // } finally { - // if (fis != null) { - // try { - // fis.close(); - // } catch (IOException e) { - // - // } - // } - // } - // } - // SSLContext sslcontext=null; - // try { - // sslcontext = SSLContexts.custom().loadKeyMaterial(keyStorePci, keystorePass).build(); - // } catch (KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException - // | KeyStoreException e) { - // LOG.warn("unable to load sslcontext: {}",e); - // } - // return httpClientBuilder.setSSLContext(sslcontext); - // } - // } - - private final RestClient client; - - protected ExtRestClient(HostInfo[] hosts) { - this(hosts, null, null,false); - } - - protected ExtRestClient(HostInfo[] hosts, String username, String password, boolean trustAll) { - this.client = RestClient.builder(get(hosts)) - .setHttpClientConfigCallback(new BasicAuthHttpClientConfigCallback(username, password,trustAll)) - .build(); - } - - public ClusterHealthResponse health(ClusterHealthRequest request) - throws UnsupportedOperationException, IOException, JSONException { - return new ClusterHealthResponse(this.client.performRequest(request.getInner())); - } - - public void close() throws IOException { - this.client.close(); - - } - - // - public boolean indicesExists(GetIndexRequest request) throws IOException { - Response response = this.client.performRequest(request.getInner()); - return response.getStatusLine().getStatusCode() == 200; - } - - public ClusterSettingsResponse setupClusterSettings(ClusterSettingsRequest request) throws IOException { - return new ClusterSettingsResponse(this.client.performRequest(request.getInner())); - } - public CreateAliasResponse updateAliases(CreateAliasRequest request) throws IOException { - return new CreateAliasResponse(this.client.performRequest(request.getInner())); - } - - public CreateIndexResponse createIndex(CreateIndexRequest request) throws IOException { - return new CreateIndexResponse(this.client.performRequest(request.getInner())); - } - - public CreateAliasResponse createAlias(CreateAliasRequest request) throws IOException { - return new CreateAliasResponse(this.client.performRequest(request.getInner())); - } - - public DeleteAliasResponse deleteAlias(DeleteAliasRequest request) throws IOException { - return new DeleteAliasResponse(this.client.performRequest(request.getInner())); - } - - public DeleteIndexResponse deleteIndex(DeleteIndexRequest request) throws IOException { - return new DeleteIndexResponse(this.client.performRequest(request.getInner())); - } - - public IndexResponse index(IndexRequest request) throws IOException { - return new IndexResponse(this.client.performRequest(request.getInner())); - } - - public DeleteResponse delete(DeleteRequest request) throws IOException { - Response response = null; - try { - response = this.client.performRequest(request.getInner()); - } catch (ResponseException e) { - new DeleteResponse(e.getResponse()); - } - return new DeleteResponse(response); - } - - public DeleteByQueryResponse deleteByQuery(DeleteByQueryRequest request) throws IOException { - Response response = null; - try { - response = this.client.performRequest(request.getInner()); - } catch (ResponseException e) { - new DeleteResponse(e.getResponse()); - } - return new DeleteByQueryResponse(response); - } - - public SearchResponse search(SearchRequest request) throws IOException { - return this.search(request, false); - } - - /** - * Search for database entries - * @param request inputRequest - * @param ignoreParseException especially for usercreated filters which may cause ES server response exceptions - * @return Response with related entries - * @throws IOException of client - */ - public SearchResponse search(SearchRequest request, boolean ignoreParseException) throws IOException { - if (ignoreParseException) { - try { - return new SearchResponse(this.client.performRequest(request.getInner())); - } catch (ResponseException e) { - LOG.debug("ignoring Exception for request {}: {}", request, e.getMessage()); - return new SearchResponse(e.getResponse()); - } - } else { - return new SearchResponse(this.client.performRequest(request.getInner())); - } - } - - public GetResponse get(GetRequest request) throws IOException { - try { - return new GetResponse(this.client.performRequest(request.getInner())); - } catch (ResponseException e) { - return new GetResponse(e.getResponse()); - } - } - - public UpdateByQueryResponse update(UpdateByQueryRequest request) throws IOException { - return new UpdateByQueryResponse(this.client.performRequest(request.getInner())); - - } - - public UpdateResponse update(UpdateRequest request) throws IOException { - return new UpdateResponse(this.client.performRequest(request.getInner())); - - } - - public RefreshIndexResponse refreshIndex(RefreshIndexRequest request) throws IOException { - return new RefreshIndexResponse(this.client.performRequest(request.getInner())); - } - - public NodeStatsResponse stats(NodeStatsRequest request) throws IOException { - return new NodeStatsResponse(this.client.performRequest(request.getInner())); - } - - public ListIndicesResponse getIndices() throws ParseException, IOException { - return new ListIndicesResponse(this.client.performRequest(new ListIndicesRequest().getInner())); - } - - public ListAliasesResponse getAliases() throws ParseException, IOException { - return new ListAliasesResponse(this.client.performRequest(new ListAliasesRequest().getInner())); - } - - public GetInfoResponse getInfo() throws IOException, Exception { - return new GetInfoResponse(this.client.performRequest(new GetInfoRequest().getInner())); - } - - public boolean waitForYellowStatus(long timeoutms) { - - ClusterHealthRequest request = new ClusterHealthRequest(); - request.timeout(timeoutms / 1000); - ClusterHealthResponse response = null; - String status = ""; - try { - response = this.health(request); - - } catch (UnsupportedOperationException | IOException | JSONException e) { - LOG.error(e.getMessage()); - } - if (response != null) { - status = response.getStatus(); - LOG.debug("Elasticsearch service started with status {}", response.getStatus()); - - } else { - LOG.warn("Elasticsearch service not started yet with status {}. current status is {}", status, "none"); - return false; - } - return response.isStatusMinimal(ClusterHealthResponse.HEALTHSTATUS_YELLOW); - - } - - private static HttpHost[] get(HostInfo[] hosts) { - HttpHost[] httphosts = new HttpHost[hosts.length]; - for (int i = 0; i < hosts.length; i++) { - httphosts[i] = new HttpHost(hosts[i].hostname, hosts[i].port, hosts[i].protocol.toString()); - } - return httphosts; - } - - public static ExtRestClient createInstance(HostInfo[] hosts) { - return new ExtRestClient(hosts); - } - - public static ExtRestClient createInstance(HostInfo[] hosts, String username, String password,boolean trustAll) { - return new ExtRestClient(hosts, username, password, trustAll); - } - - public static ExtRestClient createInstance(String hostname, int port, Protocol protocol) { - return createInstance(new HostInfo[] { new HostInfo(hostname, port, protocol) }); - - } + private static final Logger LOG = LoggerFactory.getLogger(ExtRestClient.class); + + private class BasicAuthHttpClientConfigCallback implements HttpClientConfigCallback { + + private final String basicAuthUsername; + private final String basicAuthPassword; + private final boolean trustAll; + + BasicAuthHttpClientConfigCallback(String username, String password, boolean trustAll) { + this.basicAuthUsername = username; + this.basicAuthPassword = password; + this.trustAll = trustAll; + } + + @Override + public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + HttpAsyncClientBuilder httpAsyncClientBuilder = null; + try { + httpAsyncClientBuilder = httpClientBuilder.setSSLContext(BaseHTTPClient.setupSsl(this.trustAll)); + if(this.trustAll) { + httpAsyncClientBuilder.setSSLHostnameVerifier(new HostnameVerifier() { + + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + } + } catch (NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | CertificateException | KeyStoreException | InvalidKeySpecException | IOException e) { + LOG.warn("unable to init ssl context for db client: {}",e.getMessage()); + } + if (basicAuthPassword == null || basicAuthUsername == null) { + return httpAsyncClientBuilder; + } + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, + new UsernamePasswordCredentials(basicAuthUsername, basicAuthPassword)); + + return httpAsyncClientBuilder == null ? httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider) + : httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + + } + // private class SSLCercAuthHttpClientConfigCallback implements HttpClientConfigCallback { + // + // private final String certFilename; + // + // SSLCercAuthHttpClientConfigCallback(String certfile) { + // this.certFilename = certfile; + // } + // + // @Override + // public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + // if (this.certFilename == null) { + // return httpClientBuilder; + // } + // + // char[] keystorePass = "MY PASSWORD".toCharArray(); + // + // FileInputStream fis = null; + // + // // Loading KEYSTORE in JKS format + // KeyStore keyStorePci = null; + // try { + // keyStorePci = KeyStore.getInstance(KeyStore.getDefaultType()); + // } catch (KeyStoreException e1) { + // LOG.warn("unable to load keystore: {}",e1); + // } + // if (keyStorePci != null) { + // try { + // fis = new FileInputStream(this.certFilename); + // keyStorePci.load(fis, keystorePass); + // } catch (Exception e) { + // LOG.error("Error loading keystore: " + this.certFilename); + // } finally { + // if (fis != null) { + // try { + // fis.close(); + // } catch (IOException e) { + // + // } + // } + // } + // } + // SSLContext sslcontext=null; + // try { + // sslcontext = SSLContexts.custom().loadKeyMaterial(keyStorePci, keystorePass).build(); + // } catch (KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException + // | KeyStoreException e) { + // LOG.warn("unable to load sslcontext: {}",e); + // } + // return httpClientBuilder.setSSLContext(sslcontext); + // } + // } + + private final RestClient client; + + protected ExtRestClient(HostInfo[] hosts) { + this(hosts, null, null,false); + } + + protected ExtRestClient(HostInfo[] hosts, String username, String password, boolean trustAll) { + this.client = RestClient.builder(get(hosts)) + .setHttpClientConfigCallback(new BasicAuthHttpClientConfigCallback(username, password,trustAll)) + .build(); + } + + public ClusterHealthResponse health(ClusterHealthRequest request) + throws UnsupportedOperationException, IOException, JSONException { + return new ClusterHealthResponse(this.client.performRequest(request.getInner())); + } + + public void close() throws IOException { + this.client.close(); + + } + + // + public boolean indicesExists(GetIndexRequest request) throws IOException { + Response response = this.client.performRequest(request.getInner()); + return response.getStatusLine().getStatusCode() == 200; + } + + public ClusterSettingsResponse setupClusterSettings(ClusterSettingsRequest request) throws IOException { + return new ClusterSettingsResponse(this.client.performRequest(request.getInner())); + } + public CreateAliasResponse updateAliases(CreateAliasRequest request) throws IOException { + return new CreateAliasResponse(this.client.performRequest(request.getInner())); + } + + public CreateIndexResponse createIndex(CreateIndexRequest request) throws IOException { + return new CreateIndexResponse(this.client.performRequest(request.getInner())); + } + + public CreateAliasResponse createAlias(CreateAliasRequest request) throws IOException { + return new CreateAliasResponse(this.client.performRequest(request.getInner())); + } + + public DeleteAliasResponse deleteAlias(DeleteAliasRequest request) throws IOException { + return new DeleteAliasResponse(this.client.performRequest(request.getInner())); + } + + public DeleteIndexResponse deleteIndex(DeleteIndexRequest request) throws IOException { + return new DeleteIndexResponse(this.client.performRequest(request.getInner())); + } + + public IndexResponse index(IndexRequest request) throws IOException { + return new IndexResponse(this.client.performRequest(request.getInner())); + } + + public DeleteResponse delete(DeleteRequest request) throws IOException { + Response response = null; + try { + response = this.client.performRequest(request.getInner()); + } catch (ResponseException e) { + new DeleteResponse(e.getResponse()); + } + return new DeleteResponse(response); + } + + public DeleteByQueryResponse deleteByQuery(DeleteByQueryRequest request) throws IOException { + Response response = null; + try { + response = this.client.performRequest(request.getInner()); + } catch (ResponseException e) { + new DeleteResponse(e.getResponse()); + } + return new DeleteByQueryResponse(response); + } + + public SearchResponse search(SearchRequest request) throws IOException { + return this.search(request, false); + } + + /** + * Search for database entries + * @param request inputRequest + * @param ignoreParseException especially for usercreated filters which may cause ES server response exceptions + * @return Response with related entries + * @throws IOException of client + */ + public SearchResponse search(SearchRequest request, boolean ignoreParseException) throws IOException { + if (ignoreParseException) { + try { + return new SearchResponse(this.client.performRequest(request.getInner())); + } catch (ResponseException e) { + LOG.debug("ignoring Exception for request {}: {}", request, e.getMessage()); + return new SearchResponse(e.getResponse()); + } + } else { + return new SearchResponse(this.client.performRequest(request.getInner())); + } + } + + public GetResponse get(GetRequest request) throws IOException { + try { + return new GetResponse(this.client.performRequest(request.getInner())); + } catch (ResponseException e) { + return new GetResponse(e.getResponse()); + } + } + + public UpdateByQueryResponse update(UpdateByQueryRequest request) throws IOException { + return new UpdateByQueryResponse(this.client.performRequest(request.getInner())); + + } + + public UpdateResponse update(UpdateRequest request) throws IOException { + return new UpdateResponse(this.client.performRequest(request.getInner())); + + } + + public RefreshIndexResponse refreshIndex(RefreshIndexRequest request) throws IOException { + return new RefreshIndexResponse(this.client.performRequest(request.getInner())); + } + + public NodeStatsResponse stats(NodeStatsRequest request) throws IOException { + return new NodeStatsResponse(this.client.performRequest(request.getInner())); + } + + public ListIndicesResponse getIndices() throws ParseException, IOException { + return new ListIndicesResponse(this.client.performRequest(new ListIndicesRequest().getInner())); + } + + public ListAliasesResponse getAliases() throws ParseException, IOException { + return new ListAliasesResponse(this.client.performRequest(new ListAliasesRequest().getInner())); + } + + public GetInfoResponse getInfo() throws IOException, Exception { + return new GetInfoResponse(this.client.performRequest(new GetInfoRequest().getInner())); + } + + public boolean waitForYellowStatus(long timeoutms) { + + ClusterHealthRequest request = new ClusterHealthRequest(); + request.timeout(timeoutms / 1000); + ClusterHealthResponse response = null; + String status = ""; + try { + response = this.health(request); + + } catch (UnsupportedOperationException | IOException | JSONException e) { + LOG.error("Exception", e); + } + if (response != null) { + status = response.getStatus(); + LOG.debug("Elasticsearch service started with status {}", response.getStatus()); + + } else { + LOG.warn("Elasticsearch service not started yet with status {}. current status is {}", status, "none"); + return false; + } + return response.isStatusMinimal(ClusterHealthResponse.HEALTHSTATUS_YELLOW); + + } + + private static HttpHost[] get(HostInfo[] hosts) { + HttpHost[] httphosts = new HttpHost[hosts.length]; + for (int i = 0; i < hosts.length; i++) { + httphosts[i] = new HttpHost(hosts[i].hostname, hosts[i].port, hosts[i].protocol.toString()); + } + return httphosts; + } + + public static ExtRestClient createInstance(HostInfo[] hosts) { + return new ExtRestClient(hosts); + } + + public static ExtRestClient createInstance(HostInfo[] hosts, String username, String password,boolean trustAll) { + return new ExtRestClient(hosts, username, password, trustAll); + } + + public static ExtRestClient createInstance(String hostname, int port, Protocol protocol) { + return createInstance(new HostInfo[] { new HostInfo(hostname, port, protocol) }); + + } } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/Portstatus.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/Portstatus.java new file mode 100644 index 000000000..ed6c95fd2 --- /dev/null +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/Portstatus.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) Apache Camel project + * ================================================================================================= + * Licensed 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. + * ============LICENSE_END========================================================================== + ******************************************************************************/ + +package org.onap.ccsdk.features.sdnr.wt.common.database; + +import java.io.IOException; +import java.net.Socket; +import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo; + +public class Portstatus { + + public static final int MIN_PORT_NUMBER = 0; + public static final int MAX_PORT_NUMBER = 65535; + + /** + * Checks to see if a specific port is available. + * + * @param port the port to check for availability + */ + public static boolean isAvailable(String dnsName, int port) { + if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) { + throw new IllegalArgumentException("Invalid start port: " + port); + } + + Socket ss = null; + try { + ss = new Socket(dnsName, port); + ss.setReuseAddress(true); + return true; + } catch (IOException e) { + } finally { + if (ss != null) { + try { + ss.close(); + } catch (IOException e) { + /* should not be thrown */ + } + } + } + + return false; + } + + public static boolean isAvailable(HostInfo... hosts) { + for (HostInfo host : hosts) { + if (!isAvailable(host.hostname, host.port)) { + return false; + } + } + return true; + } + + public static boolean waitSecondsTillAvailable(long timeoutSeconds, HostInfo... hosts) { + + if (timeoutSeconds < 0) { + throw new IllegalArgumentException("Invalid timeout: " + timeoutSeconds); + } + long waitSeconds = 0; + boolean res = false; + while ( (timeoutSeconds == 0 || ++waitSeconds < timeoutSeconds) && !(res = isAvailable(hosts))) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + return res; + } + + public static boolean waitSecondsTillAvailable(long timeoutSeconds, String dnsName, int port ) { + return waitSecondsTillAvailable(timeoutSeconds, new HostInfo(dnsName, port)); + } + +} diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/BoolQueryBuilder.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/BoolQueryBuilder.java index d087867d7..b362c4684 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/BoolQueryBuilder.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/BoolQueryBuilder.java @@ -39,25 +39,51 @@ public class BoolQueryBuilder extends QueryBuilder { return "BoolQueryBuilder [inner=" + inner + "]"; } + public static boolean isEmpty(JSONObject o) { + return o.keySet().size() <= 0; + } + public BoolQueryBuilder must(QueryBuilder query) { - - if(this.inner.has("must") || this.inner.has("match") || this.inner.has("regexp") || this.inner.has("range")) { - Object x = this.inner.has("must") ?this.inner.get("must"):this.inner; - if(x instanceof JSONArray) { - ((JSONArray)x).put(query.getInner()); - } - else { + + if (!isEmpty(this.inner)) { + Object x = this.inner.has("must") ? this.inner.get("must") : this.inner; + if (x instanceof JSONArray) { + ((JSONArray) x).put(query.getInner()); + } else { this.inner = new JSONObject(); this.inner.put("must", new JSONObject()); - JSONArray a=new JSONArray(); + JSONArray a = new JSONArray(); a.put(x); a.put(query.getInner()); this.inner.put("must", a); } + } else { + this.inner.put("must", query.getInner()); } - - else { - this.inner = query.getInner(); + this.setQuery("bool", this.inner); + return this; + } + + /** + * @param query + */ + public BoolQueryBuilder should(QueryBuilder query) { + if (!isEmpty(this.inner)) { + Object x = this.inner.has("should") ? this.inner.get("should") : this.inner; + if (x instanceof JSONArray) { + ((JSONArray) x).put(query.getInner()); + } else { + this.inner = new JSONObject(); + // this.inner.put("should", new JSONObject()); + JSONArray a = new JSONArray(); + if (!x.toString().equals("{}")) { + a.put(x); + } + a.put(query.getInner()); + this.inner.put("should", a); + } + } else { + this.inner.put("should", query.getInner()); } this.setQuery("bool", this.inner); return this; diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java index 82ff47175..4d5b20037 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java @@ -47,4 +47,14 @@ public class QueryBuilders { public static RegexQueryBuilder regex(String propertyName, String re) { return new RegexQueryBuilder().add(propertyName, re); } + /** + * @param object + * @return + */ + public static QueryBuilder searchAllFieldsQuery(String filter) { + JSONObject inner = new JSONObject(); + inner.put("default_field", "*"); + inner.put("query", filter==null?"":filter); + return new QueryBuilder().setQuery("query_string", inner); + } } diff --git a/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbQueries.java b/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbQueries.java index 21c68b3ae..93d4b1af6 100644 --- a/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbQueries.java +++ b/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestDbQueries.java @@ -52,7 +52,7 @@ public class TestDbQueries { "}"; private static final String MATCH_QUERY_KEY2 = "node-id"; private static final Object MATCH_QUERY_VALUE2 = "sim2"; - private static final String BOOL_QUERY = "{\n" + + private static final String BOOL_QUERY_MUST = "{\n" + " \"query\": {\n" + " \"bool\": {\n" + " \"must\": [\n" + @@ -70,6 +70,46 @@ public class TestDbQueries { " }\n" + " }\n" + "}"; + private static final String BOOL_QUERY_MUST_SINGLE = "{\n" + + " \"query\": {\n" + + " \"bool\": {\n" + + " \"must\": {\n" + + " \"match\": {\n" + + " \""+MATCH_QUERY_KEY+"\": "+MATCH_QUERY_VALUE+"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + private static final String BOOL_QUERY_SHOULD = "{\n" + + " \"query\": {\n" + + " \"bool\": {\n" + + " \"should\": [\n" + + " {\n" + + " \"match\": {\n" + + " \""+MATCH_QUERY_KEY+"\": "+MATCH_QUERY_VALUE+"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"match\": {\n" + + " \""+MATCH_QUERY_KEY2+"\":"+MATCH_QUERY_VALUE2+" \n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + "}"; + private static final String BOOL_QUERY_SHOULD_SINGLE = "{\n" + + " \"query\": {\n" + + " \"bool\": {\n" + + " \"should\": {\n" + + " \"match\": {\n" + + " \""+MATCH_QUERY_KEY+"\": "+MATCH_QUERY_VALUE+"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; private static final String RANGE_QUERY_KEY = "timestamp"; private static final String RANGE_QUERY_LTEND = "2017-08-10T20:00:00.0Z"; private static final String RANGE_QUERY = "{\n" + @@ -189,13 +229,32 @@ public class TestDbQueries { testEquals("match query is wrong", MATCH_QUERY, QueryBuilders.matchQuery(MATCH_QUERY_KEY, MATCH_QUERY_VALUE)); } @Test - public void testBool() { - testEquals("bool query is wrong", BOOL_QUERY, + public void testBoolMust() { + testEquals("bool query is wrong", BOOL_QUERY_MUST, QueryBuilders.boolQuery(). must(QueryBuilders.matchQuery(MATCH_QUERY_KEY, MATCH_QUERY_VALUE)). must(QueryBuilders.matchQuery(MATCH_QUERY_KEY2, MATCH_QUERY_VALUE2))); } @Test + public void testBoolMustSingle() { + testEquals("bool single query is wrong", BOOL_QUERY_MUST_SINGLE, + QueryBuilders.boolQuery(). + must(QueryBuilders.matchQuery(MATCH_QUERY_KEY, MATCH_QUERY_VALUE))); + } + @Test + public void testBoolShould() { + testEquals("bool query is wrong", BOOL_QUERY_SHOULD, + QueryBuilders.boolQuery(). + should(QueryBuilders.matchQuery(MATCH_QUERY_KEY, MATCH_QUERY_VALUE)). + should(QueryBuilders.matchQuery(MATCH_QUERY_KEY2, MATCH_QUERY_VALUE2))); + } + @Test + public void testBoolShouldSingle() { + testEquals("bool single query is wrong", BOOL_QUERY_SHOULD_SINGLE, + QueryBuilders.boolQuery(). + should(QueryBuilders.matchQuery(MATCH_QUERY_KEY, MATCH_QUERY_VALUE))); + } + @Test public void testRange() { testEquals("range query is wrong", RANGE_QUERY, QueryBuilders.rangeQuery(RANGE_QUERY_KEY).lte(RANGE_QUERY_LTEND)); diff --git a/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestPortstatus.java b/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestPortstatus.java new file mode 100644 index 000000000..379142db2 --- /dev/null +++ b/sdnr/wt/common/src/test/java/org/onap/ccsdk/features/sdnr/wt/common/test/TestPortstatus.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed 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. + * ============LICENSE_END========================================================================== + ******************************************************************************/ +package org.onap.ccsdk.features.sdnr.wt.common.test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.ServerSocket; +import java.time.Duration; +import java.time.Instant; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.ccsdk.features.sdnr.wt.common.database.Portstatus; +import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo; + +public class TestPortstatus extends Mockito{ + + + @Test + public void testIsAvailable() throws IOException { + assertFalse("Port status should be false", Portstatus.isAvailable("localhost", 4567) ); + ServerSocket serverSocket = new ServerSocket(4567); + assertTrue("Port status should be true", Portstatus.isAvailable("localhost", 4567) ); + serverSocket.close(); + } + + @Test + public void testWaitIsAvailable() throws IOException { + ServerSocket serverSocket = new ServerSocket(4567); + assertTrue("Port status should be true", Portstatus.waitSecondsTillAvailable(5, "localhost", 4567) ); + serverSocket.close(); + } + + @Test + public void testWaitIsAvailableHostInfo() throws IOException { + ServerSocket serverSocket = new ServerSocket(4567); + assertTrue("Port status should be true", Portstatus.waitSecondsTillAvailable(5, new HostInfo("localhost", 4567)) ); + serverSocket.close(); + } + + @Test + public void testWaitTillAvailable() throws IOException { + Instant start = Instant.now(); + assertFalse("Port status should be false", Portstatus.waitSecondsTillAvailable(5, "localhost", 4567) ); + Instant end = Instant.now(); + long seconds = Duration.between(start, end).getSeconds(); + assertTrue("Port status timeout 5 expected and not between 3 .. 7 seconds", 3 < seconds && seconds < 7 ); + } + + @Test + public void testWaitTillAvailableHostinfo() throws IOException { + Instant start = Instant.now(); + assertFalse("Port status should be false", Portstatus.waitSecondsTillAvailable(5, new HostInfo("localhost", 4567))); + Instant end = Instant.now(); + long seconds = Duration.between(start, end).getSeconds(); + assertTrue("Port status timeout 5 expected and not between 3 .. 7 seconds", 3 < seconds && seconds < 7 ); + } + + +} |