/**
* Copyright 2013-2015 Seagate Technology LLC.
*
* This Source Code Form is subject to the terms of the Mozilla
* Public License, v. 2.0. If a copy of the MPL was not
* distributed with this file, You can obtain one at
* https://mozilla.org/MP:/2.0/.
*
* This program is distributed in the hope that it will be useful,
* but is provided AS-IS, WITHOUT ANY WARRANTY; including without
* the implied warranty of MERCHANTABILITY, NON-INFRINGEMENT or
* FITNESS FOR A PARTICULAR PURPOSE. See the Mozilla Public
* License for more details.
*
* See www.openkinetic.org for more project information
*/
package com.seagate.kinetic.client.internal.p2p;
import java.util.List;
import java.util.logging.Logger;
import kinetic.client.ClientConfiguration;
import kinetic.client.KineticException;
import kinetic.client.p2p.KineticP2pClient;
import kinetic.client.p2p.Operation;
import kinetic.client.p2p.PeerToPeerOperation;
import com.google.protobuf.ByteString;
import com.seagate.kinetic.client.internal.DefaultKineticClient;
import com.seagate.kinetic.client.internal.MessageFactory;
import com.seagate.kinetic.client.lib.ClientLogger;
import com.seagate.kinetic.common.lib.KineticMessage;
import com.seagate.kinetic.proto.Kinetic.Command;
import com.seagate.kinetic.proto.Kinetic.Command.MessageType;
import com.seagate.kinetic.proto.Kinetic.Command.P2POperation;
import com.seagate.kinetic.proto.Kinetic.Command.Status.StatusCode;
/**
*
* Kinetic peer to peer client implementation.
*
* @author chiaming
*
*/
public class DefaultKineticP2pClient extends DefaultKineticClient implements
KineticP2pClient {
private final static Logger LOG = ClientLogger.get();
public DefaultKineticP2pClient(ClientConfiguration config)
throws KineticException {
super(config);
}
/**
* P2P push operation raw API.
*
* @param request
* peer to peer push request message.
*
* @return peer to peer push response message.
*
* @throws KineticException
* if any internal error occurred.
*/
public KineticMessage PeerToPeerPush(KineticMessage request)
throws KineticException {
KineticMessage response = null;
response = request(request);
return response;
}
/**
* Peer to peer push application API (prototype).
*
* @param p2pOperation
* object that hold p2p operation information.
* @return the same instance of p2pOperation as the specified parameter with
* status set by the simulator/drive.
*
* @throws KineticException
* any internal error occurred.
*/
@Override
public PeerToPeerOperation PeerToPeerPush(PeerToPeerOperation p2pOperation)
throws KineticException {
KineticMessage km = MessageFactory.createKineticMessageWithBuilder();
// create request message.
Command.Builder commandBuilder = (Command.Builder) km.getCommand();
// set request type
commandBuilder.getHeaderBuilder().setMessageType(
MessageType.PEER2PEERPUSH);
// p2p builder
P2POperation.Builder p2pBuilder = commandBuilder.getBodyBuilder()
.getP2POperationBuilder();
// set peer hots/port/tls
p2pBuilder.getPeerBuilder().setHostname(
p2pOperation.getPeer().getHost());
p2pBuilder.getPeerBuilder().setPort(p2pOperation.getPeer().getPort());
p2pBuilder.getPeerBuilder().setTls(p2pOperation.getPeer().getUseTls());
// set operation list
List<Operation> operationList = p2pOperation.getOperationList();
for (Operation op : operationList) {
// operation builder
Command.P2POperation.Operation.Builder operationBuilder = Command.P2POperation.Operation
.newBuilder();
// set force flag
operationBuilder.setForce(op.getForced());
// set key
operationBuilder.setKey(ByteString.copyFrom(op.getKey()));
// set new key
if (op.getNewKey() != null) {
operationBuilder.setNewKey(ByteString.copyFrom(op.getNewKey()));
}
// set version
if (op.getVersion() != null) {
operationBuilder
.setVersion(ByteString.copyFrom(op.getVersion()));
}
// add operation to list
p2pBuilder.addOperation(operationBuilder.build());
}
// do request
KineticMessage response = PeerToPeerPush(km);
// get p2p op response
P2POperation peerToPeerOperationResponse = response.getCommand()
.getBody().getP2POperation();
StatusCode respScode = response.getCommand().getStatus().getCode();
/**
* throws KineticException if overall status failed.
*/
if (respScode != StatusCode.SUCCESS) {
// get status message
String msg = response.getCommand().getStatus().getStatusMessage();
// get exception message from response
String emsg = (msg == null) ? "Internal error for P2P ops" : msg;
// construct and throw exception
KineticException ke = new KineticException(emsg);
// set request message
ke.setRequestMessage(km);
// set response message
ke.setResponseMessage(response);
// log warning message
LOG.warning("p2p op failed, status code: " + respScode + ", msg: "
+ emsg);
throw ke;
}
// set overall status and message
// p2pOperation
// .setStatus(response.getCommand().getStatus().getCode() ==
// StatusCode.SUCCESS);
// set overall status
p2pOperation.setStatus(peerToPeerOperationResponse
.getAllChildOperationsSucceeded());
p2pOperation.setErrorMessage(response.getCommand().getStatus()
.getStatusMessage());
// set individual operation status and message
for (int i = 0; i < operationList.size(); i++) {
// status code
StatusCode sc = peerToPeerOperationResponse.getOperation(i)
.getStatus().getCode();
// set status
operationList.get(i).setStatus(sc == StatusCode.SUCCESS);
// set status code
operationList.get(i).setStatusCode(sc);
// set status message
operationList.get(i).setErrorMessage(
peerToPeerOperationResponse.getOperation(i).getStatus()
.getStatusMessage());
}
// return p2p operation response
return p2pOperation;
}
}