Pass the error Message to XPage client from Java Server code - java

Here is my Java code, before call I call the save() method. I want to check this business rule.
if (endDate.before(startDate)){
message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "",
"The end date should be not before the start date.");
// Throw exception so that it prevents document from being saved
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage("travel_endDate",message);
return false;
}
I want this message display at the "travel_endDate" component.

You have to use the client id of your component when adding the message.
1.) Add a binding to you component
<xp:inputText
id="travel_endDate"
binding="#{errorComponent}">
</xp:inputText>
2.) resolve the variable in your save method
UIComponent cmp = (UIComponent) facesContext.getApplication().getVariableResolver().resolveVariable(facesContext, "errorComponent");
String clientId = cmp.getClientId(facesContext);
3.) Add the message with the id to the facesContext
facesContext.addMessage(clientId,message);

Related

Plaid Springboot webhook listener

I am wondering if anyone knows best practices for handling Plaid webhooks with Java Springboot?
Does the Plaid SDK offer any easy way to convert the webhook request object to a model object for the given event type? I only see they have Node Express examples which seems to only deconstruct the JSON request object by key.
Also wondering if their is anyway to verify the incoming webhook request is actually from Plaid
#PostMapping(value = "/webhook/plaid", produces =
MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity plaidWebhook(#RequestBody String payload) {
JSONParser parser = new JSONParser(payload);
JSONObject plaidWebhookRequest = null;
try {
plaidWebhookRequest = (JSONObject) parser.parse();
String webhookType = plaidWebhookRequest.has("webhook_type") ? (String) plaidWebhookRequest.get("webhook_type") : null;
String webhookCode = plaidWebhookRequest.has("webhook_code") ? (String) plaidWebhookRequest.get("webhook_code") : null;
String error = plaidWebhookRequest.has("error") ? (String) plaidWebhookRequest.get("error") : null;
String itemID = plaidWebhookRequest.has("item_id") ? (String) plaidWebhookRequest.get("item_id") : null;
if (webhookType != null && webhookCode != null && webhookType.equals(WebhookType.ITEM.name())) {
switch (webhookCode) {
case ERROR_WEBCODE:
log.info("Plaid webhook received: " + ERROR_WEBCODE);
break;
case PENDING_EXPIRATION:
log.info("Plaid webhook received: " + PENDING_EXPIRATION);
break;
case USER_PERMISSION_REVOKED:
log.info("Plaid webhook received: " + USER_PERMISSION_REVOKED);
break;
}
}
} catch (ParseException e) {
log.debug("Plaid webhook object failed to convert to JSONObject");
}
return ResponseEntity.status(HttpStatus.OK).body("");
}
I am not a Java expert but I can speak to some of the other parts of your question:
You can use the webhook verification endpoint to verify that the webhook is from Plaid: https://plaid.com/docs/api/webhooks/webhook-verification/ although I will admit the process is not as easy as most of the other things you can do with the Plaid API.
As an alternative option -- for a situation like this, you can always check the Item status by calling /item/get to confirm that the Item needs to be updated before sending the user through update mode. As a rule, Plaid doesn't ever send sensitive information in webhooks, and information in webhooks can be verified by calling endpoints that are free to call, so you should never need to "trust" a Plaid webhook without verifying it if you don't want to. This is generally smart to do anyway, for example: even if you got a webhook indicating that the Item is in an error state, the user may have resolved it or it may have self-healed in the interim.

how to make my validator conditional for my checkbox control

