Spring Batch reader using generics - spring

I'm just new in the spring architecture and I am wondering if it is possible to use a generic T (o what you want) in an ItemStreamReader.
Something like this:
public class Reader implements ItemStreamReader<T extends SomeClass>{
public T read() {
.......
}
public void open() {
.......
}
public void update() {
.......
}
public void close() {
.......
}
}
So I pass to the reader various objects that extends SomeClass.

this should work:
public class Reader<T extends SomeClass> implements ItemStreamReader<T>{
public T read() {
.......
}
public void open() {
.......
}
public void update() {
.......
}
public void close() {
.......
}
}
use it like:
Reader<SomeClass> reader = new Reader<>();
Reader<ExtendedFromSomeClass> reader2 = new Reader<>();

I recommend you to read first about java generics.
http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#What is a parameterized (or generic) type?
But if you define your class
public class Reader implements ItemStreamReader<SomeClass>{
public SomeClass read() {
.......
}
public void open() {
.......
}
public void update() {
.......
}
public void close() {
.......
}
}
Your method can return any object that is Subclass of SomeClass.
For example
Reader a = new Reader();
Subclass b = (Subclass)a.read();

Related

How to test a try...finally method only been called once in SpringBoot?

I am following this article to implement a database read/write separation feature by calling different methods. However, I got the error:
Missing method call for verify(mock) here: verify(spyDatabaseContextHolder, times(1)).set(DatabaseEnvironment.READONLY);
when doing the testing.
My test case is trying to verify DatabaseEnvironment.READONLY has been set once when using TransactionReadonlyAspect AOP annotation:
// TransactionReadonlyAspectTest.java
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = {LoadServiceImpl.class, TransactionReadonlyAspect.class})
public class TransactionReadonlyAspectTest {
#Autowired
private TransactionReadonlyAspect transactionReadonlyAspect;
#MockBean
private LoadServiceImpl loadService;
#Test
public void testReadOnlyTransaction() throws Throwable {
ProceedingJoinPoint mockProceedingJoinPoint = mock(ProceedingJoinPoint.class);
Transactional mockTransactional = mock(Transactional.class);
DatabaseContextHolder spyDatabaseContextHolder = mock(DatabaseContextHolder.class);
when(mockTransactional.readOnly()).thenReturn(true);
when(loadService.findById(16)).thenReturn(null);
when(mockProceedingJoinPoint.proceed()).thenAnswer(invocation -> loadService.findById(16));
transactionReadonlyAspect.proceed(mockProceedingJoinPoint, mockTransactional);
verify(spyDatabaseContextHolder, times(1)).set(DatabaseEnvironment.READONLY); // got the error: Missing method call for verify(mock)
verify(loadService, times(1)).findById(16);
assertEquals(DatabaseContextHolder.getEnvironment(), DatabaseEnvironment.UPDATABLE);
}
}
//TransactionReadonlyAspect.java
#Aspect
#Component
#Order(0)
#Slf4j
public class TransactionReadonlyAspect {
#Around("#annotation(transactional)")
public Object proceed(ProceedingJoinPoint proceedingJoinPoint,
org.springframework.transaction.annotation.Transactional transactional) throws Throwable {
try {
if (transactional.readOnly()) {
log.info("Inside method " + proceedingJoinPoint.getSignature());
DatabaseContextHolder.set(DatabaseEnvironment.READONLY);
}
return proceedingJoinPoint.proceed();
} finally {
DatabaseContextHolder.reset();
}
}
}
// DatabaseContextHolder.java
public class DatabaseContextHolder {
private static final ThreadLocal<DatabaseEnvironment> CONTEXT = new ThreadLocal<>();
public static void set(DatabaseEnvironment databaseEnvironment) {
CONTEXT.set(databaseEnvironment);
}
public static DatabaseEnvironment getEnvironment() {
DatabaseEnvironment context = CONTEXT.get();
System.out.println("context: " + context);
return CONTEXT.get();
}
public static void reset() {
CONTEXT.set(DatabaseEnvironment.UPDATABLE);
}
}
//DatabaseEnvironment.java
public enum DatabaseEnvironment {
UPDATABLE,READONLY
}
// LoadServiceImpl.java
#Service
public class LoadServiceImpl implements LoadService {
#Override
#Transactional(readOnly = true)
public LoadEntity findById(Integer Id) {
return this.loadDAO.findById(Id);
}
...
}
I just want to test DatabaseContextHolder.set(DatabaseEnvironment.READONLY) has been used once then in the TransactionReadonlyAspect finally block it will be reset to DatabaseEnvironment.UPDATABLE which make sense.
However, how to test DatabaseContextHolder.set(DatabaseEnvironment.READONLY) gets called once? Why does this error occur? Is there a better way to test TransactionReadonlyAspect?

