use of com.linkedin.data.ByteString in project rest.li by linkedin.
the class SyncIOHandler method loop.
public void loop() throws ServletException, IOException {
final long startTime = System.currentTimeMillis();
byte[] buf = new byte[DEFAULT_DATA_CHUNK_SIZE];
while (shouldContinue() && !_forceExit) {
Event event;
try {
long timeSpent = System.currentTimeMillis() - startTime;
long maxWaitTime = timeSpent < _timeout ? _timeout - timeSpent : 0;
event = _eventQueue.poll(maxWaitTime, TimeUnit.MILLISECONDS);
if (event == null) {
throw new TimeoutException("Timeout after " + _timeout + " milliseconds.");
}
} catch (Exception ex) {
throw new ServletException(ex);
}
switch(event.getEventType()) {
case ResponseDataAvailable:
{
ByteString data = (ByteString) event.getData();
data.write(_os);
_rh.request(1);
break;
}
case WriteRequestPossible:
{
while (_wh.remaining() > 0) {
int actualLen = _is.read(buf);
if (actualLen < 0) {
_wh.done();
_requestReadFinished = true;
break;
}
_wh.write(ByteString.copy(buf, 0, actualLen));
}
break;
}
case FullResponseReceived:
{
_os.close();
_responseWriteFinished = true;
break;
}
case ResponseDataError:
{
_os.close();
_responseWriteFinished = true;
break;
}
case WriteRequestAborted:
{
if (event.getData() instanceof AbortedException) {
// reader cancels, we'll drain the stream on behalf of reader
// we don't directly drain it here because we'd like to give other events
// some opportunities to be executed; e.g. return an error response
_eventQueue.add(Event.DrainRequestEvent);
} else {
// TODO: do we want to be smarter and return server error response?
throw new ServletException((Throwable) event.getData());
}
break;
}
case DrainRequest:
{
for (int i = 0; i < 10; i++) {
int actualLen = _is.read(buf);
if (actualLen < 0) {
_requestReadFinished = true;
break;
}
}
if (!_requestReadFinished) {
// add self back to event queue and give others a chance to run
_eventQueue.add(Event.DrainRequestEvent);
}
break;
}
case ForceExit:
{
_forceExit = true;
break;
}
default:
throw new IllegalStateException("Unknown event type:" + event.getEventType());
}
}
}
use of com.linkedin.data.ByteString in project rest.li by linkedin.
the class TestHttpClient method testClient.
@Test(dataProvider = "configs")
public void testClient(Server server, Client client) throws Exception {
try {
server.start();
RestRequestBuilder rb = new RestRequestBuilder(REQUEST_URI);
rb.setMethod("GET");
RestRequest request = rb.build();
Future<RestResponse> f = client.restRequest(request);
// This will block
RestResponse response = f.get();
final ByteString entity = response.getEntity();
if (entity != null) {
System.out.println(entity.asString("UTF-8"));
} else {
System.out.println("NOTHING!");
}
assertEquals(response.getStatus(), 200);
final FutureCallback<None> callback = new FutureCallback<None>();
client.shutdown(callback);
callback.get();
} finally {
server.stop();
}
}
use of com.linkedin.data.ByteString in project voldemort by voldemort.
the class R2Store method parseGetResponse.
private List<Versioned<byte[]>> parseGetResponse(ByteString entity) {
List<Versioned<byte[]>> results = new ArrayList<Versioned<byte[]>>();
try {
// Build the multipart object
byte[] bytes = new byte[entity.length()];
entity.copyBytes(bytes, 0);
ByteArrayDataSource ds = new ByteArrayDataSource(bytes, "multipart/mixed");
MimeMultipart mp = new MimeMultipart(ds);
for (int i = 0; i < mp.getCount(); i++) {
MimeBodyPart part = (MimeBodyPart) mp.getBodyPart(i);
String serializedVC = part.getHeader(RestMessageHeaders.X_VOLD_VECTOR_CLOCK)[0];
int contentLength = Integer.parseInt(part.getHeader(RestMessageHeaders.CONTENT_LENGTH)[0]);
if (logger.isDebugEnabled()) {
logger.debug("Received VC : " + serializedVC);
}
VectorClockWrapper vcWrapper = mapper.readValue(serializedVC, VectorClockWrapper.class);
InputStream input = part.getInputStream();
byte[] bodyPartBytes = new byte[contentLength];
input.read(bodyPartBytes);
VectorClock clock = new VectorClock(vcWrapper.getVersions(), vcWrapper.getTimestamp());
results.add(new Versioned<byte[]>(bodyPartBytes, clock));
}
} catch (MessagingException e) {
throw new VoldemortException("Messaging exception while trying to parse GET response " + e.getMessage(), e);
} catch (JsonParseException e) {
throw new VoldemortException("JSON parsing exception while trying to parse GET response " + e.getMessage(), e);
} catch (JsonMappingException e) {
throw new VoldemortException("JSON mapping exception while trying to parse GET response " + e.getMessage(), e);
} catch (IOException e) {
throw new VoldemortException("IO exception while trying to parse GET response " + e.getMessage(), e);
}
return results;
}
use of com.linkedin.data.ByteString in project voldemort by voldemort.
the class R2Store method parseGetAllResults.
private Map<ByteArray, List<Versioned<byte[]>>> parseGetAllResults(ByteString entity) {
Map<ByteArray, List<Versioned<byte[]>>> results = new HashMap<ByteArray, List<Versioned<byte[]>>>();
try {
// Build the multipart object
byte[] bytes = new byte[entity.length()];
entity.copyBytes(bytes, 0);
// Get the outer multipart object
ByteArrayDataSource ds = new ByteArrayDataSource(bytes, "multipart/mixed");
MimeMultipart mp = new MimeMultipart(ds);
for (int i = 0; i < mp.getCount(); i++) {
// Get an individual part. This contains all the versioned
// values for a particular key referenced by content-location
MimeBodyPart part = (MimeBodyPart) mp.getBodyPart(i);
// Get the key
String contentLocation = part.getHeader("Content-Location")[0];
String base64Key = contentLocation.split("/")[2];
ByteArray key = new ByteArray(RestUtils.decodeVoldemortKey(base64Key));
if (logger.isDebugEnabled()) {
logger.debug("Content-Location : " + contentLocation);
logger.debug("Base 64 key : " + base64Key);
}
// Create an array list for holding all the (versioned values)
List<Versioned<byte[]>> valueResultList = new ArrayList<Versioned<byte[]>>();
/*
* Get the nested Multi-part object. This contains one part for each unique versioned value.
*
* GetContent method can corrupt the embedded data, for example 0x8c be converted to 0xc2, 0x8c,
* hence use getInputStream.
*
* This thread tracks this question
* http://stackoverflow.com/questions/23023583/mimebodypart-getcontent-corrupts-binary-data
*
* getInputStream() : Return a decoded input stream for this Message's "content.
*
* getRawInputStream() : Return an InputStream to the raw data with any Content-Transfer-Encoding
* intact. This method is useful if the "Content-Transfer-Encoding" header is incorrect or corrupt,
* which would prevent the getInputStream method from returning the correct data. In such a case
* the application may use this method and attempt to decode the raw data itself.
*
*/
ByteArrayDataSource nestedDS = new ByteArrayDataSource(part.getInputStream(), "multipart/mixed");
MimeMultipart valueParts = new MimeMultipart(nestedDS);
for (int valueId = 0; valueId < valueParts.getCount(); valueId++) {
MimeBodyPart valuePart = (MimeBodyPart) valueParts.getBodyPart(valueId);
String serializedVC = valuePart.getHeader(RestMessageHeaders.X_VOLD_VECTOR_CLOCK)[0];
int contentLength = Integer.parseInt(valuePart.getHeader(RestMessageHeaders.CONTENT_LENGTH)[0]);
if (logger.isDebugEnabled()) {
logger.debug("Received serialized Vector Clock : " + serializedVC);
}
VectorClockWrapper vcWrapper = mapper.readValue(serializedVC, VectorClockWrapper.class);
// get the value bytes
InputStream input = valuePart.getInputStream();
byte[] bodyPartBytes = new byte[contentLength];
input.read(bodyPartBytes);
VectorClock clock = new VectorClock(vcWrapper.getVersions(), vcWrapper.getTimestamp());
valueResultList.add(new Versioned<byte[]>(bodyPartBytes, clock));
}
results.put(key, valueResultList);
}
} catch (MessagingException e) {
throw new VoldemortException("Messaging exception while trying to parse GET response " + e.getMessage(), e);
} catch (JsonParseException e) {
throw new VoldemortException("JSON parsing exception while trying to parse GET response " + e.getMessage(), e);
} catch (JsonMappingException e) {
throw new VoldemortException("JSON mapping exception while trying to parse GET response " + e.getMessage(), e);
} catch (IOException e) {
throw new VoldemortException("IO exception while trying to parse GET response " + e.getMessage(), e);
}
return results;
}
use of com.linkedin.data.ByteString in project voldemort by voldemort.
the class R2Store method delete.
@Override
public boolean delete(ByteArray key, Version version) throws VoldemortException {
try {
// Create the REST request with this byte array
String base64Key = RestUtils.encodeVoldemortKey(key.get());
RestRequestBuilder rb = new RestRequestBuilder(new URI(this.restBootstrapURL + "/" + getName() + "/" + base64Key));
// Create a HTTP POST request
rb.setMethod(DELETE);
rb.setHeader(CONTENT_LENGTH, "0");
String timeoutStr = Long.toString(this.config.getTimeoutConfig().getOperationTimeout(VoldemortOpCode.DELETE_OP_CODE));
rb.setHeader(RestMessageHeaders.X_VOLD_REQUEST_TIMEOUT_MS, timeoutStr);
rb.setHeader(RestMessageHeaders.X_VOLD_REQUEST_ORIGIN_TIME_MS, String.valueOf(System.currentTimeMillis()));
if (this.routingTypeCode != null) {
rb.setHeader(RestMessageHeaders.X_VOLD_ROUTING_TYPE_CODE, this.routingTypeCode);
}
if (this.zoneId != INVALID_ZONE_ID) {
rb.setHeader(RestMessageHeaders.X_VOLD_ZONE_ID, String.valueOf(this.zoneId));
}
// Serialize the Vector clock
VectorClock vc = (VectorClock) version;
// doing the put.
if (vc != null && vc.getEntries().size() != 0) {
String serializedVC = null;
if (!vc.getEntries().isEmpty()) {
serializedVC = RestUtils.getSerializedVectorClock(vc);
}
if (serializedVC != null && serializedVC.length() > 0) {
rb.setHeader(RestMessageHeaders.X_VOLD_VECTOR_CLOCK, serializedVC);
}
}
RestRequest request = rb.build();
Future<RestResponse> f = client.restRequest(request);
// This will block
RestResponse response = f.get();
final ByteString entity = response.getEntity();
if (entity == null) {
if (logger.isDebugEnabled()) {
logger.debug("Empty response !");
}
}
} catch (ExecutionException e) {
if (e.getCause() instanceof RestException) {
RestException exception = (RestException) e.getCause();
if (logger.isDebugEnabled()) {
logger.debug("REST EXCEPTION STATUS : " + exception.getResponse().getStatus());
}
if (exception.getResponse().getStatus() == NOT_FOUND.getCode()) {
return false;
}
} else {
throw new VoldemortException("Unknown HTTP request execution exception: " + e.getMessage(), e);
}
} catch (InterruptedException e) {
if (logger.isDebugEnabled()) {
logger.debug("Operation interrupted : " + e.getMessage());
}
throw new VoldemortException("Operation Interrupted: " + e.getMessage(), e);
} catch (URISyntaxException e) {
throw new VoldemortException("Illegal HTTP URL" + e.getMessage(), e);
}
return true;
}
Aggregations