Spring : Send automated email to member and admin after timer expires - java

I am working on a Spring-MVC application in which there is Service desk functionality I am working on. So, as a part of Service desk, users can create issues and assign a support-team member. In that, they can also assign in how much time issue needs to be resolved. I am setting the time in java.sql.TimeStamp.
Now, when the time expires, I would like to send an email to the support-team admin, the person who created the issue and the support-team member responsible for resolving the issue.
If it was a normal scheduled or cron job, I can just write a #Scheduled method and get it over with, but here, I would like to check for example after 6 hours if the issue was resolved or not. How do I accomplish that? I have no idea to be honest.
Here is service layer part the SupportRequest :
#Service
#Transactional
public class SupportRequestServiceImpl implements SupportRequestService{
private final SupportRequestDAO supportRequestDAO;
#Autowired
public SupportRequestServiceImpl(SupportRequestDAO supportRequestDAO){
this.supportRequestDAO = supportRequestDAO;
}
#Autowired
private SupportTeamService supportTeamService;
#Override
public int addSupportRequest(SupportRequest supportRequest, int assignedTeamId, Long groupId) {
SupportTeam supportTeam = this.supportTeamService.getSupportTeamMemberById(assignedTeamId);
if(!(supportTeam == null)){
supportRequest.setCreationTime(new Timestamp(System.currentTimeMillis()));
supportRequest.setAssignedTeamMemberId(supportTeam.getTeamId());
return this.supportRequestDAO.addSupportRequest(supportRequest,groupId);
}
return 0;
}
}
I don't know what else to show. Thanks a lot.
Update
Will something like this work?
long delay = 1000*60*60*12; // after 12 hrs
Timer timer = new Timer();
Calendar cal = Calendar.getInstance();
timer.schedule(new TimerTask() {
public void run() {
// Task here ...
System.out.println("inside the main");
Integer id = new Integer(10);
Assert.assertNotNull(id);
}
}, delay);

For these kind of scenario, there should be background process running. That process will check for issues that has not been fixed in given time. Then this process will send a message to whoever you want and then continue running in background.
There are different ways of doing this.
1. Batch Process
You can make batch process. Batch process will be running on your server, it will check for expired issues and then send mail to the support-team admin.
2. Techniques for Real-time Updates
You can also you real time update techniques in spring. Using this technique you will fire request after every given period that will check for expire issues. If any issue found that has not been fixed you can send mail. Please read the related document here : Spring MVC 3.2 Preview: Techniques for Real-time Updates
3. Web Socket
Web socked can also be useful for these kind of task. Find the good source here :
SPRING FRAMEWORK 4.0 M2: WEBSOCKET MESSAGING ARCHITECTURES

Related

send data to server every minute (For check status user)

For check status user i should send some data to server every 5 minutes with retrofit2.
Of course, this information should be sent when the user is in the app
This means that when the user is out of the application, there is no need to send something to the server
What is the best way to do this?
For connection to server i use retrofit2.
One solution is to use Android's work manager to ping your server with http request. You can create initial OneTimeWorkRequest when user logins and with in each execution create a new OneTimeWorkRequest with 5 minutes delay. When user exits the app cancel all the work request.
See the Jetpack Library: https://developer.android.com/topic/libraries/architecture/workmanager
Another solution for which you need to make changes in your architecture is to use Sockets with library like SocketIO. Connect the socket from your app when user login notifying server that user is online. When socket disconnect server can mark user offline: https://socket.io/blog/native-socket-io-and-android/
One other solution is to use Firebase Realtime database for presence system. Firebase has nice example of how to do this: https://firebase.googleblog.com/2013/06/how-to-build-presence-system.html
You can write this code in service and make network call every 5 minutes using handler or RxJava;
public class YourService extends Service{
public final Handler handler = new Handler();
#Override
public void onCreate() {
makeCallEvery5Min();
}
private void makeCallEvery5Min(){
runnable = new Runnable() {
#Override
public void run() {
// execute call here
}
handler.postDelayed(runnable, delay);
}
}
}
RXJava
private void makeCallEvery5min() {
Observable.interval(0, 5, TimeUnit.MINUTES)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(v -> your_network_call() );
}
May help you below approach
If user is log in, should have user id.
Now try to check for user id of particular user in user log in session.
Note: below code should be added in web page(jsp or servlet)--.
Single User Approach:if(userId==Session.getUserId(userId)){response.refresh(5);//write code to send data to server using retrofit2.}
MultiUser Approach: multiple users log in.if(Session.getUsers()!=null){response.refresh(5);//write code to send data to server using retrofit2 }

Twincat ADS event driven reading stops working after a while (Java)

We developed a Java application which uses the TwinCat ADS library (DLL) to read, write and handle events from the Beckhoff PLC (CX5120).
We successfully run this on several machines but unfortunately we’re currently having a problem case where the event handling suddenly stops.
This is the exact scenario we went through:
Read, write and events are handled correctly.
Suddenly we don’t get any events at all anymore, reading and writing are still working correctly though.
Replaced the PLC for another one, started working successfully again. We assumed it was a licensing problem then.
After a week of unattended running, the same problem started again, PLC/ADS library seems not to be triggering events anymore and we can’t seem to get it working again in any way. Reading/writing still working as it should.
Tested using another PC with the Java application, same problem. So something in the PLC seems to freeze up / stop working.
Here's how we have setup the event handling:
// Implementation of the CallbackListenerAdsState interface
public class ADSEventController implements CallbackListenerAdsState {
......
// Register itself as listener for the ADS events (in constructor)
callObject = new AdsCallbackObject();
callObject.addListenerCallbackAdsState(this);
....
// Event handling
public void onEvent(AmsAddr addr, AdsNotificationHeader notification, long user) {
log.info("Got ADS event for handle[{}] and with raw data[{}]", user, notification.getData());
......
// Registering notification handles for PLC variables
// If we already assigned a notification, delete it first (while reconnecting)
JNILong notification = new JNILong();
if(var.getNotification() != null) {
notification = var.getNotification();
AdsCallDllFunction.adsSyncDelDeviceNotificationReq(addr,notification);
}
// Specify attributes of the notificationRequest
AdsNotificationAttrib attr = new AdsNotificationAttrib();
attr.setCbLength(var.getSize());
attr.setNTransMode(AdsConstants.ADSTRANS_SERVERONCHA);
attr.setDwChangeFilter(1000); // 0.01 sec
attr.setNMaxDelay(2000); // 0.02 sec
// Create notificationHandle
long err = AdsCallDllFunction.adsSyncAddDeviceNotificationReq(
addr,
AdsCallDllFunction.ADSIGRP_SYM_VALBYHND, // IndexGroup
var.getHandle(), // IndexOffset
attr, // The defined AdsNotificationAttrib object
var.getHandle(), // Choose arbitrary number
notification);
var.setNotification(notification);
if (err != 0) {
log.error("Error: Add notification: 0x{} for var[{}]", Long.toHexString(err), var.getId());
}
We managed to find the cause.
When we register a variable we get a handle (long) from the PLC, which, in our case unexpectedly started to be negative values after a while.
We also used this long value as user reference for notifications, however, we found the user reference is an unsigned long in the ADS library.
So if we set a negative value of e.g. -1258290964 as ‘arbitrary number’ in the adsSyncAddDeviceNotificationReq call, the CallbackListenerAdsState onEvent method’s parameter ‘user’ (Long) got the unsigned long representation of our signed long user reference, which is 3036676332.
In our Java application we used this user reference to match an event to a specific plc variable by this handle. Since, in our example, we expected -1258290964 but got 3036676332, we never handled any events.

get notified when spring boot healtcheck status changes

Is there a way to get notified when the status of the registered health check indicators changes? For example, when the healthcheck indicator of database becomes down, I would like to take some actions.
Actually, my final goal is to export healthcheck status to Prometheus' metrics. So, when there is status change, I want to update health metrics.
I assume your question refers to Micrometer issue 416 and Micrometer-Docs issue 39.
As per documentation, you can register the custom HealthMetricsConfiguration. The value of the gauge is determined by the status the ComposeHealthIndicator returns and is actually changing depending on the state of the single HealthIndicators.
I am using afformentioned HealthMetricsConfiguration (just with different status value mappings as discussed in issue 416).
Wen't ahead and implemented a custom alternating health indicator:
#Component
public class AlternatingHealthIndicator extends AbstractHealthIndicator {
#Override
protected void doHealthCheck(Builder builder) throws Exception {
int minute = LocalDateTime.now().getMinute();
boolean minuteIsEven = minute % 2 == 0;
builder.status(minuteIsEven ? Status.UP : Status.DOWN);
builder.withDetail("description", "UP when current minute is even; DOWN when current minute is odd");
builder.withDetail("currentMinute", minute);
builder.withDetail("minuteIsEven", minuteIsEven);
}
}
The health gauge exported on the Prometheus endpoint is minutely changing from 1=UP to -2=DOWN. Here's a visualization:
Regarding alerting, you can use Grafana alerting or look into Prometheus' Alertmanager.

validate and expire the link using gwt - java

My Requirement is to sent a mail to the concerned users when a record is created. The mail contains a link to our system that lets the user interacting with the system without login. The link expires after a certain time. The mailing is done using javax.mail.
How can I expire the link?
Use Timer#schedule(int):
// Schedule the timer to run once in 1 minute.
new Timer()
{
#Override
public void run()
{
if(remove)
{
// Either remove it
anchor.removeFromParent();
}
else
{
// Or disable it
anchor.setEnabled(false);
}
}
}.schedule(60 * 1000);
I would generate a key/ID that you add to the link and also store to a database. With filters (web.xml) you can check if the URL (ID) is still valid and pass it on to the desired page.
If you provide us with more details, we can give you a more detailed answer.

Email using Singleton pattern

I have a webapp running on my server, which does some balance update. Once the balance is updated, I need to check if the balance is below 5000. In case, the balance goes below 5000, I should send an email alert. The point to note here is that, I need to send the alert only once in a day, alert should not keep going every time the balance is below 5000.
I believe, I should use singleton pattern for sending the mail, but I am not sure how to use this.
The program when sees the balance going below 5000, should call the singleton class which will have the function to send email alert, but how do you ensure that program will not call this function again when the balance goes down?
Can anyone guide me on this?
There is two separate things you need think about:
Email sending service.
Several ways to implement it. Yes, it could be Singleton, but it also could be a plain Java service. If you use Spring, then they have very simple and useful predefined implementations. Here is an example.
Your checking balance logic.
Depends on what you really need. If you need to check every balance update but send alerts not more that once per day, then it will be something like:
private Date lastAlertDate;
private static final BALANCE_LIMIT = 5000;
private void handleBalanceUpdated(long balance) {
if (balance < 5000) {
log.info("Balance has gone below {}", BALANCE_LIMIT);
int daysDifference = getDifferenceInDays(lastAlertDate, new Date());
if (daysDifference >= 1) {
log.info("Last alert was {} days ago, going to send email alert", daysDifference);
alertService.sendSimpleAlert("Balance has gone below " + BALANCE_LIMIT + "!");
lastAlertDate = new Date();
}
}
}
Singleton is a design pattern that makes sure only one instance of an object is created.
Doesn't sound like it has anything to do with what you need, you could add a flag in your DB like alert_sent=true/false and update it accordingly.
User Timer Task to send mail only once a day
Singleton Pattern
You do not need any "special" design patterns here. For instance you can store the date when the last email notification was sent, like:
Date lastEmail = ... // last email date
And when trying to send email chekc the condition:
If( ... ) // lastEmail is before current day
{ //send emal and update lastEmail }

Categories

Resources