Publicidad
Publicidad

Más contenido relacionado

Publicidad
Publicidad

Plugins on OnDemand with Remote Apps - Atlassian Summit 2012

  1. Plugins on OnDemand with Remote Apps Don Brown Architect, Atlassian
  2. Five years ago. . .
  3. And now. . . • Over 12k active, 9k paid OnDemand accounts • 5 out of 10 add Greenhopper • 1.5 out of 10 add Bonfire • 1 out of 10 add Team Calendars . . . Instances
  4. The Fine Print
  5. But isn‟t it just a copy?
  6. Plugin Problems: Security <% String eid = request.getParameter("eid"); %> ... Employee ID: <%= eid %>
  7. Plugin Problems: Performance java.lang.OutOfMemoryError: Java heap space at org.apache.xerces.dom.DeferredDocumentImpl.createChunk(Unknown Source) at org.apache.xerces.dom.DeferredDocumentImpl.ensureCapacity(Unknown Source) at org.apache.xerces.dom.DeferredDocumentImpl.createNode(Unknown Source) at org.apache.xerces.dom.DeferredDocumentImpl.createDeferredEntityReference(Unknown Source) at org.apache.xerces.parsers.AbstractDOMParser.startGeneralEntity(Unknown Source) at org.apache.xerces.impl.dtd.XMLDTDValidator.startGeneralEntity(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.startEntity(Unknown Source) at org.apache.xerces.impl.XMLDocumentScannerImpl.startEntity(Unknown Source) at org.apache.xerces.impl.XMLEntityManager.startEntity(Unknown Source) at org.apache.xerces.impl.XMLEntityManager.startEntity(Unknown Source
  8. Plugin Problems: Upgrades
  9. Product Dev QA Everyone‟s Angry Admins Plugin Dev
  10. Introducing Remote Apps
  11. This is a Remote App key: app1 name: Remote App - app1 version: 1 • A single descriptor file display-url: http://example.com description: This app vendor: • Can be in XML, YAML, or JSON name: Atlassian url: http://atlassian.com • Contains permissions: permission: • App metadata - scope: browse_projects • Permissions general-page: - key: first • Extension points name: First url: /first
  12. Examples: General Page Plugin Steps Remote App Steps 1. Add web-item config 1. Add general-page config 2. Add servlet config 2. Implement URL 3. Code servlet 4. Try to get output decorated
  13. Examples: React to Event Plugin Steps Remote App Steps 1. Add component config 1. Add web-hook config 2. Dig through code to find 2. Implement URL event to listen for 3. Register for events 4. Handle event 5. Make sure to unregister
  14. Examples: Custom Macro Editor Plugin Steps Remote App Steps 1. Add web-resource and rest 1. Add custom-macro-editor config config 2. Find and call JavaScript 2. Implement URL API to override edit button 3. Create AUI dialog 4. Implement REST resources
  15. Shipping….Now.
  16. Apps: Dropbox by AppFusions • Share your documents • Written in Java, deployed at Contegix • Provides a custom page macro, and macro editor with MS Office edit
  17. Apps: TFS4JIRA by Spartez • Integrate JIRA with your Team Foundation Server • Written in Java, deployed at Heroku • Uses project and issue tabs, and an admin page
  18. Apps: Lucidchart by . . .
  19. Steps to create Lucidchart app • Establish Trust • Register App • Implement General Page • Implement macro
  20. Establish Trust
  21. Steps to create Lucidchart app • Establish Trust • Register App • Implement General Page • Implement macro
  22. Register the app • Receive from OnDemand as Request params: • OAuth consumer key • OAuth RSA public key • Base URL
  23. Register the app • Return to OnDemand description of the remote app • Can be in XML, JSON or YAML
  24. Provide OAuth consumer key and RSA public key <remote-app key=“xxxxxxx" name="Lucidchart" version="1" icon-url="http://www.lucidchart.com/favicon.ico" display-url="https://www.lucidchart.com/ondemand"> <vendor name="Lucidchart" url="http://www.lucidchart.com" /> <description>Lucidchart example</description> <oauth …> <public-key>yyyyyy</public-key> </oauth> ...
  25. Request permissions ... <permissions> <permission scope="read_users_and_groups" /> <permission scope="read_content" /> <permission scope="modify_attachments" /> <permission scope="modify_content" /> </permissions> ...
  26. General Page ... <general-page section="system.content.add/space" key="lucidAppGeneral" link-name="Lucidchart Diagram" name="Select or create a diagram" url="/doclist" width="1200" height="800" icon-url="/icon"> <description>Insert or Create a Lucidchart Diagram</description> <context-param name="page_id" /> </general-page> ...
  27. General Page ... <general-page section="system.content.add/space" key="lucidAppGeneral" link-name="Lucidchart Diagram" name="Select or create a diagram" url="/doclist" width="1200" height="800" icon-url="/icon"> <description>Insert or Create a Lucidchart Diagram</description> <context-param name="page_id" /> </general-page> ...
  28. General Page ... <general-page section="system.content.add/space" key="lucidAppGeneral" link-name="Lucidchart Diagram" name="Select or create a diagram" url="/doclist" width="1200" height="800" icon-url="/icon"> <description>Insert or Create a Lucidchart Diagram</description> <context-param name="page_id" /> </general-page> ...
  29. General Page ... <general-page section="system.content.add/space" key="lucidAppGeneral" link-name="Lucidchart Diagram" name="Select or create a diagram" url="/doclist" width="1200" height="800" icon-url="/icon"> <description>Insert or Create a Lucidchart Diagram</description> <context-param name="page_id" /> </general-page> ...
  30. Macro ... <macro key="lucidchart" url="/macro" output-type="block" body-type="none"> <description>Create a Lucidchart Diagram</description> <category name="development" /> <image-placeholder url="/imagePlaceHolder" width="140" height="140" apply- chrome="true"/> <parameters> <parameter name="width" title="Width" type="string" default=“700"/> <parameter name="height" title="Height (if blank, image ratio is preserved)" type="string" /> <parameter name="align" type="enum" default="Left"> <value name="Left"/> <value name="Right" /> </parameter> </parameters> </macro>
  31. Macro ... <macro key="lucidchart" url="/macro" output-type="block" body-type="none"> <description>Create a Lucidchart Diagram</description> <category name="development" /> <image-placeholder url="/imagePlaceHolder" width="140" height="140" apply- chrome="true"/> <parameters> <parameter name="width" title="Width" type="string" default=“700"/> <parameter name="height" title="Height (if blank, image ratio is preserved)" type="string" /> <parameter name="align" type="enum" default="Left"> <value name="Left"/> <value name="Right" /> </parameter> </parameters> </macro>
  32. Macro ... <macro key="lucidchart" url="/macro" output-type="block" body-type="none"> <description>Create a Lucidchart Diagram</description> <category name="development" /> <image-placeholder url="/imagePlaceHolder" width="140" height="140" apply-chrome="true"/> <parameters> <parameter name="width" title="Width" type="string" default=“700"/> <parameter name="height" title="Height (if blank, image ratio is preserved)" type="string" /> <parameter name="align" type="enum" default="Left"> <value name="Left"/> <value name="Right" /> </parameter> </parameters> </macro>
  33. Macro ... <macro key="lucidchart" url="/macro" output-type="block" body-type="none"> <description>Create a Lucidchart Diagram</description> <category name="development" /> <image-placeholder url="/imagePlaceHolder" width="140" height="140"/> <parameters> <parameter name="width" title="Width" type="string" default=“700"/> <parameter name="height" title="Height" type="string" /> <parameter name="align" type="enum" default="Left"> <value name="Left"/> <value name="Right" /> </parameter> </parameters> </macro>
  34. Steps to create Lucidchart app • Establish Trust • Register App • Implement General Page • Implement macro
  35. Any language can be used • Lucidchart is using PHP
  36. Add Diagram (general page) function doclist() { if (!$this->_hasValidOAuthSignature()) { $this->set("oauthValid", false); return; } $userId = @$_REQUEST['user_id']; $pageId = @$_REQUEST['page_id']; $redirectURL = "https://" . $_SERVER['SERVER_NAME'] . '/ondemand/attachDocument?page_id=' . $pageId . "&user_id=" . $userId; $this->layout = „ondemand'; $this->set("baseUrl", $this->_getBaseURL()); $this->set("callback", urlencode($redirectURL)); }
  37. Add Diagram (general page) function doclist() { if (!$this->_hasValidOAuthSignature()) { $this->set("oauthValid", false); return; } $userId = @$_REQUEST['user_id']; $pageId = @$_REQUEST['page_id']; $redirectURL = "https://" . $_SERVER['SERVER_NAME'] . '/ondemand/attachDocument?page_id=' . $pageId . "&user_id=" . $userId; $this->layout = „ondemand'; $this->set("baseUrl", $this->_getBaseURL()); $this->set("callback", urlencode($redirectURL)); }
  38. Add Diagram (general page) function doclist() { if (!$this->_hasValidOAuthSignature()) { $this->set("oauthValid", false); return; } $userId = @$_REQUEST['user_id']; $pageId = @$_REQUEST['page_id']; $redirectURL = "https://" . $_SERVER['SERVER_NAME'] . '/ondemand/attachDocument?page_id=' . $pageId . "&user_id=" . $userId; $this->layout = „ondemand'; $this->set("baseUrl", $this->_getBaseURL()); $this->set("callback", urlencode($redirectURL)); }
  39. Add Diagram (general page) function doclist() { if (!$this->_hasValidOAuthSignature()) { $this->set("oauthValid", false); return; } $userId = @$_REQUEST['user_id']; $pageId = @$_REQUEST['page_id']; $redirectURL = "https://" . $_SERVER['SERVER_NAME'] . '/ondemand/attachDocument?page_id=' . $pageId . "&user_id=" . $userId; $this->layout = „ondemand'; $this->set("baseUrl", $this->_getBaseURL()); $this->set("callback", urlencode($redirectURL)); }
  40. Make API calls to attach diagram function attachDocument() { ... $fullUrl = $baseURL . "/rpc/xmlrpc?user_id=" . $userId; $auth_header = $this->_getAuthHeader($fullUrl); xmlrpc_set_type($imageBytes, "base64"); $attachmentMetaData = array("fileName"=>$attachmentName, "contentType"=>"image/png", "comment"=>"Imported from Lucidchart (do not deleted)"); $addAttachmentBody= xmlrpc_encode_request( "confluence2.addAttachment", array("", $pageId, $attachmentMetaData ,$imageBytes)); $this->_sendXMLRPCRequest($fullUrl, array( "Content-Type: text/xml", $auth_header), $addAttachmentBody); ... }
  41. Make API calls to attach diagram function attachDocument() { ... $fullUrl = $baseURL . "/rpc/xmlrpc?user_id=" . $userId; $auth_header = $this->_getAuthHeader($fullUrl); xmlrpc_set_type($imageBytes, "base64"); $attachmentMetaData = array("fileName"=>$attachmentName, "contentType"=>"image/png", "comment"=>"Imported from Lucidchart (do not deleted)"); $addAttachmentBody= xmlrpc_encode_request( "confluence2.addAttachment", array("", $pageId, $attachmentMetaData ,$imageBytes)); $this->_sendXMLRPCRequest($fullUrl, array( "Content-Type: text/xml", $auth_header), $addAttachmentBody); ... }
  42. Make API calls to attach diagram function attachDocument() { ... $fullUrl = $baseURL . "/rpc/xmlrpc?user_id=" . $userId; $auth_header = $this->_getAuthHeader($fullUrl); xmlrpc_set_type($imageBytes, "base64"); $attachmentMetaData = array("fileName"=>$attachmentName, "contentType"=>"image/png", "comment"=>"Imported from Lucidchart (do not deleted)"); $addAttachmentBody= xmlrpc_encode_request( "confluence2.addAttachment", array("", $pageId, $attachmentMetaData ,$imageBytes)); $this->_sendXMLRPCRequest($fullUrl, array( "Content-Type: text/xml", $auth_header), $addAttachmentBody); ... }
  43. Make API calls to attach diagram function attachDocument() { ... $fullUrl = $baseURL . "/rpc/xmlrpc?user_id=" . $userId; $auth_header = $this->_getAuthHeader($fullUrl); xmlrpc_set_type($imageBytes, "base64"); $attachmentMetaData = array("fileName"=>$attachmentName, "contentType"=>"image/png", "comment"=>"Imported from Lucidchart (do not deleted)"); $addAttachmentBody= xmlrpc_encode_request( "confluence2.addAttachment", array("", $pageId, $attachmentMetaData ,$imageBytes)); $this->_sendXMLRPCRequest($fullUrl, array( "Content-Type: text/xml", $auth_header), $addAttachmentBody); ... }
  44. Steps to create Lucidchart app • Establish Trust • Register App • Implement General Page • Implement macro
  45. Macro • Receive macro params • Return HTML • Will be cached (caching header can be returned) • No CSS, inline styles or JavaScript
  46. Macro : Receive macro params function macro() { $userId = $_REQUEST['user_id']; $name = $_REQUEST['name']; $pageId = $_REQUEST['pageId']; $docId = $_REQUEST['id']; $width= $_REQUEST['width']; $height = $_REQUEST['height']; $align = $_REQUEST['align']; $outputType = $_REQUEST['ctx_output_type']; ...
  47. Macro: Return HTML <div style="float: “ . $align . "; margin: 0 auto; width: " . (intVal($width) + 2) . "px;"> <img src=“$pageAttachment['url']” width=“$width” height=“$height”/> <div style="text-align: center"> <a href='sign://"$host/editDocument/$docId?attachment= $name'>Edit Diagram</a> | <a href=$baseUrl/plugins/servlet/remoteapps/lucidchart- app/lucidAppRemove?page_id=$pageId&doc_id=$docId&attachment=$name'>Remove Diagram</a> </div> </div>
  48. That‟s it! Straightforward approach to get your app available for OnDemand
  49. We‟re taking Apps to the next level
  50. What if you could . . . • Tap into our 12k+ OnDemand customer base • Register your app with one click • Have full control over your app
  51. If you want to integrate, call us! • Currently targeted towards SaaS integrations • Feature set in early stages Diagram here • Working on solution for “extensions”
  52. You can finally integrate your site into OnDemand with Remote Apps #summit12
  53. Thank you!
  54. Getting started https://remoteapps.jira.com
Publicidad