Room and RX Java - rx-java2

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()

Related

mongo query is hanging in filter of mono

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?

Inner destructured property not received by ELK stack as destructured, but as escaped string

I'm not sure if this is a Serilog, ELK, Service Fabric, code or config issue.
I am writing a Service Fabric Stateless Service. My logging configuration line is this:
Logger = new LoggerConfiguration()
.WriteTo.EventFlow(loggingOptions.DiagnosticPipeline)
.Destructure.With<JsonNetDestructuringPolicy>()
.Enrich.FromLogContext()
.CreateLogger()
.ForContext(properties);
...where properties is an array of PropertyEnricher and the Policy is from Destructurama's JsonNetDestructuringPolicy.
I have a custom object base class that is successfully being destructured, so if I call it Data, then in ELK's JSON tab I see:
"payload": {
"Data": {
"Property1": "Prop Value",
"Property2": "Prop2 Value"
}
}
However, when one of the inner objects is also destructured, it is sent as an escaped JSON string instead of being destructured, with no quotes around the property names:
"payload": {
"Data": {
"Property1": "Prop Value",
"DestructuredProp": "{InnerProperty: \"Inner Value\"}"
}
}
What I expected was:
"payload": {
"Data": {
"Property1": "Prop Value",
"DestructuredProp": {
"InnerProperty": "Inner Value"
}
}
}
I don't know why the inner property names are not given quotes, or why the entire value is being escaped and quoted instead of destructured.
I have verified that my destructuring code is being executed. I can manually add quotes around the property name, for example, but it just results in more escaped quotes in the inner value.
My own code was destructuring it directly from C#. I thought it might have been a bug in my destructuring code, so I looked around some more and found Destructurama's JsonNetDestructuringPolicy, so I tried that, converting my object with JObject.fromObject(), but the same thing happens with it.
I'm pretty sure I should be able to do this with Serilog. I don't think there would be a depth limit setting if it couldn't do more than one layer deep. Why doesn't this work? I have tried refreshing the field index in Kibana, but the JSON view shows the escaped string, so I'm pretty sure it is being sent incorrectly, and isn't an ELK issue.
---EDIT---
Here is a destructuring policy I tried. My initial object is JsonEvent, and it has a Dictionary that is not destructuring, even though the Dictionayr policy is successfully being invoked.
public class JsonEventDestructuringPolicy : IDestructuringPolicy
{
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
if (value is JsonEvent jsonEvent)
{
var properties = new List<LogEventProperty>();
foreach (var property in value.GetType().GetProperties())
{
var propertyValue = property.GetValue(value);
var isCollection = propertyValue is ICollection<Dictionary<string,string>>;
var isDictionary = propertyValue is Dictionary<string,string>;
if (isCollection)
LoggingContext.Message("Found collection of dictionary: " + property.Name);
else if (isDictionary)
LoggingContext.Message("Found dictionary: " + property.Name);
else if (property.Name.Equals("Parameters"))
LoggingContext.Message("Found Parameters: " + propertyValue.GetType());
if (propertyValue != null)
properties.Add(new LogEventProperty(property.Name, propertyValueFactory.CreatePropertyValue(propertyValue, isCollection || isDictionary)));
}
result = new StructureValue(properties);
return true;
}
if (value is Dictionary<string, string> dictionary)
{
var properties = new List<LogEventProperty>();
foreach (var kvp in dictionary)
{
if (!string.IsNullOrWhiteSpace(kvp.Value))
properties.Add(new LogEventProperty("\"" + kvp.Key + "\"", propertyValueFactory.CreatePropertyValue(kvp.Value)));
}
result = new StructureValue(properties);
return true;
}
result = null;
return false;
}
}
It is being invoked like this:
public static void Message(JsonEvent message)
{
Logger.ForContext(GetEnrichers(message))
.Information(message.Event);
}
private static IEnumerable<ILogEventEnricher> GetEnrichers(JsonEvent message)
{
return new List<ILogEventEnricher>()
.Add("Data", message, true)
.Add("CorrelationId", ServiceTracingContext.CorrelationId)
.Add("CorrelationDateTime", ServiceTracingContext.CorrelationDateTime)
.Add("RouteTemplate", ServiceTracingContext.RouteTemplate)
.ToArray();
}

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(...).

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

Ajax Popupcontrolextender issues

I have a bizarre problem. I have followed the example here (http://www.4guysfromrolla.com/articles/071107-1.aspx) to display an ajax popup, but it is not working properly.
The problem I have is that the image attributes are not set properly, I checked with Firebug and this is what I get on page 1 after load.
<img src="StyleSheets/magglass.jpg" id="mainContent_TheGrid_MagGlass_0">
Now the bizarre, if I go to page 2, the onmouseover event is set properly for all images and if I come back to page 1, it is set properly too, e.g.
<img src="StyleSheets/magglass.jpg" onmouseover="$find('pce0').showPopup(); " id="mainContent_TheGrid_MagGlass_0">
I stepped through the code and confirmed that the rowcreated event is firing for my grid, for each row
Any Ideas?
My code is slightly different to the example, see below
protected void TheGrid_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Programmatically reference the PopupControlExtender
PopupControlExtender pce = e.Row.FindControl("TheGrid_PopupControlExtender") as PopupControlExtender;
// Set the BehaviorID
string behaviorID = string.Concat("pce", e.Row.RowIndex);
pce.BehaviorID = behaviorID;
// Programmatically reference the Image control
Image i = (Image)e.Row.Cells[0].FindControl("MagGlass");
// Add the client-side attributes (onmouseover & onmouseout)
string OnMouseOverScript = string.Format("$find('{0}').showPopup(); ", behaviorID);
i.Attributes.Add("onmouseover", OnMouseOverScript);
}
}
The GetDynamicContent Method is below, which adds the hidepopup method.
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string GetDynamicContent(string contextKey)
{
GridView MyGrid = (GridView)HttpContext.Current.Session["TheGrid"];
var MyVar = from GridViewRow MyRow in MyGrid.Rows
where MyRow.Cells[MyRow.Cells.Count - 1].Text == contextKey
select MyRow;
//This is the selected row by the user
GridViewRow MyGridRow = MyVar.SingleOrDefault();
//MyGridRow.Cells[3].Text is the log entry.
string MyTable = #"<table class=""PopUpTable""><tr><td><textarea class=""textarea"">"
+ MyGridRow.Cells[3].Text + "</textarea></td>";
//MyGridRow.RowIndex is used to determine the name of popup control for the hidepopup script
MyTable += "<td><button type=\"button\" class=\"PopUpButton\" onclick=\"$find('pce" + MyGridRow.RowIndex.ToString() + "').hidePopup();\">Close</button></td></tr></table>";
return MyTable;
}
This is the pageIndexChanging event
protected void TheGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
TheGrid.PageIndex = e.NewPageIndex;
LoadFromDB();
}
The LoadFromDB method here:
private void LoadFromDB()
{
try
{
LOGDBDataContext LDC = new LOGDBDataContext(ConfigurationManager.ConnectionStrings[Constants.ConnectionStringName].ConnectionString);
string Query = #"DateTimeStamp >= #0 and DateTimeStamp <= #1";
var Tolo = LDC
.Logs
.Where(Query, this.FromCalendar.SelectedDate, this.ToCalendar.SelectedDate)
.OrderBy("DateTimeStamp desc")
.Select("new (LogID, DateTimeStamp, Organization, LogEntry, ServerHostname)");
TheGrid.DataSource = Tolo;
TheGrid.DataBind();
}
catch (Exception ex)
{
//do something here
}
}
Never Mind, found the answer.
Poor Debugging
A poor attempt at
clearing the gridview that was not
invoked by the pagechanging event
Incompetence thy name is yomismo