tech.ydb.coordination.impl.StreamMsg Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ydb-sdk-coordination Show documentation
Show all versions of ydb-sdk-coordination Show documentation
Coordination node client implementation
package tech.ydb.coordination.impl;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.google.protobuf.ByteString;
import com.google.protobuf.TextFormat;
import tech.ydb.coordination.description.SemaphoreChangedEvent;
import tech.ydb.coordination.description.SemaphoreDescription;
import tech.ydb.coordination.description.SemaphoreWatcher;
import tech.ydb.coordination.settings.DescribeSemaphoreMode;
import tech.ydb.coordination.settings.WatchSemaphoreMode;
import tech.ydb.core.Issue;
import tech.ydb.core.Result;
import tech.ydb.core.Status;
import tech.ydb.core.StatusCode;
import tech.ydb.proto.StatusCodesProtos;
import tech.ydb.proto.YdbIssueMessage;
import tech.ydb.proto.coordination.SessionRequest;
import tech.ydb.proto.coordination.SessionResponse;
/**
*
* @author Aleksandr Gorshenin
* @param Type of result
*/
abstract class StreamMsg {
protected final CompletableFuture future = new CompletableFuture<>();
public CompletableFuture getResult() {
return future;
}
public StreamMsg> nextMsg() {
return null;
}
public boolean isIdempotent() {
return false;
}
public abstract SessionRequest makeRequest(long reqId);
protected abstract boolean handleResponse(SessionResponse response);
protected abstract boolean handleError(Status status);
protected Status incorrectTypeStatus(SessionResponse response, String exptected) {
String msg = "Incorrect type of response " + TextFormat.shortDebugString(response) + ", expected " + exptected;
return Status.of(StatusCode.CLIENT_INTERNAL_ERROR, Issue.of(msg, Issue.Severity.ERROR));
}
public static StreamMsg createSemaphore(String name, long limit, byte[] data) {
return new CreateSemaphoreMsg(name, limit, data);
}
public static StreamMsg updateSemaphore(String name, byte[] data) {
return new UpdateSemaphoreMsg(name, data);
}
public static StreamMsg deleteSemaphore(String name, boolean force) {
return new DeleteSemaphoreMsg(name, force);
}
public static StreamMsg> acquireSemaphore(
String name, long count, byte[] data, boolean ephemeral, long timeoutMillis
) {
return new AcquireSemaphoreMsg(name, count, timeoutMillis, ephemeral, data);
}
public static StreamMsg> releaseSemaphore(String name) {
return new ReleaseSemaphoreMsg(name);
}
public static StreamMsg> describeSemaphore(String name, DescribeSemaphoreMode mode) {
return new DescribeSemaphoreMsg(name, mode);
}
public static StreamMsg> watchSemaphore(
String name, DescribeSemaphoreMode decribeMode, WatchSemaphoreMode watchMode) {
return new WatchSemaphoreMsg(name, decribeMode, watchMode);
}
private abstract static class BaseStatusMsg extends StreamMsg {
@Override
public boolean handleError(Status status) {
return future.complete(status);
}
protected boolean handleResult(
StatusCodesProtos.StatusIds.StatusCode code, List issues
) {
return future.complete(Status.of(StatusCode.fromProto(code), Issue.fromPb(issues)));
}
}
private abstract static class BaseResultMsg extends StreamMsg> {
@Override
public boolean handleError(Status status) {
return future.complete(Result.fail(status));
}
protected boolean handleResult(
V value, StatusCodesProtos.StatusIds.StatusCode code, List issues
) {
Status status = Status.of(StatusCode.fromProto(code), Issue.fromPb(issues));
return future.complete(status.isSuccess() ? Result.success(value, status) : Result.fail(status));
}
}
private static class CreateSemaphoreMsg extends BaseStatusMsg {
private final String name;
private final long limit;
private final ByteString data;
CreateSemaphoreMsg(String name, long limit, byte[] data) {
this.name = name;
this.limit = limit;
this.data = data == null ? ByteString.EMPTY : ByteString.copyFrom(data);
}
@Override
public SessionRequest makeRequest(long reqId) {
return SessionRequest.newBuilder().setCreateSemaphore(
SessionRequest.CreateSemaphore.newBuilder()
.setName(name)
.setLimit(limit)
.setData(data)
.setReqId(reqId)
.build()
).build();
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasCreateSemaphoreResult()) {
return handleError(incorrectTypeStatus(response, "create_semaphore_result"));
}
SessionResponse.CreateSemaphoreResult result = response.getCreateSemaphoreResult();
return handleResult(result.getStatus(), result.getIssuesList());
}
}
private static class UpdateSemaphoreMsg extends BaseStatusMsg {
private final String name;
private final ByteString data;
UpdateSemaphoreMsg(String name, byte[] data) {
this.name = name;
this.data = data == null ? ByteString.EMPTY : ByteString.copyFrom(data);
}
@Override
public SessionRequest makeRequest(long reqId) {
return SessionRequest.newBuilder().setUpdateSemaphore(
SessionRequest.UpdateSemaphore.newBuilder()
.setName(name)
.setData(data)
.setReqId(reqId)
.build()
).build();
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasUpdateSemaphoreResult()) {
return handleError(incorrectTypeStatus(response, "update_semaphore_result"));
}
SessionResponse.UpdateSemaphoreResult result = response.getUpdateSemaphoreResult();
return handleResult(result.getStatus(), result.getIssuesList());
}
}
private static class DeleteSemaphoreMsg extends BaseStatusMsg {
private final String name;
private final boolean force;
DeleteSemaphoreMsg(String name, boolean force) {
this.name = name;
this.force = force;
}
@Override
public SessionRequest makeRequest(long reqId) {
return SessionRequest.newBuilder().setDeleteSemaphore(
SessionRequest.DeleteSemaphore.newBuilder()
.setName(name)
.setForce(force)
.setReqId(reqId)
.build()
).build();
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasDeleteSemaphoreResult()) {
return handleError(incorrectTypeStatus(response, "delete_semaphore_result"));
}
SessionResponse.DeleteSemaphoreResult result = response.getDeleteSemaphoreResult();
return handleResult(result.getStatus(), result.getIssuesList());
}
}
private static class AcquireSemaphoreMsg extends BaseResultMsg {
private final String name;
private final long count;
private final long timeoutMillis;
private final boolean ephemeral;
private final ByteString data;
AcquireSemaphoreMsg(String name, long count, long timeoutMillis, boolean ephemeral, byte[] data) {
this.name = name;
this.count = count;
this.timeoutMillis = timeoutMillis;
this.ephemeral = ephemeral;
this.data = data == null ? ByteString.EMPTY : ByteString.copyFrom(data);
}
@Override
public boolean isIdempotent() {
return true;
}
@Override
public SessionRequest makeRequest(long reqId) {
return SessionRequest.newBuilder().setAcquireSemaphore(
SessionRequest.AcquireSemaphore.newBuilder()
.setName(name)
.setCount(count)
.setTimeoutMillis(timeoutMillis)
.setEphemeral(ephemeral)
.setData(data)
.setReqId(reqId)
.build()
).build();
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasAcquireSemaphoreResult()) {
return handleError(incorrectTypeStatus(response, "acquire_semaphore_result"));
}
SessionResponse.AcquireSemaphoreResult result = response.getAcquireSemaphoreResult();
return handleResult(result.getAcquired(), result.getStatus(), result.getIssuesList());
}
}
private static class ReleaseSemaphoreMsg extends BaseResultMsg {
private final String name;
ReleaseSemaphoreMsg(String name) {
this.name = name;
}
@Override
public boolean isIdempotent() {
return true;
}
@Override
public SessionRequest makeRequest(long reqId) {
return SessionRequest.newBuilder().setReleaseSemaphore(
SessionRequest.ReleaseSemaphore.newBuilder()
.setName(name)
.setReqId(reqId)
.build()
).build();
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasReleaseSemaphoreResult()) {
return handleError(incorrectTypeStatus(response, "release_semaphore_result"));
}
SessionResponse.ReleaseSemaphoreResult result = response.getReleaseSemaphoreResult();
return handleResult(result.getReleased(), result.getStatus(), result.getIssuesList());
}
}
private static class DescribeSemaphoreMsg extends BaseResultMsg {
private final String name;
private final DescribeSemaphoreMode describeMode;
DescribeSemaphoreMsg(String name, DescribeSemaphoreMode describeMode) {
this.name = name;
this.describeMode = describeMode;
}
@Override
public SessionRequest makeRequest(long reqId) {
return SessionRequest.newBuilder().setDescribeSemaphore(
SessionRequest.DescribeSemaphore.newBuilder()
.setName(name)
.setIncludeOwners(describeMode.includeOwners())
.setIncludeWaiters(describeMode.includeWaiters())
.setWatchData(false)
.setWatchOwners(false)
.setReqId(reqId)
.build()
).build();
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasDescribeSemaphoreResult()) {
return handleError(incorrectTypeStatus(response, "describe_semaphore_result"));
}
SemaphoreDescription desc = null;
SessionResponse.DescribeSemaphoreResult result = response.getDescribeSemaphoreResult();
if (result.getSemaphoreDescription() != null) {
desc = new SemaphoreDescription(result.getSemaphoreDescription());
}
return handleResult(desc, result.getStatus(), result.getIssuesList());
}
}
private static class WatchSemaphoreMsg extends BaseResultMsg {
private final String name;
private final DescribeSemaphoreMode describeMode;
private final WatchSemaphoreMode watchMode;
private final ChangedMsg changedMsg = new ChangedMsg();
WatchSemaphoreMsg(String name, DescribeSemaphoreMode describeMode, WatchSemaphoreMode watchMode) {
this.name = name;
this.describeMode = describeMode;
this.watchMode = watchMode;
}
@Override
public SessionRequest makeRequest(long reqId) {
return SessionRequest.newBuilder().setDescribeSemaphore(
SessionRequest.DescribeSemaphore.newBuilder()
.setName(name)
.setIncludeOwners(describeMode.includeOwners())
.setIncludeWaiters(describeMode.includeWaiters())
.setWatchData(watchMode.watchData())
.setWatchOwners(watchMode.watchOwners())
.setReqId(reqId)
.build()
).build();
}
@Override
public StreamMsg> nextMsg() {
return changedMsg;
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasDescribeSemaphoreResult()) {
return handleError(incorrectTypeStatus(response, "describe_semaphore_result"));
}
SemaphoreWatcher watcher = null;
SessionResponse.DescribeSemaphoreResult result = response.getDescribeSemaphoreResult();
if (result.getSemaphoreDescription() != null) {
SemaphoreDescription desc = new SemaphoreDescription(result.getSemaphoreDescription());
watcher = new SemaphoreWatcher(desc, changedMsg.getResult());
}
return handleResult(watcher, result.getStatus(), result.getIssuesList());
}
private class ChangedMsg extends BaseResultMsg {
@Override
public SessionRequest makeRequest(long reqId) {
return WatchSemaphoreMsg.this.makeRequest(reqId);
}
@Override
public boolean handleResponse(SessionResponse response) {
if (!response.hasDescribeSemaphoreChanged()) {
return handleError(incorrectTypeStatus(response, "describe_semaphore_changed"));
}
SemaphoreChangedEvent event = new SemaphoreChangedEvent(response.getDescribeSemaphoreChanged());
return handleResult(event, StatusCodesProtos.StatusIds.StatusCode.SUCCESS, Collections.emptyList());
}
}
}
}