io.quarkiverse.openfga.client.OpenFGAClient Maven / Gradle / Ivy
package io.quarkiverse.openfga.client;
import static io.quarkiverse.openfga.client.utils.PaginatedList.collectAllPages;
import static java.lang.String.format;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import io.quarkiverse.openfga.client.api.API;
import io.quarkiverse.openfga.client.model.Store;
import io.quarkiverse.openfga.client.model.dto.CreateStoreRequest;
import io.quarkiverse.openfga.client.model.dto.CreateStoreResponse;
import io.quarkiverse.openfga.client.utils.PaginatedList;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
@ApplicationScoped
public class OpenFGAClient {
private final API api;
@Inject
public OpenFGAClient(API api) {
this.api = api;
}
public Uni> listStores(@Nullable Integer pageSize, @Nullable String continuationToken) {
return api.listStores(pageSize, continuationToken)
.map(res -> new PaginatedList<>(res.getStores(), res.getContinuationToken()));
}
public Uni> listAllStores() {
return listAllStores(null);
}
public Uni> listAllStores(@Nullable Integer pageSize) {
return collectAllPages(pageSize, this::listStores);
}
public Uni createStore(String name) {
return api.createStore(new CreateStoreRequest(name)).map(CreateStoreResponse::asStore);
}
public StoreClient store(String storeId) {
return new StoreClient(api, Uni.createFrom().item(storeId));
}
private static class StoreSearchResult {
Optional storeId;
Optional token;
StoreSearchResult(Optional storeId, Optional token) {
this.storeId = storeId;
this.token = token;
}
boolean isNotFinished() {
return storeId.isEmpty() && token.isPresent();
}
}
private static final Pattern STORE_ID_PATTERN = Pattern.compile("^[ABCDEFGHJKMNPQRSTVWXYZ0-9]{26}$");
public static Uni storeIdResolver(API api, String storeIdOrName, boolean alwaysResolveStoreId) {
if (STORE_ID_PATTERN.matcher(storeIdOrName).matches() && !alwaysResolveStoreId) {
return Uni.createFrom().item(storeIdOrName);
}
return Multi.createBy()
.repeating().uni(AtomicReference::new, lastToken -> {
return api.listStores(null, lastToken.get())
.onItem().invoke(list -> lastToken.set(list.getContinuationToken()))
.map(response -> {
var storeId = response.getStores().stream()
.filter(store -> store.getName().equals(storeIdOrName)
|| store.getId().equals(storeIdOrName))
.map(Store::getId)
.findFirst();
Optional token;
if (response.getContinuationToken() != null && !response.getContinuationToken().isEmpty()) {
token = Optional.of(response.getContinuationToken());
} else {
token = Optional.empty();
}
return new StoreSearchResult(storeId, token);
});
})
.whilst(StoreSearchResult::isNotFinished)
.select().last()
.flatMap(result -> {
if (result.storeId.isEmpty() && result.token.isEmpty()) {
return Multi.createFrom()
.failure(new IllegalStateException(format("No store with name '%s'", storeIdOrName)));
}
if (result.storeId.isEmpty()) {
return Multi.createFrom().nothing();
}
return Multi.createFrom().item(result.storeId.get());
})
.toUni()
.memoize().indefinitely();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy