mongo query is hanging in filter of mono - reactive-programming

I am facing mongo reactive repository hanging issue which cause the whole application hanging.
shipment.getItems().forEach(item -> {
return deliveryRepository.findById(item.getDeliveryNumber())
.filter(delivery -> Objects.isNull(delivery.getState()) || !delivery.getState().equals(TrackObjectState.DELIVERED))
.filter(delivery -> deliveryStatusShouldBeUpdatedToDelivered(delivery, shipment, gamMessage))
.flatMap(delivery -> {
delivery.setState(TrackObjectState.DELIVERED);
return deliveryRepository.save(delivery);
}).subscribe(delivery -> log.info("delivery: " + delivery.getDeliveryNumber() + " is updated to state delivered"));
});
inside method deliveryStatusShouldBeUpdatedToDelivered, I called a another service named incotermLocationService via blow code.
var alternativeLocations = incotermLocationService.getAlternativeUnLocationCodesByUnlocationCode(destinationLocation).blockOptional();
and this incotermLocationService code as following.
public Mono<Set<String>> getAlternativeUnLocationCodesByUnlocationCode(String unlocationCode) {
if (log.isDebugEnabled()) {
log.debug("alternative location get by un-location code is called with un-location code: " + unlocationCode);
}
return incotermLocationRepository.getAlternativeLocationsByUnLocationCode(unlocationCode)
.flatMap(incotermLocation -> Flux.fromIterable(incotermLocation.getUnLocationCodes()))
.map( unloCode -> { log.debug("unlocationCode: " + unloCode + " is returned"); return unloCode;})
.collect(Collectors.toSet());
}
but this incotermLocationRepository.getAlternativeLocationsByUnLocationCode() was in hanging for ever.
I checked this method which was called in other place works well. Then I take it out from the filter.
shipment.getItems().forEach(item -> {
var deliveryOptional = deliveryRepository.findById(item.getDeliveryNumber())
.filter(delivery -> Objects.isNull(delivery.getState()) || !delivery.getState().equals(TrackObjectState.DELIVERED))
.blockOptional();
if (deliveryOptional.isPresent() && deliveryStatusShouldBeUpdatedToDelivered(deliveryOptional.get(), shipment, gamMessage)) {
var delivery = deliveryOptional.get();
deliveryOptional.get().setState(TrackObjectState.DELIVERED);
deliveryRepository.save(delivery).subscribe(savedDelivery -> log.info("delivery: " + delivery.getDeliveryNumber() + " is updated to state delivered"));
}
});
Then repository was called and the whole logic works as expected.
Did u face this before that a reactive repository used in a filter method never triggered even it is called with block?

Related

How to properly Update a Collection<Entity>?

Here's what I tried:
public Collection<User> updateUsers(Collection<User> users) {
Collection<User> usersUpdated = null;
users.stream()
.filter(u -> userRepository.existsById(u.getId()))
.forEach(
u -> {
Optional<User> user = userRepository.findById(u.getId());
userRepository.save(user);
usersUpdated.add(userRepository.findById(u.getId()));
logger.debug("Update single " + User.class.getName() + ": " + u);
}
);
return usersUpdated;
}
The issue is on userRepository.save(user) where I'm getting the following:
Inferred type 'S' for type parameter 'S' is not within its bound; should extend 'com.example.model.User'
How should I properly update a collection of this entity?
You're getting the 'Inferred type not within its bound' exception, because you're passing an Optional to the save method, instead of a User object.
And I would suggest that you can save the entire collection with one request to the database, using CrudRepository.saveAll(), like this:
userRepository.saveAll(users);

How to use doOnNext, doOnSubscribe and doOnComplete?

New to RxJava2/RxAndroid and Android development, but am pretty familiar with Java.
However, I've ran into quite a roadblock when trying to "optimize" and be able to update the UI between a bunch of calls to the same resource.
My code is as follows:
private int batch = 0;
private int totalBatches = 0;
private List<ItemInfo> apiRetItems = new ArrayList<>();
private Observable<ItemInfo[]> apiGetItems(int[] ids) {
int batchSize = 100;
return Observable.create(emitter -> {
int[] idpart = new int[0];
for(int i = 0; i < ids.length; i += batchSize) {
batch++;
idpart = Arrays.copyOfRange(ids, i, Math.min(ids.length, i+batchSize));
ItemInfo[] items = client.items().get(idpart);
emitter.onNext(items);
}
emitter.onComplete();
}).doOnSubscribe( __ -> {
Log.d("GW2DB", "apiGetItems subscribed to with " + ids.length + " ids.");
totalBatches = (int)Math.ceil(ids.length / batchSize);
progressbarUpdate(0, totalBatches);
}).doOnNext(items -> {
Log.d("GW2DB", batch + " batches of " + totalBatches + " batches completed.");
progressbarUpdate(batch, totalBatches);
}).doOnComplete( () -> {
Log.d("GW2DB", "Fetching items completed!");
progressbarReset();
});
}
If I remove the doOnSubscribe, doOnNext and doOnComplete I get no errors in Android Studio, but if I use any of them I get Incompatible types. Required: Observable<[...].ItemInfo[]>. Found: Observable<java.lang.Object>
I'm using RxAndroid 2.1.1 and RxJava 2.2.16.
Any ideas?
Since you are adding a chain of method calls, the compiler is just unable to correctly guess the type for the generic parameter in Observable.create. You can set it explicitly using Observable.<ItemInfo[]>create(...).

Room and RX Java

I have a method in which a data sheet is committed.
    
