How can I create dynamic rule in apache-flink? - java

I'm using flink with Java and I succeeded in defining a static pattern as follow:
Pattern<Event, ?> pattern = Pattern.<Event>
begin("first")
.where(
new SimpleCondition<Event>() {
#Override
public boolean filter(Event event) {
return event.getTemperature() > 50;
}
}).within(Time.seconds(10L));
Is there a way in apache-flink to create patterns in a dynamic way?
I need to define the pattern according to user's input.
Thanks

You might be interested in the "Dynamic Updates of Application Logic" pattern.
Use BroadcastStream for your rules that you connect to the stream.
With the example in the article you could even have dynamic aggregations definitions:
// Streams setup
DataStream<Transaction> transactions = [...]
DataStream<Rule> rulesUpdateStream = [...]
BroadcastStream<Rule> rulesStream = rulesUpdateStream.broadcast(RULES_STATE_DESCRIPTOR);
// Processing pipeline setup
DataStream<Alert> alerts =
transactions
.connect(rulesStream)
.process(new DynamicKeyFunction())
.keyBy((keyed) -> keyed.getKey())
.connect(rulesStream)
.process(new DynamicAlertFunction())

Related

Using resilience4j to rate limit based on API Key

I'm building an Java REST API that requires clients to use api keys in order to access. I want to implement rate limiting based on the API key, so that a single api cannot use the api too many times within a given timeframe. I'm been looking to using resilience4j for this, but I can't seem to find if resilience 4j supports implementing rate limiting based on criteria such as ip address or api key, instead of just rate limiting in general. Does anyone know if this possible, and or know of any resources that show how to do this? Thanks.
You need to have a RateLimiter instance for each IP/apiKey instead of only one RateLimiter instance for all IP/apiKey.
See the guide below:
// Define one instance of LimiterManager ( Singleton | ApplicationScoped )
// NOTES: Reuse this instance
LimiterManager limiterManager = new LimiterManager();
String apiKey = "abc"; // // Get apiKey from current client request
final RateLimiter rateLimiter = limiterManager.getLimiter(apiKey);
// You can use other RateLimiter.decorateXXX depends on your logic
Runnable runnable = RateLimiter.decorateRunnable(rateLimiter, new Runnable() {
#Override
public void run() {
// TODO: Your allowed code here
}
});
Try.runRunnable(runnable).onFailure(
error -> System.out.print(error)
);
// Define LimiterManager utility class
public static class LimiterManager {
final ConcurrentMap<String, RateLimiter> keyRateLimiters = new ConcurrentHashMap<String, RateLimiter>();
final RateLimiterConfig config = RateLimiterConfig.custom().timeoutDuration(Duration.ofMillis(100))
.limitRefreshPeriod(Duration.ofSeconds(1))
.limitForPeriod(3) // Max 3 accesses per 1 second
.build();
public RateLimiter getLimiter(String apiKey) {
return keyRateLimiters.compute(apiKey, (key, limiter) -> {
return (limiter == null) ? RateLimiter.of(apiKey, config) : limiter;
});
}
}
The problem with resilience4j is that it doesn't work with sharding, give a look at https://github.blog/2021-04-05-how-we-scaled-github-api-sharded-replicated-rate-limiter-redis/

Java/Spring -> how to structure (Design Pattern) the relationship between multiple classes involved in the same process

