Skip to content

Commit

Permalink
feat: add methods to verify service invocation
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre CHRISTIN <[email protected]>
  • Loading branch information
pierrechristinimsa committed Dec 24, 2024
1 parent bb4fa6e commit 043602c
Show file tree
Hide file tree
Showing 3 changed files with 358 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.github.microcks.testcontainers;

import io.github.microcks.testcontainers.model.DailyInvocationStatistic;
import io.github.microcks.testcontainers.model.RequestResponsePair;
import io.github.microcks.testcontainers.model.Secret;
import io.github.microcks.testcontainers.model.TestResult;
Expand All @@ -30,6 +31,7 @@
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
import org.testcontainers.shaded.com.github.dockerjava.core.MediaType;
import org.testcontainers.shaded.com.google.common.net.HttpHeaders;
import org.testcontainers.shaded.com.google.common.net.UrlEscapers;
import org.testcontainers.shaded.org.awaitility.Awaitility;
import org.testcontainers.shaded.org.awaitility.core.ConditionTimeoutException;
import org.testcontainers.utility.DockerImageName;
Expand All @@ -43,6 +45,7 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
Expand Down Expand Up @@ -561,6 +564,73 @@ public void downloadAsSecondaryRemoteArtifact(String remoteArtifactUrl) throws A
downloadArtifact(remoteArtifactUrl, false);
}

/**
* Verifies that given Service has been invoked at least one time.
* @param serviceName
* @param serviceVersion
* @return
*/
public boolean verify(String serviceName, String serviceVersion) {
DailyInvocationStatistic dailyInvocationStatistic = getServiceInvocations(getHttpEndpoint(), serviceName, serviceVersion);

if (dailyInvocationStatistic == null) {
return false;
}

BigDecimal count = dailyInvocationStatistic.getDailyCount();

return count != null && count.intValue() != 0;
}

/**
* Get the invocations' count for a given service name and version.
* @param serviceName
* @param serviceVersion
* @return
*/
public Long getServiceInvocationsCount(String serviceName, String serviceVersion) {
DailyInvocationStatistic dailyInvocationStatistic = getServiceInvocations(getHttpEndpoint(), serviceName, serviceVersion);

if (dailyInvocationStatistic == null) {
return 0L;
}

BigDecimal count = dailyInvocationStatistic.getDailyCount();

return count.longValue();
}


/**
*
* @param microcksContainerHttpEndpoint
* @param serviceName
* @param serviceVersion
* @return
*/
private static DailyInvocationStatistic getServiceInvocations(String microcksContainerHttpEndpoint, String serviceName, String serviceVersion) {
String encodedServiceName = UrlEscapers.urlFragmentEscaper().escape(serviceName);
String encodedServiceVersion = UrlEscapers.urlFragmentEscaper().escape(serviceVersion);

String restApiURL = microcksContainerHttpEndpoint + "/api/metrics/invocations/" + encodedServiceName + "/" + encodedServiceVersion;

try {
Thread.sleep(100); // to avoid race condition issue when requesting Microcks Metrics REST API
} catch (InterruptedException e) {
log.warn("Failed to sleep before calling Microcks API", e);
Thread.currentThread().interrupt();
}

try {
StringBuilder content = getFromRestApi(restApiURL);
return content.length() == 0 ? null : getMapper().readValue(content.toString(), DailyInvocationStatistic.class);
} catch (IOException e) {
log.warn("Failed to get service's invocations at address " + restApiURL, e);
}

return null;
}

private void importArtifact(String artifactPath, boolean mainArtifact) {
URL resource = Thread.currentThread().getContextClassLoader().getResource(artifactPath);
if (resource == null) {
Expand Down Expand Up @@ -727,8 +797,20 @@ private static HttpURLConnection uploadFileToMicrocks(URL microcksApiURL, File f
}

private static TestResult refreshTestResult(String microcksContainerHttpEndpoint, String testResultId) throws IOException {
StringBuilder content = getFromRestApi(microcksContainerHttpEndpoint + "/api/tests/" + testResultId);

return getMapper().readValue(content.toString(), TestResult.class);
}

/**
*
* @param restApiURL
* @return
* @throws IOException
*/
private static StringBuilder getFromRestApi(String restApiURL) throws IOException {
// Build a new client on correct API endpoint.
URL url = new URL(microcksContainerHttpEndpoint + "/api/tests/" + testResultId);
URL url = new URL(restApiURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("Accept", "application/json");
Expand All @@ -742,10 +824,10 @@ private static TestResult refreshTestResult(String microcksContainerHttpEndpoint
content.append(inputLine);
}
}

// Disconnect Http connection.
httpConn.disconnect();

return getMapper().readValue(content.toString(), TestResult.class);
return content;
}

public static class ArtifactLoadException extends RuntimeException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
/*
* Microcks API v1.10
* API offered by Microcks, the Kubernetes native tool for API and microservices mocking and testing (microcks.io)
*
* The version of the OpenAPI document: 1.10.0
* Contact: [email protected]
*
* NOTE: This class comes from microcks-java-client https://github.com/microcks/microcks-java-client
*/
package io.github.microcks.testcontainers.model;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* The daily statistic of a service mock invocations
*/
public class DailyInvocationStatistic {
public static final String JSON_PROPERTY_ID = "id";
private String id;

public static final String JSON_PROPERTY_DAY = "day";
private String day;

public static final String JSON_PROPERTY_SERVICE_NAME = "serviceName";
private String serviceName;

public static final String JSON_PROPERTY_SERVICE_VERSION = "serviceVersion";
private String serviceVersion;

public static final String JSON_PROPERTY_DAILY_COUNT = "dailyCount";
private BigDecimal dailyCount;

public static final String JSON_PROPERTY_HOURLY_COUNT = "hourlyCount";
private Map<String, Object> hourlyCount = new HashMap<>();

public static final String JSON_PROPERTY_MINUTE_COUNT = "minuteCount";
private Map<String, Object> minuteCount = new HashMap<>();

public DailyInvocationStatistic() {
}

public DailyInvocationStatistic id(String id) {
this.id = id;
return this;
}

/**
* Unique identifier of this statistic object
* @return id
*/
@JsonProperty(JSON_PROPERTY_ID)
public String getId() {
return id;
}


@JsonProperty(JSON_PROPERTY_ID)
public void setId(String id) {
this.id = id;
}


public DailyInvocationStatistic day(String day) {
this.day = day;
return this;
}

/**
* The day (formatted as yyyyMMdd string) represented by this statistic
* @return day
*/
@JsonProperty(JSON_PROPERTY_DAY)
public String getDay() {
return day;
}


@JsonProperty(JSON_PROPERTY_DAY)
public void setDay(String day) {
this.day = day;
}


public DailyInvocationStatistic serviceName(String serviceName) {
this.serviceName = serviceName;
return this;
}

/**
* The name of the service this statistic is related to
* @return serviceName
*/
@JsonProperty(JSON_PROPERTY_SERVICE_NAME)
public String getServiceName() {
return serviceName;
}


@JsonProperty(JSON_PROPERTY_SERVICE_NAME)
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}


public DailyInvocationStatistic serviceVersion(String serviceVersion) {
this.serviceVersion = serviceVersion;
return this;
}

/**
* The version of the service this statistic is related to
* @return serviceVersion
*/
@JsonProperty(JSON_PROPERTY_SERVICE_VERSION)
public String getServiceVersion() {
return serviceVersion;
}


@JsonProperty(JSON_PROPERTY_SERVICE_VERSION)
public void setServiceVersion(String serviceVersion) {
this.serviceVersion = serviceVersion;
}


public DailyInvocationStatistic dailyCount(BigDecimal dailyCount) {
this.dailyCount = dailyCount;
return this;
}

/**
* The number of service mock invocations on this day
* @return dailyCount
*/
@JsonProperty(JSON_PROPERTY_DAILY_COUNT)
public BigDecimal getDailyCount() {
return dailyCount;
}


@JsonProperty(JSON_PROPERTY_DAILY_COUNT)
public void setDailyCount(BigDecimal dailyCount) {
this.dailyCount = dailyCount;
}


public DailyInvocationStatistic hourlyCount(Map<String, Object> hourlyCount) {
this.hourlyCount = hourlyCount;
return this;
}

public DailyInvocationStatistic putHourlyCountItem(String key, Object hourlyCountItem) {
if (this.hourlyCount == null) {
this.hourlyCount = new HashMap<>();
}
this.hourlyCount.put(key, hourlyCountItem);
return this;
}

/**
* The number of service mock invocations per hour of the day (keys range from 0 to 23)
* @return hourlyCount
*/
@JsonProperty(JSON_PROPERTY_HOURLY_COUNT)
public Map<String, Object> getHourlyCount() {
return hourlyCount;
}


@JsonProperty(JSON_PROPERTY_HOURLY_COUNT)
public void setHourlyCount(Map<String, Object> hourlyCount) {
this.hourlyCount = hourlyCount;
}


public DailyInvocationStatistic minuteCount(Map<String, Object> minuteCount) {
this.minuteCount = minuteCount;
return this;
}

public DailyInvocationStatistic putMinuteCountItem(String key, Object minuteCountItem) {
if (this.minuteCount == null) {
this.minuteCount = new HashMap<>();
}
this.minuteCount.put(key, minuteCountItem);
return this;
}

/**
* The number of service mock invocations per minute of the day (keys range from 0 to 1439)
* @return minuteCount
*/
@JsonProperty(JSON_PROPERTY_MINUTE_COUNT)
public Map<String, Object> getMinuteCount() {
return minuteCount;
}


@JsonProperty(JSON_PROPERTY_MINUTE_COUNT)
public void setMinuteCount(Map<String, Object> minuteCount) {
this.minuteCount = minuteCount;
}


/**
* Return true if this DailyInvocationStatistic object is equal to o.
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DailyInvocationStatistic dailyInvocationStatistic = (DailyInvocationStatistic) o;
return Objects.equals(this.id, dailyInvocationStatistic.id) &&
Objects.equals(this.day, dailyInvocationStatistic.day) &&
Objects.equals(this.serviceName, dailyInvocationStatistic.serviceName) &&
Objects.equals(this.serviceVersion, dailyInvocationStatistic.serviceVersion) &&
Objects.equals(this.dailyCount, dailyInvocationStatistic.dailyCount) &&
Objects.equals(this.hourlyCount, dailyInvocationStatistic.hourlyCount) &&
Objects.equals(this.minuteCount, dailyInvocationStatistic.minuteCount);
}

@Override
public int hashCode() {
return Objects.hash(id, day, serviceName, serviceVersion, dailyCount, hourlyCount, minuteCount);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class DailyInvocationStatistic {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" day: ").append(toIndentedString(day)).append("\n");
sb.append(" serviceName: ").append(toIndentedString(serviceName)).append("\n");
sb.append(" serviceVersion: ").append(toIndentedString(serviceVersion)).append("\n");
sb.append(" dailyCount: ").append(toIndentedString(dailyCount)).append("\n");
sb.append(" hourlyCount: ").append(toIndentedString(hourlyCount)).append("\n");
sb.append(" minuteCount: ").append(toIndentedString(minuteCount)).append("\n");
sb.append("}");
return sb.toString();
}

/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}


Loading

0 comments on commit 043602c

Please sign in to comment.