/*
* Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 com.amazonaws.services.dynamodbv2.client;
import java.util.Map;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.amazonaws.Request;
import com.amazonaws.Response;
import com.amazonaws.handlers.RequestHandler2;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughputExceededException;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
public class FaultInjectionRequestHandler extends RequestHandler2
{
private AmazonDynamoDBClient dynamoDBClient;
private static final Random rnd = new Random(1234);
private static final Log logger = LogFactory.getLog(FaultInjectionRequestHandler.class);
public FaultInjectionRequestHandler(AmazonDynamoDBClient dynamoDBClient)
{
this.dynamoDBClient = dynamoDBClient;
}
@Override
public void beforeRequest(Request<?> request)
{
/* Things to do just before a request is executed */
if (request.getOriginalRequest() instanceof PutItemRequest)
{
/* Throw throuhgput exceeded exception for 50% of put requests */
if (rnd.nextInt(2) == 0)
{
logger.info("Injecting ProvisionedThroughputExceededException");
throw new ProvisionedThroughputExceededException("Injected Error");
}
}
/* Add latency to some Get requests */
if (request.getOriginalRequest() instanceof GetItemRequest)
{
/* Delay 50% of GetItem requests by 500 ms */
if (rnd.nextInt(2) == 0)
{
/* Delay on average 50% of the requests from client perspective */
try
{
logger.info("Injecting 500 ms delay");
Thread.sleep(500);
}
catch (InterruptedException ie)
{
logger.info(ie);
throw new RuntimeException(ie);
}
}
}
}
@Override
public void afterResponse(Request<?> request, Response<?> response)
{
/*
* The following is a hit and miss for multi-threaded clients as the
* cache size is only 50 entries
*/
String awsRequestId = dynamoDBClient.getCachedResponseMetadata(request.getOriginalRequest()).getRequestId();
logger.info("AWS RequestID: " + awsRequestId);
/*
* Here you could inspect and alter the response object to see how your
* application behaves for specific data
*/
if (request.getOriginalRequest() instanceof GetItemRequest)
{
GetItemResult result = (GetItemResult) response.getAwsResponse();
Map<String, AttributeValue> item = result.getItem();
if (item.get("name").getS().equals("Airplane"))
{
// Alter the item
item.put("name", new AttributeValue("newAirplane"));
item.put("new attr", new AttributeValue("new attr"));
// Add some delay
try
{
Thread.sleep(500);
}
catch (InterruptedException ie)
{
logger.info(ie);
throw new RuntimeException(ie);
}
}
}
}
@Override
public void afterError(Request<?> request, Response<?> response, Exception e)
{
// TODO Auto-generated method stub
}
}