use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class MockReadableStreamChannel method testLaterChunkFailure.
/**
* Tests a case where some chunks succeed and a later chunk fails and ensures that the operation fails in
* such a scenario.
*/
@Test
public void testLaterChunkFailure() throws Exception {
// choose a blob with two chunks, first one will succeed and second will fail.
requestAndResultsList.clear();
requestAndResultsList.add(new RequestAndResult(chunkSize * 2));
List<DataNodeId> dataNodeIds = mockClusterMap.getDataNodeIds();
// Set the state of the mock servers so that they return success for the first send issued,
// but later ones fail. With 3 nodes, all partitions will come from the same nodes,
// so we set the errors in such a way that the first request received by every node succeeds and later ones fail.
List<ServerErrorCode> serverErrorList = new ArrayList<>();
serverErrorList.add(ServerErrorCode.No_Error);
for (int i = 0; i < 5; i++) {
serverErrorList.add(ServerErrorCode.Unknown_Error);
}
for (DataNodeId dataNodeId : dataNodeIds) {
MockServer server = mockServerLayout.getMockServer(dataNodeId.getHostname(), dataNodeId.getPort());
server.setServerErrors(serverErrorList);
}
Exception expectedException = new RouterException("", RouterErrorCode.AmbryUnavailable);
submitPutsAndAssertFailure(expectedException, true, false, true);
}
use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class MockReadableStreamChannel method testSlippedPutsSuccess.
/**
* Tests slipped puts scenario. That is, the first attempt at putting a chunk ends up in a failure,
* but a second attempt is made by the PutManager which results in a success.
*/
@Test
public void testSlippedPutsSuccess() throws Exception {
// choose a simple blob, one that will result in a single chunk. This is to ensure setting state properly
// to test things correctly. Note that slipped puts concern a chunk and not an operation (that is,
// every chunk is slipped put on its own), so testing for simple blobs is sufficient.
requestAndResultsList.clear();
requestAndResultsList.add(new RequestAndResult(chunkSize));
List<DataNodeId> dataNodeIds = mockClusterMap.getDataNodeIds();
// Set the state of the mock servers so that they return an error for the first send issued,
// but later ones succeed. With 3 nodes, for slipped puts, all partitions will come from the same nodes,
// so we set the errors in such a way that the first request received by every node fails.
// Note: The assumption is that there are 3 nodes per DC.
List<ServerErrorCode> serverErrorList = new ArrayList<>();
serverErrorList.add(ServerErrorCode.Unknown_Error);
serverErrorList.add(ServerErrorCode.No_Error);
for (DataNodeId dataNodeId : dataNodeIds) {
MockServer server = mockServerLayout.getMockServer(dataNodeId.getHostname(), dataNodeId.getPort());
server.setServerErrors(serverErrorList);
}
submitPutsAndAssertSuccess(true);
}
use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class CloudOperationTest method testGetBlobFailoverToAzureAndCheckData.
/**
* Disk backed DC all returns failure but cloud backed DC returns the Blob information successfully.
* Check the meta data and user data are correctly returned by the cloud colo.
*/
@Test
public void testGetBlobFailoverToAzureAndCheckData() throws Exception {
// a blob size that is greater than the maxChunkSize and is not a multiple of it. Will result in a composite blob.
int blobSize = maxChunkSize * random.nextInt(10) + random.nextInt(maxChunkSize - 1) + 1;
BlobProperties blobProperties = new BlobProperties(blobSize, "serviceId", "memberId", "contentType", false, Utils.Infinite_Time, Utils.getRandomShort(random), Utils.getRandomShort(random), false, null, null, null);
byte[] userMetadata = new byte[10];
random.nextBytes(userMetadata);
byte[] putContent = new byte[blobSize];
random.nextBytes(putContent);
ByteBuf putContentBuf = PooledByteBufAllocator.DEFAULT.heapBuffer(blobSize);
putContentBuf.writeBytes(putContent);
BlobId blobId = doDirectPut(blobProperties, userMetadata, putContentBuf.retainedDuplicate());
putContentBuf.release();
// Confirm we can get the blob from the local dc.
GetBlobOptionsInternal options = new GetBlobOptionsInternal(new GetBlobOptionsBuilder().build(), false, routerMetrics.ageAtGet);
getBlobAndAssertSuccess(blobId, (short) 0, blobSize, blobProperties, userMetadata, putContent, options);
// Local DC will fail with different errors but cloud will return the blob data.
ArrayList<MockServer> mockServersArray = new ArrayList<>(mockServers);
ArrayList<ServerErrorCode> serverErrors = new ArrayList<>(Arrays.asList(ServerErrorCode.values()));
// set the disk backed server status to various server level or partition level errors (not Blob_Deleted or Blob_Expired - as they are final)
serverErrors.remove(ServerErrorCode.Blob_Deleted);
serverErrors.remove(ServerErrorCode.Blob_Expired);
serverErrors.remove(ServerErrorCode.No_Error);
serverErrors.remove(ServerErrorCode.Blob_Authorization_Failure);
for (MockServer mockServer : mockServersArray) {
ServerErrorCode code = serverErrors.get(random.nextInt(serverErrors.size()));
mockServer.setServerErrorForAllRequests(code);
}
// cloud DC will return the data
getBlobAndAssertSuccess(blobId, (short) 0, blobSize, blobProperties, userMetadata, putContent, options);
}
use of com.github.ambry.server.ServerErrorCode 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.server.ServerErrorCode in project ambry by linkedin.
the class StoredBlob method updateBlobMap.
/**
* Updates the blob map based on the {@code ttlUpdateRequest}.
* @param ttlUpdateRequest the {@link TtlUpdateRequest} that needs to be processed
*/
private ServerErrorCode updateBlobMap(TtlUpdateRequest ttlUpdateRequest) {
ServerErrorCode errorCode = ServerErrorCode.No_Error;
StoredBlob blob = blobs.get(ttlUpdateRequest.getBlobId().getID());
if (blob != null && !blob.isDeleted() && !blob.hasExpired() && !blob.isTtlUpdated()) {
blob.updateExpiry(ttlUpdateRequest.getExpiresAtMs());
} else if (blob == null) {
errorCode = ServerErrorCode.Blob_Not_Found;
} else if (blob.isDeleted()) {
errorCode = ServerErrorCode.Blob_Deleted;
} else if (blob.hasExpired()) {
errorCode = ServerErrorCode.Blob_Expired;
} else if (blob.isTtlUpdated()) {
errorCode = ServerErrorCode.Blob_Already_Updated;
} else {
throw new IllegalStateException("Could not recognize blob state");
}
return errorCode;
}
Aggregations