use of org.apache.nifi.distributed.cache.client.DistributedMapCacheClient in project nifi by apache.
the class FetchDistributedMapCache method onTrigger.
@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
FlowFile flowFile = session.get();
if (flowFile == null) {
return;
}
final ComponentLog logger = getLogger();
final String cacheKey = context.getProperty(PROP_CACHE_ENTRY_IDENTIFIER).evaluateAttributeExpressions(flowFile).getValue();
// This block retains the previous behavior when only one Cache Entry Identifier was allowed, so as not to change the expected error message
if (StringUtils.isBlank(cacheKey)) {
logger.error("FlowFile {} has no attribute for given Cache Entry Identifier", new Object[] { flowFile });
flowFile = session.penalize(flowFile);
session.transfer(flowFile, REL_FAILURE);
return;
}
List<String> cacheKeys = Arrays.stream(cacheKey.split(",")).filter(path -> !StringUtils.isEmpty(path)).map(String::trim).collect(Collectors.toList());
for (int i = 0; i < cacheKeys.size(); i++) {
if (StringUtils.isBlank(cacheKeys.get(i))) {
// Log first missing identifier, route to failure, and return
logger.error("FlowFile {} has no attribute for Cache Entry Identifier in position {}", new Object[] { flowFile, i });
flowFile = session.penalize(flowFile);
session.transfer(flowFile, REL_FAILURE);
return;
}
}
final DistributedMapCacheClient cache = context.getProperty(PROP_DISTRIBUTED_CACHE_SERVICE).asControllerService(DistributedMapCacheClient.class);
try {
final Map<String, byte[]> cacheValues;
final boolean singleKey = cacheKeys.size() == 1;
if (singleKey) {
cacheValues = new HashMap<>(1);
cacheValues.put(cacheKeys.get(0), cache.get(cacheKey, keySerializer, valueDeserializer));
} else {
cacheValues = cache.subMap(new HashSet<>(cacheKeys), keySerializer, valueDeserializer);
}
boolean notFound = false;
for (Map.Entry<String, byte[]> cacheValueEntry : cacheValues.entrySet()) {
final byte[] cacheValue = cacheValueEntry.getValue();
if (cacheValue == null) {
logger.info("Could not find an entry in cache for {}; routing to not-found", new Object[] { flowFile });
notFound = true;
break;
} else {
boolean putInAttribute = context.getProperty(PROP_PUT_CACHE_VALUE_IN_ATTRIBUTE).isSet();
if (putInAttribute) {
String attributeName = context.getProperty(PROP_PUT_CACHE_VALUE_IN_ATTRIBUTE).evaluateAttributeExpressions(flowFile).getValue();
if (!singleKey) {
// Append key to attribute name if multiple keys
attributeName += "." + cacheValueEntry.getKey();
}
String attributeValue = new String(cacheValue, context.getProperty(PROP_CHARACTER_SET).getValue());
int maxLength = context.getProperty(PROP_PUT_ATTRIBUTE_MAX_LENGTH).asInteger();
if (maxLength < attributeValue.length()) {
attributeValue = attributeValue.substring(0, maxLength);
}
flowFile = session.putAttribute(flowFile, attributeName, attributeValue);
} else if (cacheKeys.size() > 1) {
throw new IOException("Multiple Cache Value Identifiers specified without Put Cache Value In Attribute set");
} else {
// Write single value to content
flowFile = session.write(flowFile, out -> out.write(cacheValue));
}
if (putInAttribute) {
logger.info("Found a cache key of {} and added an attribute to {} with it's value.", new Object[] { cacheKey, flowFile });
} else {
logger.info("Found a cache key of {} and replaced the contents of {} with it's value.", new Object[] { cacheKey, flowFile });
}
}
}
// If the loop was exited because a cache entry was not found, route to REL_NOT_FOUND; otherwise route to REL_SUCCESS
if (notFound) {
session.transfer(flowFile, REL_NOT_FOUND);
} else {
session.transfer(flowFile, REL_SUCCESS);
}
} catch (final IOException e) {
flowFile = session.penalize(flowFile);
session.transfer(flowFile, REL_FAILURE);
logger.error("Unable to communicate with cache when processing {} due to {}", new Object[] { flowFile, e });
}
}
use of org.apache.nifi.distributed.cache.client.DistributedMapCacheClient in project nifi by apache.
the class TestHBase_1_1_2_ClientMapCacheService method testPutIfAbsent.
@Test
public void testPutIfAbsent() throws InitializationException, IOException {
final String row = "row1";
final String content = "content1";
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
// Mock an HBase Table so we can verify the put operations later
final Table table = Mockito.mock(Table.class);
when(table.getName()).thenReturn(TableName.valueOf(tableName));
// create the controller service and link it to the test processor
final MockHBaseClientService service = configureHBaseClientService(runner, table);
runner.assertValid(service);
final HBaseClientService hBaseClientService = runner.getProcessContext().getProperty(TestProcessor.HBASE_CLIENT_SERVICE).asControllerService(HBaseClientService.class);
final DistributedMapCacheClient cacheService = configureHBaseCacheService(runner, hBaseClientService);
runner.assertValid(cacheService);
final DistributedMapCacheClient hBaseCacheService = runner.getProcessContext().getProperty(TestProcessor.HBASE_CACHE_SERVICE).asControllerService(DistributedMapCacheClient.class);
assertTrue(hBaseCacheService.putIfAbsent(row, content, stringSerializer, stringSerializer));
// verify only one call to put was made
ArgumentCaptor<Put> capture = ArgumentCaptor.forClass(Put.class);
verify(table, times(1)).put(capture.capture());
verifyPut(row, columnFamily, columnQualifier, content, capture.getValue());
assertFalse(hBaseCacheService.putIfAbsent(row, content, stringSerializer, stringSerializer));
verify(table, times(1)).put(capture.capture());
}
use of org.apache.nifi.distributed.cache.client.DistributedMapCacheClient in project nifi by apache.
the class TestHBase_1_1_2_ClientMapCacheService method testGetAndPutIfAbsent.
@Test
public void testGetAndPutIfAbsent() throws InitializationException, IOException {
final String row = "row1";
final String content = "content1";
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
// Mock an HBase Table so we can verify the put operations later
final Table table = Mockito.mock(Table.class);
when(table.getName()).thenReturn(TableName.valueOf(tableName));
// create the controller service and link it to the test processor
final MockHBaseClientService service = configureHBaseClientService(runner, table);
runner.assertValid(service);
final HBaseClientService hBaseClientService = runner.getProcessContext().getProperty(TestProcessor.HBASE_CLIENT_SERVICE).asControllerService(HBaseClientService.class);
final DistributedMapCacheClient cacheService = configureHBaseCacheService(runner, hBaseClientService);
runner.assertValid(cacheService);
final DistributedMapCacheClient hBaseCacheService = runner.getProcessContext().getProperty(TestProcessor.HBASE_CACHE_SERVICE).asControllerService(DistributedMapCacheClient.class);
assertNull(hBaseCacheService.getAndPutIfAbsent(row, content, stringSerializer, stringSerializer, stringDeserializer));
// verify only one call to put was made
ArgumentCaptor<Put> capture = ArgumentCaptor.forClass(Put.class);
verify(table, times(1)).put(capture.capture());
verifyPut(row, columnFamily, columnQualifier, content, capture.getValue());
final String result = hBaseCacheService.getAndPutIfAbsent(row, content, stringSerializer, stringSerializer, stringDeserializer);
verify(table, times(1)).put(capture.capture());
assertEquals(result, content);
}
Aggregations