1515 */
1616package io .github .microcks .testcontainers ;
1717
18+ import io .github .microcks .testcontainers .model .DailyInvocationStatistic ;
1819import io .github .microcks .testcontainers .model .RequestResponsePair ;
1920import io .github .microcks .testcontainers .model .Secret ;
2021import io .github .microcks .testcontainers .model .TestResult ;
3031import org .testcontainers .shaded .com .fasterxml .jackson .databind .ObjectMapper ;
3132import org .testcontainers .shaded .com .github .dockerjava .core .MediaType ;
3233import org .testcontainers .shaded .com .google .common .net .HttpHeaders ;
34+ import org .testcontainers .shaded .com .google .common .net .UrlEscapers ;
3335import org .testcontainers .shaded .org .awaitility .Awaitility ;
3436import org .testcontainers .shaded .org .awaitility .core .ConditionTimeoutException ;
3537import org .testcontainers .utility .DockerImageName ;
4345import java .io .OutputStream ;
4446import java .io .OutputStreamWriter ;
4547import java .io .PrintWriter ;
48+ import java .math .BigDecimal ;
4649import java .net .HttpURLConnection ;
4750import java .net .URL ;
4851import java .net .URLDecoder ;
4952import java .net .URLEncoder ;
5053import java .nio .charset .StandardCharsets ;
54+ import java .text .SimpleDateFormat ;
5155import java .util .Arrays ;
56+ import java .util .Date ;
5257import java .util .HashSet ;
5358import java .util .List ;
5459import java .util .Set ;
@@ -75,6 +80,8 @@ public class MicrocksContainer extends GenericContainer<MicrocksContainer> {
7580
7681 private static ObjectMapper mapper ;
7782
83+ private static SimpleDateFormat metricsApiDayFormatter = new SimpleDateFormat ("yyyyMMdd" );
84+
7885 private Set <String > snapshotsToImport ;
7986 private Set <String > mainArtifactsToImport ;
8087 private Set <String > secondaryArtifactsToImport ;
@@ -561,6 +568,167 @@ public void downloadAsSecondaryRemoteArtifact(String remoteArtifactUrl) throws A
561568 downloadArtifact (remoteArtifactUrl , false );
562569 }
563570
571+ /**
572+ * Verifies that given Service has been invoked at least one time, for the current invocations' date.
573+ *
574+ * @param serviceName mandatory
575+ * @param serviceVersion mandatory
576+ * @return false if the given service was not found, or if the daily invocation's count is zero. Else, returns true if the daily invocations' count for the given service is at least one.
577+ */
578+ public boolean verify (String serviceName , String serviceVersion ) {
579+ return doVerify (getHttpEndpoint (), serviceName , serviceVersion , null );
580+ }
581+
582+ /**
583+ * Verifies that given Service has been invoked at least one time, for the current invocations' date.
584+ *
585+ * @param microcksContainerHttpEndpoint mandatory
586+ * @param serviceName mandatory
587+ * @param serviceVersion mandatory
588+ * @return false if the given service was not found, or if the daily invocation's count is zero. Else, returns true if the daily invocations' count for the given service is at least one.
589+ */
590+ public static boolean verify (String microcksContainerHttpEndpoint , String serviceName , String serviceVersion ) {
591+ return doVerify (microcksContainerHttpEndpoint , serviceName , serviceVersion , null );
592+ }
593+
594+ /**
595+ * Verifies that given Service has been invoked at least one time, for the given invocations' date.
596+ * In unit testing context, it should be useless to pass the invocations date, prefer calling {@link #verify(String, String)}`.
597+ *
598+ * @param serviceName mandatory
599+ * @param serviceVersion mandatory
600+ * @param invocationsDate nullable
601+ * @return false if the given service was not found, or if the daily invocation's count is zero. Else, returns true if the daily invocations' count for the given service is at least one.
602+ */
603+ public boolean verify (String serviceName , String serviceVersion , Date invocationsDate ) {
604+ return doVerify (getHttpEndpoint (), serviceName , serviceVersion , invocationsDate );
605+ }
606+
607+ /**
608+ * Verifies that given Service has been invoked at least one time, for the given invocations' date.
609+ * In unit testing context, it should be useless to pass the invocations date, prefer calling {@link #verify(String, String)}`.
610+ *
611+ * @param microcksContainerHttpEndpoint mandatory
612+ * @param serviceName mandatory
613+ * @param serviceVersion mandatory
614+ * @param invocationsDate nullable
615+ * @return false if the given service was not found, or if the daily invocation's count is zero. Else, returns true if the daily invocations' count for the given service is at least one.
616+ */
617+ public static boolean verify (String microcksContainerHttpEndpoint , String serviceName , String serviceVersion , Date invocationsDate ) {
618+ return doVerify (microcksContainerHttpEndpoint , serviceName , serviceVersion , invocationsDate );
619+ }
620+
621+ private static boolean doVerify (String microcksContainerHttpEndpoint , String serviceName , String serviceVersion , Date invocationsDate ) {
622+ DailyInvocationStatistic dailyInvocationStatistic = getServiceInvocations (microcksContainerHttpEndpoint , serviceName , serviceVersion , invocationsDate );
623+
624+ if (dailyInvocationStatistic == null ) {
625+ return false ;
626+ }
627+
628+ BigDecimal count = dailyInvocationStatistic .getDailyCount ();
629+
630+ return count != null && count .intValue () != 0 ;
631+ }
632+
633+ /**
634+ * Get the invocations' count for a given service, identified by its name and version, for the current invocations' date.
635+ *
636+ * @param serviceName mandatory
637+ * @param serviceVersion mandatory
638+ * @return zero if the given service was not found, or has never been invoked. Else, returns the daily count of invocations for the given service.
639+ */
640+ public Long getServiceInvocationsCount (String serviceName , String serviceVersion ) {
641+ return doGetServiceInvocationsCount (getHttpEndpoint (), serviceName , serviceVersion , null );
642+ }
643+
644+ /**
645+ * Get the invocations' count for a given service, identified by its name and version, for the current invocations' date.
646+ *
647+ * @param microcksContainerHttpEndpoint mandatory
648+ * @param serviceName mandatory
649+ * @param serviceVersion mandatory
650+ * @return zero if the given service was not found, or has never been invoked. Else, returns the daily count of invocations for the given service.
651+ */
652+ public static Long getServiceInvocationsCount (String microcksContainerHttpEndpoint , String serviceName , String serviceVersion ) {
653+ return doGetServiceInvocationsCount (microcksContainerHttpEndpoint , serviceName , serviceVersion , null );
654+ }
655+
656+ /**
657+ * Get the invocations' count for a given service, identified by its name and version, for the given invocations' date.
658+ * In unit testing context, it should be useless to pass the invocations date, prefer calling {@link #getServiceInvocationsCount(String, String)}`.
659+ *
660+ * @param serviceName mandatory
661+ * @param serviceVersion mandatory
662+ * @param invocationsDate nullable
663+ * @return zero if the given service was not found, or has never been invoked. Else, returns the daily count of invocations for the given service.
664+ */
665+ public Long getServiceInvocationsCount (String serviceName , String serviceVersion , Date invocationsDate ) {
666+ return doGetServiceInvocationsCount (getHttpEndpoint (), serviceName , serviceVersion , invocationsDate );
667+ }
668+
669+ /**
670+ * Get the invocations' count for a given service, identified by its name and version, for the given invocations' date.
671+ * In unit testing context, it should be useless to pass the invocations date, prefer calling {@link #getServiceInvocationsCount(String, String)}`.
672+ *
673+ * @param microcksContainerHttpEndpoint mandatory
674+ * @param serviceName mandatory
675+ * @param serviceVersion mandatory
676+ * @param invocationsDate nullable
677+ * @return zero if the given service was not found, or has never been invoked. Else, returns the daily count of invocations for the given service.
678+ */
679+ public static Long getServiceInvocationsCount (String microcksContainerHttpEndpoint , String serviceName , String serviceVersion , Date invocationsDate ) {
680+ return doGetServiceInvocationsCount (microcksContainerHttpEndpoint , serviceName , serviceVersion , invocationsDate );
681+ }
682+
683+ private static Long doGetServiceInvocationsCount (String microcksContainerHttpEndpoint , String serviceName , String serviceVersion , Date invocationsDate ) {
684+ DailyInvocationStatistic dailyInvocationStatistic = getServiceInvocations (microcksContainerHttpEndpoint , serviceName , serviceVersion , invocationsDate );
685+
686+ if (dailyInvocationStatistic == null ) {
687+ return 0L ;
688+ }
689+
690+ BigDecimal count = dailyInvocationStatistic .getDailyCount ();
691+
692+ return count .longValue ();
693+ }
694+
695+
696+ /**
697+ * Returns all data from Microcks Metrics REST API about the invocations of a given service.
698+ *
699+ * @param microcksContainerHttpEndpoint mandatory
700+ * @param serviceName mandatory
701+ * @param serviceVersion mandatory
702+ * @param invocationsDate nullable
703+ * @return
704+ */
705+ private static DailyInvocationStatistic getServiceInvocations (String microcksContainerHttpEndpoint , String serviceName , String serviceVersion , Date invocationsDate ) {
706+ String encodedServiceName = UrlEscapers .urlFragmentEscaper ().escape (serviceName );
707+ String encodedServiceVersion = UrlEscapers .urlFragmentEscaper ().escape (serviceVersion );
708+
709+ String restApiURL = String .format ("%s/api/metrics/invocations/%s/%s" , microcksContainerHttpEndpoint , encodedServiceName , encodedServiceVersion );
710+
711+ if (invocationsDate != null ) {
712+ restApiURL += "?day=" + metricsApiDayFormatter .format (invocationsDate );
713+ }
714+
715+ try {
716+ Thread .sleep (100 ); // to avoid race condition issue when requesting Microcks Metrics REST API
717+ } catch (InterruptedException e ) {
718+ log .warn ("Failed to sleep before calling Microcks API" , e );
719+ Thread .currentThread ().interrupt ();
720+ }
721+
722+ try {
723+ StringBuilder content = getFromRestApi (restApiURL );
724+ return content .length () == 0 ? null : getMapper ().readValue (content .toString (), DailyInvocationStatistic .class );
725+ } catch (IOException e ) {
726+ log .warn ("Failed to get service's invocations at address " + restApiURL , e );
727+ }
728+
729+ return null ;
730+ }
731+
564732 private void importArtifact (String artifactPath , boolean mainArtifact ) {
565733 URL resource = Thread .currentThread ().getContextClassLoader ().getResource (artifactPath );
566734 if (resource == null ) {
@@ -727,8 +895,21 @@ private static HttpURLConnection uploadFileToMicrocks(URL microcksApiURL, File f
727895 }
728896
729897 private static TestResult refreshTestResult (String microcksContainerHttpEndpoint , String testResultId ) throws IOException {
898+ StringBuilder content = getFromRestApi (microcksContainerHttpEndpoint + "/api/tests/" + testResultId );
899+
900+ return getMapper ().readValue (content .toString (), TestResult .class );
901+ }
902+
903+ /**
904+ * Does a GET HTTP call to Microcks REST API and expecting to obtain a 200 response with a `application/json` body: returns it as a StringBuilder.
905+ *
906+ * @param restApiURL mandatory
907+ * @return
908+ * @throws IOException
909+ */
910+ private static StringBuilder getFromRestApi (String restApiURL ) throws IOException {
730911 // Build a new client on correct API endpoint.
731- URL url = new URL (microcksContainerHttpEndpoint + "/api/tests/" + testResultId );
912+ URL url = new URL (restApiURL );
732913 HttpURLConnection httpConn = (HttpURLConnection ) url .openConnection ();
733914 httpConn .setRequestMethod ("GET" );
734915 httpConn .setRequestProperty ("Accept" , "application/json" );
@@ -742,10 +923,10 @@ private static TestResult refreshTestResult(String microcksContainerHttpEndpoint
742923 content .append (inputLine );
743924 }
744925 }
926+
745927 // Disconnect Http connection.
746928 httpConn .disconnect ();
747-
748- return getMapper ().readValue (content .toString (), TestResult .class );
929+ return content ;
749930 }
750931
751932 public static class ArtifactLoadException extends RuntimeException {
0 commit comments