Problem with A Sync callback function in GWT - gwt

What I'm doing is:
getSecroleByOrgNID(orgList[i-2],cu.currentUser.getProfileObj());
System.out.println("Value of sec role is "+ secondryRole);
where the getSecroleByOrgNID function is:
private String getSecroleByOrgNID(COrganization srOrg, CProfile srUser) {
analyticsSrvc.getSecroleByOrgNID(srOrg, srUser,
new AsyncCallback<String>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(String result) {
secondryRole = result;
System.out.println("Assigned role is " + secondryRole);
}
});
return null;
}
where secondryRole is
String secondryRole = " ";
The output is:
Value of sec role is
Assigned role is Admin
Query is why the "value of sec role is " statement prints before "Assigned role is Admin" since the function is called before print statement of "value of sec role is ".
And why does the value of secondryRole remain " " even though its value is reassigned inside the function?

As GWT docs says, in GWT you have to "embrace asynchronous transactions" and forget about synchronous ones.
The problem is that getSecroleByOrgNID() invoke an asynchronous call to the server but this call doesn't stop execution, so it continues his work (server needs more time to return). You are asking for secondryRole when server doesn't response yet.
You should call a method always inside onSuccess() that work with server response.

Related

Keycloack admin client hangs when attempting to make requests

I'm trying to get some user data out of Keycloack using the admin-client SDK. I've built the client like so:
Keycloak kc = KeycloakBuilder.builder() //
.serverUrl("some_url")
.realm("some-realm")
.username("admin") //
.password("password") //
.clientId("curl")
.resteasyClient(new ResteasyClientBuilder().connectionPoolSize(10).connectionCheckoutTimeout(10, TimeUnit.SECONDS).build()) //
.build();
System.out.println("built");
UsersResource baz = kc.realm(keycloakConfiguration.getRealm()).users();
System.out.println(baz.count());
What seems to happen is that my program hangs indefinitely when attempting to fetch baz - my debugger never hits it. I'm not quite sure what's going on - my credentials are correct. What is the correct way to cause the builder to either 1. fail after a certain time period, or 2.verify that my credentials are correct? It's maddeninly frustrating to debug.
You could create a custom method to check if you client is "online". This method could look like:
public boolean isKeycloakClientValid(Keycloak keycloakClient) {
try {
tryToPingKeycloak(keycloakClient);
} catch (Exception e) {
logger.error("Error while pinging the keycloak server", e);
return false;
}
return true;
}
With the help method:
private void tryToPingKeycloak(KeycloakClient keycloakClient) {
keycloakClient.serverInfo().getInfo();
}
Now you could check your client before using it:
if (isKeycloakClientValid(kc)) {
UsersResource baz = kc.realm(keycloakConfiguration.getRealm()).users();
}

Why can't I catch this EJBTransactionRolledbackException