TLDR;
Does my DailyRecordDataManager class have a code smell? Is it a 'God Class'? and how can I improve the structure?
Hi,
I'm working on my first project with Spring. It's going to fetch covid-19 data from the Madrid (where I live) government website, organise it by locality, and serve it up through an API.
Here is a sample of the JSON data I'm consuming.
{
"codigo_geometria": "079603",
"municipio_distrito": "Madrid-Retiro",
"tasa_incidencia_acumulada_ultimos_14dias": 23.4668991007149,
"tasa_incidencia_acumulada_total": 1417.23308497532,
"casos_confirmados_totales": 1691,
"casos_confirmados_ultimos_14dias": 28,
"fecha_informe": "2020/07/01 09:00:00"
}
Each JSON object is a a record of cases and the infection rate on a specific date and for a specific municipal district.
After fetching the data the program: parses it, filters it, trims/rounds some properties, maps it by locality, uses it to create an object for each locality (DistrictData), and writes the locality DistrictData objects to a MonoDB instance.
At the moment I have split each of these steps in the process separate classes, as per the single responsibility principle. As can be seen in the linked screenshot:
screenshot of intellij package structure
My problem is I don't know how to link these multiple classes together.
At the moment I have a Manager class which smells a bit like a God Class to me:
#Service
public class DailyRecordDataManager implements DataManager {
private final Logger logger = LoggerFactory.getLogger(DailyRecordDataManager.class);
private final DailyRecordDataCollector<String> dataCollector;
private final DataVerifier<String> dataVerifier;
private final JsonParser<DailyRecord> dataParser;
private final DataFilter<List<DailyRecord>> dataFilter;
private final DataTrimmer<List<DailyRecord>> dataTrimmer;
private final DataSorter<List<DailyRecord>> dataSorter;
private final DataMapper<List<DailyRecord>> dataMapper;
private final DataTransformer dataTransformer;
private final DistrictDataService districtDataService;
public DailyRecordDataManager(DailyRecordDataCollector<String> collector,
DataVerifier<String> verifier,
JsonParser<DailyRecord> parser,
DataFilter<List<DailyRecord>> dataFilter,
DataTrimmer<List<DailyRecord>> dataTrimmer,
DataSorter<List<DailyRecord>> dataSorter,
DataMapper dataMapper,
DataTransformer dataConverter,
DistrictDataService districtDataService) {
this.dataCollector = collector;
this.dataVerifier = verifier;
this.dataParser = parser;
this.dataFilter = dataFilter;
this.dataTrimmer = dataTrimmer;
this.dataSorter = dataSorter;
this.dataMapper = dataMapper;
this.dataTransformer = dataConverter;
this.districtDataService = districtDataService;
}
#Override
public boolean newData() {
String data = dataCollector.collectData();
if (!dataVerifier.verifyData(data)) {
logger.debug("Data is not new.");
return false;
}
List<DailyRecord> parsedData = dataParser.parse(data);
if (parsedData.size() == 0) {
return false;
}
List<DailyRecord> filteredData = dataFilter.filter(parsedData);
List<DailyRecord> trimmedData = dataTrimmer.trim(filteredData);
List<DailyRecord> sortedData = dataSorter.sort(trimmedData);
Map<String, List<DailyRecord>> mappedData = dataMapper.map(sortedData);
List<DistrictData> convertedData = dataTransformer.transform(mappedData);
districtDataService.save(convertedData);
return true;
}
}
I also thought about linking all of the involved classes together in a chain of Injected Dependencies -> so each class has the next class in the process as a dependency and, provided nothing goes wrong with the data, calls that next class in the chain when it's time.
I do also however feel that there must be a design pattern that solves the problem I have!
Thanks!
For anyone who finds this and wonders what I ended up opting for the Pipeline pattern.
It allowed me to easily organise all of the individual classes I was using into one clean workflow. It also made each stage of the process very easy to test. As well as the pipeline class itself!
I highly recommend anyone interested in the patter in Java to check out this article, which I used extensively.

Programmatically grouping and typehinting different classes

Given I have a class that uses some kind of searcher to get and display a list of URLs, like this:
package com.acme.displayer;
import com.acme.searcher.SearcherInterface;
class AcmeDisplayer {
private SearcherInterface searcher;
public AcmeDisplayer(SearcherInterface searcher) {
this.searcher = searcher;
}
public void display() {
List<String> urls = searcher.getUrls();
for (String url : urls) {
System.out.println(url);
}
}
}
Whereas the SearcherInterface looks like the following:
package com.acme.searcher;
public interface SearcherInterface {
List<String> getUrls();
}
There's multiple implementations of these searchers. (One, for instance, only returns a hardcoded list of Strings for testing purposes).
Another one, however, performs HTTP Requests to whatever API and parses the response for URLs, like so:
package com.acme.searcher.http;
import com.acme.searcher.SearcherInterface;
public class HttpSearcher implements SearcherInterface {
private RequestPerformerInterface requestPerformer;
private ParserInterface parser;
public HttpSearcher(RequestPerformerInterface requestPerformer, ParserInterface parser) {
this.requestPerformer = requestPerformer;
this.parser = parser;
}
List<String> getUrls() {
InputStream stream = requestPerformer.performRequest();
return parser.parse(stream);
}
}
The splitting of such an HTTP request is done because of seperation of concerns.
However, this is leading to a problem: A Parser might only be built for a certain API, which is represented by a certain RequestPerformer. So they need to be compatible. I've fiddled around with generic types for such a structure now, i.e. having a TypeInterface that both arguments of HttpSearchers constructor should implement, but I didn't get it working... Another approach would be to just implement a check in one class if the other one is compatible with it, but that seems ugly.
Is there any way to achieve such a grouping of RequestPerformers and Parsers by the API they're handling? Or is there something wrong with the architecture itself?
Your HttpSearcher seems like such a device to group these 2 together. You could create a factory class that returns HttpSearcher and other classes like it, and code that factory to group the compatible RequestPerformers and Parsers together.
The reason why I wouldn't advice leveraging the type system, e.g. through generics, is that the type InputStream can guarantee nothing about the format/type of data it holds. Separating the responsibility of getting the raw data, and parsing seems like a good idea, but you will still have to 'manually' group the compatible types together, because only you know what format/type of data the InputStream will hold.

Best design pattern/approach for a long list of if/else/execute branches of code

