Commit f46337d2 authored by chiaming2000's avatar chiaming2000
Browse files

Java API and simulator back ground operation skeleton implementation.

This provides an initial API to write Java tests against the drive.

There is no error checking for this implementaion but will be improved
shortly.

The simulator simply respond to the request with a SUCCESS status and
set the end key in the Body/BackGroundOperation/Range message construct. 
parent 0953ae99
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -40,10 +40,15 @@ import com.seagate.kinetic.client.internal.p2p.DefaultKineticP2pClient;
import com.seagate.kinetic.common.lib.HMACAlgorithmUtil;
import com.seagate.kinetic.common.lib.KineticMessage;
import com.seagate.kinetic.proto.Kinetic.Command;
import com.seagate.kinetic.proto.Kinetic.Command.BackgroundOperation;
import com.seagate.kinetic.proto.Kinetic.Command.BackgroundOperation.BackOpType;
import com.seagate.kinetic.proto.Kinetic.Command.GetLog;
import com.seagate.kinetic.proto.Kinetic.Command.GetLog.Type;
import com.seagate.kinetic.proto.Kinetic.Command.Header;
import com.seagate.kinetic.proto.Kinetic.Command.MessageType;
import com.seagate.kinetic.proto.Kinetic.Command.PinOperation.PinOpType;
import com.seagate.kinetic.proto.Kinetic.Command.Priority;
import com.seagate.kinetic.proto.Kinetic.Command.Range;
import com.seagate.kinetic.proto.Kinetic.Command.Security;
import com.seagate.kinetic.proto.Kinetic.Command.Security.ACL.HMACAlgorithm;
import com.seagate.kinetic.proto.Kinetic.Command.Setup;
@@ -772,4 +777,53 @@ public class DefaultAdminClient extends DefaultKineticP2pClient implements Kinet
        
    }

    @Override
    public KineticMessage backgroundOperation(BackOpType backopType,
            Range range, Priority priority) throws KineticException {
        
        // create request message
        KineticMessage kmreq = MessageFactory.createKineticMessageWithBuilder();
        
        Command.Builder commandBuilder = (Command.Builder) kmreq.getCommand(); 
        
        Header.Builder header = commandBuilder.getHeaderBuilder();
        
        // set message type
        header.setMessageType(MessageType.BACKOP);

        // set priority
        header.setPriority(priority);
        
        // get back ground op builder
        BackgroundOperation.Builder backop = 
                commandBuilder.getBodyBuilder().getBackgroundOperationBuilder();
        
        // set back up type
        backop.setBackOpType(backopType);
        
        // set range
        backop.setRange(range);
        
        KineticMessage kmresp = request (kmreq);

        if (kmresp.getCommand().getHeader().getMessageType() != MessageType.BACKOP_RESPONSE) {
            throw new KineticException("received wrong message type.");
        }

        if (kmresp.getCommand().getStatus().getCode() == Status.StatusCode.NOT_AUTHORIZED) {

            throw new KineticException("Authorized Exception: "
                    + kmresp.getCommand().getStatus().getCode() + ": "
                    + kmresp.getCommand().getStatus().getStatusMessage());
        }

        if (kmresp.getCommand().getStatus().getCode() != Status.StatusCode.SUCCESS) {
            throw new KineticException("Unknown Error: "
                    + kmresp.getCommand().getStatus().getCode() + ": "
                    + kmresp.getCommand().getStatus().getStatusMessage());
        }
        
        return kmresp;
    }
    
}
+21 −1
Original line number Diff line number Diff line
@@ -19,6 +19,11 @@ package kinetic.admin;

import java.util.List;

import com.seagate.kinetic.common.lib.KineticMessage;
import com.seagate.kinetic.proto.Kinetic.Command.BackgroundOperation.BackOpType;
import com.seagate.kinetic.proto.Kinetic.Command.Priority;
import com.seagate.kinetic.proto.Kinetic.Command.Range;

import kinetic.client.KineticException;
import kinetic.client.p2p.KineticP2pClient;

@@ -271,4 +276,19 @@ public interface KineticAdminClient extends KineticP2pClient {
     * @throws KineticException
     */
    public void setClusterVersion (long newClusterVersion) throws KineticException;
    
    /**
     * Performs Background operation to the Kinetic drive.
     * <p>
     * 
     * @param backupType type of background op
     * @param range range of background op
     * @param priority priority of background op
     * @return kinetic response message.
     * @throws KineticException if any internal error occurred
     * 
     * @see BackOpType
     * @see Priority
     */
    public KineticMessage backgroundOperation (BackOpType backupType, Range range, Priority priority) throws KineticException;
}
+137 −0
Original line number Diff line number Diff line
/**
 * 
 * Copyright (C) 2014 Seagate Technology.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */
