Added `BufferedEventProcessor` to manual send bunch of events and controlling their output status
This commit is contained in:
parent
a49e030d71
commit
ec8476164c
|
@ -3,6 +3,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||
# Changelog for "event-publisher-library"
|
||||
|
||||
## [v1.1.0-SNAPSHOT]
|
||||
- Added `BufferedEventProcessor` to manual send bunch of events and controlling their output status
|
||||
|
||||
## [v1.0.2]
|
||||
- Refactored/extracted event sender that uses OIDC token only and extended it for the UMA version.
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -21,7 +21,7 @@
|
|||
<dependency>
|
||||
<groupId>org.gcube.distribution</groupId>
|
||||
<artifactId>maven-portal-bom</artifactId>
|
||||
<version>3.6.3-SNAPSHOT</version>
|
||||
<version>3.6.4</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
package org.gcube.event.publisher;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class BufferedEventProcessor {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BufferedEventProcessor.class);
|
||||
|
||||
private static final int DEFAULT_BUFFER_SIZE = 10;
|
||||
private static final int RESULT_POLLING_INTERVAL = 500;
|
||||
|
||||
private ArrayBlockingQueue<Event> eventsBuffer;
|
||||
private Map<Runnable, Boolean> threadStatus;
|
||||
private int count = 0;
|
||||
private long min = 10000000000L;
|
||||
private long max = 0;
|
||||
private int errors = 0;
|
||||
|
||||
public BufferedEventProcessor(String conductorEndpoint, String clientId, String clientSecret,
|
||||
String keycloakTokenEndpoint, Function<Event, String> logInfoGenerator)
|
||||
throws EventProcessorException {
|
||||
|
||||
this(conductorEndpoint, clientId, clientSecret, keycloakTokenEndpoint, logInfoGenerator, DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public BufferedEventProcessor(String conductorEndpoint, String clientId, String clientSecret,
|
||||
String keycloakTokenEndpoint, Function<Event, String> logInfoGenerator, int bufferSize)
|
||||
throws EventProcessorException {
|
||||
|
||||
eventsBuffer = new ArrayBlockingQueue<>(bufferSize, true);
|
||||
threadStatus = Collections.synchronizedMap(new HashMap<>(bufferSize));
|
||||
final AbstractEventPublisher publisher = new AbstractEventPublisher() {
|
||||
@Override
|
||||
protected EventSender createEventSender() {
|
||||
try {
|
||||
return new HTTPWithOIDCAuthEventSender(new URL(conductorEndpoint), clientId, clientSecret,
|
||||
new URL(keycloakTokenEndpoint));
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (publisher.getEventSender() == null) {
|
||||
throw new EventProcessorException("Cannot create procrssor correctly");
|
||||
}
|
||||
|
||||
for (int i = 0; i < bufferSize; i++) {
|
||||
Thread t = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
String log = null;
|
||||
Event toBeSent;
|
||||
try {
|
||||
toBeSent = eventsBuffer.take();
|
||||
} catch (InterruptedException e) {
|
||||
// interrupted when waiting, nothing to do...
|
||||
continue;
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
threadStatus.put(this, Boolean.TRUE);
|
||||
logger.trace(" * Peeked event. Buffer size: {}", eventsBuffer.size());
|
||||
log = logInfoGenerator.apply(toBeSent);
|
||||
logger.debug(" > Sending event for: {}", log);
|
||||
boolean sent = false;
|
||||
String workflowId = null;
|
||||
do {
|
||||
try {
|
||||
workflowId = publisher.publish(toBeSent, true);
|
||||
sent = true;
|
||||
} catch (Exception e) {
|
||||
logger.warn("Publishing event for {}. It will be re-published", log, e);
|
||||
}
|
||||
} while (!sent);
|
||||
|
||||
EventStatus eventStatus;
|
||||
do {
|
||||
eventStatus = null;
|
||||
try {
|
||||
Thread.sleep(RESULT_POLLING_INTERVAL);
|
||||
eventStatus = publisher.check(workflowId);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Checking status for the event for {}", log, e);
|
||||
}
|
||||
if (eventStatus == null || eventStatus.getStatus() == null) {
|
||||
continue;
|
||||
}
|
||||
} while (eventStatus.getStatus() != EventStatus.Status.COMPLETED
|
||||
&& eventStatus.getStatus() != EventStatus.Status.FAILED);
|
||||
|
||||
long elapsed = System.currentTimeMillis() - start;
|
||||
count = count + 1;
|
||||
if (elapsed > max) {
|
||||
max = elapsed;
|
||||
}
|
||||
if (elapsed < min) {
|
||||
min = elapsed;
|
||||
}
|
||||
if (eventStatus.getStatus() == EventStatus.Status.FAILED) {
|
||||
logger.warn(" - ({}) {} -> {} [{} ms]",
|
||||
new Object[] { count, log, eventStatus.getStatus(), elapsed });
|
||||
|
||||
errors += 1;
|
||||
} else {
|
||||
logger.info(" - (" + count + ") " + log + " -> " + eventStatus.getStatus() + " ["
|
||||
+ elapsed + " ms]");
|
||||
}
|
||||
threadStatus.put(this, Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
});
|
||||
threadStatus.put(t, Boolean.FALSE);
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void enqueueEvent(Event event) throws InterruptedException {
|
||||
eventsBuffer.put(event);
|
||||
}
|
||||
|
||||
public Boolean allQueuedFinishedCorrectly() {
|
||||
return eventsBuffer.size() > 0 || threadStatus.values().stream().anyMatch(v -> v.equals(Boolean.TRUE));
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public long getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public long getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public int getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.gcube.event.publisher;
|
||||
|
||||
public class EventProcessorException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 568668418901859597L;
|
||||
|
||||
public EventProcessorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public EventProcessorException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue