SeekToCurrentErrorHandler with RetryableException handling (and not NotRetryableException) - spring

Actual SeekToCurrentErrorHandler has the ability to add not retryable exception, meaning all exception are retryable, except the initial one, and added X, Y, Z exceptions.
Stupid question : Is there a simple way to do the opposite : all exception are not retryable, except X', Y', Z'...

Yes, it is possible see this configuration method of that class:
/**
* Set an exception classifications to determine whether the exception should cause a retry
* (until exhaustion) or not. If not, we go straight to the recoverer. By default,
* the following exceptions will not be retried:
* <ul>
* <li>{#link DeserializationException}</li>
* <li>{#link MessageConversionException}</li>
* <li>{#link MethodArgumentResolutionException}</li>
* <li>{#link NoSuchMethodException}</li>
* <li>{#link ClassCastException}</li>
* </ul>
* All others will be retried.
* When calling this method, the defaults will not be applied.
* #param classifications the classifications.
* #param defaultValue whether or not to retry non-matching exceptions.
* #see BinaryExceptionClassifier#BinaryExceptionClassifier(Map, boolean)
* #see #addNotRetryableExceptions(Class...)
*/
public void setClassifications(Map<Class<? extends Throwable>, Boolean> classifications, boolean defaultValue) {
So, to make everything not-retryable you need to provide a default value as false.
The map should then container those exception you'd like to have retryable with the value for keys as true.

Related

_route parameter from Request is null with a custom operation

In my Event plugged on KernelEvents::RESPONSE => EventPriorities::PRE_READ when I check the _route attribute in a custom operation I received null as _route
I'm running a SF 4.2.7 and api-platform/core 2.3.4 and api-platform/api-pack 1.1.0
There is my entity annotation for this operation
subresourceOperations={
* "validate_user"={
* "path"="/legal_documents/{id}/validate",
* "method"="PUT",
* "controller"=LegalDocumentValidate::class
* }
* }
And there's the Controller annotation
#Route(
* name="api_legal_documents_validate_user",
* path="/legal_documents/{id}/validate",
* methods={"PUT"},
* defaults={
* "_api_resource_class"=LegalDocument::class,
* "_api_item_operation_name"="validate_user"
* }
* )
In my EventSubscriber when I dump the _route parameter I have null and a second dump with the good value, it's only with the custom operations, if I try on a operation handle by api-platform I have only 1 dump which shows the good value
It was caused by an exception triggered before the event who was dumping the _route attribute
When you're in a Exception Event the route appears to be null

Which AmqpEvent or AmqpException to handle when an exclusive consumer fails

I have two instances of the same application, running in different virtual machines. I want to grant exclusive access to a queue for the consumer of one of them, while invalidating the local cache that is used by the consumer on the other.
Now, I have figured out that I need to handle ListenerContainerConsumerFailedEvent but I am guessing that implementing an ApplicationListener for this event is not going to ensure that I am receiving this event because of an exclusive consumer exception. I might want to check the Throwable of the event, or event further checks.
Which subclass of AmqpException or what further checks should I perform to ensure that the exception is received due to exclusive consumer access?
The logic in the listener container implementations is like this:
if (e.getCause() instanceof ShutdownSignalException
&& e.getCause().getMessage().contains("in exclusive use")) {
getExclusiveConsumerExceptionLogger().log(logger,
"Exclusive consumer failure", e.getCause());
publishConsumerFailedEvent("Consumer raised exception, attempting restart", false, e);
}
So, we indeed raise a ListenerContainerConsumerFailedEvent event and you can trace the cause message like we do in the framework, but on the other hand you can just inject your own ConditionalExceptionLogger:
/**
* Set a {#link ConditionalExceptionLogger} for logging exclusive consumer failures. The
* default is to log such failures at WARN level.
* #param exclusiveConsumerExceptionLogger the conditional exception logger.
* #since 1.5
*/
public void setExclusiveConsumerExceptionLogger(ConditionalExceptionLogger exclusiveConsumerExceptionLogger) {
and catch such an exclusive situation over there.
Also you can consider to use RabbitUtils.isExclusiveUseChannelClose(cause) in your code:
/**
* Return true if the {#link ShutdownSignalException} reason is AMQP.Channel.Close
* and the operation that failed was basicConsumer and the failure text contains
* "exclusive".
* #param sig the exception.
* #return true if the declaration failed because of an exclusive queue.
*/
public static boolean isExclusiveUseChannelClose(ShutdownSignalException sig) {

Can a single Spring's KafkaConsumer listener listens to multiple topic?

Anyone know if a single listener can listens to multiple topic like below? I know just "topic1" works, what if I want to add additional topics? Can you please show example for both below? Thanks for the help!
#KafkaListener(topics = "topic1,topic2")
public void listen(ConsumerRecord<?, ?> record, Acknowledgment ack) {
System.out.println(record);
}
or
ContainerProperties containerProps = new ContainerProperties(new TopicPartitionInitialOffset("topic1, topic2", 0));
Yes, just follow the #KafkaListener JavaDocs:
/**
* The topics for this listener.
* The entries can be 'topic name', 'property-placeholder keys' or 'expressions'.
* Expression must be resolved to the topic name.
* Mutually exclusive with {#link #topicPattern()} and {#link #topicPartitions()}.
* #return the topic names or expressions (SpEL) to listen to.
*/
String[] topics() default {};
/**
* The topic pattern for this listener.
* The entries can be 'topic name', 'property-placeholder keys' or 'expressions'.
* Expression must be resolved to the topic pattern.
* Mutually exclusive with {#link #topics()} and {#link #topicPartitions()}.
* #return the topic pattern or expression (SpEL).
*/
String topicPattern() default "";
/**
* The topicPartitions for this listener.
* Mutually exclusive with {#link #topicPattern()} and {#link #topics()}.
* #return the topic names or expressions (SpEL) to listen to.
*/
TopicPartition[] topicPartitions() default {};
So, your use-case should be like:
#KafkaListener(topics = {"topic1" , "topic2"})
If we have to fetch multiple topics from the application.properties file :
#KafkaListener(topics = { "${spring.kafka.topic1}", "${spring.kafka.topic2}" })

Is the FileOutputFormat.setCompressOutput(job, true); optional?

In Hadoop program, I tried to compress the result, I wrote the following code:
FileOutputFormat.setCompressOutput(job, true);
FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
The result was compressed, and when I delete the first line:
FileOutputFormat.setCompressOutput(job, true);
and execute the program again, the result was same, was the above code
FileOutputFormat.setCompressOutput(job, true);
optional? What is the function of that code?
Please see the below methods in FileOutPutFormat.java which internally calls the method call which you have deleted.
i.e setCompressOutput(conf, true);
That means you are trying apply Gzip codec class then obviously its a pointer to code that output should be compressed. Isnt it ?
/**
* Set whether the output of the job is compressed.
* #param conf the {#link JobConf} to modify
* #param compress should the output of the job be compressed?
*/
public static void setCompressOutput(JobConf conf, boolean compress) {
conf.setBoolean("mapred.output.compress", compress);
}
/**
* Set the {#link CompressionCodec} to be used to compress job outputs.
* #param conf the {#link JobConf} to modify
* #param codecClass the {#link CompressionCodec} to be used to
* compress the job outputs
*/
public static void
setOutputCompressorClass(JobConf conf,
Class<? extends CompressionCodec> codecClass) {
setCompressOutput(conf, true);
conf.setClass("mapred.output.compression.codec", codecClass,
CompressionCodec.class);
}

What is the difference between Rx.Observable subscribe and forEach

After creating an Observable like so
var source = Rx.Observable.create(function(observer) {...});
What is the difference between subscribe
source.subscribe(function(x) {});
and forEach
source.forEach(function(x) {});
In the ES7 spec, which RxJS 5.0 follows (but RxJS 4.0 does not), the two are NOT the same.
subscribe
public subscribe(observerOrNext: Observer | Function, error: Function, complete: Function): Subscription
Observable.subscribe is where you will do most of your true Observable handling. It returns a subscription token, which you can use to cancel your subscription. This is important when you do not know the duration of the events/sequence you have subscribed to, or if you may need to stop listening before a known duration.
forEach
public forEach(next: Function, PromiseCtor?: PromiseConstructor): Promise
Observable.forEach returns a promise that will either resolve or reject when the Observable completes or errors. It is intended to clarify situations where you are processing an observable sequence of bounded/finite duration in a more 'synchronous' manner, such as collating all the incoming values and then presenting once, by handling the promise.
Effectively, you can act on each value, as well as error and completion events either way. So the most significant functional difference is the inability to cancel a promise.
I just review the latest code available, technically the code of foreach is actually calling subscribe in RxScala, RxJS, and RxJava. It doesn't seems a big different. They now have a return type allowing user to have an way for stopping a subscription or similar.
When I work on the RxJava earlier version, the subscribe has a subscription return, and forEach is just a void. Which you may see some different answer due to the changes.
/**
* Subscribes to the [[Observable]] and receives notifications for each element.
*
* Alias to `subscribe(T => Unit)`.
*
* $noDefaultScheduler
*
* #param onNext function to execute for each item.
* #throws java.lang.IllegalArgumentException if `onNext` is null
* #throws rx.exceptions.OnErrorNotImplementedException if the [[Observable]] tries to call `onError`
* #since 0.19
* #see ReactiveX operators documentation: Subscribe
*/
def foreach(onNext: T => Unit): Unit = {
asJavaObservable.subscribe(onNext)
}
def subscribe(onNext: T => Unit): Subscription = {
asJavaObservable.subscribe(scalaFunction1ProducingUnitToAction1(onNext))
}
/**
* Subscribes an o to the observable sequence.
* #param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* #param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* #param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* #returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the {#link Observable} and receives notifications for each element.
* <p>
* Alias to {#link #subscribe(Action1)}
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{#code forEach} does not operate by default on a particular {#link Scheduler}.</dd>
* </dl>
*
* #param onNext
* {#link Action1} to execute for each item.
* #throws IllegalArgumentException
* if {#code onNext} is null
* #throws OnErrorNotImplementedException
* if the Observable calls {#code onError}
* #see ReactiveX operators documentation: Subscribe
*/
public final void forEach(final Action1<? super T> onNext) {
subscribe(onNext);
}
public final Disposable forEach(Consumer<? super T> onNext) {
return subscribe(onNext);
}

Resources