/*
* Copyright 2014-2017 Real Logic Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.aeron.driver;
import io.aeron.ErrorCode;
import io.aeron.command.*;
import org.agrona.DirectBuffer;
import org.agrona.concurrent.UnsafeBuffer;
import org.agrona.concurrent.broadcast.BroadcastTransmitter;
import java.nio.ByteBuffer;
import java.util.List;
import static io.aeron.command.ControlProtocolEvents.*;
/**
* Proxy for communicating from the driver to the client conductor.
*/
public class ClientProxy
{
private static final int WRITE_BUFFER_CAPACITY = 4096;
private final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(WRITE_BUFFER_CAPACITY));
private final BroadcastTransmitter transmitter;
private final ErrorResponseFlyweight errorResponse = new ErrorResponseFlyweight();
private final PublicationBuffersReadyFlyweight publicationReady = new PublicationBuffersReadyFlyweight();
private final ImageBuffersReadyFlyweight imageReady = new ImageBuffersReadyFlyweight();
private final CorrelatedMessageFlyweight correlatedMessage = new CorrelatedMessageFlyweight();
private final ImageMessageFlyweight imageMessage = new ImageMessageFlyweight();
public ClientProxy(final BroadcastTransmitter transmitter)
{
this.transmitter = transmitter;
errorResponse.wrap(buffer, 0);
imageReady.wrap(buffer, 0);
publicationReady.wrap(buffer, 0);
correlatedMessage.wrap(buffer, 0);
imageMessage.wrap(buffer, 0);
}
public void onError(final ErrorCode errorCode, final String errorMessage, final long correlationId)
{
final String msg = null == errorMessage ? "" : errorMessage;
errorResponse
.offendingCommandCorrelationId(correlationId)
.errorCode(errorCode)
.errorMessage(msg);
transmit(ON_ERROR, buffer, 0, errorResponse.length());
}
public void onAvailableImage(
final long correlationId,
final int streamId,
final int sessionId,
final String logFileName,
final List<SubscriberPosition> subscriberPositions,
final String sourceIdentity)
{
imageReady
.sessionId(sessionId)
.streamId(streamId)
.correlationId(correlationId);
final int size = subscriberPositions.size();
imageReady.subscriberPositionCount(size);
for (int i = 0; i < size; i++)
{
final SubscriberPosition position = subscriberPositions.get(i);
imageReady.subscriberPositionId(i, position.positionCounterId());
imageReady.positionIndicatorRegistrationId(i, position.subscription().registrationId());
}
imageReady
.logFileName(logFileName)
.sourceIdentity(sourceIdentity);
final int length = imageReady.length();
transmit(ON_AVAILABLE_IMAGE, buffer, 0, length);
}
public void onPublicationReady(
final long registrationId,
final int streamId,
final int sessionId,
final String logFileName,
final int positionCounterId,
final boolean isExclusive)
{
publicationReady
.sessionId(sessionId)
.streamId(streamId)
.correlationId(registrationId)
.publicationLimitCounterId(positionCounterId)
.logFileName(logFileName);
final int length = publicationReady.length();
final int msgTypeId = isExclusive ? ON_EXCLUSIVE_PUBLICATION_READY : ON_PUBLICATION_READY;
transmit(msgTypeId, buffer, 0, length);
}
public void operationSucceeded(final long correlationId)
{
correlatedMessage.clientId(0).correlationId(correlationId);
transmit(ON_OPERATION_SUCCESS, buffer, 0, CorrelatedMessageFlyweight.LENGTH);
}
public void onUnavailableImage(final long correlationId, final int streamId, final String channel)
{
imageMessage
.correlationId(correlationId)
.streamId(streamId)
.channel(channel);
final int length = imageMessage.length();
transmit(ON_UNAVAILABLE_IMAGE, buffer, 0, length);
}
private void transmit(final int msgTypeId, final DirectBuffer buffer, final int index, final int length)
{
transmitter.transmit(msgTypeId, buffer, index, length);
}
}