Spring Boot- Autowiring interface implemented by different beans

I have multiple beans with #Component implementing a generic interface.
I have a class where I use methods from these beans. Instead of autowiring each bean separately, I was figuring out of autowiring the interface as a list.
But how do I call the methods of different beans when I just autowire the interface.
public interface Generic {
}
#Component
public class A implements Generic{
.....
public void test{
}
}
#Component
public class B implements Generic{
.....
public void read{}
}
#component class C {
#Autowired
List <Generic> mylist; // type of list is Generic
Now I need to access read from B and test from A
With your new question you CAN do it like this way but I think it's better to use 2 seperate lists instead of the instanceOf.
public interface Generic { }
public interface GenericTestable extends Generic {
void test()
}
public interface GenericReader extends Generic {
void read()
}
#Component
public class A implements GenericTestable {
public void test() { }
}
#Component
public class B implements GenericReader {
public void read() { }
}
#Component
public class C {
private final List<Generic> genericItems;
#Autowired
public C(List<Generic> genericItems) {
this.genericItems = genericItems;
}
public void callThem() {
this.genericItems.forEach(this::callMethodOnSpecificType);
}
private void callMethodOnSpecificType(Generic genericItem) {
if (genericItem instanceof GenericTestable) {
((GenericTestable) genericItem).test();
} else if (genericItem instanceof GenericReader) {
((GenericReader) genericItem).read();
}
}
}
But I think that something like this is a better approach. Cleaner and faster code. Remove the Generic interface and use only the 2 separate interfaces.
public class BetterC {
private final List<GenericTestable> genericTestables;
private final List<GenericReader> genericReaders;
#Autowired
public BetterC(List<GenericTestable> genericTestables, List<GenericReader> genericReaders) {
this.genericTestables = genericTestables;
this.genericReaders = genericReaders;
}
public void callTestables() {
this.genericTestables.forEach(GenericTestable::test);
}
public void callReaders() {
this.genericReaders.forEach(GenericReader::read);
}
}
How about using the Generic interface to route the call ?
From the java-doc api : Ordered
Ordered is an interface that can be implemented by objects that should
be orderable, for example in a Collection. The actual order can be
interpreted as prioritization, with the first object (with the lowest
order value) having the highest priority.
import org.springframework.core.Ordered;
public interface Generic extends Ordered {
void call();
}
----
#Component
public class A implements Generic {
#Override
public int getOrder() {
return 2;
}
#Override
public void call() {
test();
}
public void test() {
System.out.println("Call test()");
}
}
----
#Component
public class B implements Generic {
#Override
public int getOrder() {
return 1;
}
#Override
public void call() {
read();
}
public void read() {
System.out.println("call read()");
}
}
----
#Component
public class C {
List<Generic> list;
public C(List<Generic> list) {
this.list = list;
}
public void testMethod() {
for(Generic g: list) {
g.call();
}
}
}
try this in your implementation
#Component
#Qualifer("a")
public class A implements Generic{ ..... public void test(){ }}
#Component
#Qualifer("b")
public class B implements Generic{ ..... public void read(){ }}
#component
public class C {
#Autowired
Generic a;
#Autowired
Generic b;
... call respective methods
}

GWT, how to fire event from widget or composite using EventBus from HandlerManager