I have a "legacy" code that I want to refactor.
The code basically does a remote call to a server and gets back a reply. Then according to the reply executes accordingly.
Example of skeleton of the code:
public Object processResponse(String responseType, Object response) {
if(responseType.equals(CLIENT_REGISTERED)) {
//code
//code ...
}
else if (responseType.equals(CLIENT_ABORTED)) {
//code
//code....
}
else if (responseType.equals(DATA_SPLIT)) {
//code
//code...
}
etc
The problem is that there are many-many if/else branches and the code inside each if is not trivial.
So it becomes hard to maintain.
I was wondering what is that best pattern for this?
One thought I had was to create a single object with method names the same as the responseType and then inside processResponse just using reflection call the method with the same name as the responseType.
This would clean up processResponse but it moves the code to a single object with many/many methods and I think reflection would cause performance issues.
Is there a nice design approach/pattern to clean this up?
Two approaches:
Strategy pattern http://www.dofactory.com/javascript/strategy-design-pattern
Create dictionary, where key is metadata (in your case metadata is responseType) and value is a function.
For example:
Put this in constructor
responses = new HashMap<string, SomeAbstraction>();
responses.Put(CLIENT_REGISTERED, new ImplementationForRegisteredClient());
responses.Put(CLIENT_ABORTED, new ImplementationForAbortedClient());
where ImplementationForRegisteredClient and ImplementationForAbortedClient implement SomeAbstraction
and call this dictionary via
responses.get(responseType).MethodOfYourAbstraction(SomeParams);
If you want to follow the principle of DI, you can inject this Dictionary in your client class.
My first cut would be to replace the if/else if structures with switch/case:
public Object processResponse(String responseType, Object response) {
switch(responseType) {
case CLIENT_REGISTERED: {
//code ...
}
case CLIENT_ABORTED: {
//code....
}
case DATA_SPLIT: {
//code...
}
From there I'd probably extract each block as a method, and from there apply the Strategy pattern. Stop at whatever point feels right.
The case you've describe seems to fit perfectly to the application of Strategy pattern. In particular, you've many variants of an algorithm, i.e. the code executed accordingly to the response of the remote server call.
Implementing the Stategy pattern means that you have to define a class hierachy, such the following:
public interface ResponseProcessor {
public void execute(Context ctx);
}
class ClientRegistered implements ResponseProcessor {
public void execute(Context ctx) {
// Actions corresponding to a client that is registered
// ...
}
}
class ClientAborted implements ResponseProcessor {
public void execute(Context ctx) {
// Actions corresponding to a client aborted
// ...
}
}
// and so on...
The Context type should contain all the information that are needed to execute each 'strategy'. Note that if different strategies share some algorithm pieces, you could also use Templeate Method pattern among them.
You need a factory to create a particular Strategy at runtime. The factory will build a strategy starting from the response received. A possibile implementation should be the one suggested by #Sattar Imamov. The factory will contain the if .. else code.
If strategy classes are not to heavy to build and they don't need any external information at build time, you can also map each strategy to an Enumeration's value.
public enum ResponseType {
CLIENT_REGISTERED(new ClientRegistered()),
CLIENT_ABORTED(new ClientAborted()),
DATA_SPLIT(new DataSplit());
// Processor associated to a response
private ResponseProcessor processor;
private ResponseType(ResponseProcessor processor) {
this.processor = processor;
}
public ResponseProcessor getProcessor() {
return this.processor;
}
}

Is it possible to request fields by specific pattern in solr?

I can use fl=fld1,fld2,fld3 tor return specific fields from solr. But sometimes i generate dynamic field names like ".*_attribute_group1" and want solr to return all group.
Is it posible to extend solr 'fl' field with regexp? Where to look in solr codebase?
Solr doesn't support wildcard patterns in field names ( "fl" param ). But you could write your own component to process the request & identify the list of fileds present in the index that you want.
Pesudo Code of extending search component to implement custom fields..
// PSUEDO CODE
public class FLPatternCustomComponent extends SearchComponent {
#Override
//Gauranteed to be called before any other SearchComponent.process
public void prepare(ResponseBuilder rb) throws IOException {
SolrParams params = rb.req.getParams();
//Input fl=field_*
String[] inputFl = params.getParams(CommonParams.FL);
Collection<String> existingFl = rb.req.getSearcher().getFieldNames();
//process & find matching fields{
SolrQuery newFields = new SolrQuery();
newFields.set(CommonParams.FL, "field_1,field_2,field_3,field_4");
AppendedSolrParams appendedParams = new AppendedSolrParams(params, q);
rb.req.setParams(appendedParams);
super.prepare(rb);
}
#Override
public void process(ResponseBuilder rb) throws IOException {
//Process request
super.process(rb);
}
}
You could have this a component chained to your existing request handler or create your request handler & perhaps you could also add any additional invariants.
You may want to consider any additional performance overhead of custom component & its processing. I have created couple of custom components for custom ranking & custom request handlers & use it without much issues.
You might want to check Solr Plugin Development.

Categories