package com.seagate.kinetic.simulator.internal;

import java.util.logging.Logger;

import kinetic.client.KineticException;

import com.seagate.kinetic.common.lib.KineticMessage;
import com.seagate.kinetic.proto.Kinetic.Command;
import com.seagate.kinetic.proto.Kinetic.Command.BackgroundOperation;
import com.seagate.kinetic.proto.Kinetic.Command.BackgroundOperation.BackOpType;

import com.seagate.kinetic.proto.Kinetic.Command.MessageType;

import com.seagate.kinetic.proto.Kinetic.Command.Security.ACL.Permission;
import com.seagate.kinetic.proto.Kinetic.Command.Status.StatusCode;

/**
 * 
 * Back ground operation handler prototype implementation
 * <p>
 * The current implementation responds to the request with a SUCCESS status if it passed
 * minimal verifications.
 * 
 * @author chiaming
 *
 */
public abstract class BackGroundOpHandler {
    
    private final static Logger logger = Logger.getLogger(BackgroundOperation.class
            .getName());

    public static void handleOperation(KineticMessage request,
            KineticMessage respond, SimulatorEngine engine)
            throws KVStoreException, KineticException {

        Command.Builder commandBuilder = (Command.Builder) respond.getCommand();

        // set reply type
        commandBuilder.getHeaderBuilder().setMessageType(
                MessageType.BACKOP_RESPONSE);

        // set ack sequence
        commandBuilder.getHeaderBuilder().setAckSequence(
                request.getCommand().getHeader().getSequence());

        try {
            
            //check if message is valid
            checkIsMessageValid (request);
            
            // check permission
            checkPermission (request, engine);  
            
            /**
             *  XXX 09/09/2014 chiaming:
             *  framework to start background operation
             *  the job should be stoppable by a higher priority received
             *  before/after the long running bg ops.
             *  
             *  The following statements are for testing purpose only
             */
            
            // set response back op type
            commandBuilder
                    .getBodyBuilder()
                    .getBackgroundOperationBuilder()
                    .setBackOpType(
                            request.getCommand().getBody()
                                    .getBackgroundOperation().getBackOpType());
            
            // set endkey in response
            commandBuilder
                    .getBodyBuilder()
                    .getBackgroundOperationBuilder()
                    .getRangeBuilder()
                    .setEndKey(
                            request.getCommand().getBody()
                                    .getBackgroundOperation().getRange()
                                    .getEndKey());

        } catch (KVSecurityException se) {
            commandBuilder.getStatusBuilder()
                    .setCode(StatusCode.NOT_AUTHORIZED);
            commandBuilder.getStatusBuilder().setStatusMessage(se.getMessage());
            logger.warning("unauthorized pin opeartion request");
        } catch (InvalidRequestException ire) {
            commandBuilder.getStatusBuilder().setCode(
                    StatusCode.INVALID_REQUEST);
            commandBuilder.getStatusBuilder()
                    .setStatusMessage(ire.getMessage());
        }
    }
    
    private static void checkIsMessageValid (KineticMessage request) throws InvalidRequestException {
        
        BackgroundOperation bgo = request.getCommand().getBody().getBackgroundOperation();
        BackOpType boType = bgo.getBackOpType();
        
        switch (boType) {
        case MEDIASCAN:
        case MEDIAOPTIMIZE:
            // XXX: more request message validation here
            return;
        default:
            throw new InvalidRequestException ("not a valid back ground op type: " + boType.name());
        }
        
    }
    
    private static void checkPermission (KineticMessage request,
            SimulatorEngine engine) throws KVSecurityException {
        
        // check if client has permission
        Authorizer.checkPermission(engine.getAclMap(), request.getMessage().getHmacAuth().getIdentity(), 
                Permission.RANGE);
    }

}
+2 −0
Original line number Diff line number Diff line
@@ -514,6 +514,8 @@ public class SimulatorEngine implements MessageService {
                if (hasPermission) {
                    this.p2pHandler.push(aclmap, store, kmreq, kmresp);
                }
            } else if (kmreq.getCommand().getBody().hasBackgroundOperation()) {
                BackGroundOpHandler.handleOperation(kmreq, kmresp, this);
            }
        } catch (DeviceLockedException ire) {