Plantronics Developer Connection - Realtime APIs https://developer.plantronics.com/blog/realtime-apis en Stream processing business logic state management using REST APIs https://developer.plantronics.com/article/stream-processing-business-logic-state-management-using-rest-apis <div class="field field-name-field-keywords field-type-taxonomy-term-reference field-label-above"> <div class="field-label">Keywords:&nbsp;</div> <div class="field-items"> <span class="field-item even label label-default keyword-label"><a href="/blog/realtime-apis" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Realtime APIs</a></span> </div> </div><div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even" property="content:encoded"><p pid="2" style="box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);"><strong style="box-sizing: border-box;">Background</strong></p> <h5 pid="1" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">At Plantronics, we have taken our mission from building the best in class industry enterprise headsets to a relentless mission of providing insights for improving audio communications. The data we collect from headsets are aggregated in our cloud SaaS offering <a href="https://www.plantronics.com/us/en/support/enterprise-software" rel="nofollow" style="box-sizing: border-box; background: transparent; color: rgb(2, 136, 209); text-decoration-line: none;">Plantronics Manager Pro</a>. We also expose the data via APIs (Please refer links below) which help our partners, MSPs and customers to innovate and customize their tailored use cases with solutions, app etc.</h5> <p pid="1" style="box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);">Our APIs are of two categories(like most APIs there) :</p> <ol> <li> <h5 pid="1" style="box-sizing: border-box; padding: 0px 0px 8px;box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;">REST  pull mechanism using APIs for historical analytics use cases</h5> </li> <li> <h5 pid="1" style="box-sizing: border-box; padding: 0px 0px 8px;box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;">​Real-time Streaming - using pubnub messaging for real time relay of device and call events from Plantronics headsets (Quick Disconnect, Mute etc.)  as in our call center wall board integration e.g. <a href="http://www.eyeonit.com.au/agentq/" rel="nofollow" style="box-sizing: border-box; background: transparent; color: rgb(2, 136, 209); text-decoration-line: none;">Agentq</a> wall broad.</h5> </li> </ol> <div style="box-sizing: border-box; padding: 0px 0px 8px;"> </div> <p pid="1" style="box-sizing: border-box; padding: 0px 0px 8px;box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);"><strong style="box-sizing: border-box;">Streaming analytics backend architecture</strong></p> <h5 pid="3" style="box-sizing: border-box; padding: 0px 0px 8px;box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">Streaming API architecture uses Storm Topologies to subscribe to real time events pushed from <a href="https://www.plantronics.com/us/en/support/downloads-apps/hub-desktop" rel="nofollow" style="box-sizing: border-box; background: transparent; color: rgb(2, 136, 209); text-decoration-line: none;">Hubs</a>(Plantronics client software in a laptop / mobile platform) to a pubnub channel. </h5> <br /> <div class="media media-element-container media-default"><div id="file-300" class="file file-image file-image-png"> <h2 class="element-invisible"><a href="/files/api-architecture-plt-cloud-architecturepng">API ARCHITECTURE - PLT Cloud architecture.png</a></h2> <div class="content"> <img title="Real Time Plantronics Manager Pro Architecture" class="media-element file-default img-responsive" data-delta="1" typeof="foaf:Image" src="https://developer.plantronics.com/system/files/API%20ARCHITECTURE%20-%20PLT%20Cloud%20architecture.png" width="2227" height="966" alt="" /> </div> </div> </div><br /> <br /> <br /> <br /> <br /> <br />   <h5 pid="3" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);"><strong style="box-sizing: border-box;">Architecture flow</strong></h5> <h5 pid="3" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">The diagram above shows the command control for setting up basic authorization of realtime data flow between <a href="https://www.pubnub.com/docs" rel="nofollow" style="box-sizing: border-box; background: transparent; color: rgb(2, 136, 209); text-decoration-line: none;">pubnub</a>, Plantronics Cloud and  a partner application. For basics on starting a realtime stream with plantronics APIs, please look here: <a href="http://developer.plantronics.com/article/getting-started-real-time-apis" rel="nofollow" style="box-sizing: border-box; background: transparent; color: rgb(2, 136, 209); text-decoration-line: none;">http://developer.plantronics.com/article/getting-started-real-time-apis</a></h5> <p pid="20" style="box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);"> </p> <p pid="14" style="box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);">Components:</p> <p pid="12" style="box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);">API servers (Host REST APIs, read/ write to persistence layer MySQL, Hbase, MongoDb).</p> <h5 pid="9" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">1. 3rd party app calls into Streaming API using REST protocol to set up subscription interest for a specific real time stream.</h5> <h5 pid="11" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">2. As part of SUCCESS/201 response, the app gets pubnub subscription metadata (which pub/sub channel keyset etc). Now, the app is ready to subscribe to interested realtime events.</h5> <h5 pid="10" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">3. Plantronics cloud intenally pushes intent to subscribe to realtime events relevant to a tenant's Hubs. Now, Hub client software which communicate with customer headsets(via bluetooth, corded USB) start publishing real time events to plantronics cloud through a negotiated pubnub channel/keyset.</h5> <br /> <br />   <p pid="4" style="box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);">Apache Storm topologies</p> <h5 pid="12" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">The topology is designed to subscribe to pubnub cloud</h5> <ul style="box-sizing: border-box; margin-top: 0px; margin-bottom: 10px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);"> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h6 pid="12" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 12px;">Pub Nub spouts  -   subscribe to pubnub channels for multiple tenants to listen to  device / call stat events coming in from Hub.  Each tenant's Hubs (running on customer laptops/mobile) uses multiple pubnub channels into which clients pushes events to load balance on spouts and pubnub sdk threads.</h6> </li> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h6 pid="12" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 12px;">Pubnub Bolts - Bolt maintains a cache to relevant 3rd party app subscriptions and corresponding pubnub metadata needed. They parse event json from Spout does some aggregation, stores any analytics stat needed in hbase and pushes event to all apps that have subscription to the event stream.</h6> </li> </ul> <h4 pid="12" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 18px; background-color: rgb(255, 255, 255);">Problem</h4> <h5 pid="17" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">Now, with the background of the overall use case and workflow of setting up realtime streaming for 3rd party apps, we can get to the description of challenge that this article tries to provide an architectural pattern for.</h5> <p pid="19" style="box-sizing: border-box; margin: 5px 0px 15px; padding-top: 0px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);"><strong style="box-sizing: border-box;">Requirement</strong></p> <h5 pid="18" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">This article focusses on business logic state management and not times series data aggregation state which lots of articles deal with. With the use case description above, tenants can be  subscribed  and unsubscribed using APIs, 3party app might subscribe and unsubscribe interested streams. Tenants can come and go. Application might reach end of life. So, how to update the cached state on Storm spouts/ bolts?  I researched many options based on our requirement. Having a direct very low latency db access is not a requirement here since this will be a periodic update of cache on when to start/stop reading some tenants, publish to apps  etc. Also the real time path should not be affected while processing events due to db read/ writes was a no compromise one. </h5> <h4 pid="18" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 18px; background-color: rgb(255, 255, 255);">Solution</h4> <div class="media media-element-container media-default"><div id="file-301" class="file file-image file-image-png"> <h2 class="element-invisible"><a href="/files/stormmultitenantprocessing-page-1png">StormMultiTenantProcessing - Page 1.png</a></h2> <div class="content"> <img title="Stream Processing State Manager Storm" class="media-element file-default img-responsive" data-delta="2" typeof="foaf:Image" src="https://developer.plantronics.com/system/files/StormMultiTenantProcessing%20-%20Page%201.png" width="1224" height="1570" alt="" /> </div> </div> </div> <h5 pid="18" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">The above diagram illustrates the state mamagement we zeroed on which has worked well for us. The following component descriptions explain the ideas and flow.</h5> <ol style="box-sizing: border-box; margin-top: 0px; margin-bottom: 10px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);"> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h5 pid="18" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;"><strong style="box-sizing: border-box;">Dynamic state manager</strong>  This singleton instance will periodically kick off on an independent thread a local cache update which maintains the active apps and their event stream subscriptions, tenants which are enabled for realtime and their event subscriptions and other metadata needed for subscribing from tenants and publishing to partner applications.  The dynamic manager updates it state periodicallly using the REST API calls to API servers. They do not talk to databases directly.</h5> </li> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h5 pid="18" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;"><strong style="box-sizing: border-box;">Spout </strong>The spout periodically checks the dynamic state manager and updates it local cache for which tenants it is has a subscription for so that it can add and delete tenants as and when needed. Use something like a regular java timers to kick off this task. Do it within your stream processing framework's(In this case Storm worker thread) thread to avoid synchronization related issues.</h5> </li> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h5 pid="18" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;"><strong style="box-sizing: border-box;">Bolt </strong>The bolt periodically updates (using Tick tuple construct in Storm's doc) to kick off updates for apps and their subscripriptions.</h5> </li> </ol> <h5 pid="18" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: rgb(38, 38, 38); margin-top: 20px; margin-bottom: 5px; font-size: 14px; background-color: rgb(255, 255, 255);">The above pattern has some advantages:</h5> <ul style="box-sizing: border-box; margin-top: 0px; margin-bottom: 10px; color: rgb(38, 38, 38); font-family: Georgia, serif; font-size: 19px; background-color: rgb(255, 255, 255);"> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h5 pid="27" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;"> Avoids close coupling with database schema keeping interface contract with REST APIs.</h5> </li> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h5 pid="27" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;">Some of the APIs given to external parties can be reused. </h5> </li> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h5 pid="27" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;">Testability increases at service level and storm components using mock libraries.</h5> </li> <li style="box-sizing: border-box; padding: 0px 0px 8px;"> <h5 pid="27" style="box-sizing: border-box; font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.2; color: inherit; margin-top: 20px; margin-bottom: 5px; font-size: 14px;">Performance tuning can focussed on the API server layer instead of becoming part of Strom components. So, it gives a good isolation of sub components for performance testing. </h5> </li> </ul> </div></div></div> Fri, 08 Jun 2018 16:27:42 +0000 mramakrishnan 1443 at https://developer.plantronics.com https://developer.plantronics.com/article/stream-processing-business-logic-state-management-using-rest-apis#comments