Package voldemort.rest.coordinator

Source Code of voldemort.rest.coordinator.CoordinatorWorkerThread

package voldemort.rest.coordinator;

import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.REQUEST_TIMEOUT;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jboss.netty.channel.MessageEvent;

import voldemort.common.VoldemortOpCode;
import voldemort.rest.DeleteResponseSender;
import voldemort.rest.GetAllResponseSender;
import voldemort.rest.GetMetadataResponseSender;
import voldemort.rest.GetResponseSender;
import voldemort.rest.PutResponseSender;
import voldemort.rest.RestDeleteErrorHandler;
import voldemort.rest.RestErrorHandler;
import voldemort.rest.RestGetErrorHandler;
import voldemort.rest.RestGetVersionErrorHandler;
import voldemort.rest.RestPutErrorHandler;
import voldemort.rest.RestUtils;
import voldemort.store.CompositeVoldemortRequest;
import voldemort.store.StoreDefinition;
import voldemort.store.stats.StoreStats;
import voldemort.utils.ByteArray;
import voldemort.utils.ByteUtils;
import voldemort.utils.StoreDefinitionUtils;
import voldemort.versioning.VectorClock;
import voldemort.versioning.Versioned;

public class CoordinatorWorkerThread implements Runnable {

    private final static RestGetErrorHandler getErrorHandler = new RestGetErrorHandler();
    private final static RestGetVersionErrorHandler getVersionErrorHandler = new RestGetVersionErrorHandler();
    private final static RestPutErrorHandler putErrorHandler = new RestPutErrorHandler();
    private final static RestDeleteErrorHandler deleteErrorHandler = new RestDeleteErrorHandler();

    private MessageEvent messageEvent;
    CompositeVoldemortRequest<ByteArray, byte[]> requestObject;
    private DynamicTimeoutStoreClient<ByteArray, byte[]> storeClient = null;
    private final CoordinatorMetadata coordinatorMetadata;
    private final Logger logger = Logger.getLogger(getClass());
    private final StoreStats coordinatorPerfStats;

    public CoordinatorWorkerThread(MessageEvent channelEvent,
                                   CoordinatorMetadata coordinatorMetadata,
                                   StoreStats coordinatorPerfStats) {
        this.messageEvent = channelEvent;
        this.coordinatorMetadata = coordinatorMetadata;
        this.coordinatorPerfStats = coordinatorPerfStats;
    }