I have widget. I would like to fire an event as follow:
fireEvent(new IndicatorStartEvent("Message"));
But it dosn't work.
Normally I use Presenter for this (GWTP), but now I just would like to have regular widget:
public class FileUploadWidget extends Composite {
MaterialFileUploader uploader = new MaterialFileUploader();
#Inject
public FileUploadWidget(String triggerId, EventBus eventBus) {
super();
initWidget(uploader);
Window.alert("TEST Start");
fireEvent(new IndicatorStartEvent("Message"));
}
}
Here is event code:
public class IndicatorStartEvent extends GwtEvent<IndicatorStartEvent.IndicatorHandler> {
public static Type<IndicatorHandler> TYPE = new Type<IndicatorHandler>();
public interface IndicatorHandler extends EventHandler {
void onIndicatorProgressStart(IndicatorStartEvent event);
}
public interface IndicatorHandlers extends HasHandlers {
HandlerRegistration addStartIndicatorHandler(IndicatorHandler handler);
}
private final String message;
public IndicatorStartEvent(final String message) {
this.message = message;
}
public static Type<IndicatorHandler> getType() {
return TYPE;
}
#Override
protected void dispatch(final IndicatorHandler handler) {
handler.onIndicatorProgressStart(this);
}
#Override
public Type<IndicatorHandler> getAssociatedType() {
return TYPE;
}
public String getMessage() {
return this.message;
}
}
This is my app presenter that handle the event:
public class AppPresenter extends TabContainerPresenter<AppPresenter.MyView, AppPresenter.MyProxy> implements AppUiHandlers
, IndicatorStartEvent.IndicatorHandler {
#ProxyStandard
public interface MyProxy extends Proxy<AppPresenter> {}
public interface MyView extends TabView, HasUiHandlers<AppUiHandlers> {}
#Override
protected void onBind() {
super.onBind();
addRegisteredHandler(IndicatorStartEvent.getType(), this);
}
public void onAsyncCallFail(AsyncCallFailEvent event) {
// fireEvent is executed from: com.gwtplatform.mvp.client;PresenterWidget
fireEvent(new IndicatorStartEvent("Firing message"));
}
#Override
public void onIndicatorProgressStart(IndicatorStartEvent event) {
MaterialToast.fireToast("Indicator start: " + event.getMessage());
}
}
If I fire this event from f.e.: AppPresenter (code above), or GwtRESTY filter/callback ass follow:
class ProgressIndicatorFilter implements DispatcherFilter {
private AssistedInjectionFactory factory;
private EventBus eventBus;
#Inject
public ProgressIndicatorFilter(AssistedInjectionFactory factory, EventBus eventBus) {
this.factory = factory;
this.eventBus = eventBus;
}
#Override
public boolean filter(Method method, RequestBuilder builder) {
builder.setCallback(factory.createProgressIndicatorCallback(method));
eventBus.fireEvent(new IndicatorStartEvent("Rest-Gwt Comunication started"));
return true;
}
}
It work as expected. But in those working examples it use com.google.web.bindery.event.shared;EventBus
The firing event doesnt work from widget, where is used:
com.google.gwt.event.shared;HandlerManager;Bus class. This class Bus extends com.google.web.bindery.event.shared.SimpleEventBus which extends the proper EventBus class from com.google.web.bindery.event.shared;EventBus.
So the widget's method fireEvent() use other EventBus.
Can anyone help me with this?
I've red official and this instruction:
http://blog.arcbees.com/2015/04/01/gwt-platform-event-best-practices-revisited/ but no luck so far. Please help.
It does not work because your FileUploadWidget uses it's own EventBus and not GWTP one that is also used in all of your Presenters.
There are two solutions:
Don't use fireEvent(new IndicatorStartEvent("Message")) but use eventBus.fireEvent(new IndicatorStartEvent("Message")) on the injected EventBus inside of your Widget.
Add the IndicatorStartEvent handler to your FileUploadWidget directly instead of using addRegisteredHandler on your Presenter.
I prefer solution 2:
public class FileUploadWidget extends Composite {
MaterialFileUploader uploader = new MaterialFileUploader();
#Inject
public FileUploadWidget(String triggerId) {
super();
initWidget(uploader);
Window.alert("TEST Start");
fireEvent(new IndicatorStartEvent("Message"));
}
}
In the Presenter or to be precise the View which uses your FileUploadWidget, you add a handler directly to the FileUploadWidget:
public class UploadView extends ViewWithUiHandlers<UploadUiHandlers> implements UploadPresenter.MyView,IndicatorStartEvent.IndicatorHandler {
#UiField
FileUploadWidget uploadWidget;
#Inject
public UploadView(final Binder binder) {
widget = binder.createAndBindUi(this);
uploadWidget.addHandler(new IndicatorStartEvent.Handler(),this);
}
public void onIndicatorProgressStart(IndicatorStartEvent event) {
MaterialToast.fireToast("Indicator start: " + event.getMessage());
}
}

