Loading kinetic-client/src/main/java/com/seagate/kinetic/client/internal/ClientProxy.java +17 −7 Original line number Diff line number Diff line Loading @@ -40,12 +40,12 @@ import com.seagate.kinetic.common.lib.Hmac; import com.seagate.kinetic.common.lib.Hmac.HmacException; import com.seagate.kinetic.common.lib.KineticMessage; import com.seagate.kinetic.proto.Kinetic.Command; import com.seagate.kinetic.proto.Kinetic.Message; import com.seagate.kinetic.proto.Kinetic.Message.AuthType; import com.seagate.kinetic.proto.Kinetic.Message.Builder; import com.seagate.kinetic.proto.Kinetic.Command.Header; import com.seagate.kinetic.proto.Kinetic.Command.MessageType; import com.seagate.kinetic.proto.Kinetic.Command.Range; import com.seagate.kinetic.proto.Kinetic.Message; import com.seagate.kinetic.proto.Kinetic.Message.AuthType; import com.seagate.kinetic.proto.Kinetic.Message.Builder; /** Loading Loading @@ -594,11 +594,21 @@ public class ClientProxy { */ if (header.getMessageType() == MessageType.PUT) { if (commandBuilder.getBodyBuilder().getKeyValueBuilder().hasTag() == false) { // calculate value Hmac ByteString tag = Hmac.calcTag(kineticMessage, this.myKey); // calculate value message digest // ByteString tag = Hmac.calcTag(kineticMessage, this.myKey); // ByteString tag = // MessageDigestUtil.calculateTag(Algorithm.SHA1, // kineticMessage.getValue()); // // set tag commandBuilder.getBodyBuilder().getKeyValueBuilder() .setTag(tag); // commandBuilder.getBodyBuilder().getKeyValueBuilder() // .setTag(tag); // // Algorithm algo = Algorithm.SHA1; // commandBuilder.getBodyBuilder().getKeyValueBuilder() // .setAlgorithm(algo); } } Loading kinetic-common/src/main/java/com/seagate/kinetic/common/lib/MessageDigestUtil.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /** * Copyright (C) 2014 Seagate Technology. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.seagate.kinetic.common.lib; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import java.util.logging.Logger; import com.google.protobuf.ByteString; import com.seagate.kinetic.proto.Kinetic.Command.Algorithm; /** * * @author chiaming * */ public class MessageDigestUtil { private final static Logger logger = Logger .getLogger(MessageDigestUtil.class.getName()); public static ByteString calculateTag(Algorithm algo, byte[] value) { byte[] digest = null; // get md instance MessageDigest md = getInstance(algo); if (value == null) { value = new byte[0]; } // calculate and return digest digest = md.digest(value); return ByteString.copyFrom(digest); } public static boolean isSupportedForKineticJava(Algorithm algo) { switch (algo) { case SHA1: return true; case SHA2: return true; default: return false; } } public static MessageDigest getInstance(Algorithm algo) { switch (algo) { case SHA1: return getDigestInstance("SHA-1"); case SHA2: return getDigestInstance("SHA-256"); default: throw new java.lang.UnsupportedOperationException( "unsupported algorithm., name = " + algo.name()); } } public static MessageDigest getDigestInstance(String algoName) { MessageDigest md = null; try { md = MessageDigest.getInstance(algoName); } catch (NoSuchAlgorithmException e) { logger.log(Level.WARNING, e.getMessage(), e); } return md; } } kinetic-simulator/src/main/java/com/seagate/kinetic/simulator/internal/BackGroundOpHandler.java +166 −0 Original line number Diff line number Diff line Loading @@ -19,16 +19,23 @@ */ package com.seagate.kinetic.simulator.internal; import java.util.logging.Level; import java.util.logging.Logger; import kinetic.client.KineticException; import kinetic.simulator.SimulatorConfiguration; import com.google.protobuf.ByteString; import com.seagate.kinetic.common.lib.KineticMessage; import com.seagate.kinetic.common.lib.MessageDigestUtil; import com.seagate.kinetic.proto.Kinetic.Command; import com.seagate.kinetic.proto.Kinetic.Command.Algorithm; 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; import com.seagate.kinetic.simulator.persist.KVValue; import com.seagate.kinetic.simulator.persist.Store; import com.seagate.kinetic.simulator.persist.memory.KeyComparator; /** * Loading @@ -45,10 +52,13 @@ public abstract class BackGroundOpHandler { private final static Logger logger = Logger.getLogger(BackGroundOpHandler.class .getName()); @SuppressWarnings({ "rawtypes" }) public static void mediaScan(KineticMessage request, KineticMessage respond, SimulatorEngine engine) throws KVStoreException, KineticException { KeyComparator comparator = new KeyComparator(); Command.Builder commandBuilder = (Command.Builder) respond.getCommand(); // set reply type Loading @@ -59,13 +69,33 @@ public abstract class BackGroundOpHandler { commandBuilder.getHeaderBuilder().setAckSequence( request.getCommand().getHeader().getSequence()); // max return key count int maxReturned = request.getCommand().getBody().getRange() .getMaxReturned(); int MaxSupported = SimulatorConfiguration.getMaxSupportedKeyRangeSize(); try { // if not set, set to default if (maxReturned <= 0) { maxReturned = MaxSupported; } else if (maxReturned > MaxSupported) { throw new InvalidRequestException( "Exceed max returned key range., max allowed=" + SimulatorConfiguration .getMaxSupportedKeyRangeSize() + ", request=" + maxReturned); } // check message type checkIsMessageValid (request); // check permission checkPermission (request, engine); Store store = engine.getStore(); /** * XXX 09/09/2014 chiaming: * framework to start background operation Loading @@ -75,6 +105,116 @@ public abstract class BackGroundOpHandler { * The following statements are for testing purpose only */ // get start key ByteString startKey = request.getCommand().getBody().getRange() .getStartKey(); // get end key ByteString endKey = request.getCommand().getBody().getRange() .getEndKey(); byte[] endKeybytes = endKey.toByteArray(); // if scan to the end of the map boolean toEndOfMap = false; if (endKey.isEmpty()) { toEndOfMap = true; } // finish scan flag boolean done = false; // kv entry KVValue kv = null; // check if start key inclusive if (request.getCommand().getBody().getRange() .getStartKeyInclusive()) { // include start key kv = get(store, startKey); if (kv == null) { kv = getNext(store, startKey); } } else { // get next key kv = getNext(store, startKey); } // scan the drive long index = 0; while (done == false) { if (kv != null) { // get algo Algorithm algo = kv.getAlgorithm(); // get tag ByteString tag = kv.getTag(); // compare tag logger.info((index++) + ": scan media for key: " + kv.getKeyOf() + ", algo: " + algo); if ((tag != null) && (tag.isEmpty() == false) && MessageDigestUtil .isSupportedForKineticJava(algo)) { ByteString ctag = MessageDigestUtil.calculateTag(algo, kv.getData() .toByteArray()); if (tag.equals(ctag) == false) { logger.info("tag does not match for key: " + kv.getKeyOf() + ", algo: " + algo); if (commandBuilder.getBodyBuilder() .getRangeBuilder().getKeysCount() < maxReturned) { // add bad key commandBuilder.getBodyBuilder() .getRangeBuilder() .addKeys(kv.getKeyOf()); } else { // reached max returned keys // set endkey in response commandBuilder.getBodyBuilder() .getRangeBuilder() .setEndKey(kv.getKeyOf()); // finished scan return; } } else { logger.info("tag validated for key: " + kv.getKeyOf() + ", algo: " + algo); } } // read next key kv = getNext(store, kv.getKeyOf()); if (kv == null) { // reached to end of map done = true; } else if (toEndOfMap == false) { /** * check if passed end key */ if (comparator.compare(endKeybytes, kv.getKeyOf() .toByteArray()) < 0) { done = true; } } } else { logger.info(index + ": scan media reached end of map"); done = true; } } // set endkey in response commandBuilder .getBodyBuilder() Loading Loading @@ -182,4 +322,30 @@ public abstract class BackGroundOpHandler { Permission.RANGE); } @SuppressWarnings({ "unchecked", "rawtypes" }) private static KVValue get(Store store, ByteString key) { KVValue kv = null; try { kv = (KVValue) store.get(key); } catch (Exception e) { logger.info(e.getMessage()); } return kv; } @SuppressWarnings({ "unchecked", "rawtypes" }) private static KVValue getNext(Store store, ByteString key) { KVValue kv = null; try { kv = (KVValue) store.getNext(key); } catch (Exception e) { logger.log(Level.WARNING, e.getMessage(), e); } return kv; } } kinetic-simulator/src/main/java/com/seagate/kinetic/simulator/internal/BatchOperationHandler.java +1 −1 Original line number Diff line number Diff line Loading @@ -100,7 +100,7 @@ public class BatchOperationHandler { } } public void checkBatchMode(KineticMessage kmreq) public synchronized void checkBatchMode(KineticMessage kmreq) throws InvalidRequestException { if (kmreq.getIsInvalidBatchMessage()) { Loading kinetic-simulator/src/main/java/com/seagate/kinetic/simulator/internal/KVStoreNotFound.java +9 −1 Original line number Diff line number Diff line Loading @@ -32,4 +32,12 @@ public class KVStoreNotFound extends KVStoreException{ */ private static final long serialVersionUID = 335206057367584819L; public KVStoreNotFound() { super(); } public KVStoreNotFound(String msg) { super(msg); } } Loading
kinetic-client/src/main/java/com/seagate/kinetic/client/internal/ClientProxy.java +17 −7 Original line number Diff line number Diff line Loading @@ -40,12 +40,12 @@ import com.seagate.kinetic.common.lib.Hmac; import com.seagate.kinetic.common.lib.Hmac.HmacException; import com.seagate.kinetic.common.lib.KineticMessage; import com.seagate.kinetic.proto.Kinetic.Command; import com.seagate.kinetic.proto.Kinetic.Message; import com.seagate.kinetic.proto.Kinetic.Message.AuthType; import com.seagate.kinetic.proto.Kinetic.Message.Builder; import com.seagate.kinetic.proto.Kinetic.Command.Header; import com.seagate.kinetic.proto.Kinetic.Command.MessageType; import com.seagate.kinetic.proto.Kinetic.Command.Range; import com.seagate.kinetic.proto.Kinetic.Message; import com.seagate.kinetic.proto.Kinetic.Message.AuthType; import com.seagate.kinetic.proto.Kinetic.Message.Builder; /** Loading Loading @@ -594,11 +594,21 @@ public class ClientProxy { */ if (header.getMessageType() == MessageType.PUT) { if (commandBuilder.getBodyBuilder().getKeyValueBuilder().hasTag() == false) { // calculate value Hmac ByteString tag = Hmac.calcTag(kineticMessage, this.myKey); // calculate value message digest // ByteString tag = Hmac.calcTag(kineticMessage, this.myKey); // ByteString tag = // MessageDigestUtil.calculateTag(Algorithm.SHA1, // kineticMessage.getValue()); // // set tag commandBuilder.getBodyBuilder().getKeyValueBuilder() .setTag(tag); // commandBuilder.getBodyBuilder().getKeyValueBuilder() // .setTag(tag); // // Algorithm algo = Algorithm.SHA1; // commandBuilder.getBodyBuilder().getKeyValueBuilder() // .setAlgorithm(algo); } } Loading
kinetic-common/src/main/java/com/seagate/kinetic/common/lib/MessageDigestUtil.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /** * Copyright (C) 2014 Seagate Technology. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.seagate.kinetic.common.lib; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import java.util.logging.Logger; import com.google.protobuf.ByteString; import com.seagate.kinetic.proto.Kinetic.Command.Algorithm; /** * * @author chiaming * */ public class MessageDigestUtil { private final static Logger logger = Logger .getLogger(MessageDigestUtil.class.getName()); public static ByteString calculateTag(Algorithm algo, byte[] value) { byte[] digest = null; // get md instance MessageDigest md = getInstance(algo); if (value == null) { value = new byte[0]; } // calculate and return digest digest = md.digest(value); return ByteString.copyFrom(digest); } public static boolean isSupportedForKineticJava(Algorithm algo) { switch (algo) { case SHA1: return true; case SHA2: return true; default: return false; } } public static MessageDigest getInstance(Algorithm algo) { switch (algo) { case SHA1: return getDigestInstance("SHA-1"); case SHA2: return getDigestInstance("SHA-256"); default: throw new java.lang.UnsupportedOperationException( "unsupported algorithm., name = " + algo.name()); } } public static MessageDigest getDigestInstance(String algoName) { MessageDigest md = null; try { md = MessageDigest.getInstance(algoName); } catch (NoSuchAlgorithmException e) { logger.log(Level.WARNING, e.getMessage(), e); } return md; } }
kinetic-simulator/src/main/java/com/seagate/kinetic/simulator/internal/BackGroundOpHandler.java +166 −0 Original line number Diff line number Diff line Loading @@ -19,16 +19,23 @@ */ package com.seagate.kinetic.simulator.internal; import java.util.logging.Level; import java.util.logging.Logger; import kinetic.client.KineticException; import kinetic.simulator.SimulatorConfiguration; import com.google.protobuf.ByteString; import com.seagate.kinetic.common.lib.KineticMessage; import com.seagate.kinetic.common.lib.MessageDigestUtil; import com.seagate.kinetic.proto.Kinetic.Command; import com.seagate.kinetic.proto.Kinetic.Command.Algorithm; 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; import com.seagate.kinetic.simulator.persist.KVValue; import com.seagate.kinetic.simulator.persist.Store; import com.seagate.kinetic.simulator.persist.memory.KeyComparator; /** * Loading @@ -45,10 +52,13 @@ public abstract class BackGroundOpHandler { private final static Logger logger = Logger.getLogger(BackGroundOpHandler.class .getName()); @SuppressWarnings({ "rawtypes" }) public static void mediaScan(KineticMessage request, KineticMessage respond, SimulatorEngine engine) throws KVStoreException, KineticException { KeyComparator comparator = new KeyComparator(); Command.Builder commandBuilder = (Command.Builder) respond.getCommand(); // set reply type Loading @@ -59,13 +69,33 @@ public abstract class BackGroundOpHandler { commandBuilder.getHeaderBuilder().setAckSequence( request.getCommand().getHeader().getSequence()); // max return key count int maxReturned = request.getCommand().getBody().getRange() .getMaxReturned(); int MaxSupported = SimulatorConfiguration.getMaxSupportedKeyRangeSize(); try { // if not set, set to default if (maxReturned <= 0) { maxReturned = MaxSupported; } else if (maxReturned > MaxSupported) { throw new InvalidRequestException( "Exceed max returned key range., max allowed=" + SimulatorConfiguration .getMaxSupportedKeyRangeSize() + ", request=" + maxReturned); } // check message type checkIsMessageValid (request); // check permission checkPermission (request, engine); Store store = engine.getStore(); /** * XXX 09/09/2014 chiaming: * framework to start background operation Loading @@ -75,6 +105,116 @@ public abstract class BackGroundOpHandler { * The following statements are for testing purpose only */ // get start key ByteString startKey = request.getCommand().getBody().getRange() .getStartKey(); // get end key ByteString endKey = request.getCommand().getBody().getRange() .getEndKey(); byte[] endKeybytes = endKey.toByteArray(); // if scan to the end of the map boolean toEndOfMap = false; if (endKey.isEmpty()) { toEndOfMap = true; } // finish scan flag boolean done = false; // kv entry KVValue kv = null; // check if start key inclusive if (request.getCommand().getBody().getRange() .getStartKeyInclusive()) { // include start key kv = get(store, startKey); if (kv == null) { kv = getNext(store, startKey); } } else { // get next key kv = getNext(store, startKey); } // scan the drive long index = 0; while (done == false) { if (kv != null) { // get algo Algorithm algo = kv.getAlgorithm(); // get tag ByteString tag = kv.getTag(); // compare tag logger.info((index++) + ": scan media for key: " + kv.getKeyOf() + ", algo: " + algo); if ((tag != null) && (tag.isEmpty() == false) && MessageDigestUtil .isSupportedForKineticJava(algo)) { ByteString ctag = MessageDigestUtil.calculateTag(algo, kv.getData() .toByteArray()); if (tag.equals(ctag) == false) { logger.info("tag does not match for key: " + kv.getKeyOf() + ", algo: " + algo); if (commandBuilder.getBodyBuilder() .getRangeBuilder().getKeysCount() < maxReturned) { // add bad key commandBuilder.getBodyBuilder() .getRangeBuilder() .addKeys(kv.getKeyOf()); } else { // reached max returned keys // set endkey in response commandBuilder.getBodyBuilder() .getRangeBuilder() .setEndKey(kv.getKeyOf()); // finished scan return; } } else { logger.info("tag validated for key: " + kv.getKeyOf() + ", algo: " + algo); } } // read next key kv = getNext(store, kv.getKeyOf()); if (kv == null) { // reached to end of map done = true; } else if (toEndOfMap == false) { /** * check if passed end key */ if (comparator.compare(endKeybytes, kv.getKeyOf() .toByteArray()) < 0) { done = true; } } } else { logger.info(index + ": scan media reached end of map"); done = true; } } // set endkey in response commandBuilder .getBodyBuilder() Loading Loading @@ -182,4 +322,30 @@ public abstract class BackGroundOpHandler { Permission.RANGE); } @SuppressWarnings({ "unchecked", "rawtypes" }) private static KVValue get(Store store, ByteString key) { KVValue kv = null; try { kv = (KVValue) store.get(key); } catch (Exception e) { logger.info(e.getMessage()); } return kv; } @SuppressWarnings({ "unchecked", "rawtypes" }) private static KVValue getNext(Store store, ByteString key) { KVValue kv = null; try { kv = (KVValue) store.getNext(key); } catch (Exception e) { logger.log(Level.WARNING, e.getMessage(), e); } return kv; } }
kinetic-simulator/src/main/java/com/seagate/kinetic/simulator/internal/BatchOperationHandler.java +1 −1 Original line number Diff line number Diff line Loading @@ -100,7 +100,7 @@ public class BatchOperationHandler { } } public void checkBatchMode(KineticMessage kmreq) public synchronized void checkBatchMode(KineticMessage kmreq) throws InvalidRequestException { if (kmreq.getIsInvalidBatchMessage()) { Loading
kinetic-simulator/src/main/java/com/seagate/kinetic/simulator/internal/KVStoreNotFound.java +9 −1 Original line number Diff line number Diff line Loading @@ -32,4 +32,12 @@ public class KVStoreNotFound extends KVStoreException{ */ private static final long serialVersionUID = 335206057367584819L; public KVStoreNotFound() { super(); } public KVStoreNotFound(String msg) { super(msg); } }