Server: WildFly10
JPA with eclipseLink 2.6.3-M1
JavaEE7
I have the following EJB:
#Stateless
#LocalBean
public class HandleRollbackComponent {
private static Logger logger = Logger.getLogger(HandleRollbackComponent.class);
#EJB
private Tws14WSBatchChRequestsFacade tws14wsBatchChRequestsFacade;
public void doSomething() {
// first off go and fetch an instance of tws14 from the db
logger.debug("*************************************************");
logger.debug("1. First off go and fetch an instance of tws14 from the db");
String batchChReqId = "103";
Tws14WSBatchChRequests tws14wsBatchChRequests = tws14wsBatchChRequestsFacade.find(new BigDecimal(batchChReqId));
logger.debug("2. Found instance of tws14: " + tws14wsBatchChRequests);
logger.debug("2.1 CARD PLASTIC : " + tws14wsBatchChRequests.getCardPlastic());
try {
logger.debug("3. Now call a method that throws the EJBTrxnRollBackException....");
doSomethingThatThrowsEJBTransactionRolledbackException(tws14wsBatchChRequests);
logger.debug("---> This line should not be logged if exception was thrown....");
} catch (Exception e) {
logger.debug("5. Caught the exception....");
} finally {
logger.debug("6. Finally try and get a fresh instance from the db again...");
tws14wsBatchChRequests = tws14wsBatchChRequestsFacade.find(new BigDecimal(batchChReqId));
logger.debug("7. Was able to get instance from db: " + tws14wsBatchChRequests);
logger.debug("8. Try and update the instance of tws again...");
tws14wsBatchChRequestsFacade.edit(tws14wsBatchChRequests);
logger.debug("9. Could update the instance without problems.....");
logger.debug("10. Check the OrderCards value: " + tws14wsBatchChRequests.getOrderCards() );
}
logger.debug("11. Done...");
}
public void doSomethingThatThrowsEJBTransactionRolledbackException(Tws14WSBatchChRequests tws14wsBatchChRequests) {
logger.debug("4. Set some invalid values on tws14 in an attempt to get exception thrown...");
tws14wsBatchChRequests.setOrderCards("N");
tws14wsBatchChRequests.setOrderCards("");
tws14wsBatchChRequests.setCardPlastic(null);
tws14wsBatchChRequestsFacade.edit(tws14wsBatchChRequests);
}
}
When I call doSomething() this is what I see:
First off go and fetch an instance of tws14 from the db
Found instance of tws14: za.co.fnds.persistence.entities.Tws14WSBatchChRequests[ batchChRequestId=103 ]
2.1 CARD PLASTIC : NBCRFLI_PIN
Now call a method that throws the EJBTrxnRollBackException....
Set some invalid values on tws14 in an attempt to get exception thrown...
---> This line should not be logged if exception was thrown....
Finally trying to get a fresh instance from the db again...
Was able to get instance from db: za.co.fnds.persistence.entities.Tws14WSBatchChRequests[ batchChRequestId=103 ]
Try and update the instance of tws again...
Could update the instance without problems.....
Check the OrderCards value:
Done...
My question is why is the program not going into the catch clause because my logs indicates that a javax.validation.ConstraintViolationException was thrown. Why is the bold log above still show? What am I missing? Is there a way I'm supposed to be handling this program structure in an EJB?
To verify that the implementation is wrong is the method doSomethingThatThrowsEJBTransactionRolledbackException. You can explicitly throw the exception and see if the cath works.
public void doSomething() {
try {
doSomethingThatThrowsEJBTransactionRolledbackException(new Tws14WSBatchChRequests());
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void doSomethingThatThrowsEJBTransactionRolledbackException(Tws14WSBatchChRequests tws14wsBatchChRequests) {
throw new EJBTransactionRolledbackException();
}
If the exception is catching, then your code is not throwing anything

Test Event expiration in Drools Fusion CEP

Ciao, I have tested in several ways, but I'm still unable to test and verify the Event expiration mechanism in Drools Fusion, so I'm looking for some little guidance, please?
I've read the manual and I'm interested in this feature:
In other words, one an event is inserted into the working memory, it is possible for the engine to find out when an event can no longer match other facts and automatically retract it, releasing its associated resources.
I'm using the Drools IDE in Eclipse, 5.4.0.Final and I modified the template code created by the "New Drools Project" wizard to test and verify for Event expiration.
The code below. The way I understood to make the "lifecycle" to work correctly is that:
You must setup the KBase in STREAM mode - check
You must Insert the Events in temporal order - check
You must define temporal constraints between Events - check in my case is last Message()
However, when I inspect the EventFactHandle at the end, none of the Event() has expired.
Thanks for your help.
Java:
public class DroolsTest {
public static final void main(String[] args) {
try {
KnowledgeBase kbase = readKnowledgeBase();
// I do want the pseudo clock
KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
conf.setOption(ClockTypeOption.get("pseudo"));
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// Insert of 2 Event:
Message message = new Message();
message.setMessage("Message 1");
message.setStatus(Message.HELLO);
ksession.insert(message);
ksession.fireAllRules();
clock.advanceTime(1, TimeUnit.DAYS);
Message message2 = new Message();
message2.setMessage("Message 2");
message2.setStatus(Message.HELLO);
ksession.insert(message2);
ksession.fireAllRules();
clock.advanceTime(1, TimeUnit.DAYS);
ksession.fireAllRules();
// Now I do check what I have in the working memory and if EventFactHandle if it's expired or not:
for (FactHandle f : ksession.getFactHandles()) {
if (f instanceof EventFactHandle) {
System.out.println(((EventFactHandle)f)+" "+((EventFactHandle)f).isExpired());
} else {
System.out.println("not an Event: "+f);
}
}
logger.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
// following 2 lines is the template code modified for STREAM configuration
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
return kbase;
}
/*
* This is OK from template, as from the doc:
* By default, the timestamp for a given event is read from the Session Clock and assigned to the event at the time the event is inserted into the working memory.
*/
public static class Message {
public static final int HELLO = 0;
public static final int GOODBYE = 1;
private String message;
private int status;
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return this.status;
}
public void setStatus(int status) {
this.status = status;
}
}
}
Drools:
package com.sample
import com.sample.DroolsTest.Message;
declare Message
#role(event)
end
declare window LastMessageWindow
Message() over window:length(1)
end
rule "Hello World"
when
accumulate( $m : Message(status==Message.HELLO) from window LastMessageWindow,
$messages : collectList( $m ) )
then
System.out.println( ((Message)$messages.get(0)).getMessage() );
end
Please note: even if I add expiration of 1second to the Message event, by
#expires(1s)
I still don't get the expected result that the very first Message event inserted, I would have expected is now expired? Thanks for your help.
Found solution! Obviously it was me being stupid and not realizing I was using Drools 5.4.0.Final while still referring to old documentation of 5.2.0.Final. In the updated documentation for Drools Fusion 5.4.0.Final, this box is added for 2.6.2. Sliding Length Windows:
Please note that length based windows do not define temporal constraints for event expiration from the session, and the engine will not consider them. If events have no other rules defining temporal constraints and no explicit expiration policy, the engine will keep them in the session indefinitely.
Therefore the 3rd requirement I originally enlisted of "You must define temporal constraints between Events" is obviously NOT met because I now understand Sliding Length Window in Drools 5.4.0.Final:
Message() over window:length(1)
are indeed NOT a definition of a temporal constraints for event expiration from the session.
Updating this answer hopefully somebody will find it helpful. Also, just so for your know, me being stupid actually for relying on googling in order to reach the doc, and sometimes you don't get redirected to the current release documentation, so it seems...

Why can't I save this SalesForce Batchable class?

I am currently using the Apex Workbook to refresh my knowledge of SalesForce.
Tutorial #15, Lesson 1: Offers the following code:
global class CleanUpRecords implements Database.Batchable<Object>
{
global final String query;
global CleanUpRecords (String q) {query = q;}
global Database.Querylocator start (Database.BatchableContext BC)
{
return Database.getQueryLocator(query);
}
global void execute (Database.BatchableContext BC, List<sObject> scope)
{
delete scope;
Database.emptyRecycleBin(scope);
}
global void finish(Database.BatchableContext BC)
{
AsyncApexJob a = [
SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email
FROM AsyncApexJob
WHERE Id = :BC.getJobId()
];
// Send an email to the Apex job's submitter
// notifying of job completion.
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {a.CreatedBy.Email};
mail.setToAddresses(toAddresses);
mail.setSubject('Record Clean Up Completed ' + a.Status);
mail.setPlainTextBody (
'The batch Apex job processed ' + a.TotalJobItems +
' batches with '+ a.NumberOfErrors + ' failures.'
);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}
However, regardless of which development interface (e.g. Force IDE, console, setup) I use, when I try to save this, I get:
Multiple markers at this line
- File only saved locally, not to server
- Save error: CleanUpRecords: Class must implement the global interface method: Iterable<Object> start(Database.BatchableContext) from Database.Batchable<Object>, CleanUpRecords: Class must implement the global interface method: void execute(Database.BatchableContext, LIST<Object>) from
Database.Batchable<Object>
(Or some equivalent, depending upon how I try to save it.)
However, it seems to me the required methods are already there.
What's missing?
Prepare to be frustrated ... there's just one character off.
Your class declaration should be:
global class CleanUpRecords implements Database.Batchable<sObject> {
instead of:
global class CleanUpRecords implements Database.Batchable<Object> {

GWT Async call execution order problem

I have a problem with a throw execution in GWT. So I want to show a simple String list in Client side located on "Server Side". Ok, I have in my Main class this atributes:
private final GreetingServiceAsync greetingService = Util.getInstance(); // This is like > typing GWT.create( GreetingService.class );
public ArrayList songs = new ArrayList();
and in my onModuleLoad() method I have a call to another private method that make the Async call to the Server class:
songs.addAll(getSongsList());
So my getSongsList method is as follow:
public ArrayList<String> getSongsList() {
final int defaultSize = 4;
final ArrayList<String> temp = new ArrayList<String>();
GWT.log("Enter in getSongsLists");
greetingService.greetSongMostPopular(defaultSize,
new AsyncCallback<ArrayList<String>>() {
public void onSuccess(ArrayList<String> result) {
GWT.log("Result is:" + result);
temp.addAll(result);
GWT.log("Case 1 TEMP= " + temp);
}
public void onFailure(Throwable caught) {
// throw new
// UnsupportedOperationException("Not supported yet.");
Window.alert("Error greeting data");
}
});
GWT.log("CASE 2 TEMP = " + temp);
return temp;
}
My problem is that in Case 1 I get
[INFO] [MainModule] - Case 1 TEMP= [Song 1, Song 2, Song 3, Song 4]
but in CASE 2 I get the ArrayList empty!!!
[INFO] [MainModule] - Case 1 TEMP= []
What am I doing wrong?
Thanks in advance!
The call to greetSongsMostPopular is asynchronous. This means that the call begins and the code continues directly to the next line of code, in your case GWT.log("CASE 2 TEMP..."). When this line of code is executed, the results are not yet available and you end up with an empty list.
Later, in the background, onSuccess is called with the results. At this point you should call a function to process the results. You can use a pattern similar to the AsyncCallback class, with an onSuccess and onFailure so the caller of this code can handle both cases, or you can just have the caller pass in their own AsyncCallback instance which would make it a thin wrapper around your greetSongsMostPopular RPC function.
This is normal : the callback is called when your server send the answer but the greetSongMostPopular return imediatly.
The call is asynchronous.
All code must be done in the callback (call a function)
Here is the exact process :
greetingService.greetSongMostPopular is called
temp is empty
the second GWT.log is called : temp is always empty
the getSongsList method return : temp is always empty
the server send the answer to the callback : temp is filled
You are not doing anything wrong. This is expected since you are not dealing with synchronous calls. So the case 2 is only invoked after the asynchronous call returns from the server side.