DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Data
  4. Data Streaming in OSGi R7 applications With OSGi R7 Push Stream and Server Sent Events

Data Streaming in OSGi R7 applications With OSGi R7 Push Stream and Server Sent Events

Learn how OSGi R7 Push Stream, OSGi R7 HTTP Whiteboard, and OSGi R7 JAX-RS Whiteboard can be applied to provide data streaming functionality in your web application.

Michal H. Siemaszko user avatar by
Michal H. Siemaszko
·
Jun. 14, 19 · Tutorial
Like (3)
Save
Tweet
Share
13.14K Views

Join the DZone community and get the full member experience.

Join For Free

Image title

Providing users of your application with feedback regarding long running operations used to require utilizing pull based solutions such as polling. In modern web applications, however, utilizing push based data streaming solutions to provide such feedback is the norm. But what options do we have if we’re building modern cloud native OSGi applications and we wish to implement such monitoring solutions?

In this article, I will show you how implementations of some of the latest OSGi specifications — i.e. OSGI R7 Push Stream, OSGi R7 HTTP Whiteboard, and OSGi R7 JAX-RS Whiteboard — can be applied, along with Server Sent Events, to implement such push based data streaming solutions. So, instead of having a background JavaScript worker slamming the server with requests for status every few seconds, we’ll have the server push data updates and have them displayed onto our GUI.

All of the examples presented in this article are based on a complete application I put together, available for cloning and deploying yourself at https://github.com/ideas-into-software/automated-linguistic-analysis

To keep our focus and length of this article reasonable, let’s skip the basics such as DAO layer and other mundane parts — we have them working already and we can move on to these higher layers. The ‘service-status-impl’ https://github.com/ideas-into-software/automated-linguistic-analysis/tree/master/service-status-impl , ‘rest-status’ https://github.com/ideas-into-software/automated-linguistic-analysis/tree/master/rest-status and ‘rest-common’ https://github.com/ideas-into-software/automated-linguistic-analysis/tree/master/rest-common modules contain all the code referred to in this article.

1. Starting with the service layer, in the ‘service-status-impl’ (https://github.com/ideas-into-
software/automated-linguistic-analysis/tree/master/service-status-impl
) module you will find the software.into.ala.service.status.impl.StatusUpdatesServiceImpl class responsible for pushing events received onto an OSGi R7 Push Stream instance.

2. Here, we have the StatusUpdatesConsumer private class implemented as Runnable, which uses Camel’s consumer template to receive messages from a RabbitMQ topic pertaining to particular file being processed and pushes these onto event source, i.e.:

try {
  ConsumerTemplate consumerTemplate = getCamelContext().createConsumerTemplate();
  Endpoint endpoint = messagingService.registerStatusUpdatesEndpoint(fileId);
  FileMessageDTO fmDTO = consumerTemplate.receiveBody(endpoint,
  FileMessageDTO.class);
  while (fmDTO != null) {
    simplePushEventSource.publish(fmDTO);
    if (isProcessingFinished(fmDTO)) {
      break;
    }
    fmDTO = consumerTemplate.receiveBody(endpoint, FileMessageDTO.class);
  }
  consumerTemplate.cleanUp();
  simplePushEventSource.endOfStream();
} catch (Exception e) {
  simplePushEventSource.error(e);
}

3. In the same software.into.ala.service.status.impl.StatusUpdatesServiceImpl class we have the   software.into.ala.service.status.impl.StatusUpdatesServiceImpl.getStatusUpdates(String) method which starts a new instance of StatusUpdatesConsumer to receive status updates for a particular file being processed, then creates and returns a push based stream of processing status updates obtained from the push event source, i.e.:

public PushStream<String> getStatusUpdates(String fileId) {
  Objects.requireNonNull(fileId, "File ID must be specified!");
  fileProcessingStatusConsumerExec.execute(new StatusUpdatesConsumer(fileId));
  return pushStreamProvider.createStream(simplePushEventSource).map(fmDTO -> fmDTO.status);
}

4. Now, we move to the ‘rest-status’ module
(https://github.com/ideas-into-software/automated-linguistic-analysis/tree/master/rest-status)
which contains  software.into.ala.rest.status.StatusUpdatesRestController . It registers itself as a service with the JAX-RS Whiteboard using the   org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource  annotation, i.e.:

@JaxrsResource
public class StatusUpdatesRestController {
  (...)
}

5. Here, in  the software.into.ala.rest.status.StatusUpdatesRestController.getStatusUpdates(SseEventSink,String)  method, which produces Server Sent Events, we call the  software.into.ala.service.status.StatusUpdatesService.getStatusUpdates(String)  method from the service layer below (‘service-status-impl’ module) to receive status update push notifications — registering method to execute for each event received, as well as two callback methods for failure and resolved scenarios, i.e.:

PushStream<String> fPushStream = statusUpdateService.getStatusUpdates(fileId);
fPushStream.forEach(this::deliverEvent).onFailure(this::failure).onResolve(this::resolved);

6. The action being executed for each event received is handled by the  software.into.ala.rest.status.StatusUpdatesRestController.deliverEvent(String)  method, which simply wraps each event in OutboundSseEvent  and sends it via the  javax.ws.rs.sse.SseEventSink.send(OutboundSseEvent)  method.

7. The two callback methods — software.into.ala.rest.status.StatusUpdatesRestController.failure(Throwable)  for handling failures and software.into.ala.rest.status.StatusUpdatesRestController.resolved()  called when Promise is resolved — are very similar in that they also wrap these different types of events in OutboundSseEvent and send them via the javax.ws.rs.sse.SseEventSink.send(OutboundSseEvent)  method.

8. Finally, our GUI resides in the ‘rest-common’
https://github.com/ideas-into-software/automated-linguistic-analysis/tree/master/rest-common
module. Here, the software.into.ala.rest.common.SinglePageApp  class registers static
resources to be served with the HTTP Whiteboard using the  org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardResource annotation, i.e.:

@HttpWhiteboardResource(pattern = "/spa/*", prefix = "static")

9. The above will result in picking up all of the files which comprise our single page application (i.e. HTML5, CSS3, JavaScript, and SVG files), source residing in the ‘src/main/resources/static’ folder in the ‘rest-common’ module, and serving them via http://IP:PORT/spa/index.html in a running application.

10. It’s also here that we use JavaScript’s EventSource, wrapped in the jQuery Plugin for Server-Sent Events (SSE). Therefore, we include the jQuery and jQuery SSE dependencies as well as our custom JavaScript contained in  ala.js, where we have the monitorStatus(fileId) method responsible for receiving each of these events and passing them to displayStatusMessage method to display each event in GUI.

As perhaps you’ve noticed, even though it’s been over a year since OSGi R7 specifications were released (April 2018), along with implementations for some of those specifications, it is unfortunately still very difficult or impossible to find in public repositories actual applications utilizing these technologies. This article attempted to fill this hole of lack and hopefully it succeeded in doing so.


Event application push Server-sent events Data (computing) Stream (computing)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Rust vs Go: Which Is Better?
  • Master Spring Boot 3 With GraalVM Native Image
  • Use Golang for Data Processing With Amazon Kinesis and AWS Lambda
  • GitLab vs Jenkins: Which Is the Best CI/CD Tool?

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: