package com.zaranux.k2c;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.CreateDomainRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.PutAttributesRequest;
import com.amazonaws.services.simpledb.model.SelectRequest;
import com.zaranux.crypto.abe.kp.ABE;
import com.zaranux.crypto.abe.kp.Entity;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.io.ByteArrayInputStream;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
public class DataObject {
private static AmazonSimpleDB sdb = null;
private static AmazonS3 s3 = null;
private static String myDomain = "MetaData";
private static String myBucket = "akiajydwrw6mbq3nsk4a-test-bucket";
public static void init()
{
try
{
sdb = new AmazonSimpleDBClient(new PropertiesCredentials(
SimpleDBSample.class.getResourceAsStream("AwsCredentials.properties")));
// Create a domain
//sdb.createDomain(new CreateDomainRequest(myDomain));
s3 = new AmazonS3Client(new PropertiesCredentials(
S3Sample.class.getResourceAsStream("AwsCredentials.properties")));
//s3.createBucket(myBucket);
}catch(IOException e)
{
System.out.println(""+ e);
}
}
Entity entity = null;
String path = null;
int ReadRevisionNumber;
int WriteRevisionNumber;
public int getRRN()
{
return ReadRevisionNumber;
}
public int getWRN()
{
return WriteRevisionNumber;
}
public DataObject(String path, int RRN, int WRN, Entity entity)
{
this.path = path;
this.ReadRevisionNumber = RRN;
this.WriteRevisionNumber = WRN;
this.entity = entity;
}
public DataObject(String path, Entity entity)
{
this.entity = entity;
this.path = path;
}
public String toString()
{
String result = "";
result += "Path = " + path + "\n";
result += "ReadRevisionNumber = " + ReadRevisionNumber + "\n";
result += "WriteRevisionNumber = " + WriteRevisionNumber + "\n";
return result;
}
public boolean revokeRead()
{
boolean result = false;
ReadRevisionNumber++;
return result;
}
public boolean revokeWrite()
{
boolean result = false;
WriteRevisionNumber++;
return result;
}
public boolean load()
{
boolean result = false;
String selectExpression = "select * from `" + myDomain + "` where itemName() = '" + path + "'";
System.out.println("Selecting: " + selectExpression + "\n");
SelectRequest selectRequest = new SelectRequest(selectExpression);
for (Item item : sdb.select(selectRequest).getItems()) {
System.out.println(" Item");
System.out.println(" Name: " + item.getName());
for (Attribute attribute : item.getAttributes()) {
if(attribute.getName().equals("ReadRevisionNumber"))
{
ReadRevisionNumber = Integer.parseInt(attribute.getValue());
result = true;
}
if(attribute.getName().equals("WriteRevisionNumber"))
{
WriteRevisionNumber = Integer.parseInt(attribute.getValue());
}
// if(attribute.getName().equals("Levels"))
// {
// Levels = Integer.parseInt(attribute.getValue());
// }
System.out.println(" Attribute");
System.out.println(" Name: " + attribute.getName());
System.out.println(" Value: " + attribute.getValue());
}
}
return result;
}
public boolean save()
{
boolean result = false;
PutAttributesRequest par = new PutAttributesRequest();
par.setItemName(path);
par.withAttributes(new ReplaceableAttribute("ReadRevisionNumber", "" + ReadRevisionNumber, true));
par.withAttributes(new ReplaceableAttribute("WriteRevisionNumber", "" + WriteRevisionNumber, true));
String[] pathComp = getPathComps(path);
if(pathComp != null)
{
par.withAttributes(new ReplaceableAttribute("Levels", "" + pathComp.length, true));
for(int i = 0; i<pathComp.length; i++)
{
par.withAttributes(new ReplaceableAttribute("Level"+i, "" + pathComp[i], true));
}
par.setDomainName(myDomain);
DataObject.sdb.putAttributes(par);
}
return result;
}
public boolean create()
{
boolean result = false;
PutAttributesRequest par = new PutAttributesRequest();
par.setItemName(path);
par.withAttributes(new ReplaceableAttribute("ReadRevisionNumber", "1", true));
par.withAttributes(new ReplaceableAttribute("WriteRevisionNumber", "1", true));
String[] pathComp = getPathComps(path);
if(pathComp != null)
{
par.withAttributes(new ReplaceableAttribute("Levels", "" + pathComp.length, true));
for(int i = 0; i<pathComp.length; i++)
{
par.withAttributes(new ReplaceableAttribute("Level"+i, "" + pathComp[i], true));
}
par.setDomainName(myDomain);
DataObject.sdb.putAttributes(par);
}
return result;
}
public DataObject[] list()
{
DataObject[] result = null;
String[] paths = getPathComps(path);
String selectExpression = "select * from `" + myDomain + "` where Levels = '" + (paths.length + 1) + "'";
for(int i=0; i< paths.length ; i++)
{
selectExpression += " AND Level" + i + " = '" + paths[i] +"'";
}
System.out.println("Selecting: " + selectExpression + "\n");
SelectRequest selectRequest = new SelectRequest(selectExpression);
for (Item item : sdb.select(selectRequest).getItems()) {
System.out.println(" Item");
System.out.println(" Name: " + item.getName());
for (Attribute attribute : item.getAttributes()) {
System.out.println(" Attribute");
System.out.println(" Name: " + attribute.getName());
System.out.println(" Value: " + attribute.getValue());
}
}
return result;
}
static String[] getPathComps(String path)
{
String[] comps = null;
if(path.startsWith("/"))
{
if(path.equals("/"))
{
comps = new String[]{"/"};
}else
{
comps = path.split("/");
comps[0] = "/";
}
}
return comps;
}
public DataObject[] getAnscesstors()
{
DataObject[] anscestors = null;
String[] paths = getPathComps(path);
String path = "";
String selectExpression = "select * from `" + myDomain + "` where Levels <= '" + (paths.length) + "' AND (";
for(int i=0; i < paths.length; i++)
{
path += paths[i];
selectExpression += "itemName() = '" + path + "' OR ";
if (i != 0) path += "/";
}
if(selectExpression.endsWith(" OR "))
selectExpression = selectExpression.substring(0, selectExpression.length()-4);
selectExpression += ") order by Levels";
SelectRequest selectRequest = new SelectRequest(selectExpression);
List<Item> items = sdb.select(selectRequest).getItems();
anscestors = new DataObject[items.size()];
int i = 0;
for (Item item : items) {
int RRN = 0;
int WRN = 0;
for (Attribute attribute : item.getAttributes()) {
if(attribute.getName().equals("ReadRevisionNumber"))
{
RRN = Integer.parseInt(attribute.getValue());
}
if(attribute.getName().equals("WriteRevisionNumber"))
{
WRN = Integer.parseInt(attribute.getValue());
}
}
anscestors[i] = new DataObject(item.getName(),RRN, WRN,entity);
i++;
}
return anscestors;
}
public byte[] read()
{
byte[] data = null;
S3Object object = s3.getObject(new GetObjectRequest(myBucket, path));
InputStream is = object.getObjectContent();
byte[] signLen = new byte[4];
byte[] encLen = new byte[4];
try{
is.read(signLen);
int signLenth = ABE.getIntegerFromBytes(signLen, 0);
is.read(encLen);
int encLenth = ABE.getIntegerFromBytes(encLen, 0);
Test.out.println("Read size: " + encLenth);
byte[] sign = new byte[signLenth];
readIS(is,sign);
byte[] enc = new byte[encLenth];
readIS(is,enc);
String[] paths = getPathComps(path);
String[] atts = new String[paths.length+1];
for(int i = 0; i< paths.length ; i++)
{
atts[i] = "l"+i+ "=" + paths[i];
}
atts[paths.length] = "w";
data = entity.decrypt(enc);
boolean valid = entity.validateSignature(atts, data, sign);
System.out.println("Valid = " + valid);
}catch(IOException e)
{
}
return data;
}
public boolean write(byte[] data)
{
boolean result = false;
DataObject[] ans = getAnscesstors();
String[] atts = new String[ans.length*2];
String[] paths = getPathComps(path);
for(int i = 0; i< ans.length ; i++) //DataObject dobj:ans)
{
atts[2*i] = "l"+i+ "=" + paths[i];
atts[2*i+1] = "#lr" + i + "=" + ans[i].getRRN();
}
byte[] enc = entity.encrypt(data, atts);
Test.enc_temp = enc;
//data = entity.decrypt(enc);
byte[] sign = entity.sign(data);
byte[] all = new byte[4+4+sign.length + enc.length];
byte signLen[] = new byte[4];
byte dataLen[] = new byte[4];
ABE.getIntegerBytes(sign.length, signLen, 0) ;
ABE.getIntegerBytes(enc.length, dataLen, 0) ;
Test.out.println("Write size: " + enc.length);
System.arraycopy(signLen, 0, all, 0, 4);
System.arraycopy(dataLen, 0, all, 4, 4);
System.arraycopy(sign, 0, all, 8, sign.length);
System.arraycopy(enc , 0, all, 8 + sign.length, enc.length);
ByteArrayInputStream bais = new ByteArrayInputStream(all);
ObjectMetadata omd = new ObjectMetadata();
omd.setContentLength(all.length);
PutObjectRequest por = new PutObjectRequest(myBucket,path,bais,omd);
s3.putObject(por);
return result;
}
private int readIS(InputStream is , byte[] b)
{
return readIS(is ,b, 0, b.length);
}
private int readIS(InputStream is , byte[] b, int off, int len)
{
int read = -1;
int total = 0;
try
{
while( ( read = is.read(b, off, len)) > 0)
{
len -= read;
off += read;
total = off;
}
}catch(IOException e)
{
System.out.println("" + e);
}
return total;
}
}