JMeter Plugin - How to Listen to TestState

I am working on developing a JMeter plugin. I'm trying to create an AbstractVisualizer that is capable of monitoring the current test state. However, implementing the TestStateListener doesn't seem to be working.
I'm testing this by creating a basic listener that has a login to output arbitrary info to JMeter's logging console. When a sample is sent through the Add function, a line is sent to the console. But nothing is ever triggered on the various TestState functions. Is there something more structural I'm missing?
public class TestListener extends AbstractVisualizer
implements TestStateListener
{
private static final Logger log = LoggingManager.getLoggerForClass();
#Override
public void add(SampleResult arg0) {
log.info("add");
}
#Override
public void clearData() {
// TODO Auto-generated method stub
}
#Override
public String getStaticLabel()
{
return "Test Listener";
}
#Override
public String getLabelResource() {
return null;
}
#Override
public void testEnded() {
log.info("Test Ended");
}
#Override
public void testEnded(String arg0) {
log.info("Test Ended");
}
#Override
public void testStarted() {
log.info("Test started");
}
#Override
public void testStarted(String arg0) {
log.info("Test started");
}
}
I'm not sure how to do it in 1 class. I have 2 classes:
The UI:
public class MonitorGui extends AbstractListenerGui
{
// ...
#Override
public TestElement createTestElement()
{
TestElement element = new Monitor();// <-- this is the backend
modifyTestElement(element);
return element;
}
// ...
}
And then the backend goes like this:
public class Monitor extends AbstractListenerElement
implements SampleListener,
Clearable, Serializable,
TestStateListener, Remoteable,
NoThreadClone
{
private static final String TEST_IS_LOCAL = "*local*";
// ...
#Override
public void testStarted()
{
testStarted(TEST_IS_LOCAL);
}
#Override
public void testEnded()
{
testEnded(TEST_IS_LOCAL);
}
#Override
public void testStarted(String host)
{
// ...
}
// ...
}
You may not need to implement SampleListener like I do, but probably other things are quite similar.
I based that implementation on a built-in pair of ResultSaverGui and ResultCollector which are the components that are saving results into the file(s) for Simple Data Writer, Summary Report and so on.

how to bundle handlers in the handlerManager?

is there a option to bundle different eventhandler in one javafile?
Like:
public interface MyHandlerr extends EventHandler {
void myEvent1(Event1 event);
void myEvent2(Event2 event);
}
in the moment i have for each event one handler....but i'm not happy with it.
greetz
You can create your own EventHandler interface for handling multiple events
public interface MultipleEventsHandler extends EventHandler {
void onMyEvent(MyEvent event);
void onMyOtherEvent(MyOtherEvent event);
}
Then in your event classes you can define which of the methods should be called
public class MyEvent extends GwtEvent<MultipleEventsHandler> {
public static final Type<MultipleEventsHandler> TYPE = new Type<MultipleEventsHandler>();
#Override
public Type<MultipleEventsHandler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(MultipleEventsHandler handler) {
handler.onMyEvent(this);
}
}
public class MyOtherEvent extends GwtEvent<MultipleEventsHandler> {
public static final Type<MultipleEventsHandler> TYPE = new Type<MultipleEventsHandler>();
#Override
public Type<MultipleEventsHandler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(MultipleEventsHandler handler) {
handler.onMyOtherEvent(this);
}
}
If you just want to reduce number of classes/interfaces then you can put EventHandler's inside your event classes, e.g.
public class MyEvent extends GwtEvent<MyEvent.Handler> {
public interface Handler extends EventHandler {
void onMyEvent(SomeEvent event);
}
public static final Type<MyEvent.Handler> TYPE = new Type<MyEvent.Handler>();
#Override
public Type<MyEvent.Handler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(MyEvent.Handler handler) {
handler.onMyOtherEvent(this);
}
}

Resources