private void saveItemsToDB(List<NewsEntity> newsEntityList) {
Disposable disposable = Completable.fromCallable((Callable<Void>) () -> {
            newsDatabase.getNewsDao().deleteAll();
            Utils.log("******Delete All******");
           
 for (NewsEntity newsEntity : newsEntityList) {
                Utils.log("******Save " + newsEntity + "******");
                newsDatabase.getNewsDao().insert(newsEntity);
            }
            return null;
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe();
        compositeDisposable.add(disposable);
    }
I need to save them to the database. I work with Room. There is a method
   
 #Insert(onConflict = OnConflictStrategy.REPLACE)
  void insertAll(NewsEntity... newsEntities);
  
  #Insert(onConflict = OnConflictStrategy.REPLACE)
  void insert(NewsEntity newsEntity);
No saving occurs Link
According to RxJava2 documentation, it's not allowed to pass null through rx chain. I suppose, it's the cause of the problem.
Completable.fromCallable((Callable<Void>) () -> {
...
return null; // don't do this
})
If you don't want to return anything, use Completable.fromAction()

how to put verification in pageobject model in protractor

I have a code (credit to #kishanpatel) Traverse-through-each-row-for-a-column-text which will verify whether the value is added in grid or not. i want to put this in my page object. i was thinking to add the elements into page object and the if condition in a different helper file similar to selenium but i am not sure is that the right appraoch. see the details below.
if I call the mo.helper in spec.ts, it says gridcheck.ispresent() is not a function. How to handle this scenario?
code:
it('verify the grid that master obligation is added', function () {
var testvar = "'test_protractor'";
var row_check = element(by.xpath("//div[contains(text()," + testvar + ")]"));
if (row_check.isPresent()) {
row_check.getText().then(function (msg) {
if (row_check.isPresent()) {
console.log("Grid contains========== " + msg);
}
});
}
});
i have the below method in mo.ts(page object page):
this.grid = function (value) {
// var testvar = "'test_protractor'";
var row_check = element(by.xpath("//div[contains(text()," + value + ")]"));
return require('./mohelper.ts')
}
}
mohelper.ts:
require('../page/mo.ts')
var mohelper = function () {
this.gridvaluepresent = function () {
require('../page/mo.ts')
var gridcheck = mo.grid();
if(gridcheck.isPresent()) {
gridcheck.getText().then(function (msg) {
if (gridcheck.isPresent()) {
console.log("Grid contains========== " + msg);
}
})
}
}
}
module.exports = new mohelper();
spec.ts:
it('go to corresponding module and verify whether the master obligation is added ', function () {
browser.sleep(10000);
taxhome.selectmodule;
taxhome.selectmoduledropdown(1);
mo.grid("test_protractor");
mohelper.gridvaluepresent();
});
Couple of things here to be considered -
1) Most of the protractor's api methods are asynchronous i.e. they return promises you have to resolve/reject them to perform actions.
isPresent() also returns a promise, you need to resolve it-
var row_check = element(by.xpath("//div[contains(text()," + value + ")]"));
row_check.isPresent().then(function(present) {
if(present) { // it returns a boolean value
row_check.getText().then(function (msg) {
console.log("Grid contains========== " + msg);
});
}
});
2) Since you are using TypeScript , use its syntax rather than conventional js-
let row_check = element(by.xpath("//div[contains(text()," + value + ")]")); // Block scoped variable using 'let'
row_check.isPresent().then((present) => { // notice the thick arrow
if(present) {
row_check.getText().then((msg) => {
console.log("Grid contains========== " + msg);
});
}
});
3) Maintain Page Objects efficiently and readable-
All the helper methods, elements etc. for a single page should go in a single page object. Write them in separate classes, typescript uses the concept of classes and transpiles them to global functions.
moHelper.ts
import {ElementFinder, element} from 'protractor';
export class MoHelper {
public row_check: ElementFinder; // its of element finder type
gridValueCheck(value : string) {
row_check = element(by.xpath("//div[contains(text()," + value + ")]")); // please use Css selectors instead of Xpath!
row_check.isPresent().then((present) => {
if(present) {
row_check.getText().then((msg) => {
return msg; // here you are returning the msg of the row from your page!
});
}
});
}
}
Your spec.ts should validate that row msg!
import {MoHelper} from './moHelper.ts'
let mo: MoHelper = new MoHelper();
it('go to corresponding module and verify whether the master obligation is added ', () => {
browser.sleep(10000); // please refrain from using sleeps instead use Expected Conditions
taxhome.selectmodule;
taxhome.selectmoduledropdown(1);
expect(mo.gridValueCheck("test_protractor")).toEqual("Your Expected Message");
});
Please find the links for your reference to understand the above in more detail-
isPresent
Getting started with typescript
Using page objects in protractor/style guide
Expected Conditions

Sugar ORM - Difference between save() and update()

What is the difference between save() and update() in sugar ORM?
By referring to this Sugar ORM in Android: update a saved object in SQLite
save and update are giving same result?
I want to update the existing record if exist how to do that?
here I want to do something like:
long count = Lead.count(Lead.class);
if (count > 0) {
List<Lead> leads = Lead.find(Lead.class, "lead_id = ?", leadItem.leadId);
if (leads == null) { // save leadItem
Lead.save(lead);
logFile.writeLog("Home Activity: Lead saved in local DB. Lead Id is: " + leadItem.leadId + " leadItem Name: " + leadItem.name);
Log.d("Lead saved: ", leadItem.toString());
} else { // update leadItem
Lead.update(lead);
logFile.writeLog("Home Activity: Lead updated in local DB. Lead Id is: " + leadItem.leadId + " leadItem Name: " + leadItem.name);
Log.d("Lead updated: ", leadItem.toString());
}
}
Here when I call update it is also updating the another record which I saved with different ID and adding as new record rather update.