I have a validator defined for my checkbox control:
<xp:checkBox uncheckedValue="false"
checkedValue="true" readonly="#{!matterBean.matter.editable}"
id="cbKCSupport" style="width:100%"
value="#{matterBean.matter.creatorKCSupport}"
validator="#{matterValidators.valCreatorKCSupport}">
</xp:checkBox>
the method is nothing fancy, I just check the value true or false of the checkbox:
public void valCreatorKCSupport(FacesContext facesContext, UIComponent component, Object value) {
utils.printToConsole(this.getClass().getSimpleName().toString() + " - valCreatorKCSupport(...), value = " + value.toString());
String msg = null;
if (value.toString().equals("false")){
msg = matterProp.getProperty("gen_KCSupport");
FacesMessage message = new FacesMessage(msg);
throw new ValidatorException(message);
}
}
I notice that this validation blocks the behaviour of other components e.g. the opening of dialog boxes.
For other controls I have a similar approach where the required property is based upon which component (buttons) have initiated the call to the server:
<xp:this.required><![CDATA[#{javascript:return ( submittedBy('btnSendToCommitee') || submittedBy('btnForCompletion') )}]]></xp:this.required>
I tried to set up a similar approach for my checkbox:
but then I get presented an error message:
Error while executing JavaScript action expression
Script interpreter error, line=2, col=33: Error calling method 'valCreatorKCSupport(com.ibm.xsp.domino.context.DominoFacesContext, com.ibm.xsp.component.xp.XspInputCheckbox, string)' on java class 'se.sebank.kkom.test.MatterValidators'
Message (text with text from matterProp.getProperty("gen_KCSupport"))
Anyone a suggestion how I should apply some conditional statement to my validator?

"Unsupported protocol element" when creating Interactions programmatically

I am attempting to create new Interactions programmatically on Genesys Platform SDK 8.5 for Java.
I use the example on the API reference
public void createInteraction(String ixnType, String ixnSubtype, String queue) throws Exception
{
RequestSubmit req = RequestSubmit.create();
req.setInteractionType(ixnType);
req.setInteractionSubtype(ixnSubtype);
req.setQueue(queue);
req.setMediaType("email");
Message response = mPMService.getProtocol("IxnSrv").request(req);
if(response == null || response.messageId() != EventAck.ID) {
// For this sample, no error handling is implemented
return;
}
EventAck event = (EventAck)response;
mInteractionId = event.getExtension().getString("InteractionId");
}
However, this gives me an Unsupported protocol element error.
'EventError' (126) attributes:
attr_error_desc [str] = "Unsupported protocol element"
attr_ref_id [int] = 2
attr_error_code [int] = 4
How do I create a new Interaction programmatically?
Interaction server should be connected with ClientType as either MediaServer or AgentApplication for this request(RequestSubmit).
First of all, you must open your protocol as Media Server. After that you must submit your interaction to interaction server.
Firstly your protocol config must be like this;
interactionServerConfiguration.ClientName = "TestClient";
interactionServerConfiguration.ClientType = InteractionClient.MediaServer;
// Register this connection configuration with Protocol Manager
protocolManagementService.Register(interactionServerConfiguration);
Note : You must have MediaServer type application definition on your Configuration Env., you must see it in CME.
After open you connection to ixn server. You can submit your interaction what you like. Even you can create new type interaction just like i do. I did for our coopate sms system. Its name is not important. We defined it on our bussiness attribute, so our agent can send coopate 3rd party sms system from their agent desktop. Without new extension or new license :) Just tricked it system. Also genesys allows it. i know it because we are genesys official support team in our country :) (But agent seat license may be required depends on agent head count).
RequestSubmit request = RequestSubmit.Create();
request.TenantId = 1;
request.MediaType = "email";
request.Queue = c_inboundQueue;
request.InteractionType = "Inbound";
request.InteractionSubtype = "InboundNew";
// Prepare the message to send. It is inserted in the request as UserData
KeyValueCollection userData =
new KeyValueCollection();
// Prepare the message to send
userData.Add("Subject", "subject goes here");
request.UserData = userData; protocolManagementService[c_interactionServerConfigurationIdentifier].Send(request);
Turns out I needed to set ClientType to InteractionClient.ReportingEngine.

How to store values in a servlet without re initializing them each time a servlet is called