    @Override
    // TODO: Add perf stats in the next iteration
    public void run() {
        Object message = messageEvent.getMessage();
        if(message instanceof CoordinatorStoreClientRequest) {
            CoordinatorStoreClientRequest storeClientRequestObject = (CoordinatorStoreClientRequest) message;
            this.requestObject = storeClientRequestObject.getRequestObject();
            this.storeClient = storeClientRequestObject.getStoreClient();

            // This shouldn't ideally happen.
            if(this.requestObject != null) {

                switch(requestObject.getOperationType()) {
                    case VoldemortOpCode.GET_METADATA_OP_CODE:
                        if(logger.isDebugEnabled()) {
                            logger.debug("GET Metadata request received.");
                        }

                        try {

                            String queryStoreName = ByteUtils.getString(this.requestObject.getKey()
                                                                                          .get(),
                                                                        "UTF-8");
                            StoreDefinition storeDef = StoreDefinitionUtils.getStoreDefinitionWithName(this.coordinatorMetadata.getStoresDefs(),
                                                                                                       queryStoreName);
                            String serializerInfoXml = RestUtils.constructSerializerInfoXml(storeDef);
                            GetMetadataResponseSender metadataResponseSender = new GetMetadataResponseSender(messageEvent,
                                                                                                             serializerInfoXml.getBytes());

                            metadataResponseSender.sendResponse(this.coordinatorPerfStats,
                                                                true,
                                                                this.requestObject.getRequestOriginTimeInMs());
                            if(logger.isDebugEnabled()) {
                                logger.debug("GET Metadata successful !");
                            }
                        } catch(Exception e) {
                            /*
                             * We might get InsufficientOperationalNodes
                             * exception due to a timeout, thus creating
                             * confusion in the root cause. Hence explicitly
                             * check for timeout.
                             */
                            if(System.currentTimeMillis() >= (this.requestObject.getRequestOriginTimeInMs() + this.requestObject.getRoutingTimeoutInMs())) {
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    REQUEST_TIMEOUT,
                                                                    "GET METADATA request timed out: "
                                                                            + e.getMessage());
                            } else {
                                getErrorHandler.handleExceptions(messageEvent, e);
                            }
                        }
                        break;

                    case VoldemortOpCode.GET_OP_CODE:
                        if(logger.isDebugEnabled()) {
                            logger.debug("GET request received.");
                        }

                        try {
                            boolean keyExists = false;
                            List<Versioned<byte[]>> versionedValues = this.storeClient.getWithCustomTimeout(this.requestObject);
                            if(versionedValues == null || versionedValues.size() == 0) {
                                if(this.requestObject.getValue() != null) {
                                    if(versionedValues == null) {
                                        versionedValues = new ArrayList<Versioned<byte[]>>();
                                    }
                                    versionedValues.add(this.requestObject.getValue());
                                    keyExists = true;

                                }
                            } else {
                                keyExists = true;
                            }

                            if(keyExists) {
                                GetResponseSender responseConstructor = new GetResponseSender(messageEvent,
                                                                                              requestObject.getKey(),
                                                                                              versionedValues,
                                                                                              this.storeClient.getStoreName());
                                responseConstructor.sendResponse(this.coordinatorPerfStats,
                                                                 true,
                                                                 this.requestObject.getRequestOriginTimeInMs());
                                if(logger.isDebugEnabled()) {
                                    logger.debug("GET successful !");
                                }

                            } else {
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    NOT_FOUND,
                                                                    "Requested Key does not exist");
                            }

                        } catch(Exception e) {
                            /*
                             * We might get InsufficientOperationalNodes
                             * exception due to a timeout, thus creating
                             * confusion in the root cause. Hence explicitly
                             * check for timeout.
                             */
                            if(System.currentTimeMillis() >= (this.requestObject.getRequestOriginTimeInMs() + this.requestObject.getRoutingTimeoutInMs())) {
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    REQUEST_TIMEOUT,
                                                                    "GET request timed out: "
                                                                            + e.getMessage());
                            } else {
                                getErrorHandler.handleExceptions(messageEvent, e);
                            }
                        }
                        break;

                    case VoldemortOpCode.GET_ALL_OP_CODE:
                        if(logger.isDebugEnabled()) {
                            logger.debug("GET ALL request received.");
                        }

                        try {
                            Map<ByteArray, List<Versioned<byte[]>>> versionedResponses = this.storeClient.getAllWithCustomTimeout(this.requestObject);
                            if(versionedResponses == null
                               || versionedResponses.values().size() == 0) {
                                logger.error("Error when doing getall. Keys do not exist.");

                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    NOT_FOUND,
                                                                    "Error when doing getall. Keys do not exist.");
                            } else {
                                GetAllResponseSender responseConstructor = new GetAllResponseSender(messageEvent,
                                                                                                    versionedResponses,
                                                                                                    this.storeClient.getStoreName());
                                responseConstructor.sendResponse(this.coordinatorPerfStats,
                                                                 true,
                                                                 this.requestObject.getRequestOriginTimeInMs());

                                if(logger.isDebugEnabled()) {
                                    logger.debug("GET ALL successful !");
                                }

                            }

                        } catch(Exception e) {
                            /*
                             * We might get InsufficientOperationalNodes
                             * exception due to a timeout, thus creating
                             * confusion in the root cause. Hence explicitly
                             * check for timeout.
                             */
                            if(System.currentTimeMillis() >= (this.requestObject.getRequestOriginTimeInMs() + this.requestObject.getRoutingTimeoutInMs())) {
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    REQUEST_TIMEOUT,
                                                                    "GET ALL request timed out: "
                                                                            + e.getMessage());
                            } else {
                                getErrorHandler.handleExceptions(messageEvent, e);
                            }
                        }
                        break;

                    // TODO: Implement this in the next pass
                    case VoldemortOpCode.GET_VERSION_OP_CODE:

                        if(logger.isDebugEnabled()) {
                            logger.debug("Incoming get version request");
                        }

                        try {

                            if(logger.isDebugEnabled()) {
                                logger.debug("GET versions request successful !");
                            }

                        } catch(Exception e) {
                            /*
                             * We might get InsufficientOperationalNodes
                             * exception due to a timeout, thus creating
                             * confusion in the root cause. Hence explicitly
                             * check for timeout.
                             */
                            if(System.currentTimeMillis() >= (this.requestObject.getRequestOriginTimeInMs() + this.requestObject.getRoutingTimeoutInMs())) {
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    REQUEST_TIMEOUT,
                                                                    "GET VERSION request timed out: "
                                                                            + e.getMessage());
                            } else {
                                getVersionErrorHandler.handleExceptions(messageEvent, e);
                            }
                        }
                        break;

                    case VoldemortOpCode.PUT_OP_CODE:
                        if(logger.isDebugEnabled()) {
                            logger.debug("PUT request received.");
                        }

                        try {
                            VectorClock successfulPutVC = null;

                            if(this.requestObject.getValue() != null) {
                                successfulPutVC = ((VectorClock) this.storeClient.putVersionedWithCustomTimeout(this.requestObject)).clone();
                            } else {
                                successfulPutVC = ((VectorClock) this.storeClient.putWithCustomTimeout(this.requestObject)).clone();
                            }

                            PutResponseSender responseConstructor = new PutResponseSender(messageEvent,
                                                                                          successfulPutVC,
                                                                                          this.storeClient.getStoreName(),
                                                                                          this.requestObject.getKey());
                            responseConstructor.sendResponse(this.coordinatorPerfStats,
                                                             true,
                                                             this.requestObject.getRequestOriginTimeInMs());

                            if(logger.isDebugEnabled()) {
                                logger.debug("PUT successful !");
                            }

                        } catch(Exception e) {
                            /*
                             * We might get InsufficientOperationalNodes
                             * exception due to a timeout, thus creating
                             * confusion in the root cause. Hence explicitly
                             * check for timeout.
                             */
                            if(System.currentTimeMillis() >= (this.requestObject.getRequestOriginTimeInMs() + this.requestObject.getRoutingTimeoutInMs())) {
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    REQUEST_TIMEOUT,
                                                                    "PUT request timed out: "
                                                                            + e.getMessage());
                            } else {
                                putErrorHandler.handleExceptions(messageEvent, e);
                            }
                        }

                        break;

                    case VoldemortOpCode.DELETE_OP_CODE:
                        if(logger.isDebugEnabled()) {
                            logger.debug("Incoming delete request");
                        }

                        try {
                            boolean isDeleted = this.storeClient.deleteWithCustomTimeout(this.requestObject);
                            if(isDeleted) {
                                DeleteResponseSender responseConstructor = new DeleteResponseSender(messageEvent,
                                                                                                    this.storeClient.getStoreName(),
                                                                                                    this.requestObject.getKey());
                                responseConstructor.sendResponse(this.coordinatorPerfStats,
                                                                 true,
                                                                 this.requestObject.getRequestOriginTimeInMs());

                                if(logger.isDebugEnabled()) {
                                    logger.debug("DELETE request successful !");
                                }

                            } else {
                                logger.error("Requested Key with the specified version does not exist");
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    NOT_FOUND,
                                                                    "Requested Key with the specified version does not exist");
                            }

                        } catch(Exception e) {

                            /*
                             * We might get InsufficientOperationalNodes
                             * exception due to a timeout, thus creating
                             * confusion in the root cause. Hence explicitly
                             * check for timeout.
                             */
                            if(System.currentTimeMillis() >= (this.requestObject.getRequestOriginTimeInMs() + this.requestObject.getRoutingTimeoutInMs())) {
                                RestErrorHandler.writeErrorResponse(this.messageEvent,
                                                                    REQUEST_TIMEOUT,
                                                                    "DELETE request timed out: "
                                                                            + e.getMessage());
                            } else {
                                deleteErrorHandler.handleExceptions(messageEvent, e);
                            }
                        }
                        break;

                    default:
                        System.err.println("Illegal operation.");
                        return;
                }

            }
        }
    }
}
TOP

Related Classes of voldemort.rest.coordinator.CoordinatorWorkerThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.