All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.camunda.zeebe.broker.transport.commandapi.CommandResponseWriterImpl Maven / Gradle / Ivy

There is a newer version: 8.7.0-alpha1
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Licensed under the Camunda License 1.0. You may not use this file
 * except in compliance with the Camunda License 1.0.
 */
package io.camunda.zeebe.broker.transport.commandapi;

import static io.camunda.zeebe.protocol.record.ExecuteCommandResponseEncoder.keyNullValue;
import static io.camunda.zeebe.protocol.record.ExecuteCommandResponseEncoder.partitionIdNullValue;
import static io.camunda.zeebe.protocol.record.ExecuteCommandResponseEncoder.valueHeaderLength;

import io.camunda.zeebe.protocol.Protocol;
import io.camunda.zeebe.protocol.record.ExecuteCommandResponseEncoder;
import io.camunda.zeebe.protocol.record.MessageHeaderEncoder;
import io.camunda.zeebe.protocol.record.RecordType;
import io.camunda.zeebe.protocol.record.RejectionType;
import io.camunda.zeebe.protocol.record.ValueType;
import io.camunda.zeebe.protocol.record.intent.Intent;
import io.camunda.zeebe.stream.api.CommandResponseWriter;
import io.camunda.zeebe.transport.ServerOutput;
import io.camunda.zeebe.transport.impl.ServerResponseImpl;
import io.camunda.zeebe.util.buffer.BufferWriter;
import java.util.Objects;
import org.agrona.DirectBuffer;
import org.agrona.MutableDirectBuffer;
import org.agrona.concurrent.UnsafeBuffer;

public final class CommandResponseWriterImpl implements CommandResponseWriter, BufferWriter {

  private final MessageHeaderEncoder messageHeaderEncoder = new MessageHeaderEncoder();
  private final ExecuteCommandResponseEncoder responseEncoder = new ExecuteCommandResponseEncoder();
  private final ServerResponseImpl response = new ServerResponseImpl();
  private final ServerOutput output;
  private final UnsafeBuffer rejectionReason = new UnsafeBuffer(0, 0);
  private int partitionId = partitionIdNullValue();
  private long key = keyNullValue();
  private BufferWriter valueWriter;
  private RecordType recordType = RecordType.NULL_VAL;
  private ValueType valueType = ValueType.NULL_VAL;
  private short intent = Intent.NULL_VAL;
  private RejectionType rejectionType = RejectionType.NULL_VAL;

  public CommandResponseWriterImpl(final ServerOutput output) {
    this.output = output;
  }

  @Override
  public CommandResponseWriterImpl partitionId(final int partitionId) {
    this.partitionId = partitionId;
    return this;
  }

  @Override
  public CommandResponseWriterImpl key(final long key) {
    this.key = key;
    return this;
  }

  @Override
  public CommandResponseWriterImpl intent(final Intent intent) {
    this.intent = intent.value();
    return this;
  }

  @Override
  public CommandResponseWriterImpl recordType(final RecordType recordType) {
    this.recordType = recordType;
    return this;
  }

  @Override
  public CommandResponseWriterImpl valueType(final ValueType valueType) {
    this.valueType = valueType;
    return this;
  }

  @Override
  public CommandResponseWriterImpl rejectionType(final RejectionType rejectionType) {
    this.rejectionType = rejectionType;
    return this;
  }

  @Override
  public CommandResponseWriterImpl rejectionReason(final DirectBuffer rejectionReason) {
    this.rejectionReason.wrap(rejectionReason);
    return this;
  }

  @Override
  public CommandResponseWriterImpl valueWriter(final BufferWriter writer) {
    valueWriter = writer;
    return this;
  }

  @Override
  public void tryWriteResponse(final int remoteStreamId, final long requestId) {
    Objects.requireNonNull(valueWriter);

    try {
      response.reset().setPartitionId(remoteStreamId).setRequestId(requestId).writer(this);

      output.sendResponse(response);
    } finally {
      reset();
    }
  }

  @Override
  public int getLength() {
    return MessageHeaderEncoder.ENCODED_LENGTH
        + ExecuteCommandResponseEncoder.BLOCK_LENGTH
        + valueHeaderLength()
        + valueWriter.getLength()
        + ExecuteCommandResponseEncoder.rejectionReasonHeaderLength()
        + rejectionReason.capacity();
  }

  @Override
  public void write(final MutableDirectBuffer buffer, int offset) {
    // protocol header
    messageHeaderEncoder
        .wrap(buffer, offset)
        .blockLength(responseEncoder.sbeBlockLength())
        .templateId(responseEncoder.sbeTemplateId())
        .schemaId(responseEncoder.sbeSchemaId())
        .version(responseEncoder.sbeSchemaVersion());

    offset += messageHeaderEncoder.encodedLength();

    // protocol message
    responseEncoder
        .wrap(buffer, offset)
        .recordType(recordType)
        .partitionId(partitionId)
        .valueType(valueType)
        .intent(intent)
        .key(key)
        .rejectionType(rejectionType);

    offset = responseEncoder.limit();

    final int valueLength = valueWriter.getLength();
    buffer.putInt(offset, valueLength, Protocol.ENDIANNESS);

    offset += valueHeaderLength();
    valueWriter.write(buffer, offset);

    offset += valueLength;

    responseEncoder.limit(offset);
    responseEncoder.putRejectionReason(rejectionReason, 0, rejectionReason.capacity());
  }

  private void reset() {
    partitionId = partitionIdNullValue();
    key = keyNullValue();
    valueWriter = null;
    recordType = RecordType.NULL_VAL;
    intent = Intent.NULL_VAL;
    valueType = ValueType.NULL_VAL;
    rejectionType = RejectionType.NULL_VAL;
    rejectionReason.wrap(0, 0);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy