use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class TtlUpdateOperation method fetchRequests.
/**
* Fetch {@link TtlUpdateRequest}s to send for the operation.
* @param requestRegistrationCallback the {@link RequestRegistrationCallback} to use for addition of requests that
* need to be sent to the storage server
*/
private void fetchRequests(RequestRegistrationCallback<TtlUpdateOperation> requestRegistrationCallback) {
Iterator<ReplicaId> replicaIterator = operationTracker.getReplicaIterator();
while (replicaIterator.hasNext()) {
ReplicaId replica = replicaIterator.next();
String hostname = replica.getDataNodeId().getHostname();
Port port = RouterUtils.getPortToConnectTo(replica, routerConfig.routerEnableHttp2NetworkClient);
TtlUpdateRequest ttlUpdateRequest = createTtlUpdateRequest();
ttlUpdateRequestInfos.put(ttlUpdateRequest.getCorrelationId(), new TtlUpdateRequestInfo(time.milliseconds(), replica));
RequestInfo requestInfo = new RequestInfo(hostname, port, ttlUpdateRequest, replica, operationQuotaCharger);
requestRegistrationCallback.registerRequestToSend(this, requestInfo);
replicaIterator.remove();
if (RouterUtils.isRemoteReplica(routerConfig, replica)) {
LOGGER.trace("Making request with correlationId {} to a remote replica {} in {} ", ttlUpdateRequest.getCorrelationId(), replica.getDataNodeId(), replica.getDataNodeId().getDatacenterName());
routerMetrics.crossColoRequestCount.inc();
} else {
LOGGER.trace("Making request with correlationId {} to a local replica {} ", ttlUpdateRequest.getCorrelationId(), replica.getDataNodeId());
}
routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).ttlUpdateRequestRate.mark();
}
}
use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class StoredBlob method send.
/**
* Take in a request in the form of {@link Send} and return a response in the form of a
* {@link BoundedNettyByteBufReceive}.
* @param send the request.
* @return the response.
* @throws IOException if there was an error in interpreting the request.
*/
public BoundedNettyByteBufReceive send(Send send) throws IOException {
if (!shouldRespond) {
return null;
}
ServerErrorCode serverError = hardError != null ? hardError : serverErrors.size() > 0 ? serverErrors.poll() : ServerErrorCode.No_Error;
RequestOrResponseType type = ((RequestOrResponse) send).getRequestType();
RequestOrResponse response;
requestCounts.computeIfAbsent(type, k -> new LongAdder()).increment();
switch(type) {
case PutRequest:
response = makePutResponse((PutRequest) send, serverError);
break;
case GetRequest:
response = makeGetResponse((GetRequest) send, serverError);
break;
case DeleteRequest:
response = makeDeleteResponse((DeleteRequest) send, serverError);
break;
case TtlUpdateRequest:
response = makeTtlUpdateResponse((TtlUpdateRequest) send, serverError);
break;
case UndeleteRequest:
response = makeUndeleteResponse((UndeleteRequest) send, serverError);
break;
default:
throw new IOException("Unknown request type received");
}
ByteBufferChannel channel = new ByteBufferChannel(ByteBuffer.allocate((int) response.sizeInBytes()));
response.writeTo(channel);
response.release();
ByteBuffer payload = channel.getBuffer();
payload.flip();
BoundedNettyByteBufReceive receive = new BoundedNettyByteBufReceive(100 * 1024 * 1024);
receive.readFrom(Channels.newChannel(new ByteBufferInputStream(payload)));
return receive;
}
use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class AmbryServerRequestsTest method sendAndVerifyOperationRequest.
/**
* Sends and verifies that an operation specific request works correctly.
* @param requestType the type of the request to send.
* @param ids the partitionIds to send requests for.
* @param expectedErrorCode the {@link ServerErrorCode} expected in the response. For some requests this is the
* response in the constituents rather than the actual response ({@link GetResponse} and
* {@link ReplicaMetadataResponse}).
* @param forceCheckOpReceived if {@code true}, checks the operation received at the {@link Store} even if
* there is an error expected. Always checks op received if {@code expectedErrorCode} is
* {@link ServerErrorCode#No_Error}. Skips the check otherwise.
* @param clientIdStr the clientId string to construct request. if null, generate a random string as clientId.
* @throws InterruptedException
* @throws IOException
* @return a list of {@link Response}(s) associated with given partition ids.
*/
private List<Response> sendAndVerifyOperationRequest(RequestOrResponseType requestType, List<? extends PartitionId> ids, ServerErrorCode expectedErrorCode, Boolean forceCheckOpReceived, String clientIdStr) throws InterruptedException, IOException {
List<Response> responses = new ArrayList<>();
for (PartitionId id : ids) {
int correlationId = TestUtils.RANDOM.nextInt();
String clientId = clientIdStr == null ? TestUtils.getRandomString(10) : clientIdStr;
BlobId originalBlobId = new BlobId(CommonTestUtils.getCurrentBlobIdVersion(), BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, Utils.getRandomShort(TestUtils.RANDOM), Utils.getRandomShort(TestUtils.RANDOM), id, false, BlobId.BlobDataType.DATACHUNK);
BlobId convertedBlobId = new BlobId(CommonTestUtils.getCurrentBlobIdVersion(), BlobId.BlobIdType.CRAFTED, ClusterMap.UNKNOWN_DATACENTER_ID, originalBlobId.getAccountId(), originalBlobId.getContainerId(), id, false, BlobId.BlobDataType.DATACHUNK);
conversionMap.put(originalBlobId, convertedBlobId);
validKeysInStore.add(convertedBlobId);
RequestOrResponse request;
switch(requestType) {
case PutRequest:
BlobProperties properties = new BlobProperties(0, "serviceId", originalBlobId.getAccountId(), originalBlobId.getAccountId(), false);
request = new PutRequest(correlationId, clientId, originalBlobId, properties, ByteBuffer.allocate(0), Unpooled.wrappedBuffer(ByteBuffer.allocate(0)), 0, BlobType.DataBlob, null);
break;
case DeleteRequest:
request = new DeleteRequest(correlationId, clientId, originalBlobId, SystemTime.getInstance().milliseconds());
break;
case UndeleteRequest:
request = new UndeleteRequest(correlationId, clientId, originalBlobId, SystemTime.getInstance().milliseconds());
break;
case GetRequest:
PartitionRequestInfo pRequestInfo = new PartitionRequestInfo(id, Collections.singletonList(originalBlobId));
request = new GetRequest(correlationId, clientId, MessageFormatFlags.All, Collections.singletonList(pRequestInfo), GetOption.Include_All);
break;
case ReplicaMetadataRequest:
ReplicaMetadataRequestInfo rRequestInfo = new ReplicaMetadataRequestInfo(id, findTokenHelper.getFindTokenFactoryFromReplicaType(ReplicaType.DISK_BACKED).getNewFindToken(), "localhost", "/tmp", ReplicaType.DISK_BACKED, replicationConfig.replicaMetadataRequestVersion);
request = new ReplicaMetadataRequest(correlationId, clientId, Collections.singletonList(rRequestInfo), Long.MAX_VALUE, replicationConfig.replicaMetadataRequestVersion);
break;
case TtlUpdateRequest:
request = new TtlUpdateRequest(correlationId, clientId, originalBlobId, Utils.Infinite_Time, SystemTime.getInstance().milliseconds());
break;
default:
throw new IllegalArgumentException(requestType + " not supported by this function");
}
responses.add(sendAndVerifyOperationRequest(request, expectedErrorCode, forceCheckOpReceived));
}
return responses;
}
use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class InMemoryCloudDestinationErrorSimulationTest method testTtlUpdateErrorSimulation.
/**
* test error simulation for TtlUpdateRequest
* @throws Exception
*/
@Test
public void testTtlUpdateErrorSimulation() throws Exception {
BlobId blobId = doPut(partitionId);
TtlUpdateRequest ttlUpdateRequest = new TtlUpdateRequest(1234, "clientId", blobId, Utils.Infinite_Time, SystemTime.getInstance().milliseconds());
RequestInfo requestInfo = new RequestInfo(hostname, port, ttlUpdateRequest, replica, null);
ResponseInfo responseInfo = sendAndWaitForResponses(requestInfo);
TtlUpdateResponse response = responseInfo.getError() == null ? (TtlUpdateResponse) RouterUtils.mapToReceivedResponse((Response) responseInfo.getResponse()) : null;
Assert.assertEquals("TtlUpdate should succeed.", response.getError(), ServerErrorCode.No_Error);
response.release();
// inject error for cloud colo.
cloudDestination.setServerErrorForAllRequests(StoreErrorCodes.TTL_Expired);
ttlUpdateRequest = new TtlUpdateRequest(1234, "clientId", blobId, Utils.Infinite_Time, SystemTime.getInstance().milliseconds());
requestInfo = new RequestInfo(hostname, port, ttlUpdateRequest, replica, null);
responseInfo = sendAndWaitForResponses(requestInfo);
response = responseInfo.getError() == null ? ((TtlUpdateResponse) RouterUtils.mapToReceivedResponse((Response) responseInfo.getResponse())) : null;
Assert.assertEquals("TtlUpdate should return Blob_Expired.", response.getError(), ServerErrorCode.Blob_Expired);
response.release();
}
use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class TtlUpdateManager method handleResponse.
/**
* Handles responses received for each of the {@link TtlUpdateOperation} within this TtlUpdateManager.
* @param responseInfo the {@link ResponseInfo} containing the response.
*/
void handleResponse(ResponseInfo responseInfo) {
long startTime = time.milliseconds();
TtlUpdateResponse ttlUpdateResponse = RouterUtils.extractResponseAndNotifyResponseHandler(responseHandler, routerMetrics, responseInfo, TtlUpdateResponse::readFrom, TtlUpdateResponse::getError);
RequestInfo routerRequestInfo = responseInfo.getRequestInfo();
int correlationId = ((TtlUpdateRequest) routerRequestInfo.getRequest()).getCorrelationId();
TtlUpdateOperation ttlUpdateOperation = correlationIdToTtlUpdateOperation.remove(correlationId);
// If it is still an active operation, hand over the response. Otherwise, ignore.
if (ttlUpdateOperations.contains(ttlUpdateOperation)) {
boolean exceptionEncountered = false;
try {
ttlUpdateOperation.handleResponse(responseInfo, ttlUpdateResponse);
} catch (Exception e) {
exceptionEncountered = true;
ttlUpdateOperation.setOperationException(new RouterException("TTLUpdate handleResponse encountered unexpected error", e, RouterErrorCode.UnexpectedInternalError));
}
if (exceptionEncountered || ttlUpdateOperation.isOperationComplete()) {
if (ttlUpdateOperations.remove(ttlUpdateOperation)) {
onComplete(ttlUpdateOperation);
}
}
routerMetrics.ttlUpdateManagerHandleResponseTimeMs.update(time.milliseconds() - startTime);
} else {
routerMetrics.ignoredResponseCount.inc();
}
}
Aggregations