001/*-
002 * #%L
003 * Smile CDR - CDR
004 * %%
005 * Copyright (C) 2016 - 2026 Smile CDR, Inc.
006 * %%
007 * All rights reserved.
008 * #L%
009 */
010package ca.cdr.test.app.clients;
011
012import ca.cdr.api.model.json.portal.PortalAppsJson;
013import ca.cdr.api.model.json.portal.SmilePortalConfigJson;
014import ca.cdr.test.app.clients.common.HttpClientOwnership;
015import ca.cdr.test.app.clients.common.RequestFactoryUtil;
016import ca.cdr.test.app.clients.common.SmileTestHttpClient;
017import jakarta.annotation.Nonnull;
018import jakarta.annotation.Nullable;
019import org.springframework.http.MediaType;
020import org.springframework.http.client.support.BasicAuthenticationInterceptor;
021import org.springframework.web.client.RestClient;
022
023import java.util.Objects;
024
025public class SmilePortalClient implements AutoCloseable {
026
027        private final RestClient myRestClient;
028
029        @Nullable
030        private final HttpClientOwnership myOwnership;
031
032        SmilePortalClient(RestClient theRestClient) {
033                this(theRestClient, null);
034        }
035
036        private SmilePortalClient(RestClient theRestClient, @Nullable HttpClientOwnership theOwnership) {
037                myRestClient = theRestClient;
038                myOwnership = theOwnership;
039        }
040
041        public static @Nonnull SmilePortalClient open(
042                        @Nonnull String theBaseUrl, @Nonnull String theUsername, @Nonnull String thePassword) {
043                return authenticatedClient(HttpClientOwnership.resolve(null), theBaseUrl, theUsername, thePassword);
044        }
045
046        public static @Nonnull SmilePortalClient openAnonymous(@Nonnull String theBaseUrl) {
047                HttpClientOwnership ownership = HttpClientOwnership.resolve(null);
048                return new SmilePortalClient(builderFor(theBaseUrl, ownership.client()).build(), ownership);
049        }
050
051        public static @Nonnull SmilePortalClient issuingOn(
052                        @Nonnull SmileTestHttpClient theHttpClient,
053                        @Nonnull String theBaseUrl,
054                        @Nonnull String theUsername,
055                        @Nonnull String thePassword) {
056                return authenticatedClient(
057                                HttpClientOwnership.resolve(theHttpClient), theBaseUrl, theUsername, thePassword);
058        }
059
060        private static @Nonnull SmilePortalClient authenticatedClient(
061                        @Nonnull HttpClientOwnership theOwnership,
062                        @Nonnull String theBaseUrl,
063                        @Nonnull String theUsername,
064                        @Nonnull String thePassword) {
065                RestClient restClient = builderFor(theBaseUrl, theOwnership.client())
066                                .requestInterceptor(new BasicAuthenticationInterceptor(theUsername, thePassword))
067                                .build();
068                return new SmilePortalClient(restClient, theOwnership);
069        }
070
071        private static @Nonnull RestClient.Builder builderFor(
072                        String theBaseUrl, @Nonnull SmileTestHttpClient theHttpClient) {
073                return RestClient.builder()
074                                .baseUrl(theBaseUrl)
075                                .requestFactory(RequestFactoryUtil.wrap(theHttpClient))
076                                .defaultRequest(r -> r.accept(MediaType.APPLICATION_JSON));
077        }
078
079        @Nonnull
080        public PortalAppsJson getApplications() {
081                PortalAppsJson result = myRestClient.get().uri("api/applications").retrieve().body(PortalAppsJson.class);
082                return Objects.requireNonNull(result);
083        }
084
085        @Nonnull
086        public SmilePortalConfigJson getConfig() {
087                SmilePortalConfigJson result =
088                                myRestClient.get().uri("api/config").retrieve().body(SmilePortalConfigJson.class);
089                return Objects.requireNonNull(result);
090        }
091
092        @Override
093        public void close() {
094                if (myOwnership != null) {
095                        myOwnership.closeIfOwned();
096                }
097        }
098}