Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions src/main/java/apu/saerok_admin/infra/CurrentAdminClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestClientResponseException;
import org.springframework.web.util.UriBuilder;
import org.springframework.util.StringUtils;

@Component
public class CurrentAdminClient {
Expand Down Expand Up @@ -57,11 +57,14 @@ public Optional<CurrentAdminProfile> fetchCurrentAdminProfile() {
return Optional.empty();
}

List<String> roles = response.roles() != null ? List.copyOf(response.roles()) : List.of();

return Optional.of(new CurrentAdminProfile(
response.nickname(),
response.email(),
response.profileImageUrl(),
toRoleDescriptions(response.roles())
toRoleDescriptions(roles),
normalizeRoleCodes(roles)
));
} catch (RestClientResponseException exception) {
log.warn(
Expand Down Expand Up @@ -118,4 +121,21 @@ private List<String> toRoleDescriptions(List<String> roles) {

return descriptions.isEmpty() ? List.of() : List.copyOf(descriptions);
}

private List<String> normalizeRoleCodes(List<String> roles) {
if (roles == null || roles.isEmpty()) {
return List.of();
}
Set<String> normalized = new LinkedHashSet<>();
for (String role : roles) {
if (!StringUtils.hasText(role)) {
continue;
}
normalized.add(role.toUpperCase(Locale.ROOT));
}
if (normalized.isEmpty()) {
return List.of();
}
return List.copyOf(normalized);
}
}
138 changes: 138 additions & 0 deletions src/main/java/apu/saerok_admin/infra/ad/AdminAdClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package apu.saerok_admin.infra.ad;

import apu.saerok_admin.infra.SaerokApiProps;
import apu.saerok_admin.infra.ad.dto.AdImagePresignResponse;
import apu.saerok_admin.infra.ad.dto.AdminAdImagePresignRequest;
import apu.saerok_admin.infra.ad.dto.AdminAdListResponse;
import apu.saerok_admin.infra.ad.dto.AdminAdPlacementListResponse;
import apu.saerok_admin.infra.ad.dto.AdminCreateAdPlacementRequest;
import apu.saerok_admin.infra.ad.dto.AdminCreateAdRequest;
import apu.saerok_admin.infra.ad.dto.AdminCreateSlotRequest;
import apu.saerok_admin.infra.ad.dto.AdminSlotListResponse;
import apu.saerok_admin.infra.ad.dto.AdminUpdateAdPlacementRequest;
import apu.saerok_admin.infra.ad.dto.AdminUpdateAdRequest;
import apu.saerok_admin.infra.ad.dto.AdminUpdateSlotRequest;
import java.net.URI;
import java.util.List;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;
import org.springframework.web.util.UriBuilder;

@Component
public class AdminAdClient {

private static final String[] ADMIN_AD_SEGMENTS = {"admin", "ad"};

private final RestClient saerokRestClient;
private final String[] missingPrefixSegments;

public AdminAdClient(RestClient saerokRestClient, SaerokApiProps saerokApiProps) {
this.saerokRestClient = saerokRestClient;
List<String> missing = saerokApiProps.missingPrefixSegments();
this.missingPrefixSegments = missing.toArray(new String[0]);
}

public AdminAdListResponse listAds() {
return get(AdminAdListResponse.class, "list");
}

public AdminAdListResponse.Item createAd(AdminCreateAdRequest request) {
return post(AdminAdListResponse.Item.class, request, "create");
}

public AdminAdListResponse.Item updateAd(Long adId, AdminUpdateAdRequest request) {
return put(AdminAdListResponse.Item.class, request, adId.toString());
}

public void deleteAd(Long adId) {
delete(adId.toString());
}

public AdImagePresignResponse generateAdImagePresignUrl(AdminAdImagePresignRequest request) {
return post(AdImagePresignResponse.class, request, "image", "presign");
}

public AdminSlotListResponse listSlots() {
return get(AdminSlotListResponse.class, "slot");
}

public AdminSlotListResponse.Item createSlot(AdminCreateSlotRequest request) {
return post(AdminSlotListResponse.Item.class, request, "slot");
}

public AdminSlotListResponse.Item updateSlot(Long slotId, AdminUpdateSlotRequest request) {
return put(AdminSlotListResponse.Item.class, request, "slot", slotId.toString());
}

public void deleteSlot(Long slotId) {
delete("slot", slotId.toString());
}

public AdminAdPlacementListResponse listPlacements() {
return get(AdminAdPlacementListResponse.class, "placement");
}

public AdminAdPlacementListResponse.Item createPlacement(AdminCreateAdPlacementRequest request) {
return post(AdminAdPlacementListResponse.Item.class, request, "placement");
}

public AdminAdPlacementListResponse.Item updatePlacement(Long placementId, AdminUpdateAdPlacementRequest request) {
return put(AdminAdPlacementListResponse.Item.class, request, "placement", placementId.toString());
}

public void deletePlacement(Long placementId) {
delete("placement", placementId.toString());
}

private <T> T get(Class<T> responseType, String... segments) {
T response = saerokRestClient.get()
.uri(uriBuilder -> buildUri(uriBuilder, segments))
.retrieve()
.body(responseType);
if (response == null) {
throw new IllegalStateException("Empty response from admin ad API");
}
return response;
}

private <T> T post(Class<T> responseType, Object body, String... segments) {
T response = saerokRestClient.post()
.uri(uriBuilder -> buildUri(uriBuilder, segments))
.body(body)
.retrieve()
.body(responseType);
if (response == null) {
throw new IllegalStateException("Empty response from admin ad API");
}
return response;
}

private <T> T put(Class<T> responseType, Object body, String... segments) {
T response = saerokRestClient.method(HttpMethod.PUT)
.uri(uriBuilder -> buildUri(uriBuilder, segments))
.body(body)
.retrieve()
.body(responseType);
if (response == null) {
throw new IllegalStateException("Empty response from admin ad API");
}
return response;
}

private void delete(String... segments) {
saerokRestClient.delete()
.uri(uriBuilder -> buildUri(uriBuilder, segments))
.retrieve()
.toBodilessEntity();
}

private URI buildUri(UriBuilder builder, String... segments) {
if (missingPrefixSegments.length > 0) {
builder.pathSegment(missingPrefixSegments);
}
builder.pathSegment(ADMIN_AD_SEGMENTS);
builder.pathSegment(segments);
return builder.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package apu.saerok_admin.infra.ad.dto;

public record AdImagePresignResponse(
String presignedUrl,
String objectKey
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package apu.saerok_admin.infra.ad.dto;

public record AdminAdImagePresignRequest(String contentType) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package apu.saerok_admin.infra.ad.dto;

import java.time.OffsetDateTime;
import java.util.List;

public record AdminAdListResponse(List<Item> items) {

public record Item(
Long id,
String name,
String memo,
String imageUrl,
String contentType,
String targetUrl,
OffsetDateTime createdAt,
OffsetDateTime updatedAt
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package apu.saerok_admin.infra.ad.dto;

import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.List;

public record AdminAdPlacementListResponse(List<Item> items) {

public record Item(
Long id,
Long adId,
String adName,
String adImageUrl,
Long slotId,
String slotName,
LocalDate startDate,
LocalDate endDate,
Short weight,
Boolean enabled,
OffsetDateTime createdAt,
OffsetDateTime updatedAt
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package apu.saerok_admin.infra.ad.dto;

import java.time.LocalDate;

public record AdminCreateAdPlacementRequest(
Long adId,
Long slotId,
LocalDate startDate,
LocalDate endDate,
Short weight,
Boolean enabled
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package apu.saerok_admin.infra.ad.dto;

public record AdminCreateAdRequest(
String name,
String memo,
String objectKey,
String contentType,
String targetUrl
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package apu.saerok_admin.infra.ad.dto;

public record AdminCreateSlotRequest(
String name,
String memo,
Double fallbackRatio,
Integer ttlSeconds
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package apu.saerok_admin.infra.ad.dto;

import java.time.OffsetDateTime;
import java.util.List;

public record AdminSlotListResponse(List<Item> items) {

public record Item(
Long id,
String name,
String memo,
Double fallbackRatio,
Integer ttlSeconds,
OffsetDateTime createdAt,
OffsetDateTime updatedAt
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package apu.saerok_admin.infra.ad.dto;

import java.time.LocalDate;

public record AdminUpdateAdPlacementRequest(
Long slotId,
LocalDate startDate,
LocalDate endDate,
Short weight,
Boolean enabled
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package apu.saerok_admin.infra.ad.dto;

public record AdminUpdateAdRequest(
String name,
String memo,
String objectKey,
String contentType,
String targetUrl
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package apu.saerok_admin.infra.ad.dto;

public record AdminUpdateSlotRequest(
String memo,
Double fallbackRatio,
Integer ttlSeconds
) {
}
Loading