I'm making a queue management system. I've hit on stump here. I'm letting the customer/user select their desired service whose token they want to get, but the thing is each time the servlet is called it re-initializes the service-option objects and the token number for that chosen services goes back to 1. How can I store the token count so that it doesn't goes back to 1 again.
public class XmlServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String Service_Option = request.getParameter("Service_Option");
out.println("You selected Service is: "+ Service_Option);
Customer_Console cc1 = new Customer_Console();
Customer_Console cc2 = new Customer_Console();
Customer_Console cc3 = new Customer_Console();
if(Service_Option.equals("Cash Withdrawal"))
{
cc1.setConsole(1,Service_Option);
Database_Manager.Insert(cc1);
}
else if(Service_Option.equals("Account Service"))
{
cc2.setConsole(2,Service_Option);
Database_Manager.Insert(cc2);
}
else
{
cc3.setConsole(3,Service_Option);
Database_Manager.Insert(cc3);
}
}
}
The Console class contains
private int serviceNum;
private String Service_Option;
private Token token;
and the setConsole method is
public void setConsole(int sNum,String sName)
{
serviceNum = sNum;
Service_Option = sName;
token.incrementToken();
}
UPDATE
I'm having problems with dealing the session for more then 1 customer consoles
HttpSession session = request.getSession(false);
if(session == null)
{
session = request.getSession(true);
Integer count = 0;
session.setAttribute("tokenCount",count);
}
if(Service_Option.equals("Cash Withdrawal"))
{
Integer count = (int)session.getAttribute("tokenCount");
count = new Integer(count.intValue() + 1);
cc1.setToken(count);
Database_Manager.Insert(cc1);
session.setAttribute("tokenCount",count);
}
Also how can I reset the session that every time I restart tomcat I get started with the token number 1.
If I'm supposed to use only one session for all three consoles then how can I do that?
I tried with placing the console objects
if(session == null)
{
session = request.getSession(true);
session.setAttribute("cc1", cc1);
}
if(Service_Option.equals("Cash Withdrawal"))
{
cc1.issueToken();
session.setAttribute("cc1", cc1);
cc1 = (Customer_Console)session.getAttribute("cc1");
Database_Manager.Insert(cc1);
}
But still it doesn't save the increments, again reinitializes the token, why is that?
Store Your service-option Object in session Scope So every time your servlet it called you can access the Object using
HttpSession session = request.getSession();
Console service-option=null;
service-option=(Console)session.getAttribute("console");
if(service-option==null){
service-option=new Console();
}
// After doing your work(setting some variables etc)of Console Class Object
// you can set that Object in Session Like this
session.setAttribute("console", service-option); // here "console" is key
In this way it is reinitialized only for the first time
As Java Docs Says
void setAttribute(String name,Object value)
Binds an object to this session, using the name specified. If an
object of the same name is already bound to the session, the object is
replaced.
Update
A HttpSession is created when calling request.getSession() and it get destroyed/invalidated when you call session.invalidate() or session timeout occurs .
Now coming to
Also how can I reset the session that every time I restart tomcat I
get started with the token number 1. If I'm supposed to use only one
session for all three consoles then how can I do that?
It will automatically get restarted but there will be no token number exist into it because it is fresh , if you need to access token number from your entire application then i suggest you to use Servlet Context
An object of ServletContext is created by the web container at time of
deploying the project.This object can be used to get configuration
information from web.xml file. There is only one ServletContext object
per web application.
If any information is shared to many servlet, it is better to provide
it from the web.xml file using the element.
Now your another confusion
I'm having problems with dealing the session for more then 1 customer
consoles
Please read Session Management in Java . As this topic is too broad so i have given you the link to read it yourself

JSF 2.0 Custom Validation problem

I want to validate the inputs to my JSF page inside my Managed bean, but for some reason it does not work?
#ManagedBean
#RequestScoped
public class RegistrationController {
//values passed from the JSF page
private String name;
...
public void validateName(FacesContext context, UIComponent validate,
Object value) {
String inputFromField = (String) value;
String simpleTextPatternText = "^[a-zA-Z0-9]+$";
Pattern textPattern = null;
Matcher nameMatcher = null;
textPattern = Pattern.compile(simpleTextPatternText);
nameMatcher = textPattern.matcher(getName());
if (!nameMatcher.matches()) {
((UIInput) validate).setValid(false);
FacesMessage msg = new FacesMessage(
"your name cant contain special characters");
context.addMessage(validate.getClientId(), msg);
}
}
This is how input component looks like(Inside a form):
<h:inputText value="#{registrationController.name}" validator="#{registrationController.validateName}" required="true">
<h:message for="nameInput"/>
When i enter a wrong input i dont see the validation message, and in the console i see this:
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
INFO: WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
sourceId=bRegForm:j_idt7[severity=(ERROR 2), summary=(bRegForm:j_idt7: Validation Error: Value is required.), detail=(bRegForm:j_idt7: Validation Error: Value is required.)]
What it could be? Am i forgetting something? Do i have to add something to my configuration files...?
You forgot to give your input component an id. That's where the for attribute of <h:message> should point to.
<h:inputText id="nameInput">
Unrelated to the concrete problem, your approach is clumsy and technically wrong. As per the specification, you should throw a ValidatorException. So instead of
((UIInput) validate).setValid(false);
context.addMessage(validate.getClientId(), msg);
do
throw new ValidatorException(msg);
Then JSF will worry about setting the component as invalid and adding the message to the context.
There's a second problem, you're validating the local value instead of the submitted value.
Replace
nameMatcher = textPattern.matcher(getName());
by
nameMatcher = textPattern.matcher(inputFromField);

Categories

Resources