/*******************************************************************************
* /*
* *
* * Copyright 2013 Netflix, Inc.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
* *
* *
******************************************************************************/
package com.netflix.staash.rest.resources;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.google.common.io.Files;
import com.google.inject.Inject;
import com.netflix.staash.json.JsonArray;
import com.netflix.staash.json.JsonObject;
import com.netflix.staash.rest.util.StaashConstants;
import com.netflix.staash.rest.util.StaashRequestContext;
import com.netflix.staash.service.DataService;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import com.sun.jersey.spi.container.ResourceFilters;
@Path("/staash/v1/data")
public class StaashDataResourceImpl {
private DataService datasvc;
@Inject
public StaashDataResourceImpl(DataService data) {
this.datasvc = data;
}
@GET
@Path("{db}/{table}")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String listAllRow(@PathParam("db") String db,
@PathParam("table") String table) {
return datasvc.listRow(db, table, "", "");
}
@GET
@Path("{db}/{table}/{keycol}/{key}")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String listRow(@PathParam("db") String db,
@PathParam("table") String table,
@PathParam("keycol") String keycol, @PathParam("key") String key) {
return datasvc.listRow(db, table, keycol, key);
}
@GET
@Path("/join/{db}/{table1}/{table2}/{joincol}/{value}")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String doJoin(@PathParam("db") String db,
@PathParam("table1") String table1,
@PathParam("table2") String table2,
@PathParam("joincol") String joincol,
@PathParam("value") String value) {
return datasvc.doJoin(db, table1, table2, joincol, value);
}
@GET
@Path("/timeseries/{db}/{table}/{eventtime}")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String readEvent(@PathParam("db") String db,
@PathParam("table") String table,
@PathParam("eventtime") String time) {
String out;
try {
out = datasvc.readEvent(db, table, time);
} catch (RuntimeException e) {
out = "{\"msg\":\"" + e.getMessage() + "\"}";
}
return out;
}
@GET
@Path("/timeseries/{db}/{table}/{prefix}/{eventtime}")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String readEvent(@PathParam("db") String db,
@PathParam("table") String table,
@PathParam("prefix") String prefix,
@PathParam("eventtime") String time) {
String out;
try {
out = datasvc.readEvent(db, table, prefix, time);
} catch (RuntimeException e) {
out = "{\"msg\":\"" + e.getMessage() + "\"}";
}
return out;
}
@GET
@Path("/timeseries/{db}/{table}/{prefix}/{starttime}/{endtime}")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String readEvent(@PathParam("db") String db,
@PathParam("table") String table,
@PathParam("prefix") String prefix,
@PathParam("starttime") String starttime,
@PathParam("endtime") String endtime) {
String out;
try {
out = datasvc.readEvent(db, table, prefix, starttime, endtime);
} catch (RuntimeException e) {
out = "{\"msg\":\"" + e.getMessage() + "\"}";
}
return out;
}
@POST
@Path("{db}/{table}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String updateRow(@PathParam("db") String db,
@PathParam("table") String table, String rowObject) {
return datasvc.writeRow(db, table, new JsonObject(rowObject));
}
@POST
@Path("/timeseries/{db}/{table}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String insertEvent(@PathParam("db") String db,
@PathParam("table") String table, String rowStr) {
JsonArray eventsArr = new JsonArray(rowStr);
return datasvc.writeEvents(db, table, eventsArr);
}
@GET
@Path("/kvstore/{key}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@ResourceFilters(StaashAuditFilter.class)
public byte[] getObject(@PathParam("key") String key) {
byte[] value = datasvc.readChunked("kvstore", "kvmap", key);
StaashRequestContext.addContext("N-BYTES", String.valueOf(value.length));
return value;
}
@POST
@Path("/kvstore")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String storeFile(
@FormDataParam("value") InputStream uploadedInputStream,
@FormDataParam("value") FormDataContentDisposition fileDetail) {
try {
writeToChunkedKVStore(uploadedInputStream, fileDetail.getFileName());
} catch (IOException e) {
e.printStackTrace();
return "{\"msg\":\"file could not be uploaded\"}";
}
return "{\"msg\":\"file successfully uploaded\"}";
}
@POST
@Path("/kvstore/name/{name}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(StaashAuditFilter.class)
public String storeNamedFile(
@FormDataParam("value") InputStream uploadedInputStream,
@PathParam("name") String name) {
try {
writeToChunkedKVStore(uploadedInputStream, name);
} catch (IOException e) {
e.printStackTrace();
return "{\"msg\":\"file could not be uploaded\"}";
}
return "{\"msg\":\"file successfully uploaded\"}";
}
private void writeToChunkedKVStore(InputStream is, String objectName) throws IOException {
InputStream input = null;
File tmpFile = null;
try {
String uploadedFileLocation = "/tmp/" + "staashFile-" + UUID.randomUUID();
tmpFile = new File(uploadedFileLocation);
OutputStream out = new FileOutputStream(tmpFile);
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = is.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
byte[] fbytes = Files.toByteArray(new File(uploadedFileLocation));
StaashRequestContext.addContext("N-BYTES", String.valueOf(fbytes.length));
if (fbytes!=null && fbytes.length>StaashConstants.MAX_FILE_UPLOAD_SIZE_IN_KB*1000) {
throw new RuntimeException("File is too large to upload, max size supported is 2MB");
}
input = new FileInputStream(new File(uploadedFileLocation));
datasvc.writeChunked("kvstore", "kvmap", objectName, input);
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (input!=null) input.close();
if (tmpFile!=null) {
tmpFile.delete();
}
}
}
//
// private void writeToKVStore(InputStream uploadedInputStream,
// String uploadedFileName) {
//
// try {
// String uploadedFileLocation = "/tmp/" + uploadedFileName;
// OutputStream out = new FileOutputStream(new File(
// uploadedFileLocation));
// int read = 0;
// byte[] bytes = new byte[1024];
//
// out = new FileOutputStream(new File(uploadedFileLocation));
// while ((read = uploadedInputStream.read(bytes)) != -1) {
// out.write(bytes, 0, read);
// }
// out.flush();
// out.close();
// byte[] fbytes = Files.toByteArray(new File(uploadedFileLocation));
// if (fbytes!=null && fbytes.length>StaashConstants.MAX_FILE_UPLOAD_SIZE_IN_KB*1000) {
// throw new RuntimeException("File is too large to upload, max size supported is 2MB");
// }
// JsonObject obj = new JsonObject();
// obj.putString("key", uploadedFileName);
// obj.putBinary("value", fbytes);
// datasvc.writeToKVStore("kvstore", "kvmapnochunks", obj);
//
// } catch (IOException e) {
// throw new RuntimeException(e.getMessage());
// }
// }
}