Skip to content

Commit f38096a

Browse files
authored
Add support to bind blob trigger input to POJO/String (#259)
* Add support to convert Bytes source to POJO/String
1 parent 04975db commit f38096a

File tree

4 files changed

+91
-12
lines changed

4 files changed

+91
-12
lines changed

endtoendtests/src/main/java/com/microsoft/azure/functions/endtoend/BlobTriggerTests.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,39 @@ public void BlobTriggerToBlobTest(
2525
) {
2626
context.getLogger().info("Java Blob trigger function processed a blob.\n Name: " + fileName + "\n Size: " + triggerBlob.length + " Bytes");
2727
outputBlob.setValue(inputBlob);
28-
}
28+
}
29+
30+
/*
31+
* Verified via Unit tests. Added test here for sample code
32+
*/
33+
@FunctionName("BlobTriggerPOJOTest")
34+
@StorageAccount("AzureWebJobsStorage")
35+
public void BlobTriggerPOJOTest(
36+
@BlobTrigger(name = "triggerBlob", path = "test-triggerinputpojo-java/{name}") TestBlobData triggerBlobText,
37+
@BindingName("name") String fileName,
38+
@BlobOutput(name = "outputBlob", path = "test-outputpojo-java/{name}") OutputBinding<TestBlobData> outputBlob,
39+
final ExecutionContext context
40+
) {
41+
context.getLogger().info("Java Blob trigger function processed a blob.\n Name: " + fileName + "\n Content: " + triggerBlobText.blobText);
42+
outputBlob.setValue(triggerBlobText);
43+
}
44+
45+
/*
46+
* Verified via Unit tests. Added test here for sample code
47+
*/
48+
@FunctionName("BlobTriggerStringTest")
49+
@StorageAccount("AzureWebJobsStorage")
50+
public void BlobTriggerStringTest(
51+
@BlobTrigger(name = "triggerBlob", path = "test-triggerinputstring-java/{name}") String triggerBlobText,
52+
@BindingName("name") String fileName,
53+
@BlobOutput(name = "outputBlob", path = "test-outputstring-java/{name}") OutputBinding<String> outputBlob,
54+
final ExecutionContext context
55+
) {
56+
context.getLogger().info("Java Blob trigger function processed a blob.\n Name: " + fileName + "\n Content: " + triggerBlobText);
57+
outputBlob.setValue(triggerBlobText);
58+
}
59+
60+
public static class TestBlobData {
61+
public String blobText;
62+
}
2963
}

