None - Use Upload https://www.avioconsulting.com/taxonomy/term/366 en Mule CloudHub Logging with Custom Logger and ELK https://www.avioconsulting.com/blog/mule-cloudhub-logging-custom-logger-and-elk <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-11/Screen%20Shot%202018-11-28%20at%2012.13.01%20AM.png" width="2542" height="1868" alt="Mule-ELK" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/mule-cloudhub-logging-custom-logger-and-elk" hreflang="en">Mule CloudHub Logging with Custom Logger and ELK</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h2 dir="ltr"><strong>Objective:</strong></h2> <p>The objective here is to share a Robust, Consistent logging solution for Mule Cloudhub apps that are easy to maintain, visualize and track down software bugs or production issues quickly.</p> <p>Logging is a powerful aid for understanding and debugging programs run-time behavior. Logs capture and persist important data and make it available for analysis at any point in time.</p> <p>This article deals with creating a logging framework for MuleSoft apps that will suit any enterprise which is concerned about consistent and structured logging, zero log message loss and log analyzing.</p> <h2>Logging in CloudHub:</h2> <p>We don’t need to be concerned with the logging configuration inside Mule apps when we choose to deploy them to CloudHub. CloudHub writes all the logs to the console, provides a way to search by keyword and by the level and gives us an ability to change applications root log level on the fly, and to switch to debug mode and such.</p> <h3>So, why not use CloudHub’s default logging then?</h3> <p dir="ltr">Whenever Mule apps are deployed to CloudHub, logging capabilities can quickly become very limited in terms of visibility, persistence etc. especially when you have large amounts of logs that are generated by applications. Here are some things that you have to keep in mind before considering default CloudHub logging as your long-term thing.</p> <ul dir="ltr"><li>Persists logs only up to 100 MB or 30 days whichever comes first.</li> <li>After you delete applications, you lose all logs of that application.</li> <li>The only way to see logs is by logging into Anypoint platform and see CloudHub console per application.</li> <li>Cannot ship logs to your desired system easily, they can only be accessed via the REST API.</li> <li>No single place to analyze all your applications logs especially if you have API-led architecture. This can help to take some preventive measures.</li> </ul><h3><strong>So...</strong></h3> <ul dir="ltr"><li>We need a logging framework that can generate logs in a consistent and structured manner.</li> <li>Use any external log analyzer like ELK and feed all the logs to it to analyze your data in the most efficient way.</li> </ul><h3>First things first.</h3> <ul><li>Raise a support ticket with MuleSoft to disable CloudHub logging.  This is the setting that MuleSoft team has to do to in order for you to override the default CloudHub log4j2 configuration with your own custom application configuration.</li> <li>Setup Elastic stack(E.L.K) to analyze log data. Two things to consider here. <ul><li>As those three products are open source, you can use this <a href="https://elk-docker.readthedocs.io/">docker image</a> to set up your own environment and maintain all the configurations, deployments, disaster recovery, security, backup etc.</li> <li>There is a company called <a href="https://www.elastic.co/">elastic.co</a> which takes care of all the pain in managing instances, disaster recovery, backup etc. and they provide a way to set up stack on-premise or on their managed cloud.</li> </ul></li> </ul><pre dir="ltr"> <strong>Note: </strong>You will lose the ability to change application’s root log level on the fly when you disabled default CloudHub logging.</pre> <h2>Design a Custom logger for your Mule applications:</h2> <p>The default Mule logger is simple to use for logging but can be too simple because it doesn’t enforce any standards or best practices.  It also doesn’t provide a way to generate structured or consistent log messages. Designing a custom logger is the best solution here to generate structured logs and to enforce standards on the log data to be generated and of course, for seamless developer usage. The idea of this module should be to generate consistently structured logs in JSON format.</p> <p>It would be very good to provide a mule custom module for a developer to use for logging, requires specific information, and also be extended with additional information as key-value pairs, to log at a certain point, in a neat GUI. Then it’s the custom module’s job to take all the information, convert that data to JSON and log.</p> <p dir="ltr">Here is the look of Generic Mule Custom Logger developed by AVIO to use for any log purposes.</p> <p dir="ltr"><img alt="AVIO Logger" data-entity-type="file" data-entity-uuid="e5e3fe42-fedc-4010-984d-028b798af559" src="/sites/default/files/inline-images/Screen%20Shot%202018-11-28%20at%209.41.52%20PM.png" /></p> <p dir="ltr">And this module will produce a JSON like this</p> <table><colgroup></colgroup><tbody><tr><td> <p dir="ltr">{<br />    "timestamp": "2018-11-15T14:27:54.740-06:00[America/Chicago]",<br />    "request_id": "6c133127-35c7-4c84-93a0-c206ef4fbeb8",<br />    "app_name": "some-system-api",<br />    "app_version": "1.0.0",<br />    "env": "dev",<br />    "payload":"",<br />    "log": {<br />        "message": "This is my log message",<br />        "level": "INFO",<br />        "category": "com.lamar.avio" <br />    },<br />    "extended": {<br />        "myCustomKey1": "myValue1",<br />        "myCustonKey2": "myValue2"<br />    },<br />    "exception": {<br />        "detail": "Unhandled exception occured",<br />        "status_code": "500",<br />        "type": "APIKIT-UNKNOWN"<br />    }<br /> }</p> </td> </tr></tbody></table><p>We now have to feed this JSON to the ELK stack where Logstash will read this JSON message, parse it and ships to elasticsearch. Here is the high-level overview of ELK Stack. Now we have a great UI and a mechanism to generate logs in a consistent structured manner.  Also if we ever need to change the implementation of how and where we are logging to, the custom module can be updated and each project simply needs to update to the latest version of the module.</p> <p dir="ltr"><img src="https://lh6.googleusercontent.com/PhuGjzxicTZkcrrmYDvoJLIBlIEsjvdKaBoUeec1gYiQU6Xg7pimtNMFR_RSzua9WvxS6ExuMVRZh181MxEvbns1XuyxHLPBCxh57vrohQRteKDEN-Ee6d67lXGNusPhZPHsGEPn" /></p> <p>When you disabled CloudHub logging for an application, There are multiple ways to ship logs from CloudHub to any external system(Logstash in our case). Here are some.</p> <ul dir="ltr"><li>Use Log4j2 appenders like socket appender to post all logs to a specified destination.</li> <li>Use MuleSoft provided <a href="https://anypoint.mulesoft.com/exchange/portals/anypoint-platform/f1e97bc6-315a-4490-82a7-23abe036327a.anypoint-platform/cloudhub-api/1.0.5/pages/home/">CloudHub API</a> to retrieve logs periodically and send to your destination.</li> <li> <div>[Recommended]: Use a log4j2 appender to push all your CloudHub logs to Amazon SQS queue and have Logstash read messages from it. This way, we can scale SQS queue for high availability when there is huge log flow and we can ensure zero log message loss from CloudHub to Logstash as there is a highly scalable queue in between. <a href="https://github.com/cbonthala/log4j2-sqs-appender">Here is the code</a> for the custom log4j2 appender to push all application logs to AWS SQS queue.</div> </li> </ul><h3>Logstash Pipeline:</h3> <p>Considering that you have <a href="https://www.elastic.co/guide/en/logstash/current/setup-logstash.html">Logstash setup</a>, you can write pipelines in Logstash to read messages from the queue, parse them and send to elasticsearch.</p> <p dir="ltr">Here is an example of Logstash pipeline that reads a message from AWS SQS queue, parses each message and send to elastic to store.</p> <table><colgroup></colgroup><tbody><tr><td> <p dir="ltr">input {<br />  sqs {<br />    id =&gt; "mule-sqs"<br />    access_key_id =&gt; "&lt;&lt;aws-access-key&gt;&gt;"<br />    secret_access_key =&gt; "&lt;&lt;aws-secret&gt;&gt;"<br />    id_field =&gt; "sqs.id"<br />    md5_field =&gt; "sqs.md5"<br />    sent_timestamp_field =&gt; "sqs.sent_time"<br />    polling_frequency =&gt; 5<br />    queue =&gt; "&lt;&lt;sqs-queue-name&gt;&gt;"<br />    region =&gt; "&lt;&lt;aws-region&gt;&gt;"<br />    codec =&gt; "plain"<br />  }<br /> }<br /><br /> filter {<br />  grok {<br />    match =&gt; {<br />      message =&gt; "%{WORD}%{SPACE}%{TIMESTAMP_ISO8601:logdate}\s\[%{GREEDYDATA:thread}]%{SPACE}%{GREEDYDATA}: %{GREEDYDATA:message}"<br />    }<br />    overwrite =&gt; ["message"]<br />  }<br />  date {<br />    match =&gt; ["logdate", "yyyy-MM-dd HH:mm:ss,SSS", "ISO8601"]<br />  }<br />  json {<br />    source =&gt; "message"<br />  }<br /> }</p> <p dir="ltr"><br /> output {<br />  elasticsearch {<br />    hosts =&gt; "&lt;&lt;elastic-host&gt;&gt;"<br />    ssl =&gt; true<br />    manage_template =&gt; false<br />    index =&gt; "mulesoft-%{+YYYY.MM.dd}"<br />    user =&gt; "&lt;&lt;elastic-username&gt;&gt;"<br />    password =&gt; "&lt;&lt;elastic-password&gt;&gt;"<br />    codec =&gt; "plain"<br />  }<br /> }</p> </td> </tr></tbody></table><p>This Logstash pipeline has 3 parts.</p> <ul dir="ltr"><li><strong>Input{}:</strong> This has some configuration to read a message from the specified AWS SQS queue.</li> <li><strong>Filter{}:</strong> This takes each log message from SQS queue, reads and parses it as JSON, creates appropriate fields based on the incoming JSON.</li> <li><strong>Output{}:</strong> This has the configuration to send all parsed messages to a specified destination. It should be the elastic endpoint in this case.</li> </ul><p>As Logstash reads and parses the log data, elastic on the other hand stores all the data with the appropriate fields as we see below in Kibana.</p> <p dir="ltr"><img src="https://lh6.googleusercontent.com/K3H6Y1x53rENtsbo78zQOq8h7r7FMyjYH1PYkEeBs2ohY0TzJQDZVBYga3FM7uW0T8IuxO1p9uODjwgQXYA1cVcow9mCJFr47j-tiu0op8c4ktYxS8ZBAGmO-7-Em9uNefexnEMt" /></p> <p>In the above picture, you are seeing details about one log message in Kibana dashboard that is generated by our custom logger. You can also see all the JSON fields from the log message on the left pane.</p> <p>Note that the Logstash pipeline is reading the entire JSON log message from SQS queue and creates corresponding fields to each of the key-value pairs out of that incoming JSON.  When you have a dedicated field in elastic for each of the data points you send from your mule app, it is incredibly easy to create stunning dashboards and charts in Kibana.</p> <p>Now you can use Kibana to create charts and dashboards out of the data point fields in elastic for a much better visualization of log messages. You can also configure your elastic instance to persist logs for an extended period of time as well as provide rollups and archiving options, things that aren’t possible in standard Cloudhub logging.</p> <p>We have now streamlined the generation of consistently structured log data from the Mule application and transported it to a highly available AWS SQS queue, where it was read and parsed by Logstash, and then sent to elasticsearch with all the fields for you to play with inside Kibana.</p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <a id="comment-2299"></a> <div class="container blog-comments"> <div class="row"> <div class="col-sm-12"> <div class="pull-left author"> <div>Kalyan Kankanala</div> </div> <div class="comment-date"> <div>December 12, 2018</div> </div> </div> </div> <div class="row"> <div class="col-sm-12 comment-body"> <div><p>Hi Team,</p> <p>Could you please let me know what is the configuration used in log4j2.xml file . I have all the things needed from logzio and Mulesoft , however Mulesoft is throwing error LogzioAppender is not valid. Can you throw some sample .xml and pom file if any.</p> <p>Appreciate your help.</p> <p>Regards,<br /> KK</p></div> </div> </div> </div> <a id="comment-2301"></a> <div class="container blog-comments"> <div class="row"> <div class="col-sm-12"> <div class="pull-left author"> <div>Chakri Bonthala</div> </div> <div class="comment-date"> <div>December 12, 2018</div> </div> </div> </div> <div class="row"> <div class="col-sm-12 comment-body"> <div><p>Hello Kalyan,</p> <p>We have a custom appender developed by AVIO to push all the mule application logs to a highly available Amazon SQS queue and we have Logstash pipelines read messages from SQS queue and send to Kibana. So, In our log4j2.xml, we have a custom appender config for AWS SQS queue.</p></div> </div> </div> </div> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=737&amp;2=comment_node_blog&amp;3=comment_node_blog" token="2giSD4QVq97-bVfXya9CeHDIFdH1NitylDlDDM8jgXY"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog%3Fbid%3D332" hreflang="en">MuleSoft</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Tue, 04 Dec 2018 17:16:18 +0000 Chakri Bonthala 737 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/mule-cloudhub-logging-custom-logger-and-elk#comments Guide to Securing Mule 4 APIs with OAuth 2.0 and Okta https://www.avioconsulting.com/blog/secure-mule-4-apis-oauth-20-and-okta <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-11/Okta%20MuleSoft_0.png" width="1919" height="1003" alt="Okta MuleSoft" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/secure-mule-4-apis-oauth-20-and-okta" hreflang="en">Guide to Securing Mule 4 APIs with OAuth 2.0 and Okta</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h2><meta charset="utf-8" /><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7">Introduction </b></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Okta is a popular enterprise identity and access management provider, and the Anypoint API Manager enables you to govern and secure Mule APIs with a comprehensive policy library and integrated access management.  </span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">I am going to guide you through the set up of Okta as the OpenID Connect (OIDC) Identity provider for your Anypoint organization so you can use its OAuth 2.0 authorization server and access management capabilities to secure your APIs.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">OIDC is an identity layer on top of the <a href="https://oauth.net/2/">OAuth 2.0</a> protocol and I am going to cover OAuth 2.0 using the <a href="https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/">client credentials grant</a>. However, this setup will let you implement other grants and add the OIDC layer.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">According to the MuleSoft documentation, this process should work for any standard OpenID Connect Identity Provider that supports Dynamic Client Registration.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">The diagram below gives a quick overview of the OAuth dance (OAuth authorization process) used for the client credentials grant type, which is used for machine to machine applications. With this grant type, there is no user involved in the OAuth dance. In Okta, the token URL (/token) of your authorization server is used by the client application to request the access token, and the token introspection URL (/introspect) is used internally by the API Manager policy to validate the access token. We are going to review every step in detail in the following sections.</span></p> <p dir="ltr"><meta charset="utf-8" /><b id="docs-internal-guid-f5147696-7fff-e611-f610-3314228dba35"><img height="379" src="https://lh6.googleusercontent.com/fvmaS1k-BZBocsR9B1nN9K3h9g-4zr8A8MNb1fBByf24_SfIytmhklGsfPxublXQPTQEvqFM5AMUNH9o9XZtxxp385KeoPF_JwXw58HB1i3Fby99V-rbEXrBVi2FlNS5RUGtcow" width="624" /></b></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Prerequisites</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">There are few things that you need to make sure you have set up and signed up for before you get started:</span></p> <ul><li style="margin:5pt 0pt 0pt"><span style="line-height:100%">A <a href="https://www.mulesoft.com/anypoint-pricing">Platinum or Titanium subscription</a>. The feature that allows integration with an OpenID Connect Identity provider is called External Identity Management</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">You need administrator privileges to the Master Organization in Anypoint Platform. If you don’t have Admin privileges, you can sign up for a trial account here: <a href="https://anypoint.mulesoft.com/login/#/signup">https://anypoint.mulesoft.com/login/#/signup</a></span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">An Okta Account. You can get an Okta Developer Account here: <a href="https://developer.okta.com/signup/">https://developer.okta.com/signup</a></span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">An API deployed, active in the API Manager, and published in Exchange</span></li> </ul><p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="309" src="https://lh3.googleusercontent.com/nCvoRbOelJjuBWkCBFBmn7jTG31WlWNcn5AY02K46g_1YIid7Q5UPYN004tSNNJ8EsJZLcunnzYd9227A07B5gXwy2pLdXyZqJB5YZd1Qv4xrqUa7bsyZVTeGKHNWYAdkj56bwQ" width="624" /></b></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">What We Are Covering</span></h2> <ul dir="ltr"><li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Set up Token Introspection Client app in Okta </span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Generate SSWS token in Okta.</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Register Okta as an OpenID Connect Identity Provider / OAuth 2.0 Authorization Server in Anypoint Platform.</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Register your API in Okta and add the client credentials grant.</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Add a custom scope in Okta and assign it to your application. </span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Apply the OAuth 2.0 security policy to the Mule API.</span></li> </ul><h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Set up Token Introspection Client app n Okta</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In Okta, add a new application by going to the Applications menu on the top of the screen, click on Add Application, select Web, and click Next. In the Application Settings form, enter the application name, check the Client Credentials Grant type, and click Done. </span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="602" src="https://lh4.googleusercontent.com/qAjXMuGLFvbN2eldF1eM1VDaxIWO5aeXmTlmA3LheUbI32RMana5PAhP_kL3yfbUG3Jj0MlTTcqhGy9ZHJ6J_R_lq2qtQ-bJx_AWhW3vtsv41mpsEidhx3rEtQDn3ddT_BK7YCw" width="630" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">From the next screen, copy the Client ID and Client Secret in a notepad for later use.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">I called the application “Token Introspection Client” to match the name in the Anypoint’s Dynamic Client Registration form. This will allow Anypoint’s API Manager to validate the OAuth 2.0 access token using the information provided by Okta’s <a href="https://developer.okta.com/docs/api/resources/oidc#introspect">introspection endpoint</a>.</span></p> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Generate SSWS token in Okta</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In Okta, go to the API menu, select Authorization Servers, go to the Tokens tab, click Create Token, and copy the token in a notepad for later use. This is the Single Sign-On Web System (SSWS) token.    </span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="321" src="https://lh5.googleusercontent.com/mUeb23HakH5IfZzr2vAZ5cojdLpb0Qyze6SVQgsEyVn25JjVS5cvCjpVQ99kDJfjXmvdTt4aZnYknFeB-zVi4-hUwrUcJo8x0vvp6Y-O4Iwv55E3OSs215Nr34k_o8rOjk2yBHU" width="571" /></b></p> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Register Okta as an OpenID Connect Identity Provider / OAuth 2.0 Authorization server in Anypoint Platform</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Go to the Anypoint Platform’s menu on the left, select Access Management under Management Center, then click on External Identity.  Expand Client Management and select OpenID Connect Dynamic Client Registration.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="187" src="https://lh4.googleusercontent.com/YkfZB_jubNVdZuqmJvshZ3MZU4iLQY3lUnHyjbXBzNpx7ep5X6SIGf70YbdB6yX_sKCOjnu5fIv1ZRiBkHMdU4BWHK3vlf30Y4R-yG6zTPG6zrzdR0nGI5O57pgCju4ZFCfta-A" width="499" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Fill out the Dynamic Client Registration form: </span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="703" src="https://lh6.googleusercontent.com/jmkNoAZJTZjVY6yDecPV5MUVvmwer5qnz3dIKJdTr29JjwmJ0Ano1O5ZttI5yNbVkPy-JNcVKoIfMfC_QvjxZqar6j7ztGqEE5uEgx5Cw1EfathrkZlWrcYgPowwvvHy61_U1Ks" width="583" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The Client ID and Client Secret come from the Token Introspection Client app we registered in Okta in the previous section. The Authorization Token is the SSWS we also created in the previous section, and the rest of the information comes from the authorization server metadata in Okta. </span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">To get the server’s metadata, go to Okta’s API menu and select Authorization Servers. Click on the default server (or the server you are using) and follow the metadata URI link to get the URLs needed and save the form.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="460" src="https://lh5.googleusercontent.com/-_cuAv5p9a5BtDFDfapblzZSLspnEu8N50kfMGbImsk7QOwRFUBZD7FXXPzBOruLbNoCPQ3ASM6O2yvwX2MyotK428aWnwzjmkUH2k5DKlbVjkCpfy3xTOLGkiqQKDUSdcCp1BI" width="584" /></b></p> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Register your API in Okta and add the client credentials grant</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Go to your API in Anypoint Exchange and from the vertical ellipses select Request Access.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="139" src="https://lh3.googleusercontent.com/KCs9xdxCQ2GampZ-g5J1gARl-2flnY7cBi8opA6BB2dIzBArqw1s0I0rNwcrjQHS7fO52JhDmtrlJvK6BPMDjtoSHsdUJFU-blIGFg3iSxQEss3ia-wOSVtJG_ueRYIJRXV4WzA" width="589" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In the Request API access window, click on Create a new application. In the Create new application form, enter your application’s name, select Authorization Code Grant because you have to select a grant (later we’ll add the Client Credentials Grant in Okta). The OAuth 2.0 redirect URI is not needed for the Client Credentials grant flow, but I added it to try the Authorization Code grant flow later. </span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="633" src="https://lh4.googleusercontent.com/veEEtoa5Ox7I8UXdg2wu3rhxQRSXb1_9YrK81h--u5SkVTcrkyEGK60gRhLPg6KkXx0hVYRSSLkL5JCBtCNBbn_BeqjU3nRRpH98qTkOMdN9J16-vbkeHmBcdl2NJvV6TKp7Sgk" width="512" /></b></p> <p style="margin:11pt 0pt 0pt"><span style="line-height:200%">In the following Request API access window select the API Instance and click Request API Access. This step will create your API in Okta and will return its client id and Client secret. Copy the Client id and Client secret for later use.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="348" src="https://lh3.googleusercontent.com/ygHZ9YR0X_OfzELOq2xgaMy00eSxT2bGA6lDN1L6sVCCF0wj8LZZs7VVAGP-e02jTT4bg-rKreEyhRYiQI0qqArKbf85PReA_x4-ydHytpw4m160-w9EuApQ6RzTuuaUXqZ5L-M" width="437" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In Okta, go to Applications and you will see your application listed there. Click on the application’s settings gear icon, select Assign to Groups, assign to Everyone and click Done.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="256" src="https://lh6.googleusercontent.com/FiF27e6OQlQydRA6OUiu7y_lVO6tkvYtTqnRbaYJrK2KtPbOaBGDXtMlt9MvnhjlcavB_P4ncb4FfP8kGIGSpL0hsFJ2vsKKJtfvjs1m4CfkMJCxN1zDv2Ji0mC6kiaP611ZMdI" width="524" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Then click on your application (Products API in my case), go to the General tab to display the General Settings, click on Edit, check the Client Credentials box and save it. </span></p> <h3 style="margin: 20pt 0pt 0pt;"><span style="line-height:107%">Add a custom scope in Okta and assign it to your application</span></h3> <p style="margin:1pt 0pt 0pt">In Okta, go to the API menu and select Authorization Servers, click on the link to your server, and go to the Scopes tab. Click Add Scope and fill out the form to create “myscope.” We are going to authorize this scope in the API Manager when we apply the security policy.</p> <p style="margin:10pt 0pt 0pt">Let’s note that the default access policies in Okta allow any registered app to use any scope and any grant assigned to the app to request tokens. You can add and customize access policies, but the administration of Okta is out of the scope of this blog.</p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="421" src="https://lh6.googleusercontent.com/OnD0sttwMrkEGDEvUNX0QJrKaEc8RchIpBB7thIUnQTLOQc3f8yt2x90fnwlKkMFPePCucM6a2x4xAILv8g0C7h7w7xUE0ihJTgxjmXvnrA6U0v32oGYwsE5l_z_Zg1s8WToNWM" width="624" />  </b></p> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Apply the OAuth 2.0 security policy to the Mule API</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In Anypoint, go to your API settings in the API Manager and click on Policies.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="376" src="https://lh3.googleusercontent.com/IYYHxTrWsk52VEYXsogJOl4437Bh7molNPet1HcZyUuBkm_aI41uvTmv6-UOw0VlEEBTb72PhLJT5VDcVn-bGkp6KYmxWYOxEBVpNlAnEgF8du2eXqITRktS7oFp6umdIKXEjq0" width="488" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Click on Apply New Policy, in the Categories drop-down menu select Security, expand OpenId Connect access token enforcement, and select the version for your application. Click on Configure Policy.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="355" src="https://lh6.googleusercontent.com/ufoO1fnC6WarDIGgY7F75l71g_pNeOb4bHLnZkaJzrdGP7cA008xypSoWP-OUblAv0NdvNGfZOziyqjKzru6MDF3z8ak1xwpIeNTe6A5xc1ry5tCWcwhIfbBWs0n5vIb5g0NcNU" width="624" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Add “myscope” and click Apply. The policy takes about a minute to become in effect. I am applying the policy to all the API methods and resources, but you can also apply more granular policies and even create a <a href="https://docs.mulesoft.com/api-manager/2.x/custom-policy-4-reference">custom policy</a> according to your project needs.</span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="371" src="https://lh3.googleusercontent.com/FGbrbiz_gFdjKmgneEiDSPcRpnySiJLH3mee6Ysq-aq_fO4rrWbAYtzlzqjjtjnoV3VaHB89VXVYiuWIVxN2NTtIT_qd1OBIOlmjuYQDUR6uYJt-I7vNzEzrp8HaNWKeUVZ_kK0" width="624" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The last step is to update your application’s RAML with the RAML snippet provided. </span></p> <p dir="ltr"><b id="docs-internal-guid-5b7eef97-7fff-b5c0-e579-176b929401e7"><img height="104" src="https://lh6.googleusercontent.com/vG91Gfsg8oDeK-a1vc6BmPbAtdiXObdzFi2xGzVk3Z3ufC4DsnRf_Du2NVZv_AyxPZApCcH0piv9RXspnS5pEqZb5Sp_imDaGI-X-dC14XIGQYPR50hrTfXZ3AFw0xRobnBvS_4" width="624" /></b></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">At this point, your API is protected. If you try to access it without a token you will get a 400 error "error": "Access token was not provided."</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">To get an access token you need to send a POST Request to Okta’s token URL (/token) provided by your server’s metadata when you filled out the dynamic registration form above. The POST request should be of content-type application/x-www-form-urlencoded, with the parameters grant_type=client_credentials and scope=myscope. Use basic authentication with your application’s client id as the user and client secret as the password.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Now you can make a call to your API by either adding the query param access_token with the access token or sending the token as a Bearer token in the Authorization header.</span></p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=733&amp;2=comment_node_blog&amp;3=comment_node_blog" token="jlRO_cTlRnCUwaG99GecbwJ1mIgPTr2SZJQgyBQ3dTA"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog%3Fbid%3D332" hreflang="en">MuleSoft</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Thu, 15 Nov 2018 14:49:42 +0000 Miguel Martinez 733 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/secure-mule-4-apis-oauth-20-and-okta#comments Oracle OpenWorld 2018 - 5 Things I Learned https://www.avioconsulting.com/blog/oracle-openworld-2018-5-things-i-learned <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-11/20181024_083157_0_1.jpg" width="2886" height="755" alt="Oracle Red Carpet" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/oracle-openworld-2018-5-things-i-learned" hreflang="en">Oracle OpenWorld 2018 - 5 Things I Learned</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p style="margin:1pt 0pt 0pt"><span style="line-height:200%">This was my first time at Oracle OpenWorld, and WOW.... Oracle really goes overboard.  They had massive banners and signs calling out the 'Oracle Autonomous Database Cloud', 'Self-Repairing Database', 'Innovative', it goes on and on.  They laid out a literal red carpet, covering all of Howard Street between 3rd and 4th streets.  It's just impressive to see.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%"><img alt="Oracle Red Carpet" data-entity-type="file" data-entity-uuid="e79caf05-7ad5-4365-837e-9b4788c0065e" src="/sites/default/files/inline-images/20181024_083157_1.jpg" /></span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">But, I was here to learn.  Being an architect in the Integration realm (SOA, ICS, OIC, etc), I tried to focus on sessions that would pertain to me and hopefully learn a few new tricks.  There were tons of sessions on everything Oracle, but only a handful interested me.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Along with learning about the Oracle (and non-oracle) products, I was able to meet up with many great colleagues from outside the US that I haven't seen in a while, or only had the opportunity to communicate with through email or conferences calls.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Here is a small (I went to many sessions) breakdown of the ones I enjoyed.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Citizen Developer Self-Service Integration</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The self-service integration cloud is intended to 'empower the business user' by providing pre-built templates for application integrations.  The idea is that a business user can connect the applications they use every day to share data or trigger other applications when an event occurs.  These are not company wide integrations, but for a single user.  The scenario that was discussed involved connecting Gmail with Google Sheets.  When a business user creates a new contact in Gmail, that contact is immediately exported and added to a Google sheet.  This didn't seem like a very useful scenario, but I could see the data being sent to other applications, like creating the same contact in a different system.  </span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">The self-service integration cloud is currently licensed separately, but based heavily on the OIC platform.  It looks very similar to OIC when building integrations.  If you have any experience using OIC, the self-service integration will feel right at home.  I'm always wary of when products are designed for the 'citizen developer' or 'business user' because these products typically have limited functionality (due to 'ease-of-use') or are actually harder than originally intended.Eduardo Chiocconi, Tuck Chang and Srikant Tirumalai did a great job demonstrating the features that have been developed and showed off some of the advanced use cases.  I'm looking forward to exploring some more of the available options with this new(ish) product!</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">The Future of Serverless Is Now: CI/CD for the Oracle Fn Project</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">I spent quite a bit of time working with Leo Gonzalez from <a href="https://www.spsolutions.com.mx/en/">S&amp;P Solutions</a> on a previous engagement and was thrilled to reconnect with him at Oracle OpenWorld.  He and his colleague Rolando Carrasco presented on the simplicity of deploying Oracle functions and provided a quick live demo starting and deploying a hello world function (Hola Mundo for them!) in a few different programming languages.  These code sets were all changed during the demo and were all automatically deployed using a continuous integration pipeline.  I have had limited exposure to the Oracle function, however, the presentation piqued my interest, with its simplicity.  I'll have to go back and check it out myself.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">DevOps in the Cloud with Oracle Developer Cloud Service</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Having some basic experience with DCS, I was interested to find what type of Hands-On Lab the Oracle team would come up with.  The lab, meant to take under an hour, was surprisingly thorough.  It had participants create a new project inside of DCS, initialize a GIT repository, create and assign development tasks, start a newsprint including development tasks, make a code change, create build triggers and a build pipeline, merge a feature branch, and watch it all get deployed.  Abhinav Shroff and Murtaza Amiji did a great job preparing and presenting the lab.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Serverless, the Future of the Cloud?</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">I went to see Bert Ertman's present on serverless integrations.  After seeing an earlier presentation on Oracle functions, I was interested in what Bert had to say.  He provided some interesting points calling out a variety of options for serverless... Amazon Lambda is one of the most prevalent.  His presentation included a demo of using an event-based process, where the lambda function monitored an S3 bucket for images, and when a new image was uploaded, it would crop the image down to 100 x 100 pixels, and move to a different bucket.  His use case was for adding employee images taken from a camera or phone, and cropping them down to be used as a thumbnail in a profile picture was perfect for a serverless integration.  The processing power would only be used when necessary, and not require a company to keep an integration active, and only Pay As You Go (PAYGO).</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Oracle Integration Cloud Best Practices Panel: Transforming to Hybrid Cloud</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">This presentation was based on actual implementations from 3 different companies.These companies included Minnkota Power Cooperative, ICU Medical, and GE.  There was a short presentation by each of the companies, followed by some Q&amp;A.  With product management on hand, some great insight into new features was discussed to make the integration lifecycle easier, including whole environment cloning (all integrations, connections, lookups, etc).  There were discussions about best-practices of how to promote integrations (shameless plug - <a href="https://www.avioconsulting.com/blog/avio-ics-maven-plugin">AVIO Maven ICS Plugin</a>) but also questions regarding the storing of integrations (and other artifacts) into a code repository for safe keeping.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">When connecting OIC to on-prem applications, a connectivity agent is used.  There were some questions and concerns regarding the stability of this, but Product Management indicated that the new version added HA, a smaller footprint, auto-updating, and several bug fixes.  Be on the look for this if you are connecting on-prem applications to your cloud applications.</span></p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=732&amp;2=comment_node_blog&amp;3=comment_node_blog" token="2Wsx9DKhokDpl41IZAv3FPO6eZrkXDr8eHGT2Yh6N0U"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Thu, 01 Nov 2018 14:12:37 +0000 Kevin King 732 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/oracle-openworld-2018-5-things-i-learned#comments How to Integrate Salesforce with MuleSoft https://www.avioconsulting.com/blog/how-integrate-salesforce-mulesoft <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-09/MuleSoft%20plus%20SalesForce.png" width="1920" height="1080" alt="MuleSoft plus SalesForce" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/how-integrate-salesforce-mulesoft" hreflang="en">How to Integrate Salesforce with MuleSoft</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h1 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Integration Patterns:</span></h1> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Salesforce is one of the most integration-friendly products available that supports real-time, asynchronous or even batch processing. This blog discusses the various options we have for integrate with salesforce rather than how each of these to be implemented.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Outbound (Integrate Salesforce to Remote Systems):</span></h2> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Real Time:</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Integration platforms can expose a web service using the WSDL generated by Salesforce which means integration should implement salesforce interfaces. MuleSoft does provide all the tools needed for the integration.</span></p> <p><img alt="apiFlow" data-entity-type="file" data-entity-uuid="3728e00b-0fc9-4579-aaac-edccd0d530c1" src="/sites/default/files/inline-images/image%201_0.png" /></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In the test use case I choose, the implementation looks like the following</span></p> <p><img alt="Implementation" data-entity-type="file" data-entity-uuid="60858d35-14aa-4196-aa0a-d6a9a3b04072" src="/sites/default/files/inline-images/Image%202.png" /></p> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Near Real Time:</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">MuleSoft provided Connector can be scheduled to bring in data which makes it near real-time depending on the scheduler settings. Connector can be used to Query the Salesforce objects very much like SQL queries.</span></p> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Event Driven:</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Internal to Salesforce, we can define to trigger an event with defined criteria. When the action happens triggering the event, the data can be sent to integration using the integration URL. In addition to sending data to URL, Salesforce has the capability to store the data in Queue before sending it out to remote systems. This gives a much-needed reliability for the data. Queues can be configured to retry x number of times with x interval. Depending on the use case Queue can be set up for reliability either in Salesforce or an integration layer.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Inbound  (Integrate Remote Systems to Salesforce):</span></h2> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Real Time:</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">MuleSoft does provide a very robust Connector for the Salesforce to integrate which can be used for real-time updates to Salesforce.</span></p> <p><img alt="Salesforce Connector" data-entity-type="file" data-entity-uuid="ba0db125-5078-45e3-8977-26aa8904a475" src="/sites/default/files/inline-images/Image%204.png" /></p> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Bulk Data Transfer:</span></h3> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The connector in itself provides features for the bulk data transfers. However, with bulk operations, there are chances that integration could overload Salesforce. All the bulk data transfer use case should be thoroughly tested for resource utilization.</span></p> <p><img alt="Salesforce Connector Confiuragion" data-entity-type="file" data-entity-uuid="744a5cca-2bda-43cd-9e30-b2ddd77bff20" src="/sites/default/files/inline-images/Image%205.png" /></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">There is no silver bullet on the pattern to be used, it all depends on the use case.</span></p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=724&amp;2=comment_node_blog&amp;3=comment_node_blog" token="-oLlOb5u0r_e8a_gw_dCRuRYOgjHGfdq1AhTu5yqDnU"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog%3Fbid%3D332" hreflang="en">MuleSoft</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Thu, 13 Sep 2018 19:08:35 +0000 Karthik Dega 724 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/how-integrate-salesforce-mulesoft#comments Risky Business — How to Test With Priority https://www.avioconsulting.com/blog/how-test-with-priority <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-07/internet-3484137_1920.jpg" width="1920" height="1202" alt="Agile Testing" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/how-test-with-priority" hreflang="en">Risky Business — How to Test With Priority </a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p style="margin:1pt 0pt 0pt"><span style="line-height:200%">If you’ve ever had difficulty prioritizing testing activities, you’re not alone. Iterative frameworks like Agile mean testing is performed in miniature cycles that add up to what eventually becomes a product release. Unfortunately, though, testers don’t necessarily get to choose which tickets developers complete first. One test release may have several JIRA tickets the client considers high priority while another might have none. This begs a question: <strong><em>How does one prepare to handle such variability?</em></strong></span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">A risk-based testing approach is my favorite testing adaptation for evening out the peaks and valleys that sometimes accompany the Scrum-Agile style.  Although 1/3 (sometimes 17 or more) of the JIRA tickets in our sprints may be marked as high-priority items, not all tickets the business considers a high priority necessarily require the same level of testing.  Here’s my process for converting high-priority business items into risk categories that help me better manage the testing activities surrounding these VIPs of the development sprint.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Static Testing</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">For me, I like to start testing when the requirements are just that — the requirements.  Every time I read (and re-read) a new specification document and JIRA tickets, I notice areas of agreement and areas of misalignment.  Not only does this static testing approach allow me to start identifying bugs before they make it into the code, it allows me to determine how complex the development outcome(s) for a particular user story might be.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">As the complexity grows, so too does my estimation of testing risk.  True enough, an un-skilled developer can make the re-labeling of a text field an unholy affair, but that just doesn’t happen very often.  Over time, the simple jobs start to become easy to pick out from the list.  This makes the more hairy tickets easier to identify as well.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Organize Data</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Either simultaneously (or just after performing static testing), I like to begin organizing my data.  This is where ye good olde spreadsheet comes in handy.</span></p> <img alt="Risk Priority Spreadsheet" data-entity-type="file" data-entity-uuid="a5cf676f-1c7f-4769-93d8-5603d16bbf3d" src="/sites/default/files/inline-images/download-3.png" class="align-center" /><p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Notice that the business risk column connotes a high level of risk (5) for every item listed.  The 5 indicates that these items are listed as high-priority business items in JIRA.  It’s worth noting that medium-priority items are given a business risk rating of 3, and low-priority items are given a business risk rating of 1.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">In the adjacent column, the risk priority numbers (RP# = Testing Risk x Business Risk) assigned to each record appear to vary considerably.  When I first performed this exercise, I was shocked to find that the risk priority number for each of these high-priority business items rarely approached the apparent severity of the business need.</span></p> <p style="margin:10pt 2pt 0pt"><span style="line-height:200%">The reason for this is simple: the testing risk rating was relatively low for all but a couple of cases.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">To be clear, this is not a case of quality control undervaluing what the business has assigned a high-value to.  Rather, it’s the realization that not every high-priority business item requires the same degree of testing.  When a test release is made available, provided your test cases, state and decision tables, and cyclonic complexity analyses are in order (You prepared them in advance, right?), you should be ready to test with risk priority helping steer the ship.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Whatever you do, though, don’t forget to …</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Consult Your Roadmap!</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In a hypothetical release containing 18 or more high and medium priority tickets, feeling overwhelmed is expected.  Note in the image below that there are a lot of tickets whose risk priority number is a 5/Report Bugs (the lowest level of testing priority).  </span></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Several are medium-priority items while several more or high-priority items.  Which ones should be tackled first?  Yup, the ones with a business risk level of 5!</span></p> <img alt="Risk Priority Spreadsheet 2" data-entity-type="file" data-entity-uuid="8e6ca9be-c3bc-4d5b-b63d-c8f98150f514" src="/sites/default/files/inline-images/download-1_0.png" class="align-center" /><p style="margin:10pt 0pt 0pt"><span style="line-height:200%">However, don’t forget that among those tickets marked as high-priority items, there’s a hierarchy.  So, unless circumstances prevent me from doing so, I like to hit the high-priority items with the highest risk priority numbers first.  Again, if I’ve been a boy scout and prepared all of my test cases and artifacts in advance, I should be able to make relatively quick work of these more demanding tickets.  The thing to remember here is that it’s easy to get distracted, so stick to the roadmap you made for yourself.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Wrap-up</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Testing tickets by business risk, then by risk priority number is an effective way of testing large numbers of tickets.  I like to think of this as a win-win for quality control.  The most gnarly of the items the business considers a high priority get tested first, which means they either get returned for bugs and defects earlier (win) or verified under test sooner (win).</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">By processing tickets in this way, I’m not only better organizing myself for efficient testing, I’m helping my team meet deadlines by keeping the testing activity contextualized and optimized.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">What are your thoughts about this approach?  Let me know in the comments below.</span></p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=720&amp;2=comment_node_blog&amp;3=comment_node_blog" token="6_Bgrg5O2NdJxODPue_TzmJSPmE1GevX-TS9-tzLLlw"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog/categories/other" hreflang="en">Other</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Fri, 20 Jul 2018 13:10:59 +0000 Mark Hearon 720 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/how-test-with-priority#comments UI issue in Anypoint Studio with Ubuntu https://www.avioconsulting.com/blog/ui-issue-anypoint-studio-ubuntu <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-06/Untitled%20design%20%281%29.png" width="1920" height="1080" alt="Mulesoft Ubuntu" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/ui-issue-anypoint-studio-ubuntu" hreflang="en">UI issue in Anypoint Studio with Ubuntu</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h1 dir="ltr" style="margin-top: 0pt; margin-bottom: 0pt; margin-left: -0.75pt;">The Problem</h1> <p>I've downloaded the latest Anypoint Studio(Version 7.1.2) to use on Ubuntu(18.04) and I wasn't able to view pop up dialog windows, for example, when clicking the Exchange button. This blocked me because of the several pop up dialogs you need to configure single components.</p> <p><img alt="Anypoint Studio Exchange Button" data-entity-type="file" data-entity-uuid="416d9c1e-0290-4f2b-a4da-e6339e8112d6" src="/sites/default/files/inline-images/sMYiqbPuU9JdB82FDNeTi5g.png" /></p> <h1> </h1> <h1>Overview</h1> <p>After doing some research, I found some people fighting this same issue (or similar) with different versions of Ubuntu and multiple versions of Anypoint Studio as well.</p> <p>After that, I ran into a topic in the Mulesoft Official Forum where a couple people solved the issue by updating the file AnypointStudio.ini to use Linux GTK (Graphic Libraries for Linux) 2.x</p> <p>BUT I realized my Anypoint was indeed using the correct GTK.</p> <h1> </h1> <h1>Solution</h1> <p>I decided to see what versions of GTK I have installed in my Linux using in the command line:</p> <ul><li>dpkg -l libgtk2.0-0 libgtk-3-0 S</li> </ul><p>and the result was:</p> <ul><li>libgtk-2-0/ 2.24.31-2ubuntu1</li> <li>Libgtk-3-0/ 3.22.25-0ubuntu0.1</li> </ul><p>By default AnypointStudio.ini file (in my case) - that is in the root folder of your Anypoint Studio installation - had</p> <p><img alt="anypointstudio.ini file" data-entity-type="file" data-entity-uuid="610cf3e1-cfe8-4a34-838a-47f2412c56dc" src="/sites/default/files/inline-images/swxepEcuNh_QtjFO7POyYYg.png" /></p> <p>so I changed it to</p> <p><img alt="anypointstudio.ini file 2" data-entity-type="file" data-entity-uuid="a0a434fb-4060-4f35-b3d8-b749515cea98" src="/sites/default/files/inline-images/sZiHIlG63kEUl1zBHXumoRg.png" /></p> <p>With this update to the .ini file and after restarting Studio, I am now able to see all of the pop-up windows!  For example the, Anypoint Exchange User Login window:</p> <p><img alt="Anypoint Exchange User Login" data-entity-type="file" data-entity-uuid="20efa124-8d94-4530-89fc-42d5c43f9a44" src="/sites/default/files/inline-images/pasted%20image%200.png" /></p> <p> </p> <p> </p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=710&amp;2=comment_node_blog&amp;3=comment_node_blog" token="-jFMRNj1eQbRlKABmZSfNJbUg2JlcJ0QSPbHg_npeNU"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog%3Fbid%3D332" hreflang="en">MuleSoft</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Tue, 19 Jun 2018 13:40:07 +0000 Alvaro Zorzini 710 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/ui-issue-anypoint-studio-ubuntu#comments 3 Reasons TestRail is a QA Dream App https://www.avioconsulting.com/blog/3-reasons-testrail-qa-dream-app <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-02/rainbow.jpg" width="1920" height="1200" alt="Does TestRail offer QA testers a testing dream land full of rainbows and butterflies?" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/3-reasons-testrail-qa-dream-app" hreflang="en">3 Reasons TestRail is a QA Dream App</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p>Testing is full of organizational challenges that take a lot of our time.  Let’s face it, changing requirements, backend updates that influence UI behavior, busted cases, and fixing simple grammatical/syntactical errors all take their toll — both on us and our test documentation.  </p> <p>If the above describes more of your life as a QA tester than you’d care to admit, let me shine a ray of sunshine into your day.  The difficulties of day-to-day testing life won’t go away, but (as I discovered) there are better ways to engage with and manage these challenges.  After a recent, successful trial with <a href="http://www.gurock.com/testrail/">TestRail</a>, we’ve chosen to evaluate it for the next few months to determine just how good a fit it really is for us.</p> <p>The following are three standout attributes that really caught our attention.  </p> <h2>1. Test Case Organization and Orchestration<img alt="TestRail UI Screen Grab of Test Run" data-entity-type="file" data-entity-uuid="aabbcea9-6052-400e-9b1c-e02541a169da" height="304" src="/sites/default/files/inline-images/Test%20Run_0.png" width="458" class="align-right" /></h2> <p>TestRail enables testers to create test cases very quickly.  Like super-fast.  Prior to TestRail, our method for creating test cases was a rather tedious and inefficient Google spreadsheet.  Apparently, this isn’t all-too-uncommon among the crowd offering TestRail testimonials.  Depending on your preference (either for a long, descriptive or step-based test case), a simple 5-8 step test case can be created in a matter of seconds to a minute.  </p> <p>Also, the level of organization TestRail enables when it comes to writing, grouping, and executing test cases is, well, a revelation.  Once a decent amount of cases have been written, they can be executed in a test run.  Cases completed within a test run contribute real-time feedback as to the success of the run as a whole and the individual cases being tested.  Previously, this kind of data came at the end of testing via JIRA reports.  Now, we can see it as testing is underway.  </p> <h2>2. JIRA Integration</h2> <p>Speaking of Atlassian's JIRA Software, it’s a great tool.  TestRail makes using JIRA that much better, though.  After the aforementioned spreadsheet was filled out, that information had to then be translated to a bug ticket in JIRA — manually.  </p> <p>Now, with TestRail’s JIRA integration capability, the results logged against a test case can be pushed directly into a defect report in JIRA.  I won’t lie, the implementation is a little bit of a faff because the ticket TestRail creates is titled with the case’s title in TestRail.  This forces me to perform updates to the ticket in JIRA because of our project’s naming conventions.  Obviously, this won’t affect everyone.  </p> <p>Bottom line, the ability to push 80-90% of the necessary defect information to JIRA while operating in TestRail is a huge productivity boost. </p> <h2>3. Reporting </h2> <p><img alt="TestRail UI Screen Grab" data-entity-type="file" data-entity-uuid="eea49f74-b343-4ce1-9915-14a2e5f2cbd8" height="349" src="/sites/default/files/inline-images/push.png" width="479" class="align-left" />Ok, this one is probably the biggest for us.  If you’re a QA tester and a follower of Donald Firesmith, then Common System and Software Testing Pitfalls is either on your reading list or soon to be.  Apparently, a major pitfall of software testing isn’t using metrics to guide decision-making.  Who would’ve thunk it?  </p> <p>Maybe we’re just not that into JIRA reports.  JIRA has some great features for showing sprint velocity, issues solved versus issues created, etc.  What it doesn’t show, however, is how often, when, and under what conditions a test case fails or has failed.  Needless to say, we’ve come up with all sorts of pulse checks, stability assessments and such.  That’s not something we have to endure any longer, though!<img alt="Scheduled Delivery of Reports" data-entity-type="file" data-entity-uuid="59ef4e8b-3863-4dd7-9e31-ec01d8e31539" height="414" src="/sites/default/files/inline-images/schedule-1.png" width="411" class="align-right" /></p> <p> </p> <p> </p> <p>TestRail’s reporting feature is a huge plus for us because we have better visibility into every part of the QA process.  Whether it’s in-the-moment test case passes or failures, a review of the latest test run or major milestone, or a super-granular performance report on a single test case over the last quarter, it’s possible.  </p> <p>Additionally, manually or automatically generated reports can be shared with all — or a very few, specific — parties.  Options include email links to reports in test rail (fine if the recipient is a registered user) or attachments (great for non-user stakeholders).  Email reports can also be scheduled at regular intervals.  These can be viewed in TestRail at one’s leisure or can be emailed automatically at runtime.  </p> <h2>Wrapping Up</h2> <p>Is TestRail a QA dream app?  Well, for me at least, it’s too early to tell.  However, it checks all of my boxes at this time.  Perhaps familiarity will breed a certain level of contempt.  Then again, it may just be the perfect tool for our QA team to grow with for years to come.</p> <h3>So, my questions for you are . . . </h3> <p>1. Have you demoed TestRail?<br /> 2. What are some standout features to you and your team?<br /> 3. What’s something you hate about TestRail?</p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=700&amp;2=comment_node_blog&amp;3=comment_node_blog" token="yw9DIT7cOTtq5MwvAnZb4qGUUfw68-NVo5L8NeFsgrc"></drupal-render-placeholder> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Fri, 09 Mar 2018 23:34:29 +0000 Mark Hearon 700 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/3-reasons-testrail-qa-dream-app#comments How to Avoid Agile's Wrath https://www.avioconsulting.com/blog/how-avoid-agiles-wrath <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-01/nebula_small_square.jpg" width="600" height="600" alt="How to Avoid Agile&#039;s Wrath" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/how-avoid-agiles-wrath" hreflang="en">How to Avoid Agile&#039;s Wrath</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><figure role="group" class="align-right"><img alt="Wow Airplane" data-entity-type="file" data-entity-uuid="2afd9e0f-018e-4de2-9363-f20044b614d6" src="/sites/default/files/inline-images/WOW-4.jpg" /><figcaption>By Oliver Holzbauer via Flickr<br /> https://creativecommons.org/licenses/by-sa/2.0/legalcode<br />  </figcaption></figure><p>We’ve all been there.  It’s three days to the end of the sprint and suddenly the business decides that the world will END unless a brand-new feature (that they just hatched) is implemented immediately ... if not sooner.  <em>Are you done yet?  How about now?</em> Being a good and faithful Agile scrumling, the Scrum Master tells the Product Owner that this awe-inspiring new feature "will need to go into the next sprint."</p> <p> </p> <h2>The Consequences of Extending a Sprint</h2> <p>You can imagine that this is met with a reaction that would melt most inexperienced Scrum Masters and send their shiny little sprint spiraling off into the abyss. </p> <p>You can’t blame the Product Owner either.  These poor souls have the entire business clawing at them daily about everything from bug fixes to wanting new features to wondering why the color of this button is grey and not chartreuse.  The Product Owner is worried that missing deployment dates or not having enough "<font color="red"><strong>WOW</strong></font>" factor in each release will put a stranglehold on future budgets – not to mention their own career prospects.  What this person doesn’t want to deal with is a Scrum Master who seems to be pedantically obsessed with priorities and deadlines and doesn’t seem to want to just get moving on what’s important right now!!!!!</p> <p>On the other hand, we have our haggard Agile Scrum Master who has been down this road far too many times.  It seems that there is always something earth-shattering that must absolutely be added to the sprint right at the end of development … or God-forbid in the middle of UAT.  This person is worried that the Development Team is always under huge time pressure and that this critical new feature only further increases chances of bugs and unforeseen ripple effects.  The stench of scope creep is only surpassed by the radioactive decay of growing technical debt.</p> <p>Well, we’re in a fine pickle now.</p> <p>What is a faithful agile scrumling to do??  Let’s go flipping thru our handy <a href="http://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-US.pdf#zoom=100">Scrum Guide</a> and find out what the folks in the Ivory Tower have dictated from On High: </p> <img alt="Quote1" data-entity-type="file" data-entity-uuid="e8aa72d0-7f6f-491b-a03f-0099679b5dd1" src="/sites/default/files/inline-images/Quote1_1.png" class="align-center" /><p><span><span><span>You heard that right folks.  If big new requirements come in, then the official Scrum Methodology dictates that you should restart your sprint…</span></span></span></p> <p><span><span><span>The Agile Scrum Master is getting that look again from the Product Owner who has memorized the second gospel of the <a href="http://agilemanifesto.org/principles.html">Agile Manifesto</a>: </span></span></span></p> <img alt="Quote2" data-entity-type="file" data-entity-uuid="97b25ac2-33a2-4197-bdc1-502ef042d490" src="/sites/default/files/inline-images/Quote2.png" class="align-center" /><p> </p> <p><span><span><span>So clearly some horse trading has got to be done here.  To start with, and this is really important, it’s critical that everybody understands that we’re all trying to do the right thing.  This is the moment when everybody needs to put down their manifestos and their guides and whatever other religious weapons they’ve got tucked into their socks and talk to each other.  Having lived this moment many times over here’s 3 things I suggest to keep in mind:</span></span></span></p> <h3>1. Minimum Viable Product</h3> <ul><li>Determine if there is a minimum viable piece of this new requirement that can be delivered within the remaining development time.  This is a phased approach that gets you through this initial crisis and lets you implement the full change next sprint while still delivering value this sprint</li> </ul><h3>2.The Story Point</h3> <ul><li>Determine what the scope of this minimum viable piece is and have the Development Team story point it as you always would</li> </ul><h3>3.Negotiate a Trade</h3> <ul><li>This is the really important part.  Remove a feature (or features) from the sprint that roughly equate to the story points for this minimum viable piece.  The removed features would then be implemented in future sprints</li> </ul><p>This isn’t perfect, but it avoids restarting the sprint which translates into missed deadlines and honestly really translates into what can feel like a soul-crushingly-endless sprint – especially if this happens again and again.  Don’t say that would never happen because I’ve lived it on too many occasions. </p> <p> </p> <h2><img alt="Why???" data-entity-type="file" data-entity-uuid="4941ce3b-2ef0-4031-8248-f6dd501f6cd0" src="/sites/default/files/inline-images/why-150.png" class="align-right" />Helping the Product Owner Understand</h2> <p>Why is it in the Product Owner’s best interest to deliver this minimum viable product versus just extending the sprint for however long this new feature takes.  Why should the Product Owner be willing to sacrifice anything?  Isn’t the Product Owner the boss?  Isn’t what they’re asking for the <span><font color="red"><strong>WOW </strong></font></span>factor that is always the goal?  Isn’t this precisely how we "harness change for the customer's competitive advantage?"</p> <p>Here’s what the seasoned Product Owner is gaining by understanding this compromise:</p> <h3>Less Chance of Bugs</h3> <ul><li>Avoiding a Bugzilla wave of issues after this goes to production.   If the Product Owner had chosen to insist on getting everything (including their cake in the kitchen sink with that enticing cherry on top) they would be signing themselves up for a huge testing effort that probably would miss critical issues. </li> </ul><h3>Fewer Opportunities for Unintended Side Effects</h3> <ul><li>Insisting on any new feature late in the development cycle is honestly risky at best because this means we’re rushing our Technical Team to quickly architect a solution that, chances are high, will miss something.  Product Owners hate bugs even more than the Technical Team does so it behooves them to avoid scenarios that are proven bug magnets. </li> </ul><h3>Decreased Likelihood of Missed Dates</h3> <ul><li>An experienced team knows its velocity.  Therefore, if you story point this new minimum viable product accurately and swap out an equivalent amount of unstarted tickets then you theoretically should be able to still make your production targets</li> </ul><h3>Reduced Risk of Burning out your Technical Team and Testing Team</h3> <ul><li>Seasoned Product Owners and Scrum Masters should always be aware of anything that can lead to burnout.  You’re only as good as the people around you.  If they are abused too often there will eventually be a price to pay.  This translates into higher turnover and lower product quality </li> </ul><figure role="group" class="align-right"><img alt="Not the end of the world" data-entity-type="file" data-entity-uuid="bf8aef00-45db-4147-9dda-4021643b0c42" src="/sites/default/files/inline-images/End_Of_World_Small_320.png" /><figcaption>Image Credit: NASA/Don Davis</figcaption></figure><p>And honestly … if this world-ending change comes in the middle of UAT, do yourself a favor and wait for the next sprint.  Otherwise, you’re pretty much guaranteed fire and brimstone when you unleash this 11th-hour meteor into your code – and ultimately onto your users.  Remember that part of the old maps that said, "Here be Dragons?"</p> <p>Unfortunately, there are no shortcuts in software development.  Investing in automated testing is going to pay off in a big way in situations like this because if you have good code coverage you’ll quickly find out what you missed when you decided to play dice with the devil.</p> <p>OK, kids, I’m going to get off my soapbox with this simple recap.  If you have a change late in the game, do yourself a favor and wait for the next sprint.  If you can’t do that, figure out that little golden nugget in the change request that will keep the wolves at bay and swap this out for a few of those little straggler tickets that are always pending at the end of the development cycle.  Automated tests are your friend.  </p> <p>And remember, we’re all on the same side.  We all want to satisfy the customer.  We’re all trying to do the right thing … which is to deliver the most high-quality code possible that satisfies the customer’s needs by the date we promised it.</p> <p>Please be sure to check out some of my earlier blogs that discuss other aspects of the development process:</p> <ul><li><a href="http://www.avioconsulting.com/blog/highway-danger-zone">Highway to the Danger Zone</a></li> <li><a href="http://www.avioconsulting.com/blog/illusive-agile-waterfall">The Illusive Agile Waterfall</a></li> </ul></div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=696&amp;2=comment_node_blog&amp;3=comment_node_blog" token="h8-J-vzhC5Cu9Ee-d_VjAFEQ1E4AtMY1x70v5lxDLU8"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog/categories/other" hreflang="en">Other</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Tue, 16 Jan 2018 02:53:37 +0000 Aaron Dolan 696 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/how-avoid-agiles-wrath#comments Padawan to Master(ish)[?] |How QA Software Testing Changed Me https://www.avioconsulting.com/blog/padawan-masterish-how-qa-software-testing-changed-me <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-01/Software%20QA%20Testing.png" width="1800" height="850" alt="Software QA Testing" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/padawan-masterish-how-qa-software-testing-changed-me" hreflang="en">Padawan to Master(ish)[?] |How QA Software Testing Changed Me</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p>Software QA testing is so much more than plugging away at a UI or finding <a href="http://www.avioconsulting.com/blog/6-tips-make-most-soapui-part-2"><b>new ways to employ your suite of automated testing tools</b></a>.  In a world where we work tirelessly, neglect ourselves, and go through the motions to get from point A to point B,  we trend toward two-dimensional thinking, mindless checklist completion, and risk de-valuing ourselves and the pivotal role we play in the Agile development process.  Recently, I’ve discovered it pays an ethical and motivational dividend to reflect on the positive value of software QA testing.</p> <p>The following are three ways that becoming a software QA tester has changed me [for the better].</p> <h2>1. Visibility is more important than identifying problems<img alt="Testing improvement through greater visibility" data-entity-type="file" data-entity-uuid="51b1e9e4-def2-49ec-b28c-8c5ab6807f1c" height="300" src="/sites/default/files/inline-images/product-img-monitoring.png" width="464" class="align-right" /></h2> <p>When I began testing, I believed my value centered on finding problems — and the more the better. </p> <p>In fact, I was so motivated to find problems, my confirmation bias would get me into trouble!  With time, though, I began to realize I was having a different impact than I intended.  </p> <p>The real impact of my effort wasn’t in identifying or fixing bugs, but rather providing a record that enhanced visibility to the project manager and product owner.  This had the following effects:</p> <ul><li>Low-performance areas were identified.</li> <li>Identification of low-performance areas gave rise to themes that could be compared/contrasted.</li> <li>Analysis gave way to evaluation and better decision-making.</li> </ul><p>Without realizing it, I began influencing the decision-making process at higher levels of management.  When this clicked for me it became clear that providing visibility into the inner workings of the product is far more valuable than logging an arbitrary number of bugs.  </p> <h2><b>2. Development outcomes become less important than empowering clients. </b></h2> <p>Ostensibly, there’s nothing better than testing a simple JIRA ticket.  You know, an improvement ticket with development outcomes that resemble the following.</p> <ul><li>Move this here.</li> <li>Re-label that there.</li> <li>Disable this feature for role X.</li> </ul><p>Oh, the simplicity!  </p> <p>However, that simplicity can come at a cost if not wielded properly. </p> <blockquote> <p><em>"What happens when re-labeling a field causes it to come into conflict with a labeling scheme somewhere else in the application?"</em></p> </blockquote> <blockquote> <p><em>"What if disabling this feature for role X inadvertently subverts a security hierarchy because of complex dependencies?"  </em></p> </blockquote> <p>As a Padawan tester, I might have said “Eh, doesn’t matter.  I just validate tickets.”</p> <p>However, a wise Jedi once said, “That leads to the Dark Side.”</p> <p>Nowadays, I see situations like the above as an opportunity to ask questions.  It’s ultimately the client’s decision (and it should be) as to how to deal with said labeling schemes and security dependencies.  However, if I own the knowledge that we could be heading for a future headache, then I <b>own</b> that knowledge and have a responsibility to ask about it.  </p> <p>Empowering clients to make seminal decisions about the product’s development is deeply satisfying and a great value-add.  </p> <h2><b>3. Improvement becomes more important than consistency</b></h2> <p>It’s been said that “If you find adventure dangerous, try routine — it’s lethal.”  While a bit hyperbolic in this context, there’s still applicability.  You see, we have to continually improve as software QA testers.  Otherwise, we’re not performing at our best.  </p> <p>Every time we testers make a change to an existing automated test or dabble in a new way of writing an assertion, we introduce the possibility of failure and pain.  It’s true.  And at first, it feels pretty bad.  </p> <p>However, it’s our failures and the pain they sometimes bring that teach us the most valuable and lasting lessons.  Without these moments of pause forced upon us, the proper improvement steps won’t take place, we’ll stop asking questions, and ultimately fall into a pattern of consistency.  </p> <p>Consistency really is a semantically innocuous alternative for stagnant, right?</p> <h3>What are some ways software QA testing have changed you?</h3> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=697&amp;2=comment_node_blog&amp;3=comment_node_blog" token="yrDqhLRXoFAL4xCUuxp2pDZR7z9U0aG68TvAVNVhEaw"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog/categories/other" hreflang="en">Other</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Tue, 02 Jan 2018 17:35:24 +0000 Mark Hearon 697 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/padawan-masterish-how-qa-software-testing-changed-me#comments Using a Multi-Instance Subprocess as a Complex Gateway in Oracle PCS https://www.avioconsulting.com/blog/using-multi-instance-subprocess-complex-gateway-oracle-pcs <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2017-10/multi%203.png" width="600" height="600" alt="Using a Multi-Instance Subprocess to Duplicate Complex Gateway Functionality in PCS" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/using-multi-instance-subprocess-complex-gateway-oracle-pcs" hreflang="en">Using a Multi-Instance Subprocess as a Complex Gateway in Oracle PCS</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p>To speed the time it takes for a work item instance to flow through a process, copies of the instance can be sent to people in multiple roles simultaneously in the <a href="https://cloud.oracle.com/en_US/process">Oracle Integration Cloud Process Cloud Service (PCS)</a>.  Someone in each of the roles can then approve or reject the work item instance.  The challenge comes when an early release from all of the parallel copies is desired when anyone in any of the roles rejects their instance and the original work item instance should then continue in the process. </p> <p>                                                                                                                                                                                                  </p> <p>The Business Process Model and Notation (BPMN) has a complex gateway artifact with this process pattern in mind. When needed, the complex gateway's early release capability makes it one of the most powerful tools process modelers have today when designing executable BPMN processes.  Currently, PCS does not support complex gateways. Because its functionality often needed, this blog describes how to duplicate its functionality when modeling processes using PCS.                                                                                                                                                                                                          </p> <p> </p> <p>Recently added to PCS in May 2017, I recommend that the use of a multi-instance subprocess to do this because:                        </p> <ul><li>One of the multi-instance subprocess activity's options is to send work item instances to people in multiple roles simultaneously</li> <li>Each person in a role can approve or reject the work item instances sent to them</li> <li>If one person rejects the instance, an early release can occur by defining a termination condition in its properties and the original instance can then leave the multi-instance subprocess</li> <li>If a rejection occurs, all of the other copies can automatically be removed from the other role queues </li> </ul><p>Antonis Antoniou has written an <a href="http://antonis-antoniou.blogspot.com/2017/07/multi-instance-subprocess-in-oracle.html">excellent blog on the PCS multi-instance subprocess</a>.  This expands the scope of what he wrote a little to include how to assign the instances spawned to people in different roles, and shows how to cause an early release occur when a one person rejects their copy of the instance.                                                                                                                                                                                                                                               </p> <p> </p> <p>Shown below is a process that illustrates this pattern (in the <a href="https://drive.google.com/file/d/0Bwqetn0fpi74ZjJpa3kyT3lFTkE/view?usp=sharing">PCS application export file</a> this is the “Approval Using MultiInstance Subprocess” process).  If any of the three approvers performing the “Accounting Approval”, “Auditor Approval” or “IT Manager Approval” reject their copy of the instance, the instance will be rejected and immediately leave the multi-instance subprocess.                                                                                                                                                          </p> <p><img alt="Multi-Instance Subprocess with Three Assigned Activities" data-entity-type="file" data-entity-uuid="47633d08-0d47-4ac5-9e11-6b036304b89b" height="289" src="/sites/default/files/inline-images/2m.png" width="802" /></p> <p>To create this, first create a process that starts with a form in PCS.  In this example, the start event’s form only has 3 fields and looks like this.</p> <p><img alt="Process Start Event's Form with Three Fields" data-entity-type="file" data-entity-uuid="791ae280-9403-4ce2-8182-9e56a6bddc4a" height="307" src="/sites/default/files/inline-images/3%20form.png" width="868" /></p> <p>Next, from the System activities in the palette, add a Subprocess activity to the process. </p> <p><img alt="Add the Subprocess Activity to the Process" data-entity-type="file" data-entity-uuid="cedcc804-0687-4c81-bd41-991bd19860d3" height="510" src="/sites/default/files/inline-images/4%20sub%20add.png" width="858" /></p> <p>As shown above, define its properties to have a “Repetition Cycle” of “Generate multiple instances”, and select “In Parallel” so that they all are created at one time.  In this example, people in three different roles will be assigned copies of the instance so select the “Condition” radio button, and click the button to the right of the “How many instances do you want to create?” field and type the number 3.  We will come back later to the checkbox and field in the lower right corner to enable this activity’s early release functionality.                                                                                                                                                                    </p> <p> </p> <p>Add the 5 Approve and Submit Human activities as shown below.  Assign the form that was created to each of them.  Add the two exclusive gateways shown below into the process.  The “Assign” exclusive gateway’s purpose is to send the copy of the instance to only one of the three different Approve Human activities based on the multi-instance subprocess’s predefined “loopCounter” variable.  The first copy will be sent to the “Auditor Approval” activity, the second copy will be sent to the “IT Manager Approval” activity, and the third copy will be sent to the “Accounting Approval” activity.                                                           </p> <p><img alt="Multi-instance Subprocess with Activities Added" data-entity-type="file" data-entity-uuid="66e7ab12-ebfa-4710-a9bf-285adf87e8cd" height="300" src="/sites/default/files/inline-images/5%20prc.png" width="834" /></p> <p>Recall that the number “3” was entered previously in the multi-instance activity’s property panel.  This means at runtime, three copies are created simultaneously with the predefined loopCounter automatically set to 1, 2 and 3 respectively.  The logic in the conditional sequence flow going to the “Auditor Approval” activity is “loopCounter==1”.  This can either be typed in manually, or to be able to select “loopCounter” check the “Show predefined variables” checkbox as shown below.                                                                                                                                                                                                                   </p> <p><img alt="Logic in the Conditional Sequence Flows using the &quot;loopcounter&quot; Predefined Variable" data-entity-type="file" data-entity-uuid="0ad93651-99b2-49f1-aebe-19a3ddc26b9a" height="694" src="/sites/default/files/inline-images/6%20loopcounter.png" width="440" /></p> <p>Similarly, set the logic in the conditional sequence flow going to the “IT Manager Approval” activity to “loopCounter==2”.  The unconditional default sequence flow in this example goes to the “Accounting Approval” activity.                                                                                                                                                          </p> <p> </p> <p>Rather than using the default role modeled in the process, assign each of these activities to their respective roles by selecting one of the Approval activities inside the subprocess, open its “Properties”, and select the “Edit” button beside the “Assignees” field.                                                                                             </p> <p><img alt="Setting the Assignees in Each Activity" data-entity-type="file" data-entity-uuid="8f544a80-ae02-4b50-ac17-cd9f04ae2748" height="425" src="/sites/default/files/inline-images/7%20assignees.png" width="437" /></p> <p>Select “Names and Expressions” from the “Build a list of participants …” dropdown.  Click the + button to add a role to be assigned to the activity.  In the example below, it is assigned to people in the application role named “Vendor Management.IT Manager”.                                                                                         </p> <p><img alt="Assign the Role to the Activity" data-entity-type="file" data-entity-uuid="a87f4fad-352d-453b-8da3-28fd7acb7f52" src="/sites/default/files/inline-images/Add%20Assignees.png" /></p> <p>Do the same thing for the "Accounting Approval" and "Auditor Approval" activities, assigning them to different application roles or LDAP groups that exist.          </p> <p> </p> <p>So that there is an early release if one of the approvers rejects their task, select the multi-instance subprocess activity in the process, and open its properties panel.  Check the “Define a condition that terminates execution of subprocess instances” checkbox, and define the logic that will enable this early release by clicking the “Edit Expression” button shown below.                                                                                                                                                                             </p> <p><img alt="Early Release Termination Logic" data-entity-type="file" data-entity-uuid="cd875f6e-953a-4129-84ad-efb43dbaf505" src="/sites/default/files/inline-images/9.%20early%20release%20termination%20logic.png" /></p> <p>Adding the expression is a little tricky because there are two output string variables to select from that have the same name.  As shown below, use the "taskOutput" string data object under the process ("ApprovalUsing MultiInstanceSubprocess" in this case) and not the copy's output data object (under "Subprocess").                                                                                                                                                                                                                                     </p> <p><img alt="Adding the Early Release Termination Logic" data-entity-type="file" data-entity-uuid="4c669324-4c50-44e8-b97e-16410220948e" src="/sites/default/files/inline-images/10.%20Add%20Termination%20Logic.png" /></p> <p>Because a copy of the original work item instance is being used to populate the three copies, fix this by changing the data associations in each of the three Approval activities.  Select each one of the activities, select “Data Associations”, and change each one's "Input" data association.  As shown below, on the left note that the object under the “Subprocess” was automatically used for the initial input data association mapping.  Remove this and change it to instead use the process’s data object (“multiIntanceFormDataObject” in this case).  Similarly, on the right side set the title of this copy of the instance task by expanding “execData” on the right and dragging “title” in from the right.   For this activity, note that the title is set to: </p> <p>    “Acounting Approval for “ + loopCounter</p> <p><img alt="Assign the Activity Input Data Associations" data-entity-type="file" data-entity-uuid="2f5957c0-496a-4d39-865d-89c27154a9a3" height="270" src="/sites/default/files/inline-images/11.%20Data%20Assoc.png" width="962" /></p> <p>As shown below, click the “Output” tab.  For each one of the three activities remove the automatically mapped Subprocess data objects, and replace them with the process’s data objects “taskOutput” and “muiltiInstanceFormDataObject” as shown below.</p> <p><img alt="Assign the Output Data Associations" data-entity-type="file" data-entity-uuid="a0709d98-2b1f-4ab3-889b-916257e0f043" height="255" src="/sites/default/files/inline-images/12%20output.png" width="962" /></p> <p>Ensure these data association mapping changes have been made to the other two Approval activities in the process.  The final exclusive gateway and the two Human Submit activities shown below are simply there to help determine if the early release works correctly.  The conditional sequence flow going to the “Rejected by Multi” Submit Human activity has the logic:</p> <p>     taskOutput==”REJECT”</p> <p><img alt="Exclusive Gateway's Conditional Sequence Flow Logic" data-entity-type="file" data-entity-uuid="b1976a42-fcd4-4cea-af97-5961f6ba23e3" src="/sites/default/files/inline-images/13%20ex%20gw%20logic.png" /></p> <p>Although I would be the first to admit that the BPMN complex gateway is missed in PCS, and that this approach takes a bit of work to accomplish, the complex gateway's early release functionality can be achieved using the process modeling pattern described here. </p> <p>Reference:</p> <p>1. “<b>Multi-Instance Subprocess in Oracle Process Cloud Service</b>” by Antonis Antoniou - <a href="http://antonis-antoniou.blogspot.com/2017/07/multi-instance-subprocess-in-oracle.html">http://antonis-antoniou.blogspot.com/2017/07/multi-instance-subprocess-…</a></p> <p>2. "<strong>Dynamically Assigning an Oracle PCS Task to an Application Role</strong>" by Dan Atwood - <a href="http://www.avioconsulting.com/blog/dynamically-assigning-oracle-pcs-task-application-role">http://www.avioconsulting.com/blog/dynamically-assigning-oracle-pcs-tas…</a></p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=684&amp;2=comment_node_blog&amp;3=comment_node_blog" token="7869zgMTUFm9yq6iXkc8ybfAvjZjcInipzWkPMrSig8"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog/categories/bpm" hreflang="en">BPM</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Mon, 23 Oct 2017 15:56:45 +0000 Dan Atwood 684 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/using-multi-instance-subprocess-complex-gateway-oracle-pcs#comments