Skip to content

Commit

Permalink
Added a better documentation to the GsonUtils class that makes clear …
Browse files Browse the repository at this point in the history
…which method expects the length of a String value and which doesn't. removed the error details property since it is not needed. updated the error reporting classes accordingly.
  • Loading branch information
MichaelRoeder committed Dec 17, 2023
1 parent 76aeabd commit 46c4444
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 57 deletions.
34 changes: 4 additions & 30 deletions src/main/java/org/hobbit/core/data/ErrorData.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,14 @@ public class ErrorData {
protected String errorType;
/**
* A string that can be used as short label of an error (optional, the error
* type label will be used as default)
* type label might be used as default)
*/
protected String label;
/**
* A string that can be used as a short description of an error (optional, the
* error type description will be used as default).
* error type description might be used as default).
*/
protected String description;
/**
* A string that contains details about the error, e.g., a stack trace
* (optional).
*/
protected String details;

/**
* @return the containerId
Expand Down Expand Up @@ -93,27 +88,12 @@ public void setDescription(String description) {
this.description = description;
}

/**
* @return the details
*/
public String getDetails() {
return details;
}

/**
* @param details the details to set
*/
public void setDetails(String details) {
this.details = details;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((containerName == null) ? 0 : containerName.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((details == null) ? 0 : details.hashCode());
result = prime * result + ((errorType == null) ? 0 : errorType.hashCode());
result = prime * result + ((label == null) ? 0 : label.hashCode());
return result;
Expand All @@ -138,11 +118,6 @@ public boolean equals(Object obj) {
return false;
} else if (!description.equals(other.description))
return false;
if (details == null) {
if (other.details != null)
return false;
} else if (!details.equals(other.details))
return false;
if (errorType == null) {
if (other.errorType != null)
return false;
Expand Down Expand Up @@ -172,14 +147,13 @@ public static ErrorData createFromException(Exception e, String containerName) {
ErrorData result = new ErrorData();
result.containerName = containerName;
result.errorType = HobbitErrors.UnhandledException.getURI();
result.label = e.getClass().getName();
result.description = e.getMessage();
result.label = e.getMessage();
// Get the full stack trace
StringWriter writer = new StringWriter();
PrintWriter pwriter = new PrintWriter(writer);
e.printStackTrace(pwriter);
pwriter.flush();
result.details = writer.toString();
result.description = writer.toString();
pwriter.close();

return result;
Expand Down
49 changes: 42 additions & 7 deletions src/main/java/org/hobbit/core/rabbit/GsonUtils.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.hobbit.core.rabbit;

import java.nio.ByteBuffer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -34,6 +36,34 @@ public static <T> byte[] serializeObjectWithGson(Gson gson, T object) {
return null;
}

/**
* Deserialize a Java data object that was received as JSON with a command.
* First, the given byte array will be transformed into a String using the
* {@link RabbitMQUtils} class, before it will be deserialized using the given
* {@link Gson} object.
*
* @param <T> The class that the data object should have.
* @param gson The Gson instance used to deserialize the JSON object.
* @param data The byte array that has been received.
* @param clazz The class that the data object should have.
* @param containsLength This flag indicates whether the given byte array
* contains the data with a preceeded int value containing
* the length of the next piece of data
* @return The deserialized object or null if an error occurred
*/
public static <T> T deserializeObjectWithGson(Gson gson, byte[] data, Class<? extends T> clazz,
boolean containsLength) {
if (data != null) {
if (containsLength) {
return deserializeObjectWithGson(gson, ByteBuffer.wrap(data), clazz);
} else {
String dataString = RabbitMQUtils.readString(data);
return deserializeObjectWithGson(gson, dataString, clazz);
}
}
return null;
}

/**
* Deserialize a Java data object that was received as JSON with a command.
* First, the given byte array will be transformed into a String using the
Expand All @@ -42,19 +72,24 @@ public static <T> byte[] serializeObjectWithGson(Gson gson, T object) {
*
* @param <T> The class that the data object should have.
* @param gson The Gson instance used to deserialize the JSON object.
* @param data The byte array that has been received.
* @param data A ByteBuffer containing the data and the length of the data.
* @param clazz The class that the data object should have.
* @return The deserialized object or null if an error occurred
*/
public static <T> T deserializeObjectWithGson(Gson gson, byte[] data, Class<? extends T> clazz) {
public static <T> T deserializeObjectWithGson(Gson gson, ByteBuffer data, Class<? extends T> clazz) {
if (data != null) {
String dataString = RabbitMQUtils.readString(data);
try {
return gson.fromJson(dataString, clazz);
} catch (Exception e) {
LOGGER.error("Error while parsing JSON data. Returning null.");
}
return deserializeObjectWithGson(gson, dataString, clazz);
}
return null;
}

protected static <T> T deserializeObjectWithGson(Gson gson, String dataString, Class<? extends T> clazz) {
try {
return gson.fromJson(dataString, clazz);
} catch (Exception e) {
LOGGER.error("Error while parsing JSON data form String \"" + dataString + "\". Returning null.", e);
return null;
}
}
}
1 change: 0 additions & 1 deletion src/main/java/org/hobbit/vocab/Algorithm.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public class Algorithm {
public static final Resource Result = resource("Result");

// Properties sorted alphabetically
public static final Property errorDetails = property("errorDetails");
public static final Property instanceOf = property("instanceOf");
public static final Property parameter = property("parameter");
public static final Property produces = property("produces");
Expand Down
73 changes: 54 additions & 19 deletions src/test/java/org/hobbit/core/rabbit/GsonUtilsTest.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,74 @@
package org.hobbit.core.rabbit;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import org.hobbit.core.data.ErrorData;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.google.gson.Gson;

@RunWith(Parameterized.class)
public class GsonUtilsTest {

@Test
public void testErrorData() {
ErrorData original = new ErrorData();
original.setErrorType("http://example.org/generalError");
original.setContainerId("123");
protected static Gson gson = new Gson();

protected Object original;
protected Class<?> clazz;

Gson gson = new Gson();
ErrorData received;
public GsonUtilsTest(Object original, Class<?> clazz) {
super();
this.original = original;
this.clazz = clazz;
}

received = GsonUtils.deserializeObjectWithGson(gson, GsonUtils.serializeObjectWithGson(gson, original),
ErrorData.class);
@Test
public void testDirect() {
Object received = GsonUtils.deserializeObjectWithGson(gson, GsonUtils.serializeObjectWithGson(gson, original),
ErrorData.class, false);
Assert.assertEquals(original, received);
}

original.setLabel("Example label");
received = GsonUtils.deserializeObjectWithGson(gson, GsonUtils.serializeObjectWithGson(gson, original),
ErrorData.class);
@Test
public void testWithLengthPrefix() {
byte[] data = GsonUtils.serializeObjectWithGson(gson, original);
ByteBuffer buffer = ByteBuffer.allocate(data.length + 4);
buffer.putInt(data.length);
buffer.put(data);

Object received = GsonUtils.deserializeObjectWithGson(gson, buffer.array(),
ErrorData.class, true);
Assert.assertEquals(original, received);
}

@Parameters
public static List<Object[]> parameters() {
List<Object[]> testCases = new ArrayList<>();
ErrorData original;

original = new ErrorData();
original.setErrorType("http://example.org/generalError");
original.setContainerId("123");
testCases.add(new Object[] {original, original.getClass()});

original = new ErrorData();
original.setErrorType("http://example.org/generalError");
original.setContainerId("123");
original.setLabel("Example label");
testCases.add(new Object[] {original, original.getClass()});

original = new ErrorData();
original.setErrorType("http://example.org/generalError");
original.setContainerId("123");
original.setLabel("Example label");
original.setDescription("Some description");
received = GsonUtils.deserializeObjectWithGson(gson, GsonUtils.serializeObjectWithGson(gson, original),
ErrorData.class);
Assert.assertEquals(original, received);
testCases.add(new Object[] {original, original.getClass()});

original.setDetails("A lot of details....");
received = GsonUtils.deserializeObjectWithGson(gson, GsonUtils.serializeObjectWithGson(gson, original),
ErrorData.class);
Assert.assertEquals(original, received);
return testCases;
}
}

0 comments on commit 46c4444

Please sign in to comment.