How to render a StreamObserver in WebUI (ktor + freemarker) - kotlin

How to handle the output of a StreamObserver in freemarker ?
I have the following controller code so as to subscribe to a stream channel.
else -> {
try {
//jsonResponse = gnhc.getRequestJsonOutput(pathlist,pretty = true)
jsonResponseRaw = gnhc.subscribev1(pathlist, subId, writer).toString()
jsonResponse = jsonResponseRaw
application.log.debug("SDN_JSON_PROCESSOR: ${jsonResponse}")
} catch (e: Exception) {
jsonResponse = e.toString()
application.log.error("Failed to set channel", e)
} finally {
gnhc.shutdownNow()
}
}
}
call.respond(FreeMarkerContent("subscribe.ftl", mapOf("hostname" to hostname, "port" to port, "cmd" to cmd, "result" to jsonResponse,"rawresult" to jsonResponseRaw, "pathlist" to pathlist, "error" to error), etag = "e"))
}
The Observer is declared here:
try {
// simple observer without writer and subId
val sr: StreamObserver<Gnmi.SubscribeRequest> = stub.subscribe(GnmiStreamObserver(this))
// Writer + Id
//val sr: StreamObserver<Gnmi.SubscribeRequest> = stub.subscribe(StreamResponseWriter(_path,_id,_writer))
sr.onNext(subRequest)
waitCompleted()
sr.onCompleted()
}

Related

How to get the value of another function synchronously

I am using the ktor websocket module
When I send data to the client, how do I get the data back from the client after this send?
val result = serverSession.send(json)
// result
Just like this
It is actually the Unit type
But I want to get the String
There are great examples on official site of Ktor.
If you are server-side, check this link (https://ktor.io/docs/websocket.html#handle-single-session) and the below example.
webSocket("/echo") {
send("Please enter your name")
for (frame in incoming) {
when (frame) {
is Frame.Text -> {
val receivedText = frame.readText()
if (receivedText.equals("bye", ignoreCase = true)) {
close(CloseReason(CloseReason.Codes.NORMAL, "Client said BYE"))
} else {
send(Frame.Text("Hi, $receivedText!"))
}
}
}
}
}
If you are client-side, check this link (https://ktor.io/docs/websocket-client.html#example) and the below example.
client.webSocket(method = HttpMethod.Get, host = "127.0.0.1", port = 8080, path = "/echo") {
while(true) {
val othersMessage = incoming.receive() as? Frame.Text
println(othersMessage?.readText())
val myMessage = Scanner(System.`in`).next()
if(myMessage != null) {
send(myMessage)
}
}
}

How to validate error body in Webflux/Webclient

I have a handler method for an endpoint, that is this one:
public Mono<ServerResponse> create(ServerRequest serverRequest) {
Validator validator = new CreateUserValidator();
Mono<UserDto> userDtoMono = serverRequest.bodyToMono(UserDto.class);
return userDtoMono.flatMap(user ->
{
Errors errors = new BeanPropertyBindingResult(user, UserDto.class.getName());
validator.validate(user, errors);
if (errors == null || errors.getAllErrors().isEmpty()) {
return userService.create(user).flatMap(aa -> ServerResponse.status(HttpStatus.CREATED)
.contentType(MediaType.APPLICATION_JSON).body(fromValue(aa))).onErrorResume(this::handleException);
} else {
Set<String> errors1 = new HashSet<String>();
errors.getAllErrors().forEach(message -> {
errors1.add(message.getDefaultMessage());
});
return handleException(new InvalidAttributesException(errors1));
}
});
}
private Mono<ServerResponse> handleException(Throwable exception) {
ErrorResponse errorResponse = new ErrorResponse();
if (exception instanceof InvalidAttributesException) {
InvalidAttributesException asd = (InvalidAttributesException) exception;
asd.getErrors().forEach(error ->
errorResponse.addMessage(messagesService.getMessage(error)));
} else {
errorResponse.addMessage(messagesService.getMessage(exception.getMessage()));
}
logger.info("Error:" + errorResponse);
return ServerResponse.status(HttpStatus.BAD_REQUEST).body(fromValue(errorResponse));
}
As you can see, if the validator fails, the method return a bad request error with a ErrorResponse as a body.
I use a WebClient in order to test it. The WebClient has a filter to get the ErrorResponse in case of a error status:
WebClient client = WebClient.builder().clientConnector(new
ReactorClientHttpConnector(HttpClient.create(ConnectionProvider.newConnection()))).filter(ExchangeFilterFunction.ofResponseProcessor(clientResponse ->
{
if (clientResponse.statusCode().isError()){
return clientResponse.bodyToMono(ErrorResponse.class).flatMap(errorResponse ->
Mono.error(new InvalidAttributesException(new HashSet<>(errorResponse.getMessages())))
);
}
return Mono.just(clientResponse);
})).baseUrl("http://localhost:8080").build();
Mono<ErrorResponse> response = (Mono<ErrorResponse>) client.post().uri(thingsEndpoint(url)).accept( MediaType.APPLICATION_JSON ).body(Mono.just(userDto),UserDto.class).ti
.exchange();
response.subscribe(as -> {
List<String> expectedMessages = new ArrayList<>();
expectedMessages.add("name is mandatory");
expectedMessages.add("email is mandatory");
assertTrue(as.getMessages().containsAll(expectedMessages));
});
But it doesn't work. When I debug the test, it seems that when the exchange() method is called returns an exception before calling the endpoint. What am I doing bad?

onMessageReceived method is not called, when app is not open

I have implemented FCM in my app, and I need to pass some data from Firebase service to Activity. I have implemented the following code, which works fine, when the app is in foreground(open). When the app is killed or in background, onMessageReceived method is not called, and the launcher activity is loaded while click on the push notification. Also, when the app is open, push message is blank. Kindly advise what I have done wrong. FYI, from backend, they are sending data payload, not notification.
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
public FirebaseMessagingService() {
}
private static final String TAG = com.google.firebase.messaging.FirebaseMessagingService.class.getSimpleName();
public static String CHAT_PUSH_NOTIFICATION_INTENT = "chatPushNotificationIntent";
private PreferencesManager preferencesManager;
#Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.e("push token >>", s);
String reliableIdentifier = FirebaseInstanceId.getInstance().getId();
FCMPreferencesManager pref = FCMPreferencesManager.getInstance(this);
if (pref != null) {
pref.setStringValue(FCMPreferencesManager.FCM_KEY_VALUE, s);
pref.setStringValue(FCMPreferencesManager.DEVICE_ID, reliableIdentifier);
}
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
try {
preferencesManager = PreferencesManager.getInstance(this);
int userId = preferencesManager.getIntValue(PreferencesManager.LOGIN_USER_ID);
Log.e("onMessage received >>", "inside service");
Log.e("userId >>", userId + "");
if (userId > 0) {
Log.e("remote message >>", remoteMessage.getNotification().getBody() + "");
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void classApprovedNotification(int jobId, String stage) {
if (!Utils.isAppIsInBackground(getApplicationContext())) {
Intent pushNotification = new Intent(Constants.PUSH_NOTIFICATION_INTENT);
pushNotification.putExtra("jobId", jobId);
pushNotification.putExtra("stage", stage);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
}
}
private void handleDataMessage(JSONObject json) {
try {
Log.e("total json >> ", json.toString());
JSONObject data = json.optJSONObject("data");
Log.e("data >> ", data.toString());
String title = data.optString("title");
String message = data.optString("message");
Log.e("title >>", title);
Log.e("message >>", message);
localNotification(data, title, message, false);
} catch (Exception e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
}
}
private void localNotification(JSONObject data, String title, String message, boolean isSendBird) {
int type = 0, groupId = 0, classId = 0, jobId = 0;
String stage = "";
int notificationId = (int) System.currentTimeMillis();
int userId = preferencesManager.getIntValue(PreferencesManager.LOGIN_USER_ID);
String className = "", fileName = "";
if (data != null) {
jobId = data.optInt("job_id");
stage = data.optString("stage", "");
}
Log.e("jobId in service >>", jobId + "");
Log.e("stage in service >>", stage);
Intent intent = new Intent(FirebaseMessagingService.this, VendorHomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("jobId", jobId);
intent.putExtra("stage","stage");
int requestID = (int) System.currentTimeMillis();
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
requestID,
intent,
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
);
String channelId = "";
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.fyxt_logo)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
/* NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(this);*/
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(notificationId /* ID of notification */, notificationBuilder.build());
try {
PowerManager.WakeLock screenLock = null;
if ((getSystemService(POWER_SERVICE)) != null) {
screenLock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "OOTUSER:WAKE");
screenLock.acquire(10 * 60 * 1000L /*10 minutes*/);
screenLock.release();
}
} catch (Exception e) {
e.printStackTrace();
}
classApprovedNotification(jobId, stage);
}
}
In my Activity, I have the following code.
private BroadcastReceiver notificationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
jobIdFromNotification = intent.getIntExtra("jobId", 0);
stageFromNotification = intent.getStringExtra("stage");
Log.e("jobIdFromNotification >>", jobIdFromNotification + "");
Log.e("stageFromNotification >>", stageFromNotification);
prefManager.setIntValue(PreferencesManager.JOB_ID_IN_PREF, jobIdFromNotification);
prefManager.setStringValue(PreferencesManager.JOB_STAGE_IN_PREF, stageFromNotification);
classApprovedViewUpdate();
}
};
private void classApprovedViewUpdate() {
if (jobIdFromNotification > 0) {
fragmentInteractionCallback = (BaseFragment.FragmentInteractionCallback) this;
Log.e("inside push receiver update ", "sfs");
if (stageFromNotification.trim().equalsIgnoreCase(Constants.STAGE_TICKET_APPROVAL)) {
sendActionToActivity(ACTION_CREATE_MAINTENANCE_REQUEST, currentTab, true, fragmentInteractionCallback);
}
}
}
Edit:
data payload:
{
"data": {
"type": 0,
"job_id": 123,
"stage": "STAGE_TICKET_APPROVAL",
}

org.apache.fop.fo.flow.ExternalGraphic catches and logs ImageException I want to handle myself

I am transforming an Image into pdf for test purposes.
To ensure that the Image is compatible with the printing process later on, I'm running a quick test print during the upload.
I'm creating a simple Test-PDF with a transformer. When I try to print an image with an incompatible format, the ImageManager of the transformer throws an ImageException, starting in the preloadImage() function:
public ImageInfo preloadImage(String uri, Source src)
throws ImageException, IOException {
Iterator iter = registry.getPreloaderIterator();
while (iter.hasNext()) {
ImagePreloader preloader = (ImagePreloader)iter.next();
ImageInfo info = preloader.preloadImage(uri, src, imageContext);
if (info != null) {
return info;
}
}
throw new ImageException("The file format is not supported. No ImagePreloader found for "
+ uri);
}
throwing it to:
public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager)
throws ImageException, IOException {
//Fetch unique version of the URI and use it for synchronization so we have some sort of
//"row-level" locking instead of "table-level" locking (to use a database analogy).
//The fine locking strategy is necessary since preloading an image is a potentially long
//operation.
if (isInvalidURI(uri)) {
throw new FileNotFoundException("Image not found: " + uri);
}
String lockURI = uri.intern();
synchronized (lockURI) {
ImageInfo info = getImageInfo(uri);
if (info == null) {
try {
Source src = session.needSource(uri);
if (src == null) {
registerInvalidURI(uri);
throw new FileNotFoundException("Image not found: " + uri);
}
info = manager.preloadImage(uri, src);
session.returnSource(uri, src);
} catch (IOException ioe) {
registerInvalidURI(uri);
throw ioe;
} catch (ImageException e) {
registerInvalidURI(uri);
throw e;
}
putImageInfo(info);
}
return info;
}
}
throwing it to :
public ImageInfo getImageInfo(String uri, ImageSessionContext session)
throws ImageException, IOException {
if (getCache() != null) {
return getCache().needImageInfo(uri, session, this);
} else {
return preloadImage(uri, session);
}
}
Finally it gets caught and logged in the ExternalGraphic.class:
/** {#inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
src = pList.get(PR_SRC).getString();
//Additional processing: obtain the image's intrinsic size and baseline information
url = URISpecification.getURL(src);
FOUserAgent userAgent = getUserAgent();
ImageManager manager = userAgent.getFactory().getImageManager();
ImageInfo info = null;
try {
info = manager.getImageInfo(url, userAgent.getImageSessionContext());
} catch (ImageException e) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageError(this, url, e, getLocator());
} catch (FileNotFoundException fnfe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageNotFound(this, url, fnfe, getLocator());
} catch (IOException ioe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageIOError(this, url, ioe, getLocator());
}
if (info != null) {
this.intrinsicWidth = info.getSize().getWidthMpt();
this.intrinsicHeight = info.getSize().getHeightMpt();
int baseline = info.getSize().getBaselinePositionFromBottom();
if (baseline != 0) {
this.intrinsicAlignmentAdjust
= FixedLength.getInstance(-baseline);
}
}
}
That way it isn't accessible for me in my code that uses the transformer.
I tried to use a custom ErrorListener, but the transformer only registers fatalErrors to the ErrorListener.
Is there any way to access the Exception and handle it myself without changing the code of the library?
It was easier than I thought. Before I call the transformation I register a costum EventListener to the User Agent of the Fop I'm using. This Listener just stores the Information what kind of Event was triggered, so I can throw an Exception if it's an ImageError.
My Listener:
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
public class ImageErrorListener implements EventListener
{
private String eventKey = "";
private boolean imageError = false;
#Override
public void processEvent(Event event)
{
eventKey = event.getEventKey();
if(eventKey.equals("imageError")) {
imageError = true;
}
}
public String getEventKey()
{
return eventKey;
}
public void setEventKey(String eventKey)
{
this.eventKey = eventKey;
}
public boolean isImageError()
{
return imageError;
}
public void setImageError(boolean imageError)
{
this.imageError = imageError;
}
}
Use of the Listener:
// Start XSLT transformation and FOP processing
ImageErrorListener imageListener = new ImageErrorListener();
fop.getUserAgent().getEventBroadcaster().addEventListener(imageListener);
if (res != null)
{
transformer.transform(xmlDomStreamSource, res);
}
if(imageListener.isImageError()) {
throw new ImageException("");
}
fop is of the type Fop ,xmlDomStreamSource ist the xml-Source I want to transform and res is my SAXResult.

java mail keeping Transport object connected

How do i keep the java mail transport object alive or connected.
I have written this in my code in a simple class file inside a web application : -
#Resource(name = "myMailServer")
private Session mailSession;
Transport transport ;
public boolean sendMail(String recipient, String subject, String text) {
boolean exe = false;
Properties p = new Properties();
String username = "someone#gmail.com";
String password = "password";
InitialContext c = null;
try
{
c = new InitialContext();
mailSession = (javax.mail.Session) c.lookup("java:comp/env/myMailServer");
}
catch(NamingException ne)
{
ne.printStackTrace();
}
try
{
Message msg = new MimeMessage(mailSession);
msg.setRecipients(Message.RecipientType.TO,InternetAddress.parse(recipient, false));
msg.setSubject(subject);
msg.setText(text);
msg.setHeader("MIME-Version" , "1.0" );
msg.setHeader("Content-Type" , "text/html" );
msg.setHeader("X-Mailer", "Recommend-It Mailer V2.03c02");
msg.saveChanges();
//Transport.send(msg);
if(transport == null) {
transport = mailSession.getTransport("smtps");
System.out.println("" + transport.isConnected());
if(!transport.isConnected()) {
transport.connect(username, password);
}
}
transport.sendMessage(msg, msg.getAllRecipients());
exe = true;
}
catch (AddressException e)
{
e.printStackTrace();
exe = false;
}
catch (MessagingException e)
{
e.printStackTrace();
exe = false;
}
finally {
/*try {
if(transport != null)
transport.close();
}
catch(MessagingException me) {
me.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}*/
}
return exe;
}
the full code here
Now everytime i run this code it takes some time to connect with the mail server
and the line
System.out.println("" + transport.isConnected());
prints a false
How do i retain the object transport as it does gets null and into the block
if(transport == null) {
or the transport object remains connected...
Thanks
Pradyut
the code should be....
with a static initialization of transport object
without any problems but can be good with a function
static Transport getTransport() method
#Resource(name = "myMailServer")
private Session mailSession;
static Transport transport ;
public boolean sendMail(String recipient, String subject, String text) {
boolean exe = false;
Properties p = new Properties();
String username = "someone#gmail.com";
String password = "password";
InitialContext c = null;
try
{
c = new InitialContext();
mailSession = (javax.mail.Session) c.lookup("java:comp/env/myMailServer");
}
catch(NamingException ne)
{
ne.printStackTrace();
}
try
{
Message msg = new MimeMessage(mailSession);
msg.setRecipients(Message.RecipientType.TO,InternetAddress.parse(recipient, false));
msg.setSubject(subject);
msg.setText(text);
msg.setHeader("MIME-Version" , "1.0" );
msg.setHeader("Content-Type" , "text/html" );
msg.setHeader("X-Mailer", "Recommend-It Mailer V2.03c02");
msg.saveChanges();
//Transport.send(msg);
if(transport == null) {
transport = mailSession.getTransport("smtps");
}
if(!transport.isConnected()) {
transport.connect(username, password);
}
transport.sendMessage(msg, msg.getAllRecipients());
exe = true;
}
catch (AddressException e)
{
e.printStackTrace();
exe = false;
}
catch (MessagingException e)
{
e.printStackTrace();
exe = false;
}
finally {
/*try {
if(transport != null)
transport.close();
}
catch(MessagingException me) {
me.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}*/
}
return exe;
}
Thanks
Regards
Pradyut