src/main/java/com/microsoft/azure/functions/worker/binding/DataOperations.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.lang.reflect.Type;
55
import java.util.ArrayList;
66
import java.util.Arrays;
7+
import java.util.Base64;
78
import java.util.Collection;
89
import java.util.HashMap;
910
import java.util.List;
@@ -87,8 +88,17 @@ Optional<R> apply(T sourceValue, Type targetType) {
8788
.get(TypeUtils.getRawType(targetType, null));
8889
if (matchingOperation != null) {
8990
resultValue = Optional.ofNullable(matchingOperation).map(op -> op.tryApply(sourceValue, targetType));
90-
} else {
91-
String sourceData = (String) sourceValue;
91+
} else {
92+
String sourceData;
93+
Class<?> sourceValueClass = sourceValue.getClass();
94+
if (sourceValueClass.isAssignableFrom(byte[].class)) {
95+
sourceData = new String((byte[]) sourceValue);
96+
}
97+
else
98+
{
99+
sourceData = (String) sourceValue;
100+
}
101+
92102
// Try POJO
93103
if (Collection.class.isAssignableFrom(TypeUtils.getRawType(targetType, null))) {
94104
Class<?> collectionItemType = (Class<?>) CoreTypeResolver

src/main/java/com/microsoft/azure/functions/worker/binding/RpcByteArrayDataSource.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ public RpcByteArrayDataSource(String name, ByteString value) {
1313
static {
1414
BYTE_ARRAY_DATA_OPERATIONS.addOperation(Byte[].class, ArrayUtils::toObject);
1515
BYTE_ARRAY_DATA_OPERATIONS.addOperation(byte[].class, ArrayUtils::clone);
16+
BYTE_ARRAY_DATA_OPERATIONS.addGenericOperation(String.class, (v,t) -> new String(v));
1617
}
1718
}

src/test/java/com/microsoft/azure/functions/worker/binding/tests/RpcByteArrayDataSourceTests.java

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,65 @@ public class RpcByteArrayDataSourceTests {
1818
public void rpcByteArrayDataSource_To_byteArray() {
1919
String sourceKey = "testByteArray";
2020
String expectedString = "Example String";
21-
byte[] inputBytes = expectedString.getBytes();
21+
byte[] inputBytes = expectedString.getBytes();
2222
ByteString inputByteString = ByteString.copyFrom(inputBytes);
2323
RpcByteArrayDataSource stringData = new RpcByteArrayDataSource(sourceKey, inputByteString);
24-
2524

2625
Optional<BindingData> actualBindingData = stringData.computeByName(sourceKey, byte[].class);
2726
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
28-
byte[] actualBytes = (byte[])actualArg.getValue();
29-
String actualString = new String (actualBytes);
27+
byte[] actualBytes = (byte[]) actualArg.getValue();
28+
String actualString = new String(actualBytes);
3029
assertEquals(actualString, expectedString);
3130
}
32-
31+
3332
@Test
3433
public void rpcByteArrayDataSource_To_ByteArray() {
3534
String sourceKey = "testByteArray";
3635
String expectedString = "Example String";
37-
byte[] inputBytes = expectedString.getBytes();
36+
byte[] inputBytes = expectedString.getBytes();
3837
ByteString inputByteString = ByteString.copyFrom(inputBytes);
3938
RpcByteArrayDataSource stringData = new RpcByteArrayDataSource(sourceKey, inputByteString);
40-
4139

4240
Optional<BindingData> actualBindingData = stringData.computeByName(sourceKey, Byte[].class);
4341
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
44-
Byte[] actualBytes = (Byte[])actualArg.getValue();
45-
String actualString = new String (ArrayUtils.toPrimitive(actualBytes));
42+
Byte[] actualBytes = (Byte[]) actualArg.getValue();
43+
String actualString = new String(ArrayUtils.toPrimitive(actualBytes));
4644
assertEquals(actualString, expectedString);
4745
}
46+
47+
@Test
48+
public void rpcByteArrayDataSource_To_POJO() {
49+
String sourceKey = "testByteArray";
50+
String expectedString = "{\"blobText\":\"Example String\"}";
51+
TestBlobData testBlobData = new TestBlobData();
52+
testBlobData.blobText = "Example String";
53+
byte[] inputBytes = expectedString.getBytes();
54+
ByteString inputByteString = ByteString.copyFrom(inputBytes);
55+
RpcByteArrayDataSource stringData = new RpcByteArrayDataSource(sourceKey, inputByteString);
56+
57+
Optional<BindingData> actualBindingData = stringData.computeByName(sourceKey,
58+
TestBlobData.class);
59+
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
60+
TestBlobData actualBlobData = (TestBlobData) actualArg.getValue();
61+
assertEquals(actualBlobData.blobText, testBlobData.blobText);
62+
}
63+
64+
@Test
65+
public void rpcByteArrayDataSource_To_String() {
66+
String sourceKey = "testByteArray";
67+
String expectedString = "Example String";
68+
byte[] inputBytes = expectedString.getBytes();
69+
ByteString inputByteString = ByteString.copyFrom(inputBytes);
70+
RpcByteArrayDataSource stringData = new RpcByteArrayDataSource(sourceKey, inputByteString);
71+
72+
Optional<BindingData> actualBindingData = stringData.computeByName(sourceKey,
73+
String.class);
74+
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
75+
String actualBlobData = (String) actualArg.getValue();
76+
assertEquals(actualBlobData, expectedString);
77+
}
78+
79+
public static class TestBlobData {
80+
public String blobText;
81+
}
4882
}

0 commit comments

Comments
 (0)