<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thomas Südbröcker</title>
    <description>The latest articles on DEV Community by Thomas Südbröcker (@tsuedbroecker).</description>
    <link>https://dev.to/tsuedbroecker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F142736%2F65817a7d-cfee-42bc-ac1c-330592f901b1.jpg</url>
      <title>DEV Community: Thomas Südbröcker</title>
      <link>https://dev.to/tsuedbroecker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tsuedbroecker"/>
    <language>en</language>
    <item>
      <title>SIMPLE NODE.JS SERVER EXAMPLE USING THE WATSON ASSISTANT API V2</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Sun, 08 Jan 2023 11:13:50 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/simple-nodejs-server-example-using-the-watson-assistant-api-v2-19ao</link>
      <guid>https://dev.to/tsuedbroecker/simple-nodejs-server-example-using-the-watson-assistant-api-v2-19ao</guid>
      <description>&lt;p&gt;This blog post is about a simple example to use the &lt;a href="https://cloud.ibm.com/apidocs/assistant/assistant-v2" rel="noopener noreferrer"&gt;Watson Assistant API v2&lt;/a&gt; with the &lt;a href="https://github.com/watson-developer-cloud/node-sdk" rel="noopener noreferrer"&gt;Node.js SDK&lt;/a&gt; to get a &lt;a href="https://cloud.ibm.com/catalog/services/watson-assistant#about" rel="noopener noreferrer"&gt;Watson Assistant&lt;/a&gt; sessionID and send a message to &lt;a href="https://cloud.ibm.com/catalog/services/watson-assistant#about" rel="noopener noreferrer"&gt;Watson Assistant&lt;/a&gt; using this sessionID. Here is the GitHub project &lt;strong&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-assistant-simple-node-js-server-example" rel="noopener noreferrer"&gt;watson-assistant-simple-node-js-server-example&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The objective is only to start a chat session and return the values we get from &lt;a href="https://cloud.ibm.com/apidocs/assistant/assistant-v2" rel="noopener noreferrer"&gt;Watson Assistant API v2&lt;/a&gt; methods. The simple Node.js server has implemented following REST endpoints :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-assistant-simple-node-js-server-example/blob/main/code/simple-server/server.js#L37" rel="noopener noreferrer"&gt;&lt;code&gt;GET&lt;/code&gt; getsession (which creates a new &lt;code&gt;sessionID&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-assistant-simple-node-js-server-example/blob/main/code/simple-server/server.js#L64" rel="noopener noreferrer"&gt;&lt;code&gt;POST&lt;/code&gt; sendmessage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The project contains examples for using &lt;a href="https://www.postman.com/downloads/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;. &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2Fsvg%2F1f609.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs0.wp.com%2Fwp-content%2Fmu-plugins%2Fwpcom-smileys%2Ftwemoji%2F2%2Fsvg%2F1f609.svg" alt="😉" width="36" height="36"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The blog post is structured in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect to an assistant in the right environment&lt;/li&gt;
&lt;li&gt;Implement a simple endpoint&lt;/li&gt;
&lt;li&gt;Use the example&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CONNECT TO AN ASSISTANT IN THE RIGHT ENVIRONMENT
&lt;/h2&gt;

&lt;p&gt;Therefor we will first connect to our &lt;strong&gt;Watson Assistant service&lt;/strong&gt; instance with the &lt;strong&gt;environmentID&lt;/strong&gt;. Because we need to know to which environment we want to connect our server.&lt;/p&gt;

&lt;p&gt;A small diagram with simplified dependencies. In my case I connected to the draft environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s7av5ooobwyysr2kgey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s7av5ooobwyysr2kgey.png" alt="img" width="731" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The GitHub project also contains a &lt;a href="https://github.com/thomassuedbroecker/watson-assistant-simple-node-js-server-example/blob/main/code/assistant-get-environment-ids.sh" rel="noopener noreferrer"&gt;bash script to list the environments using cRUL&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following code shows an extract of a return value of a bash script execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"environments"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"draft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"My Example Assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"draft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"assistant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"df8d00f8-e9cc-XXXXXXXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"orchestration"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"search_skill_fallback"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"environment_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"3d6d1cd6-29fd-XXXXXXXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"session_timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relevant code in&lt;a href="https://github.com/thomassuedbroecker/watson-assistant-simple-node-js-server-example/blob/main/code/simple-server/server.js#L28" rel="noopener noreferrer"&gt; &lt;strong&gt;server.js&lt;/strong&gt;&lt;/a&gt; file to connect to the right environment of the Watson Assistant service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;assistant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AssistantV2&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;authenticator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IamAuthenticator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;apikey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e_apikey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;serviceUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e_serverUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  IMPLEMENT A SIMPLE ENDPOINT
&lt;/h2&gt;

&lt;p&gt;When we are connected to the right assistant with the right environment, we can use this connection and we mostly just reuse the code given in the &lt;a href="https://cloud.ibm.com/apidocs/assistant/assistant-v2" rel="noopener noreferrer"&gt;Watson Assistant API v2&lt;/a&gt; documentation for the Node.js SDK in the implementation of our REST endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/getsession&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   
    &lt;span class="nx"&gt;assistant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;assistantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e_environmentID&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createSessionresult&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createSessionresult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;sessionID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createSessionresult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createSessionError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createSessionError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createSessionError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;  
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simplified diagram of the given dependencies of our scenario.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtzy0ff0g9u5c90e48i0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtzy0ff0g9u5c90e48i0.png" alt="img" width="701" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  USE THE EXAMPLE
&lt;/h2&gt;

&lt;p&gt;Here are the steps you can follow to run this example on your local machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 1: CLONE THE PROJECT TO YOUR LOCAL COMPUTER
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/thomassuedbroecker/
watson-assistant-simple-node-js-server-example.git
&lt;span class="nb"&gt;cd
&lt;/span&gt;watson-assistant-simple-node-js-server-example/code/simple-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 2: CONFIGURE THE ENVIRONMENT VARIABLES
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://cloud.ibm.com/apidocs/assistant/assistant-v2#createsession" rel="noopener noreferrer"&gt;Here we need an &lt;code&gt;environmentID&lt;/code&gt;. We can find this &lt;code&gt;ID&lt;/code&gt; in the &lt;code&gt;Watson Assistant user interface&lt;/code&gt;, by navigating to the &lt;code&gt;Environments page&lt;/code&gt; and selecting the environment you want to use (such as Draft or Live). Then you open the &lt;code&gt;environment settings&lt;/code&gt; and copy the value from the appropriate field.&lt;/a&gt; (Contains the Link to the IBM Cloud documentation)&lt;/p&gt;

&lt;p&gt;The image below shows the &lt;code&gt;environment ID&lt;/code&gt; in the &lt;a href="https://cloud.ibm.com/resources" rel="noopener noreferrer"&gt;IBM Cloud UI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnchtezwptc1k7vxl0hh4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnchtezwptc1k7vxl0hh4.png" alt="img" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also need an &lt;code&gt;API key&lt;/code&gt; and a base &lt;code&gt;URL&lt;/code&gt; from the Credentials. The image blow shows the &lt;code&gt;API key&lt;/code&gt; and the &lt;code&gt;URL&lt;/code&gt; in the &lt;a href="https://cloud.ibm.com/resources" rel="noopener noreferrer"&gt;IBM Cloud UI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhieac1nmsrbilyz6vnat.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhieac1nmsrbilyz6vnat.png" alt="img" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an &lt;code&gt;.env&lt;/code&gt; file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .env-template &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configure the &lt;code&gt;.env&lt;/code&gt; file to your needs
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;WATSON_ASSISTANT_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2021-11-27'&lt;/span&gt;
&lt;span class="nv"&gt;WATSON_ASSISTANT_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'XXXX'&lt;/span&gt;
&lt;span class="nv"&gt;WATSON_ASSISTANT_SERVICE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'https://api.us-south.assistant.watson.cloud.ibm.com'&lt;/span&gt;
&lt;span class="nv"&gt;WATSON_ASSISTANT_ENVIRONMENT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'XXX'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 3: RUN LOCAL ON PORT 3010
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 4: OPEN BROWSER AND INVOKE THE GET SESSION ENDPOINT
&lt;/h3&gt;

&lt;p&gt;It returns the newly created &lt;code&gt;sessionID&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;open http://localhost:3010/getsession
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Example output:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"session_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"37d13c72-1643-4add-bee5-574c6fd062dc"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 5: IMPORT THE POSTMAN COLLECTION INTO POSTMAN
&lt;/h3&gt;

&lt;p&gt;The images shows the import button in postman.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkz9b99erodv6m167bo7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkz9b99erodv6m167bo7u.png" alt="img" width="800" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the &lt;code&gt;/postman/watson-assistant-example.postman_collection.json&lt;/code&gt; in the project for the import.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 6: AFTER THE IMPORT YOU HAVE A NEW COLLECTION INSIDE YOUR POSTMAN
&lt;/h3&gt;

&lt;p&gt;The images shows the imported collection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5z266wzcuat2ivwg2w32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5z266wzcuat2ivwg2w32.png" alt="img" width="656" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 7: SEND A MESSAGE
&lt;/h3&gt;

&lt;p&gt;Here again the simplified diagram of the given dependencies of our scenario.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtzy0ff0g9u5c90e48i0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtzy0ff0g9u5c90e48i0.png" alt="img" width="701" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 7.1: GET A SESSIONID
&lt;/h3&gt;

&lt;p&gt;Now we need to get the sessionID with &lt;code&gt;GET request&lt;/code&gt; using the &lt;code&gt;getsession&lt;/code&gt; endpoint. We copy the value of the &lt;strong&gt;sessionID&lt;/strong&gt; to use it inside the next REST endpoint invocation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwajr7ft69bldfboyducu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwajr7ft69bldfboyducu.png" alt="img" width="678" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 7.2: INSERT THE &lt;code&gt;SESSION ID&lt;/code&gt; INTO THE BODY OF THE &lt;code&gt;POST&lt;/code&gt; REQUEST USING THE &lt;code&gt;SENDMESSAGE ENDPOINT&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the &lt;strong&gt;JSON&lt;/strong&gt; format which is used in the &lt;strong&gt;POST request sendmessage&lt;/strong&gt; body in Postman. Now we insert the copied &lt;strong&gt;sessionID&lt;/strong&gt; into the body of the request inside postman.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"sendmessage"&lt;/span&gt; : &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"sessionID"&lt;/span&gt; : &lt;span class="s2"&gt;"XXXX"&lt;/span&gt;,
  &lt;span class="s2"&gt;"message_type"&lt;/span&gt;: &lt;span class="s2"&gt;"text"&lt;/span&gt;,
  &lt;span class="s2"&gt;"text"&lt;/span&gt;: &lt;span class="s2"&gt;"Hello"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcs84b188nzawqq44qmud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcs84b188nzawqq44qmud.png" alt="img" width="694" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we see the output of the &lt;strong&gt;sendmessage&lt;/strong&gt; request in the expected &lt;strong&gt;JSON&lt;/strong&gt; format.&lt;/p&gt;

&lt;h2&gt;
  
  
  SUMMARY
&lt;/h2&gt;

&lt;p&gt;The usage of the &lt;a href="https://cloud.ibm.com/apidocs/assistant/assistant-v2" rel="noopener noreferrer"&gt;Watson Assistant API v2&lt;/a&gt; is very easy and good documented, but you &lt;strong&gt;need to understand the environment topic&lt;/strong&gt;. At the moment the documentation talks about the &lt;strong&gt;assistantID&lt;/strong&gt; to pass into an invocation as an example, this can cause a misunderstanding. Here a screen shot of the &lt;a href="https://cloud.ibm.com/apidocs/assistant/assistant-v2?code=node#createsession" rel="noopener noreferrer"&gt;IBM Cloud documentation “createsession”&lt;/a&gt; created on 09.12.2022.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fho1e7pzqzrvwxobtydhj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fho1e7pzqzrvwxobtydhj.png" alt="img" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

&lt;h1&gt;
  
  
  watsonassistant, #nodejs, #ibmcloud, #rest, #javascript
&lt;/h1&gt;

&lt;p&gt;Original blog post on &lt;a href="http://www.suedbroecker.net" rel="noopener noreferrer"&gt;www.suedbroecker.net&lt;/a&gt; &lt;a href="https://suedbroecker.net/2022/12/09/simple-node-js-server-example-for-using-the-watson-assistant-api-v2/" rel="noopener noreferrer"&gt;SIMPLE NODE.JS SERVER EXAMPLE USING THE WATSON ASSISTANT API V2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>watsonassistant</category>
      <category>node</category>
      <category>rest</category>
      <category>javascript</category>
    </item>
    <item>
      <title>RUN WATSON NLP FOR EMBED ON IBM CLOUD CODE ENGINE</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Wed, 04 Jan 2023 18:41:25 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/run-watson-nlp-for-embed-on-ibm-cloud-code-engine-15ag</link>
      <guid>https://dev.to/tsuedbroecker/run-watson-nlp-for-embed-on-ibm-cloud-code-engine-15ag</guid>
      <description>&lt;p&gt;This blog post is about using the &lt;a href="https://www.ibm.com/docs/en/watson-libraries?topic=watson-natural-language-processing-library-embed-home" rel="noopener noreferrer"&gt;IBM Watson Natural Language Processing Library for Embed&lt;/a&gt; on &lt;a href="https://www.ibm.com/cloud/code-engine" rel="noopener noreferrer"&gt;IBM Cloud Code Engine&lt;/a&gt; and is related to my blog post &lt;a href="https://suedbroecker.net/2022/12/15/run-watson-nlp-for-embed-on-your-local-computer-with-docker/" rel="noopener noreferrer"&gt;Run Watson NLP for Embed on your local computer with Docker&lt;/a&gt;. &lt;a href="https://www.ibm.com/cloud/code-engine" rel="noopener noreferrer"&gt;IBM Cloud Code Engine&lt;/a&gt; is a fully managed, serverless platform where you can run container images or &lt;a href="https://www.ibm.com/cloud/blog/running-batch-jobs-in-ibm-cloud-code-engine" rel="noopener noreferrer"&gt;batch jobs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.ibm.com/docs/en/watson-libraries?topic=watson-natural-language-processing-library-embed-home" rel="noopener noreferrer"&gt;IBM Watson Libraries for Embed&lt;/a&gt; are made for IBM Business Partners. Partners can get additional details about &lt;code&gt;embeddable AI&lt;/code&gt; on the &lt;a href="https://www.ibm.com/partnerworld/program/embeddableai" rel="noopener noreferrer"&gt;IBM Partner World&lt;/a&gt; page. If you are an IBM Business Partner you can get a free access to the &lt;a href="https://www.ibm.com/account/reg/us-en/signup?formid=urx-51726" rel="noopener noreferrer"&gt;&lt;code&gt;IBM Watson Natural Language Processing Library for Embed&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get started with the libraries you can use the link &lt;a href="https://www.ibm.com/docs/en/watson-libraries?topic=watson-natural-language-processing-library-embed-home" rel="noopener noreferrer"&gt;&lt;code&gt;Watson Natural Language Processing Library for Embed home&lt;/code&gt;&lt;/a&gt;. It is an awesome documentation and it is public available.&lt;/p&gt;

&lt;p&gt;I used parts of the IBM Watson documentation in my Code Engine example and I created a GitHub project with some additional example bash scripting. The project is called &lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine" rel="noopener noreferrer"&gt;&lt;code&gt;Run Watson NLP for Embed on your IBM Cloud Code Engine&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The blog post is structured in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some simplified technical basics about &lt;strong&gt;IBM Watson Libraries for Embed&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Some screen shots from a running example using &lt;strong&gt;IBM Cloud Code Engine&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Execute the example on &lt;strong&gt;IBM Cloud Code Engine&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. SOME SIMPLIFIED TECHNICAL BASICS ABOUT &lt;strong&gt;IBM WATSON LIBRARIES FOR EMBED&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;IBM Watson Libraries for Embed&lt;/strong&gt; do provide a lot of pre-trained models you can find in the related model catalog for the Watson Libraries. Here is a link to the &lt;a href="https://www.ibm.com/docs/en/watson-libraries?topic=models-catalog" rel="noopener noreferrer"&gt;model catalog for Watson NLP&lt;/a&gt;, the catalog is public available.&lt;/p&gt;

&lt;p&gt;There are runtime containers for the AI functionalities like &lt;strong&gt;NLP&lt;/strong&gt;, &lt;strong&gt;Speech to Text&lt;/strong&gt; and so on. You can integrate the container into your application and customize them, for example existing pre-trained models, but it’s also possible to use own created models. By separating the container runtime and the models to be loaded into the container, we are free to include the right models we need to integrate in our application to fulfil the needs of our business use case.&lt;/p&gt;

&lt;p&gt;The resources are available in a &lt;a href="https://www.ibm.com/cloud/container-registry" rel="noopener noreferrer"&gt;IBM Cloud Container Registry&lt;/a&gt;. The image below shows a simplified overview.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-02-1.png%3Fw%3D541" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-02-1.png%3Fw%3D541" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next gif shows a simplified overview of the dependencies and steps we need to execute when we using &lt;a href="https://www.ibm.com/cloud/code-engine" rel="noopener noreferrer"&gt;IBM Cloud Code Engine&lt;/a&gt; to run a custom Watson NLP runtime container. You can find the detailed instructions in the official IBM documentation &lt;a href="https://www.ibm.com/docs/en/watson-libraries?topic=installing-running-containers" rel="noopener noreferrer"&gt;installing running containers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-01.gif%3Fw%3D619" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-01.gif%3Fw%3D619" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are the simplified steps which are automated with bash scripting, which we see in the image above.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We create a &lt;strong&gt;custom Watson NLP container locally&lt;/strong&gt;, by using the Watson NLP runtime image and select models for the example. Therefor we define a &lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/Dockerfile" rel="noopener noreferrer"&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/a&gt; and we use the &lt;strong&gt;IBM entitlement key&lt;/strong&gt; to access the runtime image and the models on the &lt;a href="https://www.ibm.com/cloud/container-registry" rel="noopener noreferrer"&gt;IBM Cloud Container Registry&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We use the &lt;a href="https://www.ibm.com/cloud/container-registry" rel="noopener noreferrer"&gt;IBM Cloud Container Registry&lt;/a&gt; to save and protect our &lt;strong&gt;custom container image&lt;/strong&gt;. In the container image registry we create a namespace where we upload the image. &lt;a href="https://cloud.ibm.com/docs/Registry?topic=Registry-troubleshoot-add-namespace" rel="noopener noreferrer"&gt;The namespace name must be unique in the IBM Cloud region of the container registry&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We create a &lt;strong&gt;Code Engine project&lt;/strong&gt;. &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-manage-project" rel="noopener noreferrer"&gt;The project must be unique in the IBM Cloud region of Code Engine&lt;/a&gt;. We also create a secret to access our IBM Cloud container registry and in this context the automation also need to create an &lt;a href="https://cloud.ibm.com/docs/account?topic=account-userapikey&amp;amp;interface=ui" rel="noopener noreferrer"&gt;IBM Cloud API key&lt;/a&gt; to do that task.&lt;/li&gt;
&lt;li&gt;Now we configure a &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-application-workloads" rel="noopener noreferrer"&gt;&lt;strong&gt;Code Engine application&lt;/strong&gt;&lt;/a&gt;. For the configuration we use the &lt;strong&gt;container registry secret&lt;/strong&gt; to load the container image from the IBM Cloud Container Registry and we configure an environment variable that we are going to &lt;strong&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L201" rel="noopener noreferrer"&gt;accept the license&lt;/a&gt;&lt;/strong&gt; when we run our custom Watson NLP container image.&lt;/li&gt;
&lt;li&gt;To verify the running container image is working, we invoke a curl command to execute a &lt;em&gt;SyntaxPredict&lt;/em&gt; from the &lt;a href="https://developer.ibm.com/apis/catalog/embeddableai--watson-natural-language-processing-apis/Introduction/" rel="noopener noreferrer"&gt;Watson NLP API&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. SOME SCREEN SHOTS FROM A RUNNING EXAMPLE ON CODE ENGINE
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cloud.ibm.com/registry/namespaces" rel="noopener noreferrer"&gt;IBM Cloud Container Registry namespace&lt;/a&gt; and the uploaded container image:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-02.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-02.png%3Fw%3D1024" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The created &lt;a href="https://cloud.ibm.com/iam/apikeys" rel="noopener noreferrer"&gt;IBM Cloud API key&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-03.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-03.png%3Fw%3D1024" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The created &lt;a href="https://cloud.ibm.com/codeengine/projects" rel="noopener noreferrer"&gt;Code Engine project&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-04.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-04.png%3Fw%3D1024" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The created &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-application-workloads" rel="noopener noreferrer"&gt;Code Engine application&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-05.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-05.png%3Fw%3D1024" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The created &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-add-registry" rel="noopener noreferrer"&gt;Code Engine &lt;code&gt;Registry Access&lt;/code&gt;&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-06.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-06.png%3Fw%3D1024" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The created &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-cli#cli-application-create" rel="noopener noreferrer"&gt;Envionment variable&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-07.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-07.png%3Fw%3D1024" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The mapped custom Watson NLP container image:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-08.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fwatson-nlp-ce-08.png%3Fw%3D1024" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. EXECUTE THE EXAMPLE ON IBM CLOUD CODE ENGINE
&lt;/h2&gt;

&lt;p&gt;These are the steps you can follow along to run the example with custom Watson NLP container image on IBM Cloud Code Engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 1: CLONE THE EXAMPLE PROJECT TO YOUR LOCAL COMPUTER
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/thomassuedbroecker/watson-nlp-example-code-engine
&lt;span class="nb"&gt;cd &lt;/span&gt;watson-nlp-example-code-engine/code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 2: SET NEEDED ENVIRONMENT VARIABLES IN THE &lt;code&gt;.ENV&lt;/code&gt; FILE
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .env-template &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;We need …&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;… an &lt;code&gt;IBM_ENTITLEMENT_KEY&lt;/code&gt; to get the Watson NLP resources.&lt;/li&gt;
&lt;li&gt;… an &lt;code&gt;IBMCLOUD_APIKEY&lt;/code&gt; that the bash script can automate all tasks.&lt;/li&gt;
&lt;li&gt;… an unique IBM Cloud Container Registry namespace name &lt;code&gt;CR_NAMESPACE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;… to configure an email &lt;code&gt;CE_EMAIL&lt;/code&gt; related to our container image registry access.&lt;/li&gt;
&lt;li&gt;… an unique Code Engine project name &lt;code&gt;CE_PROJECT_NAME&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# used as 'environment' variables&lt;/span&gt;
&lt;span class="nv"&gt;IBM_ENTITLEMENT_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_KEY"&lt;/span&gt;
&lt;span class="nv"&gt;IBMCLOUD_APIKEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_KEY"&lt;/span&gt;
&lt;span class="nv"&gt;CR_NAMESPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"custom-watson-nlp-YOUR_NAME"&lt;/span&gt;
&lt;span class="nv"&gt;CE_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_EMAIL"&lt;/span&gt;
&lt;span class="nv"&gt;CE_PROJECT_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"custom-watson-nlp-YOURNAME"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 3: EXECUTE THE &lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh" rel="noopener noreferrer"&gt;&lt;code&gt;RUN-WATSON-NLP-WITH-CODE-ENGINE.SH&lt;/code&gt;&lt;/a&gt; BASH SCRIPT
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The bash script execution can take several minutes.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh run-watson-nlp-with-code-engine.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;EXAMPLE OUTPUT&lt;/strong&gt; AND THE &lt;strong&gt;LINKS TO THE RELATED FUNCTIONS IN THE BASH SCRIPT CODE&lt;/strong&gt;
&lt;/h4&gt;

&lt;h4&gt;
  
  
  LINKS TO THE RELATED FUNCTIONS IN THE BASH SCRIPT CODE
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L42" rel="noopener noreferrer"&gt;Connect to IBM Container Registry for the Watson NLP resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L69" rel="noopener noreferrer"&gt;Load the models from the IBM Container Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L104" rel="noopener noreferrer"&gt;Log on to IBM Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L117" rel="noopener noreferrer"&gt;Log on to IBM Cloud Container Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L131" rel="noopener noreferrer"&gt;Push the container image to the IBM Cloud Container Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L151" rel="noopener noreferrer"&gt;Create and configure a IBM Cloud Code Engine project to use the IBM Cloud Container Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L187" rel="noopener noreferrer"&gt;Create a Code Engine application with the needed secret and environment variable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/watson-nlp-example-code-engine/blob/main/code/run-watson-nlp-with-code-engine.sh#L211" rel="noopener noreferrer"&gt;Verify the running custom Watson NLP image&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  EXAMPLE OUTPUT
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Create custom Watson NLP container image&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;


&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Connect to IBM Cloud Container Image Registry: cp.icr.io/cp/ai&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

...
Login Succeeded

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# List model array content&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

Model 0 : watson-nlp_syntax_izumo_lang_en_stock:1.0.7
Model 1 : watson-nlp_syntax_izumo_lang_fr_stock:1.0.7

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Download the models&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

...

&lt;span class="c"&gt;# 2. Put models into the file share&lt;/span&gt;
Archive:  /app/model.zip
  inflating: config.yml              
...

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Create container image&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

Image name: watson-nlp-runtime-with-models
&lt;span class="o"&gt;[&lt;/span&gt;+] Building 0.1s &lt;span class="o"&gt;(&lt;/span&gt;7/7&lt;span class="o"&gt;)&lt;/span&gt; FINISHED                                                
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;internal] load build definition from Dockerfile                       0.0s

...

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Upload image to IBM Cloud container registry &lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

...

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Configure IBM Cloud Registry&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

The region is &lt;span class="nb"&gt;set &lt;/span&gt;to &lt;span class="s1"&gt;'us-south'&lt;/span&gt;, the registry is &lt;span class="s1"&gt;'us.icr.io'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

OK
Adding namespace &lt;span class="s1"&gt;'custom-watson-nlp-tsued'&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;resource group &lt;span class="s1"&gt;'default'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;account XXXX Account &lt;span class="k"&gt;in &lt;/span&gt;registry us.icr.io ...

OK
Logging &lt;span class="s1"&gt;'docker'&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;to &lt;span class="s1"&gt;'us.icr.io'&lt;/span&gt;...
Logged &lt;span class="k"&gt;in &lt;/span&gt;to &lt;span class="s1"&gt;'us.icr.io'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

OK
Container image: us.icr.io/custom-watson-nlp-tsued/watson-nlp-runtime-with-models:1.0.0
The push refers to repository &lt;span class="o"&gt;[&lt;/span&gt;us.icr.io/custom-watson-nlp-tsued/watson-nlp-runtime-with-models]
2de7f9fb3378: Pushed 
...
9aaca8eae7c0: Pushed 
1.0.0: digest: sha256:8ad1b4bdd6a89b0686c48fc2325900018a1ddfec0ffb1689457b5c433300d61c size: 4290

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Create Code Engine project&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

&lt;span class="k"&gt;**********************************&lt;/span&gt;
 Create Code Engine project: custom-watson-nlp-tsued
&lt;span class="k"&gt;**********************************&lt;/span&gt;

...

Creating project &lt;span class="s1"&gt;'custom-watson-nlp-tsued'&lt;/span&gt;...
ID &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'custom-watson-nlp-tsued'&lt;/span&gt; is &lt;span class="s1"&gt;'b879a212-XXXX'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Waiting &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'custom-watson-nlp-tsued'&lt;/span&gt; to be active...
Now selecting project &lt;span class="s1"&gt;'custom-watson-nlp-tsued'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
OK
&lt;span class="k"&gt;**********************************&lt;/span&gt;
 Configure IBM Cloud Container Registry Access &lt;span class="o"&gt;(&lt;/span&gt;us.icr.io&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;custom-watson-nlp-tsued&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;**********************************&lt;/span&gt;
&lt;span class="k"&gt;**********************************&lt;/span&gt;
 Create Code Engine project: custom-watson-nlp-tsued
&lt;span class="k"&gt;**********************************&lt;/span&gt;
API key: 
Creating API key cliapikey_custom-watson-nlp-tsued under 641ebfXXXXXXb45279e as XXXXX...
OK
API key cliapikey_custom-watson-nlp-tsued was created
Successfully save API key information to cli_key.json
Creating image registry access secret &lt;span class="s1"&gt;'custom.watson.nlp.cr.sec'&lt;/span&gt;...
OK

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Create Code Engine application custom-watson-nlp-application&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

Creating application &lt;span class="s1"&gt;'custom-watson-nlp-application'&lt;/span&gt;...
Configuration &lt;span class="s1"&gt;'custom-watson-nlp-application'&lt;/span&gt; is waiting &lt;span class="k"&gt;for &lt;/span&gt;a Revision to become ready.
Ingress has not yet been reconciled.
Waiting &lt;span class="k"&gt;for &lt;/span&gt;load balancer to be ready.
Run &lt;span class="s1"&gt;'ibmcloud ce application get -n custom-watson-nlp-application'&lt;/span&gt; to check the application status.
OK

Set CE_APPLICATION_NAME URL: https://custom-watson-nlp-application.wqtmqy9e03u.us-south.codeengine.appdomain.cloud

&lt;span class="c"&gt;# ******&lt;/span&gt;
&lt;span class="c"&gt;# Verify the custom image&lt;/span&gt;
&lt;span class="c"&gt;# ******&lt;/span&gt;

...

&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;:&lt;span class="s2"&gt;"This is a test sentence."&lt;/span&gt;, &lt;span class="s2"&gt;"producerId"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"Izumo Text Processing"&lt;/span&gt;, &lt;span class="s2"&gt;"version"&lt;/span&gt;:&lt;span class="s2"&gt;"0.0.1"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="s2"&gt;"tokens"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"span"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"begin"&lt;/span&gt;:0, &lt;span class="s2"&gt;"end"&lt;/span&gt;:4, &lt;span class="s2"&gt;"text"&lt;/span&gt;:&lt;span class="s2"&gt;"This"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, 
...
&lt;span class="s2"&gt;"features"&lt;/span&gt;:[]&lt;span class="o"&gt;}]&lt;/span&gt;, &lt;span class="s2"&gt;"sentences"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"span"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"begin"&lt;/span&gt;:0, &lt;span class="s2"&gt;"end"&lt;/span&gt;:24, &lt;span class="s2"&gt;"text"&lt;/span&gt;:&lt;span class="s2"&gt;"This is a test sentence."&lt;/span&gt;&lt;span class="o"&gt;}}]&lt;/span&gt;, &lt;span class="s2"&gt;"paragraphs"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"span"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"begin"&lt;/span&gt;:0, &lt;span class="s2"&gt;"end"&lt;/span&gt;:24, &lt;span class="s2"&gt;"text"&lt;/span&gt;:&lt;span class="s2"&gt;"This is a test sentence."&lt;/span&gt;&lt;span class="o"&gt;}}]}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. SUMMARY
&lt;/h2&gt;

&lt;p&gt;It is easy to create a customize &lt;a href="https://www.ibm.com/docs/en/watson-libraries?topic=watson-natural-language-processing-library-embed-home" rel="noopener noreferrer"&gt;&lt;code&gt;Watson Natural Language Processing Library for Embed&lt;/code&gt;&lt;/a&gt; container image and run it on &lt;code&gt;IBM Cloud Code Engine&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

&lt;p&gt;Original Blog Post: &lt;a href="https://suedbroecker.net/2022/12/21/run-watson-nlp-for-embed-on-ibm-cloud-code-engine/" rel="noopener noreferrer"&gt;RUN WATSON NLP FOR EMBED ON IBM CLOUD CODE ENGINE&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ibmcloud</category>
      <category>watsonnlp</category>
      <category>bashscripting</category>
      <category>codeengine</category>
    </item>
    <item>
      <title>CUSTOM DOMAIN AND TLS CERTIFICATE FOR YOUR APPLICATION ON IBM CLOUD CODE ENGINE</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Wed, 04 Jan 2023 18:13:00 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/custom-domain-and-tls-certificate-for-your-application-on-ibm-cloud-code-engine-1fnj</link>
      <guid>https://dev.to/tsuedbroecker/custom-domain-and-tls-certificate-for-your-application-on-ibm-cloud-code-engine-1fnj</guid>
      <description>&lt;p&gt;This blog post is about using the &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-domain-mappings" rel="noopener noreferrer"&gt;domain mapping&lt;/a&gt; functionality in &lt;a href="https://cloud.ibm.com/codeengine" rel="noopener noreferrer"&gt;IBM Cloud Code Engine&lt;/a&gt; to use custom domains and TLS certificates for your applications. The source code related to an example setup is in the GitHub project &lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp" rel="noopener noreferrer"&gt;example WebApp build on Vue.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When we deploy an application to &lt;a href="https://cloud.ibm.com/codeengine" rel="noopener noreferrer"&gt;IBM Cloud Code Engine&lt;/a&gt; we get an IBM Cloud domain in following format &lt;code&gt;**[CODE_ENGINE_APPLICATION].[CODE_ENGINE_PROJECT].[IBM_CLOUD_REGION].codeengine.appdomain.cloud**&lt;/code&gt; and a &lt;strong&gt;TLS certificate&lt;/strong&gt; provided by &lt;strong&gt;&lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt;.&lt;/strong&gt; We are free to use this &lt;code&gt;out-of-the-box&lt;/code&gt; for our application.&lt;/p&gt;

&lt;p&gt;But now we are going to use a &lt;a href="https://en.wikipedia.org/wiki/Wildcard_certificate" rel="noopener noreferrer"&gt;wild card certificate&lt;/a&gt; for our domain &lt;code&gt;*.example.com&lt;/code&gt;. With a &lt;a href="https://en.wikipedia.org/wiki/Transport_Layer_Security" rel="noopener noreferrer"&gt;TLS&lt;/a&gt; &lt;a href="https://en.wikipedia.org/wiki/Wildcard_certificate" rel="noopener noreferrer"&gt;certificate&lt;/a&gt; for that domain.&lt;/p&gt;

&lt;p&gt;The blog post is structured in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used services or software&lt;/li&gt;
&lt;li&gt;Simplified architecture overview&lt;/li&gt;
&lt;li&gt;Example setup&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. USED SERVICES OR SOFTWARE
&lt;/h3&gt;

&lt;p&gt;These are the services or software which are used in this example.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;IBM Cloud&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cloud.ibm.com/codeengine" rel="noopener noreferrer"&gt;IBM Cloud Code Engine&lt;/a&gt; is a fully managed, serverless platform where you can run container images or batch jobs.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.ibm.com/catalog/infrastructure/domain_registration" rel="noopener noreferrer"&gt;IBM Cloud Domain Name Registration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;“IBM Cloud offers domain registration services complete with dedicated support staff, knowledgeable customer service, and reasonable prices, all delivered over a secure network.“&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Open Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://certbot.eff.org/" rel="noopener noreferrer"&gt;Certbot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;“Certbot is a free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS.“&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Let’s Encrypt is a free, automated, and open certificate authority (CA), run for the public’s benefit. It is a service provided by the Internet Security Research Group (ISRG).“&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Red Hat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://quay.io/" rel="noopener noreferrer"&gt;Quay.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;“Quay.io is a registry for storing and building container images as well as distributing other OCI artifacts. The service is free for those who want to set up their own public repositories and available for a fee, if you want to create private repositories.“&lt;/p&gt;

&lt;h3&gt;
  
  
  2. SIMPLIFIED ARCHITECTURE OVERVIEW
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9ocvj43exryn5s29gl9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9ocvj43exryn5s29gl9.gif" alt="img" width="619" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The gif above shows a very simplified diagram with dependencies and steps related to the setup for an example application. The example application container is in my case saved in the public &lt;a href="https://quay.io/" rel="noopener noreferrer"&gt;Quay.io&lt;/a&gt; container registry and the application container is based on the &lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp" rel="noopener noreferrer"&gt;“Example WebApp build on Vue.js” GitHub project&lt;/a&gt;. We have in place a &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-plan-codeengine" rel="noopener noreferrer"&gt;&lt;code&gt;Code Engine project&lt;/code&gt;&lt;/a&gt; and the example web application is already deployed.&lt;/p&gt;

&lt;p&gt;The following sections are a very simplified description of the steps in the simplified diagram above.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, we buy a domain. In my case I bought the domain &lt;code&gt;www.suedbroecker-example.com&lt;/code&gt; at the &lt;a href="https://cloud.ibm.com/catalog/infrastructure/domain_registration" rel="noopener noreferrer"&gt;IBM Cloud Domain Name Registration&lt;/a&gt; for 10,00 Euro.&lt;/li&gt;
&lt;li&gt;Then we use &lt;a href="https://certbot.eff.org/" rel="noopener noreferrer"&gt;Certbot&lt;/a&gt; to create/request a TLS certificate at &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt; from our local computer. In my case I used a &lt;a href="https://en.wikipedia.org/wiki/Wildcard_certificate" rel="noopener noreferrer"&gt;wildcard certificate&lt;/a&gt; ‘&lt;em&gt;’ for the `&lt;/em&gt;.suedbroecker-example.com&lt;code&gt; domain. I wanted to be flexible so that I can define new subdomains very easily and use this subdomain names for my new applications, for example with a naming like &lt;/code&gt;app01.suedbroecker-example.com&lt;code&gt;, &lt;/code&gt;app02.suedbroecker-example.com` and so on.&lt;/li&gt;
&lt;li&gt;Now &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt; provides a &lt;a href="https://letsencrypt.org/de/docs/challenge-types/" rel="noopener noreferrer"&gt;challenge&lt;/a&gt; we need to insert at our domain provider.&lt;/li&gt;
&lt;li&gt;We need to insert the &lt;a href="https://letsencrypt.org/de/docs/challenge-types/" rel="noopener noreferrer"&gt;challenge&lt;/a&gt; to the domain provider in a &lt;a href="https://en.wikipedia.org/wiki/TXT_record" rel="noopener noreferrer"&gt;TXT&lt;/a&gt; record. With that &lt;a href="https://letsencrypt.org/de/docs/challenge-types/" rel="noopener noreferrer"&gt;challenge&lt;/a&gt; &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt; can verify, if we are able to configure/own the given &lt;code&gt;www.example.com&lt;/code&gt; domain using the &lt;a href="https://letsencrypt.org/de/docs/challenge-types/" rel="noopener noreferrer"&gt;challenge&lt;/a&gt;. &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt; will verify it and provide us the result with &lt;code&gt;cert bot&lt;/code&gt; on the local computer. That can take sometimes several minutes.&lt;/li&gt;
&lt;li&gt;When the verification was successful we get issued from &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt; a &lt;strong&gt;public TLS certifcate&lt;/strong&gt; and &lt;strong&gt;private key&lt;/strong&gt; which will be saved on our local computer by the &lt;a href="https://certbot.eff.org/" rel="noopener noreferrer"&gt;cert bot&lt;/a&gt; application.&lt;/li&gt;
&lt;li&gt;Now it’s time to start to configure the &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-domain-mappings#prepare-custom-domain" rel="noopener noreferrer"&gt;IBM Cloud Code Engine &lt;code&gt;domain mapping&lt;/code&gt;&lt;/a&gt;. We add a new &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-domain-mappings#prepare-custom-domain" rel="noopener noreferrer"&gt;&lt;code&gt;domain mapping&lt;/code&gt;&lt;/a&gt; and we insert the &lt;strong&gt;public TLS certificate&lt;/strong&gt; and &lt;strong&gt;private key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Now we need to configure in our domain provider the &lt;a href="https://en.wikipedia.org/wiki/CNAME_record" rel="noopener noreferrer"&gt;&lt;code&gt;CNAME&lt;/code&gt;&lt;/a&gt;. In my case I configured the &lt;a href="https://en.wikipedia.org/wiki/CNAME_record" rel="noopener noreferrer"&gt;&lt;code&gt;CNAME&lt;/code&gt;&lt;/a&gt; to map the &lt;a href="https://en.wikipedia.org/wiki/Wildcard_certificate" rel="noopener noreferrer"&gt;wild card certificate&lt;/a&gt; ‘*’ to the link provided by Code Engine.&lt;/li&gt;
&lt;li&gt;In my case I used a &lt;a href="https://en.wikipedia.org/wiki/Wildcard_certificate" rel="noopener noreferrer"&gt;wild card&lt;/a&gt; ‘&lt;em&gt;’ `&lt;/em&gt;.suedbroecker-example.com&lt;code&gt; certificate, so I can configure a custom domain to point to the application. I configured the domain &lt;/code&gt;webapp.suedbroecker-example.com`.&lt;/li&gt;
&lt;li&gt;Now we can invoke the domain &lt;code&gt;webapp.suedbroecker-example.com&lt;/code&gt; with &lt;code&gt;https&lt;/code&gt;. Our connection is now secured, and the browser can verify the TLS certificate is valid. The image below shows my running application on Code Engine using my TLS certificate.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The image below shows the example application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdpt1a75c2ihtjs2wkzx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdpt1a75c2ihtjs2wkzx.png" alt="img" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. EXAMPLE SETUP
&lt;/h3&gt;

&lt;p&gt;These are the steps you can follow along to run the example application on IBM Cloud Code Engine. The GitHub project &lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp" rel="noopener noreferrer"&gt;“Example WebApp build on Vue.js”&lt;/a&gt; contains the source code for this simple &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue.js&lt;/a&gt; web application.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.1 GET THE SOURCE CODE
&lt;/h4&gt;

&lt;h5&gt;
  
  
  STEP 1: CLONE THE PROJECT
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/thomassuedbroecker/vue-simple-webapp
&lt;span class="nb"&gt;cd &lt;/span&gt;vue-simple-webapp/code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  STEP 2: SET THE NEEDED ENVIRONMENT VARIABLES IN THE &lt;code&gt;.ENV&lt;/code&gt; FILE&lt;a href="http://127.0.0.1:8000/openshift-security/ibmdomain-codeengine/#step-2-set-the-needed-environment-variables-in-the-env-file" rel="noopener noreferrer"&gt;¶&lt;/a&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .env-template &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the &lt;code&gt;.env&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ASSISTANT_INTEGRATION_ID="YOUR_ID"
ASSISTANT_REGION="YOUR_REGION"
ASSISTANT_SERVICE_INSTANCE_ID="YOUR_SERVICE_INSTANCE"
ROOTFOLDER="YOUR_ROOTFOLDER" #Location on your local machine
MYPROJECT="YOUR_MYPROJECT" #IBM Cloud Code Engine project name
RESOURCE_GROUP="default" #IBM Cloud resource group
REGION="YOUR_REGION" #IBM Cloud region
CERT_EMAIL="YOUR_EMAIL" # If you want to create a TLS certification
CERT_DOMAIN="YOUR_DOMAIN" # If you want to create a TLS certification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can follow the steps in the README.md of the &lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp" rel="noopener noreferrer"&gt;“Example WebApp build on Vue.js” GitHub project&lt;/a&gt;. Then run the Vue.js application locally or as a container. When you run the application in a container a Nginx is used as the webserver. You are also able to deploy the application to IBM Cloud Code Engine. All of the options are automated with bash scripts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  3.2 REGISTER A DOMAIN
&lt;/h4&gt;

&lt;p&gt;The following steps are showing, how to buy a domain at IBM Cloud.&lt;/p&gt;

&lt;h5&gt;
  
  
  STEP 1: REGISTER DOMAIN AT IBM CLOUD
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Buy the domain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fibmcloud-domain-01.gif%3Fw%3D619" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsuedbroecker.files.wordpress.com%2F2022%2F12%2Fibmcloud-domain-01.gif%3Fw%3D619" alt="img" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify your contact information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frysiaoa72evv3gyaj08t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frysiaoa72evv3gyaj08t.png" alt="img" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure the data sharing preferences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenk55xsl5qhelekm28q6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenk55xsl5qhelekm28q6.png" alt="img" width="667" height="1023"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  STEP 2: VERIFY YOUR DOMAIN IS READY TO USE
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndmu45romx8kp9iw3d1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndmu45romx8kp9iw3d1y.png" alt="img" width="800" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3 REQUEST/CREATE A TLS CERTIFICATE WITH &lt;code&gt;LET’S ENCRYPT AND CERTBOT&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;In this context this blog post &lt;a href="https://medium.com/@saurabh6790/generate-wildcard-ssl-certificate-using-lets-encrypt-certbot-273e432794d7" rel="noopener noreferrer"&gt;Generate Wildcard TSL certificate using Let’s Encrypt/Certbot&lt;/a&gt; was very useful. (&lt;a href="https://en.wikipedia.org/wiki/Certificate_authority" rel="noopener noreferrer"&gt;Certificate authority CA&lt;/a&gt;)&lt;/p&gt;

&lt;h5&gt;
  
  
  STEP 1: INSTALL CERTBOT ON &lt;a href="https://certbot.eff.org/lets-encrypt/osx-other.html" rel="noopener noreferrer"&gt;MACOS&lt;/a&gt;&lt;a href="http://127.0.0.1:8000/openshift-security/ibmdomain-codeengine/#step-1-install-certbot-on-macos" rel="noopener noreferrer"&gt;¶&lt;/a&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew ``install` `certbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  STEP 2: EXECUTE TO &lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp/blob/main/SimpleWebApp/create-cert.sh" rel="noopener noreferrer"&gt;CREATE-CERT.SH&lt;/a&gt; TO CREATE THE TLS CERTIFICATE
&lt;/h5&gt;

&lt;p&gt;We are using the staging environment from &lt;a href="https://letsencrypt.org/docs/staging-environment/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt;. If you’re experimenting with different ACME clients, use the &lt;a href="https://letsencrypt.org/docs/staging-environment/" rel="noopener noreferrer"&gt;staging environment&lt;/a&gt; &lt;a href="https://letsencrypt.org/docs/staging-environment/" rel="noopener noreferrer"&gt;Let’s encrypt&lt;/a&gt; to avoid hitting rate limits.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp/blob/main/SimpleWebApp/create-cert.sh" rel="noopener noreferrer"&gt;create-cert.sh&lt;/a&gt; does following automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp/blob/main/SimpleWebApp/create-cert.sh#L11" rel="noopener noreferrer"&gt;It requests/creates the certificate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp/blob/main/SimpleWebApp/create-cert.sh#L22" rel="noopener noreferrer"&gt;Save the &lt;code&gt;cert&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt; location&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp/blob/main/SimpleWebApp/create-cert.sh#L33" rel="noopener noreferrer"&gt;Copy the &lt;code&gt;cert&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt; to the current project to read the content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/vue-simple-webapp/blob/main/SimpleWebApp/create-cert.sh#L47" rel="noopener noreferrer"&gt;Show the &lt;code&gt;cert&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt; to easily copy the file content to Code Engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind the certificate will be valid for 90 days.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh create-cert.sh 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Output and interaction:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Insert your wild card domain: &lt;code&gt;*.suedbroecker-example.com&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Password:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel): *.suedbroecker-example.com
Requesting a certificate for *.suedbroecker-example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.www.suedbroecker-example.com.

with the following value:

n4H_yuDtBb6zXdZWg-XXXXXXX

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.www.suedbroecker-example.com.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Insert the challenge in &lt;a href="https://cloud.ibm.com/catalog/infrastructure/domain_registration" rel="noopener noreferrer"&gt;IBM Cloud Domain Name Registration&lt;/a&gt; in a &lt;a href="https://en.wikipedia.org/wiki/TXT_record" rel="noopener noreferrer"&gt;TXT&lt;/a&gt; record:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvyqil08rdb3l2b0vfjm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvyqil08rdb3l2b0vfjm.png" alt="img" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify the challenge with the &lt;a href="https://toolbox.googleapps.com/" rel="noopener noreferrer"&gt;&lt;code&gt;Google Toolbox&lt;/code&gt;&lt;/a&gt;. This task can take several minutes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ezfhyl48h2o2v1rvct7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ezfhyl48h2o2v1rvct7.png" alt="img" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now we can move on with the script and we see the downloaded certificates.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/www.suedbroecker-example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/www.suedbroecker-example.com/privkey.pem
This certificate expires on 2023-03-24.
These files will be updated when the certificate renews.

NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now you can insert the given locations for the &lt;code&gt;cert&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt; and the script creates new files with different endings and it displays the &lt;code&gt;cert&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt; we can easily copy and paste to the domain mapping.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Question: How to get .crt and .key files from? I just have .pem files &lt;a href="https://community.letsencrypt.org/t/how-to-get-crt-and-key-files-from-i-just-have-pem-files/7348/6" rel="noopener noreferrer"&gt;answered here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Insert SOURCE_CERTIFICATE
/etc/letsencrypt/live/www.suedbroecker-example.com/fullchain.pem
Value: /etc/letsencrypt/live/www.suedbroecker-example.com/fullchain.pem

Insert SOURCE_KEY
/etc/letsencrypt/live/www.suedbroecker-example.com/privkey.pem
Value: /etc/letsencrypt/live/www.suedbroecker-example.com/privkey.pem

mkdir: /Users/thomassuedbroecker/Downloads/dev/vue-simple-webapp/simplewebapp/tls-cert
mkdir: /Users/thomassuedbroecker/Downloads/dev/vue-simple-webapp/simplewebapp/tls-cert/letsencrypt

Public cert:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Private key:
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  STEP 3: &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-domain-mappings#custom-domain-ui" rel="noopener noreferrer"&gt;CONFIGURE THE DOMAIN MAPPING IN CODE ENGINE&lt;/a&gt;
&lt;/h5&gt;

&lt;p&gt;Now we copy the certificate and key content into the domain mapping, and we configure the domain name. In my case I used the name &lt;code&gt;webapp.suedbroecker-example.com&lt;/code&gt;, because I am free to choose the name and this related to the &lt;code&gt;wild card&lt;/code&gt; certificate I use. In the image below you see the finally saved configuration in Code Engine domain mapping.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqy3cfrv4p02ejf79xg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqy3cfrv4p02ejf79xg4.png" alt="img" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  STEP 4: WE NEED TO INSERT THE LINK FROM CODE ENGINE INTO THE &lt;code&gt;CNAME&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;In my case I mapped the &lt;code&gt;wild card '*'&lt;/code&gt; to the &lt;code&gt;link from Code Engine&lt;/code&gt; in the &lt;code&gt;CNAME&lt;/code&gt;. It can take several minutes until you can use the mapped domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofc32jtyi7sccngavza2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofc32jtyi7sccngavza2.png" alt="img" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For details, please visit the &lt;a href="https://cloud.ibm.com/docs/codeengine?topic=codeengine-domain-mappings#custom-domain-ui" rel="noopener noreferrer"&gt;Code Engine documentation &lt;code&gt;custom domain configuration&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  STEP 5: OPEN THE DOMAIN URL
&lt;/h5&gt;

&lt;p&gt;In my case it was webapp.suedbroecker-example.com.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdpt1a75c2ihtjs2wkzx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdpt1a75c2ihtjs2wkzx.png" alt="img" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. SUMMARY
&lt;/h3&gt;

&lt;p&gt;It’s awesome that Code Engine provides this functionality. With this functionality we are very flexible to configure our own domain. Maybe we can just use an &lt;a href="https://cloud.ibm.com/catalog/infrastructure/domain_registration" rel="noopener noreferrer"&gt;IBM Cloud Domain Name Registration&lt;/a&gt;. You need to keep in mind you have to manage the certificate and update, because i will expire after 90 days. There are other blog posts about Code Engine and domain mapping out there like&lt;a href="https://blog.4loeser.net/2022/05/custom-domain-ibmcloud-code-engine.html" rel="noopener noreferrer"&gt; Custom domain for your serverless Code Engine app&lt;/a&gt; available.&lt;/p&gt;




&lt;p&gt;I hope this was useful to you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;




&lt;p&gt;Original blog post: &lt;a href="https://suedbroecker.net/2022/12/26/custom-domain-and-tls-certificate-for-your-application-on-ibm-cloud-code-engine/" rel="noopener noreferrer"&gt;suedbroecker.net - CUSTOM DOMAIN AND TLS CERTIFICATE FOR YOUR APPLICATION ON IBM CLOUD CODE ENGINE&lt;/a&gt;&lt;/p&gt;

</description>
      <category>certbot</category>
      <category>letsencrypt</category>
      <category>codeengine</category>
      <category>bashscript</category>
    </item>
    <item>
      <title>CONNECT TO A POSTGRESQL DATABASE, CREATE TABLES, INSERT DATA, AND USE A FILE FROM A GITHUB PROJECT WITH GO</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Thu, 03 Mar 2022 15:57:14 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/connect-to-a-postgresql-database-create-tables-insert-data-and-use-a-file-from-a-github-project-with-go-mei</link>
      <guid>https://dev.to/tsuedbroecker/connect-to-a-postgresql-database-create-tables-insert-data-and-use-a-file-from-a-github-project-with-go-mei</guid>
      <description>&lt;p&gt;This blog post covers the topic connect to a &lt;a href="https://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; database, create tables, insert data and use a file from a GitHub project and do the implementation with &lt;a href="https://go.dev/"&gt;GO&lt;/a&gt;. That blog post is also related to my last blog post called &lt;a href="https://suedbroecker.net/2022/02/22/connect-to-a-postgressql-database-using-go/"&gt;Connect to a PostgreSQL database using GO&lt;/a&gt;. You find the related code to my new blog post in that &lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data"&gt;GitHub project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The file to create the example tables and content is a part of the GitHub project called &lt;a href="https://github.com/IBM/multi-tenancy/blob/main/installapp/postgres-config/create-populate-tenant-a.sql"&gt;Multi-tenancy assets for IBM clients to build SaaS&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  OBJECTIVE
&lt;/h3&gt;

&lt;p&gt;Connect to a PostgresSQL database, create tables, insert data using a file from a GitHub project.&lt;/p&gt;

&lt;h3&gt;
  
  
  BASIC FLOW
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Connect to the database&lt;/li&gt;
&lt;li&gt;Get a file from a GitHub project with the SQL statements to create tables and insert data&lt;/li&gt;
&lt;li&gt;Execute the SQL statement&lt;/li&gt;
&lt;li&gt;Verify one value with a query&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  BASIC PROGRAMMING STEPS
&lt;/h3&gt;

&lt;p&gt;Each step contains the link to the line in the source code inside the &lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L37"&gt;Create HTTP request using the GitHub API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L44"&gt;Define HTTP header&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L47"&gt;Create client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L50"&gt;Invoke HTTP request&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L59"&gt;Verify the request status&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L62"&gt;Get only body from response&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L69"&gt;Convert body to JSON content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L76"&gt;Extract and decode file content from JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L80"&gt;Connect to a database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://create%20a%20sql%20statement%20from%20file%20content/"&gt;Create a SQL statement from file content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thomassuedbroecker/go-access-postgres-create-table-insert-data/blob/main/gopostgressql/gopostgressql.go#L102"&gt;Verify the created tables with a query&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  UNDERSTAND THE GITHUB URL FORMAT
&lt;/h3&gt;

&lt;p&gt;As I said before, we use an example file from a GitHub project called &lt;a href="https://github.com/IBM/multi-tenancy/blob/main/installapp/postgres-config/create-populate-tenant-a.sql"&gt;Multi-tenancy assets for IBM clients to build SaaS&lt;/a&gt;. So, we need to get a bit familiar with the &lt;a href="https://github.com/public-apis/public-apis"&gt;GitHub public APIs&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example url we use: &lt;code&gt;https://api.github.com/repos/IBM/multi-tenancy/contents/installapp/postgres-config/create-populate-tenant-a.sql&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mapping to the used GitHub API endpoint: &lt;code&gt;https://api.github.com/repos/$NAME/$REPO/contents/$FILENAME&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These are the related values of the example GitHub API endpoint above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub API: &lt;a href="https://api.github.com/repos/"&gt;https://api.github.com/repos/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Name: “IBM/”&lt;/li&gt;
&lt;li&gt;Repo: “multi-tenancy”&lt;/li&gt;
&lt;li&gt;GitHub API: /contents/&lt;/li&gt;
&lt;li&gt;Filename: “installapp/postgres-config/create-populate-tenant-a.sql”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details visit the &lt;a href="https://github.com/public-apis/public-apis"&gt;GitHub public APIs&lt;/a&gt; documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  SOME USEFUL RESOURCES:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://freshman.tech/snippets/go/http-response-to-string/"&gt;How to convert an HTTP response body to a string in Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gobyexample.com/base64-encoding"&gt;Go by Example: Base64 Encoding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/9272535/how-to-get-a-file-via-github-apis"&gt;How to get a file via GitHub APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gobyexample.com/json"&gt;Go by Example: JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/38673673/access-http-response-as-string-in-go"&gt;Access HTTP response as string in Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jackc/pgx"&gt;pgx – PostgreSQL Driver and Toolkit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RUN THE EXAMPLE APPLICATION
&lt;/h3&gt;

&lt;p&gt;These are the steps you need to follow to run the example on your local machine.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You need a running PostgresSQL database somewhere&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  STEP 1: GIT CLONE
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/thomassuedbroecker/go-access-postgres-example.git 
&lt;span class="nb"&gt;cd &lt;/span&gt;go-access-postgres-example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 2: VERIFY THAT THE &lt;a href="https://go.dev/doc/modules/gomod-ref"&gt;MOD FILE&lt;/a&gt; “GO.MOD”
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;gopostgressql 
&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 3: SET THE ENVIRONMENT VARIABLE
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"postgres://username:password@localhost:5432/database_name"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Don’t forget to insert your &lt;em&gt;DATABASE_URL&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 5: EXECUTE THE GO PROGRAM
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  SUMMARY
&lt;/h1&gt;

&lt;p&gt;We touched in that simple example different essentials and useful topics in GO programming I would say (for example: base64, access HTTP endpoints, handle JSON and so on) and that makes it worth to take a note 😉&lt;/p&gt;




&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://suedbroecker.net/2022/02/22/connect-to-postgresql-database-create-tables-insert-data-and-use-a-file-from-a-github-project-with-go/"&gt;www.suedbroecker.net&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  go, #postgressql, #github, #buildlabs4saas
&lt;/h1&gt;

</description>
      <category>go</category>
      <category>postgressql</category>
      <category>github</category>
    </item>
    <item>
      <title>DEBUG A KUBERNETES OPERATOR WRITTEN IN GO</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Thu, 03 Mar 2022 15:48:13 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/debug-a-kubernetes-operator-written-in-go-5m6</link>
      <guid>https://dev.to/tsuedbroecker/debug-a-kubernetes-operator-written-in-go-5m6</guid>
      <description>&lt;p&gt;In this blog post I want to share how to debug a GO Operator on your local machine on macOS. &lt;a href="https://www.linkedin.com/in/deleeuwa/"&gt;Adam de Leeuw&lt;/a&gt; and I verified it in different GO operator projects. Sometimes you find on Google information which uses the &lt;a href="https://auscunningham.medium.com/debug-kubernetes-operator-sdk-locally-using-vscode-a233aa7c750e"&gt;older Operator SDK&lt;/a&gt;. The following instructions worked for us in March 2022. 😉&lt;/p&gt;

&lt;p&gt;The blog post is structured in four sections:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Basics&lt;/li&gt;
&lt;li&gt;Configure Visual Studio Code to debug the operator&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sdk.operatorframework.io/docs/building-operators/golang/"&gt;Debug your GO operator&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. PREREQUISITES
&lt;/h3&gt;

&lt;p&gt;You need to …&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;… ensure you have the Operator SDK installed (&lt;a href="https://suedbroecker.net/2022/02/15/fata0009-failed-to-create-api-unable-to-run-post-scaffold-tasks-of-base-go-kubebuilder-io-v3-exit-status-2/"&gt;that also installs GO when you use brew for the installation&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;… setup the &lt;a href="https://code.visualstudio.com/docs/languages/go"&gt;Visual Studio Code extension for GO&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;… install &lt;a href="https://github.com/go-delve/delve"&gt;DELVE debugger for GO&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;… setup the integration of the &lt;a href="https://github.com/golang/vscode-go"&gt;DELVE debugger for Visual Studio Code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;… run an example &lt;a href="https://github.com/thomassuedbroecker/multi-tenancy-frontend-operator"&gt;GO operator&lt;/a&gt; 😉&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. BASICS
&lt;/h3&gt;

&lt;p&gt;Please keep in mind some essentially basics when you run your operator locally with the &lt;strong&gt;make&lt;/strong&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;make &lt;span class="nb"&gt;install &lt;/span&gt;run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;make install run&lt;/code&gt; command does …&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;… &lt;strong&gt;deploy the needed manifests (&lt;code&gt;yaml's&lt;/code&gt;)&lt;/strong&gt; to the Kubernetes cluster you use and create the connection.&lt;/li&gt;
&lt;li&gt;… it starts the local GO application with the file called &lt;code&gt;main.go&lt;/code&gt; 
(in the last step inside make file with the command &lt;code&gt;go run ./main.go&lt;/code&gt; )&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. CONFIGURE VISUAL STUDIO CODE TO DEBUG THE OPERATOR
&lt;/h3&gt;

&lt;p&gt;With that in mind we know how to debug.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, you to run the &lt;code&gt;make install run&lt;/code&gt; command to ensure you operator will find all need &lt;code&gt;manifests&lt;/code&gt; configurations on your cluster.&lt;/li&gt;
&lt;li&gt;Now you need to configure the DELVE GO debug in Visual Studio Code &lt;code&gt;.vscode/launch.json&lt;/code&gt; configurations file in your workspace.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  STEP 1: CREATE A &lt;code&gt;.VSCODE/LAUNCH.JSON&lt;/code&gt; FILE IN VISUAL STUDIO CODE WITH A GO CONFIGURATION&lt;a href="http://127.0.0.1:8000/openshift-security/debug-go-operator-sdk/#step-1-create-a-vscodelaunchjson-with-go"&gt;¶&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The following short gif shows the creation of a &lt;code&gt;.vscode/launch.json&lt;/code&gt; file. In that case it uses the folder where my workspace file is located and you see that &lt;strong&gt;&lt;code&gt;go package&lt;/code&gt;&lt;/strong&gt; was used as debug a configuration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3-mqkxkE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-01.gif%3Fw%3D619" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3-mqkxkE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-01.gif%3Fw%3D619" alt="img" width="619" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s the example result you saw in the gif.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;      
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"Launch Package"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"go"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      
  &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      
  &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"auto"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      
  &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"${fileDirname}"&lt;/span&gt;&lt;span class="w"&gt;    
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 2: NOW YOU CAN OPTIONAL CONFIGURE THE LOCATION WHERE YOU WANT TO START THE &lt;code&gt;MAIN.GO&lt;/code&gt; FILE.
&lt;/h3&gt;

&lt;p&gt;Just to ensure the right &lt;code&gt;operator&lt;/code&gt; will be started. The gif below show how to customize the &lt;code&gt;.vscode/launch.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1WwcZ_p---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-02-2.gif%3Fw%3D619" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1WwcZ_p---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-02-2.gif%3Fw%3D619" alt="img" width="619" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s the example result you saw in the gif.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IntelliSense&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;learn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;about&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;possible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes.&lt;/span&gt;&lt;span class="w"&gt;    
     &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Hover&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;view&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;descriptions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;existing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;attributes.&lt;/span&gt;&lt;span class="w"&gt;    
     &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;For&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;information&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;visit:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://go.microsoft.com/fwlink/?linkid=&lt;/span&gt;&lt;span class="mi"&gt;830387&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"0.2.0"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;      
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"Launch Frontend Operator"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        
                    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"go"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        
            &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"auto"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
             &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"/Users/thomassuedbroecker/Downloads/dev/multi-tenancy-frontend-operator/frontendOperator"&lt;/span&gt;&lt;span class="w"&gt;      
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. DEBUG YOUR GO OPERATOR
&lt;/h3&gt;

&lt;h3&gt;
  
  
  STEP 1: EXECUTE THE[ &lt;code&gt;MAKE INSTALL RUN&lt;/code&gt;] FOR YOUR OPERATOR
&lt;/h3&gt;

&lt;p&gt;You see the my example operator I used for my blog post and live stream &lt;a href="https://suedbroecker.net/2022/02/18/start-to-develop-a-simple-operator-to-deploy-the-frontend-application-of-the-open-source-multi-cloud-asset-to-build-saas%C2%B6/"&gt;Develop a simple operator to deploy a web application using the GO Operator SDK¶&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make install run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Example output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/Users/thomassuedbroecker/Downloads/dev/multi-tenancy-frontend-operator/frontendOperator/bin/controller-gen
rbac:roleName&lt;span class="o"&gt;=&lt;/span&gt;manager-role crd webhook &lt;span class="nv"&gt;paths&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./..."&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;output:crd:artifacts:config&lt;span class="o"&gt;=&lt;/span&gt;config /crd/bases /Users/thomassuedbroecker/Downloads/dev/multi-tenancy-frontend-operator/frontendOperator/bin/kustomize&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;build config /crd | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; - customresourcedefinition.apiextensions.k8s.io /tenancyfrontends .multitenancy.example.net configured /Users/thomassuedbroecker/Downloads/dev/multi-tenancy-frontend-operator/frontendOperator/bin/controller-gen&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;object:headerFile&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hack/boilerplate.go.txt"&lt;/span&gt; 
&lt;span class="nv"&gt;paths&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./..."&lt;/span&gt; go  &lt;span class="nb"&gt;fmt&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;./... go vet ./... go run &lt;span class="nb"&gt;.&lt;/span&gt; /main .go 1.6461312240985138e+09 INFO  controller-runtime.metrics   Metrics server is starting to listen   &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"addr"&lt;/span&gt; :  &lt;span class="s2"&gt;":8080"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
1.646131224098974e+09  INFO  setup  starting manager 1.646131224099315e+09  INFO  Starting server &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"path"&lt;/span&gt; :  &lt;span class="s2"&gt;"/metrics"&lt;/span&gt; ,  &lt;span class="s2"&gt;"kind"&lt;/span&gt; :  &lt;span class="s2"&gt;"metrics"&lt;/span&gt; ,  &lt;span class="s2"&gt;"addr"&lt;/span&gt; :  &lt;span class="s2"&gt;"[::]:8080"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
1.646131224099315e+09  INFO  Starting server &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"kind"&lt;/span&gt; :  &lt;span class="s2"&gt;"health probe"&lt;/span&gt; ,  &lt;span class="s2"&gt;"addr"&lt;/span&gt; :  &lt;span class="s2"&gt;"[::]:8081"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
1.6461312240993888e+09 INFO  controller.tenancyfrontend   Starting EventSource   &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"reconciler group"&lt;/span&gt; :  &lt;span class="s2"&gt;"multitenancy.example.net"&lt;/span&gt; ,  &lt;span class="s2"&gt;"reconciler kind"&lt;/span&gt; :  &lt;span class="s2"&gt;"TenancyFrontend"&lt;/span&gt; ,  &lt;span class="s2"&gt;"source"&lt;/span&gt; :  &lt;span class="s2"&gt;"kind source: *v1alpha1.TenancyFrontend"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
1.6461312240994549e+09 INFO  controller.tenancyfrontend   Starting Controller    &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"reconciler group"&lt;/span&gt; :  &lt;span class="s2"&gt;"multitenancy.example.net"&lt;/span&gt; ,  &lt;span class="s2"&gt;"reconciler kind"&lt;/span&gt; :  &lt;span class="s2"&gt;"TenancyFrontend"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
1.646131224200895e+09  INFO  controller.tenancyfrontend   Starting workers &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"reconciler group"&lt;/span&gt; :  &lt;span class="s2"&gt;"multitenancy.example.net"&lt;/span&gt; ,  &lt;span class="s2"&gt;"reconciler kind"&lt;/span&gt; :  &lt;span class="s2"&gt;"TenancyFrontend"&lt;/span&gt; ,  &lt;span class="s2"&gt;"worker count"&lt;/span&gt; : 1&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  STEP 2: STOP THE OPERATOR EXECUTION
&lt;/h3&gt;

&lt;h3&gt;
  
  
  STEP 3: ADD A BREAK POINT TO THE CONTROLLER AND START THE DEBUGGING FOR THE GO OPERATOR[¶]
&lt;/h3&gt;

&lt;p&gt;The gif below shows how create a break point and start the debugging. You need to take a look in the debug console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CjJDJ4uo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-03.gif%3Fw%3D619" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CjJDJ4uo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-03.gif%3Fw%3D619" alt="img" width="619" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the following image you see a screen shot of the running debugging.&lt;/p&gt;

&lt;p&gt;Take a short look at&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run and debug

&lt;ul&gt;
&lt;li&gt;Start the debug session with the just defined GO configuration for the Operator&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Observe

&lt;ul&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;Watch&lt;/li&gt;
&lt;li&gt;Stack&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Debug console

&lt;ul&gt;
&lt;li&gt;Show the output we would see, when we would have started operator with a &lt;a href="https://en.wikipedia.org/wiki/Make_(software)"&gt;make&lt;/a&gt; command&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v6soijKA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-02.jpg%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v6soijKA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2022/03/operator-debug-02.jpg%3Fw%3D1024" alt="img" width="880" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  SUMMARY
&lt;/h1&gt;

&lt;p&gt;It’s awesome to use the powerful &lt;a href="https://github.com/go-delve/delve"&gt;DELVE debugger for GO&lt;/a&gt; inside &lt;a href="https://github.com/golang/vscode-go"&gt;Visual Studio Code&lt;/a&gt; when you build a GO Operator. 🙂&lt;/p&gt;




&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://suedbroecker.net/2022/03/01/debug-a-kubernetes-operator-written-in-go/#more-4460"&gt;www.suedbroecker.net&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  operator, #go, #operatorsdk, #kubernetes, #delve, #buildlabs4saas
&lt;/h1&gt;

</description>
      <category>go</category>
      <category>operatorsdk</category>
      <category>kubernetes</category>
      <category>delve</category>
    </item>
    <item>
      <title>How to simply examine a JSON response from a Cloudant search in Java</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Thu, 01 Jul 2021 13:16:08 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/how-to-simply-examine-a-json-response-from-a-cloudant-search-in-java-1a30</link>
      <guid>https://dev.to/tsuedbroecker/how-to-simply-examine-a-json-response-from-a-cloudant-search-in-java-1a30</guid>
      <description>&lt;p&gt;This is a short cheat sheet about, how to simply examine a JSON response from a &lt;a href="https://github.com/IBM/cloudant-java-sdk"&gt;Cloudant&lt;/a&gt; search in Java. I found different examples, but these examples were (more or less) older examples, where I missed some pieces and at the end for me the &lt;a href="https://javaee.github.io/javaee-spec/javadocs/javax/json/JsonObject.html"&gt;Java EE documentation&lt;/a&gt; was the best resource to realize it.&lt;/p&gt;

&lt;p&gt;The JSON I wanted to examine, was a JSON with a nested JSON array and that array also contains a nested JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON format of the Cloudant search response
&lt;/h3&gt;

&lt;p&gt;Here you see is the JSON format I wanted to examine.  As I said: It's a JSON with a nested JSON array and the array also contains a nested JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"total_rows"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bookmark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"g2wAAAABaANkAClkYmNvcmVAZGI3LmJtLWNjLXVzLXNvdXRoLTExLmNsb3VkYW50Lm5ldGwAAAACYhAAAABiH____2poAkY_8AAAAAAAAGEAag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rows"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://haralduebele.github.io/2019/02/17/blue-cloud-mirror-dont-open-the-doors/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-blogs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Blue Cloud Mirror — (Don’t) Open The Doors!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"articles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"authorName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Harald Uebele"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"7a5f27ce3ef66f895cb666e46ce45e55"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the simply content I need from the JSON response of the &lt;a href="https://github.com/IBM/cloudant-java-sdk"&gt;Cloudant search&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AuthorName&lt;/li&gt;
&lt;li&gt;Title&lt;/li&gt;
&lt;li&gt;URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example in JavaScript format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorName&lt;/span&gt;
&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;
&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java code and imports
&lt;/h3&gt;

&lt;p&gt;Here is the Java code and the imports I used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Imports
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JSON&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.json.Json&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.json.JsonObject&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.json.JsonArray&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.json.JsonReader&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Need to the string input&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.StringReader&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get Cloudant search response value&lt;/li&gt;
&lt;li&gt;Create simple JSON object from search response value&lt;/li&gt;
&lt;li&gt;Extract nested JSON array from simple JSON object&lt;/li&gt;
&lt;li&gt;Get the first JSON object entry in the JSON array&lt;/li&gt;
&lt;li&gt;Extract the nested JSON object from the first JSON object entry&lt;/li&gt;
&lt;li&gt;Extract the relevant data from the nested JSON object.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Cloudant search response value&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--&amp;gt;log: search_response.toString: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;search_response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Create simple json object from response value&lt;/span&gt;
&lt;span class="nc"&gt;JsonReader&lt;/span&gt; &lt;span class="n"&gt;jsonReader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonReader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readObject&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;jsonReader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Extract nested json array from simple json object &lt;/span&gt;
&lt;span class="nc"&gt;JsonArray&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJsonArray&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rows"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--&amp;gt;log: rows: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Get the first json object entry in the json array &lt;/span&gt;
&lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="n"&gt;row_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJsonObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--&amp;gt;log: row_object: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;row_object&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Extract the nested json object from the first json object entry&lt;/span&gt;
&lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJsonObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fields"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--&amp;gt;log:  fields: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Extract the relevant data from the nested json object&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;authorName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"authorName"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"--&amp;gt;log: Author : "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;authorName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" Title: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" url: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Console output for the example
&lt;/h3&gt;

&lt;p&gt;This is an example console output of the running application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;log: search_response.toString: &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"total_rows"&lt;/span&gt;: 1,
  &lt;span class="s2"&gt;"bookmark"&lt;/span&gt;: &lt;span class="s2"&gt;"g2wAAAABaANkAClkYmNvcmVAZGI3LmJtLWNjLXVzLXNvdXRoLTExLmNsb3VkYW50Lm5ldGwAAAACYhAAAABiH____2poAkY_8AAAAAAAAGEAag"&lt;/span&gt;,
  &lt;span class="s2"&gt;"rows"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"fields"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://haralduebele.github.io/2019/02/17/blue-cloud-mirror-dont-open-the-doors/"&lt;/span&gt;,
        &lt;span class="s2"&gt;"customer"&lt;/span&gt;: &lt;span class="s2"&gt;"your-blogs"&lt;/span&gt;,
        &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Blue Cloud Mirror — (Don’t) Open The Doors!"&lt;/span&gt;,
        &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"articles"&lt;/span&gt;,
        &lt;span class="s2"&gt;"authorName"&lt;/span&gt;: &lt;span class="s2"&gt;"Harald Uebele"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"id"&lt;/span&gt;: &lt;span class="s2"&gt;"7a5f27ce3ef66f895cb666e46ce45e55"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;log: rows: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"fields"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;:&lt;span class="s2"&gt;"https://haralduebele.github.io/2019/02/17/blue-cloud-mirror-dont-open-the-doors/"&lt;/span&gt;,&lt;span class="s2"&gt;"customer"&lt;/span&gt;:&lt;span class="s2"&gt;"your-blogs"&lt;/span&gt;,&lt;span class="s2"&gt;"title"&lt;/span&gt;:&lt;span class="s2"&gt;"Blue Cloud Mirror — (Don’t) Open The Doors!"&lt;/span&gt;,&lt;span class="s2"&gt;"type"&lt;/span&gt;:&lt;span class="s2"&gt;"articles"&lt;/span&gt;,&lt;span class="s2"&gt;"authorName"&lt;/span&gt;:&lt;span class="s2"&gt;"Harald Uebele"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;,&lt;span class="s2"&gt;"id"&lt;/span&gt;:&lt;span class="s2"&gt;"7a5f27ce3ef66f895cb666e46ce45e55"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;log: row_object: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"fields"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;:&lt;span class="s2"&gt;"https://haralduebele.github.io/2019/02/17/blue-cloud-mirror-dont-open-the-doors/"&lt;/span&gt;,&lt;span class="s2"&gt;"customer"&lt;/span&gt;:&lt;span class="s2"&gt;"your-blogs"&lt;/span&gt;,&lt;span class="s2"&gt;"title"&lt;/span&gt;:&lt;span class="s2"&gt;"Blue Cloud Mirror — (Don’t) Open The Doors!"&lt;/span&gt;,&lt;span class="s2"&gt;"type"&lt;/span&gt;:&lt;span class="s2"&gt;"articles"&lt;/span&gt;,&lt;span class="s2"&gt;"authorName"&lt;/span&gt;:&lt;span class="s2"&gt;"Harald Uebele"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;,&lt;span class="s2"&gt;"id"&lt;/span&gt;:&lt;span class="s2"&gt;"7a5f27ce3ef66f895cb666e46ce45e55"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;log:  fields: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;:&lt;span class="s2"&gt;"https://haralduebele.github.io/2019/02/17/blue-cloud-mirror-dont-open-the-doors/"&lt;/span&gt;,&lt;span class="s2"&gt;"customer"&lt;/span&gt;:&lt;span class="s2"&gt;"your-blogs"&lt;/span&gt;,&lt;span class="s2"&gt;"title"&lt;/span&gt;:&lt;span class="s2"&gt;"Blue Cloud Mirror — (Don’t) Open The Doors!"&lt;/span&gt;,&lt;span class="s2"&gt;"type"&lt;/span&gt;:&lt;span class="s2"&gt;"articles"&lt;/span&gt;,&lt;span class="s2"&gt;"authorName"&lt;/span&gt;:&lt;span class="s2"&gt;"Harald Uebele"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;log: Author : Harald Uebele Title:  url: https://haralduebele.github.io/2019/02/17/blue-cloud-mirror-dont-open-the-doors/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional useful links :
&lt;/h3&gt;

&lt;p&gt;Here are some additional links, which can give you an additional point of view.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/2591098/how-to-parse-json-in-java"&gt;How to parse JSON in Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.programmersought.com/article/34134601410/"&gt;java parse JSON object (nested json array)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other useful links:
&lt;/h3&gt;

&lt;p&gt;Here are some additional links, which can give you an additional point of view.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/2591098/how-to-parse-json-in-java"&gt;How to parse JSON in Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.programmersought.com/article/34134601410/"&gt;java parse JSON object (nested json array)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Finally it's pretty easy to handle JSON in Java. I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

</description>
      <category>jsonarray</category>
      <category>jsonreader</category>
      <category>java</category>
      <category>cloudant</category>
    </item>
    <item>
      <title>Run a Docker image as a Cloud Foundry App on IBM Cloud</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Wed, 13 May 2020 07:45:21 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/run-a-docker-image-as-a-cloud-foundry-app-on-ibm-cloud-1f75</link>
      <guid>https://dev.to/tsuedbroecker/run-a-docker-image-as-a-cloud-foundry-app-on-ibm-cloud-1f75</guid>
      <description>&lt;p&gt;In that blog post I want to point out an awesome topic: “Run a Docker container image as a Cloud Foundry App on IBM Cloud”&lt;/p&gt;

&lt;p&gt;Rainer Hochecker, Simon Moser and I had an interesting exchange about running a Docker image as a Cloud Foundry App on IBM Cloud.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The advantage with that approach is: you don’t need to instantiate a Kubernetes or OpenShift cluster. You can just run a single Docker image with your single application on IBM Cloud. That can be useful in different situations where you need to control the contents of your application, and the cloud foundry build-pack mechanism maybe restricts you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;IBM offers to run &lt;a href="https://www.ibm.com/cloud/cloud-foundry"&gt;Cloud Foundry Apps on IBM Cloud&lt;/a&gt; and supports a set of &lt;a href="https://cloud.ibm.com/docs/cloud-foundry?topic=cloud-foundry-available_buildpacks"&gt;build packs&lt;/a&gt;.  But, by the fact IBM uses &lt;a href="https://www.cloudfoundry.org"&gt;Cloud Foundry&lt;/a&gt;, you can also upload a Docker image as a Cloud Foundry application, it’s an officially supported feature. Yes there is no documentation related to that topic in the IBM Cloud documentation, but you can apply the Cloud Foundry documentation.&lt;/p&gt;

&lt;p&gt;By the fact IBM uses , you can also try to upload a Docker image as a Cloud Foundry application, currenlty there is no restriction, but it's not offically supported. You not will find any documentation for that on IBM Cloud, but as IBM Cloud uses Cloud Foundry you can apply topics from the &lt;a href="https://docs.cloudfoundry.org/devguide/deploy-apps/push-docker.html"&gt;Cloud Foundry documentation&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;One impact of that situation is, you don’t see the &lt;a href="https://suedbroecker.net/2018/09/06/can-i-use-vcap-when-i-have-a-cloud-foundry-application-and-iam-enabled-service-in-ibm-cloud/"&gt;VCAP variables&lt;/a&gt; and you can’t use the out of the box binding for IBM Cloud services. You have to manage the bindings to your IBM Cloud services by yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  LET’S START WITH A SHORT GUIDE: HOW TO SETUP A CLOUD FOUNDRY APPLICATION USING A DOCKER IMAGE
&lt;/h2&gt;

&lt;p&gt;When you follow the steps, you need to replace the name for the domain, port or hostname with your own settings. We will use in that example the [IBM Cloud Shell(&lt;a href="https://cloud.ibm.com/docs/cloud-shell?topic=cloud-shell-getting-started)"&gt;https://cloud.ibm.com/docs/cloud-shell?topic=cloud-shell-getting-started)&lt;/a&gt;] on IBM Cloud and &lt;a href="https://nodered.org/docs/getting-started/docker"&gt;Node-RED&lt;/a&gt; as our Docker image.&lt;/p&gt;

&lt;h3&gt;
  
  
  The following images shows a simplified overview.
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We push the Docker image and run it as a container in a Cloud Foundry app&lt;/li&gt;
&lt;li&gt;We define a route with a port mapping to access the application from the internet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PnS5REv0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/simplified-overview.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PnS5REv0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/simplified-overview.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  STEP 1: LOGON TO IBM CLOUD AND OPEN THE IBM CLOUD SHELL.
&lt;/h3&gt;

&lt;p&gt;The gif shows how to access the IBM Cloud Shell from the IBM Cloud UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--up_JRb1k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/open-ibmcloud-shell.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--up_JRb1k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/open-ibmcloud-shell.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 2: CHANGE TO THE IBM CLOUD UI TO CREATE A CLOUD FOUNDRY SPACE IN YOUR REGION, IF YOU DON’T HAVE ONE.
&lt;/h3&gt;

&lt;p&gt;The gif shows how to create a new space &lt;strong&gt;dev&lt;/strong&gt;, in the existing organization &lt;strong&gt;thomas.suedbroecker&lt;/strong&gt; , in the region &lt;strong&gt;Germany&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sy_hwLPo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/create-cloud-foundry-space.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sy_hwLPo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/create-cloud-foundry-space.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  STEP 3: GO BACK TO THE IBM CLOUD SHELL AND SET THE &lt;a href="https://cloud.ibm.com/docs/cloud-foundry-public?topic=cloud-foundry-public-endpoints"&gt;CLOUD FOUNDRY ENDPOINT&lt;/a&gt;, ORGANIZATION AND SPACE. I MY CASE I USED FOLLOWING VALUES.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Endpoint: &lt;code&gt;api.eu-de.cf.cloud.ibm.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Organization: &lt;code&gt;thomas.suedbroecker&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Space: &lt;code&gt;dev&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Resource group: &lt;code&gt;Default&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud target &lt;span class="nt"&gt;--cf-api&lt;/span&gt; api.eu-de.cf.cloud.ibm.com &lt;span class="nt"&gt;-o&lt;/span&gt; thomas.suedbroecker &lt;span class="nt"&gt;-s&lt;/span&gt; dev &lt;span class="nt"&gt;-g&lt;/span&gt; Default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 4: VERIFY YOUR CLOUD FOUNDRY SETTINGS ON IBM CLOUD (IBM CLOUD DOCUMENTATION)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 5: PUSH A DOCKER IMAGE FROM A CONTAINER REGISTRY.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;node-red&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Image: &lt;code&gt;node-red-docker:v10&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the IBM Cloud Shell you need to install the Cloud Foundry API with &lt;code&gt;ibmcloud cf install&lt;/code&gt; and verify the API version &lt;code&gt;ibmcloud cf -v&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud cf push node-red &lt;span class="nt"&gt;--docker-image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;docker.io/nodered/node-red-docker:v10  &lt;span class="nt"&gt;--no-start&lt;/span&gt; &lt;span class="nt"&gt;--no-route&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Of course you can also use a private container image registry like the &lt;a href="https://cloud.ibm.com/docs/Registry?topic=registry-registry_overview"&gt;IBM Cloud Image Container Registry&lt;/a&gt; , if you want.&lt;/p&gt;

&lt;p&gt;In this case, you’d need understand the &lt;a href="https://docs.cloudfoundry.org/devguide/deploy-apps/push-docker.html"&gt;Cloud Foundry documentation&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CF_DOCKER_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR-PASSWORD cf push APP-NAME &lt;span class="nt"&gt;--docker-image&lt;/span&gt; REPO/IMAGE:TAG &lt;span class="nt"&gt;--docker-username&lt;/span&gt; USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://cloud.ibm.com/docs/Registry?topic=registry-registry_overview"&gt;IBM Cloud Image Container Registry&lt;/a&gt; also contains the &lt;a href="https://cloud.ibm.com/docs/Registry?topic=registry-registry_access#registry_access_apikey_auth_other_example_cf"&gt;documentation how to do this for Cloud Foundry&lt;/a&gt;, here is the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CF_DOCKER_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;apikey&amp;gt;
ibmcloud cf push appname &lt;span class="nt"&gt;-o&lt;/span&gt; &amp;lt;region&amp;gt;.icr.io/&amp;lt;namespace&amp;gt;/&amp;lt;image_repo&amp;gt; &lt;span class="nt"&gt;--docker-username&lt;/span&gt; iamapikey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 6: GET THE GUID FROM THE CLOUD FOUNDRY APP INSTANCE. &lt;code&gt;A_GUID=APPLICATION GUID&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;A_GUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ibmcloud cf app node-red &lt;span class="nt"&gt;--guid&lt;/span&gt;|awk &lt;span class="s1"&gt;'/[0-9]/{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$A_GUID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 7:  SET THE PORT TO ACCESS THE APPLICATION INSIDE THE DOCKER CONTAINER OF THE CLOUD FOUNDRY APPLICATION.
&lt;/h3&gt;

&lt;p&gt;The port information you get from the Docker image description.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PORT: &lt;code&gt;1880&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud cf curl /v2/apps/&lt;span class="nv"&gt;$A_GUID&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"ports": [1880]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 8: IN THIS STEP WE CREATE A ROUTE TO THE CLOUD FOUNDRY APP, TO ACCESS LATER THE RUNNING APPLICATION FROM THE INTERNET.
&lt;/h3&gt;

&lt;p&gt;The Domain name eu-de.mybluemix.net depends on the region you create the Cloud Foundry App. In that sample we using eu-de. (&lt;a href="https://cloud.ibm.com/docs/overview?topic=overview-locations&amp;amp;locale=en"&gt;see IBM Cloud documentation&lt;/a&gt; )&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain: &lt;code&gt;eu-de.mybluemix.net&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Hostname: &lt;code&gt;node-red-tsuedbroecker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud cf create-route dev eu-de.mybluemix.net &lt;span class="nt"&gt;--hostname&lt;/span&gt; node-red-tsuedbroecker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 9: WE NEED TO MAP THE ROUTE TO THE CLOUD FOUNDRY APP , TO ACCESS THE RUNNING APPLICATION FROM THE INTERNET.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Application name: &lt;code&gt;node-red&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Domain: &lt;code&gt;eu-de.mybluemix.net&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Hostname: &lt;code&gt;node-red-tsuedbroecker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud cf map-route node-red eu-de.mybluemix.net &lt;span class="nt"&gt;--hostname&lt;/span&gt; node-red-tsuedbroecker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now we extract the GUID for the created route. (&lt;code&gt;R_GUID=route GUID&lt;/code&gt;)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;R_GUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ibmcloud cf curl &lt;span class="s2"&gt;"/v2/routes?q=host:node-red-tsuedbroecker"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'s|.*"guid": "\([^"]*\)".*|\1|p'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$R_GUID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 10: NOW WE EXTRACT THE GUID FOR THE NEWLY CREATED ROUTE. (&lt;code&gt;R_GUID=ROUTE GUID&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud cf curl /v2/route_mappings &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"app_guid": "'&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$A_GUID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s1"&gt;'", "route_guid": "'&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$R_GUID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s1"&gt;'", "app_port": 1880}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 11: WE NEED TO UPDATE THE ROUTE MAPPINGS WITH OUR GUID’S. (&lt;code&gt;R_GUID&lt;/code&gt; AND &lt;code&gt;A_GUID&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud cf curl /v2/route_mappings &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"app_guid": "'&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$A_GUID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s1"&gt;'", "route_guid": "'&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$R_GUID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s1"&gt;'", "app_port": 1880}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 12: START THE CLOUD FOUNDRY APPLICATION.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ibmcloud cf start node-red
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  STEP 13: VISIT THE CLOUD FOUNDRY APP IN THE IBM CLOUD UI AND INSPECT THE POSSIBILITIES.
&lt;/h3&gt;

&lt;p&gt;In the gif you see, there is no build pack information and there are no environment variables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nx4x1phg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/open-cloud-foundry-app.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nx4x1phg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/open-cloud-foundry-app.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  STEP 14: NOW OPEN THE APPLICATION URL AND USE THE RUNNING NODE-RED INSTANCE.
&lt;/h3&gt;

&lt;p&gt;The gif shows, how to access the application URL inside the Cloud Foundry App.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QbV_wrO8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/visit-cloud-foundry-application.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QbV_wrO8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/05/visit-cloud-foundry-application.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

</description>
      <category>ibmcloud</category>
      <category>cloudfoundry</category>
      <category>ibmdeveloper</category>
      <category>docker</category>
    </item>
    <item>
      <title>A Node-RED Twitter-follower-flow</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Thu, 26 Mar 2020 09:18:46 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/a-node-red-twitter-follower-flow-3o1l</link>
      <guid>https://dev.to/tsuedbroecker/a-node-red-twitter-follower-flow-3o1l</guid>
      <description>&lt;p&gt;In my last blog post I did an introduction "how use the starter kit for Node-RED on IBM Cloud" and in that new blog post I want to highlight the Node-RED Twitter-follower-flow I developed as an introduction to different topics I frequently face at hackathons. Here is the link to the &lt;a href="https://github.com/thomassuedbroecker/node-red-twitter-follower"&gt;"Twitter-follower-flow" GitHub project&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Node-RED is very good for prototyping, that is the reason why it is often used in hackathons. If you are new to Node-RED and you start to develop a Node-RED flow, you normally have following challenges: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;How to ...&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;... define own &lt;strong&gt;REST endpoints&lt;/strong&gt; to encapsulate an external API?&lt;/li&gt;
&lt;li&gt;... automate the &lt;strong&gt;authentication&lt;/strong&gt; to that external API?&lt;/li&gt;
&lt;li&gt;... &lt;strong&gt;extract data&lt;/strong&gt; from the external API?&lt;/li&gt;
&lt;li&gt;... &lt;strong&gt;customize data&lt;/strong&gt; and &lt;strong&gt;CRUD&lt;/strong&gt; with databases? &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Node-RED flow of that project has the objective to provide an (little advanced) introduction to the first three topics above.&lt;br&gt;
The CRUD (Create, Read, Update, Delete) topic is not covered here. Visit that &lt;a href="https://github.com/gitjps/Node-RED-Cloudant-CRUD"&gt;CRUD example&lt;/a&gt; for more information.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The "Twitter-follower-flow" example ...&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;... uses open technologies (Node-RED is a Project of the &lt;a href="https://openjsf.org/"&gt;OpenJS foundation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;... creates no additional costs &lt;/li&gt;
&lt;li&gt;Uses a free runtime on &lt;a href="https://ibm.biz/BdqZTm"&gt;IBM Cloud&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Uses the free &lt;a href="https://developer.twitter.com/en"&gt;Twitter developer API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;... has following technical level:&lt;/li&gt;
&lt;li&gt;Beginner to intermediate &lt;/li&gt;
&lt;li&gt;Needs a basic knowledge of JavaScript and REST&lt;/li&gt;
&lt;li&gt;... takes 30 - 45 min to setup the example from scratch&lt;/li&gt;
&lt;li&gt;Register on IBM Cloud &lt;/li&gt;
&lt;li&gt;Create a Node-RED instance on IBM Cloud&lt;/li&gt;
&lt;li&gt;Register at Twitter for a developer API Account &lt;/li&gt;
&lt;li&gt;Copy the existing Node-RED flow&lt;/li&gt;
&lt;li&gt;Configure the flow&lt;/li&gt;
&lt;li&gt;Run the flow&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The YouTube video gives a 13 min introduction to the &lt;em&gt;Twitter-follower-flow&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4HvBya4Zhn8"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TMeRa9LX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://img.youtube.com/vi/4HvBya4Zhn8/0.jpg" alt="Introduction to the Node-RED flow"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. The UseCase
&lt;/h2&gt;

&lt;p&gt;The UseCase &lt;strong&gt;&lt;em&gt;"Extract the twitter follower list"&lt;/em&gt;&lt;/strong&gt; addresses three topics listed above in the Node-RED &lt;em&gt;Twitter-follower-flow&lt;/em&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define own &lt;strong&gt;REST endpoints&lt;/strong&gt; to encapsulate Twitter developer API calls.&lt;/li&gt;
&lt;li&gt;Automate the &lt;strong&gt;authentication&lt;/strong&gt; the two step authentication of the Twitter developer API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract data&lt;/strong&gt; from the Twitter follower list and build an own list.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  2. Topics related to the Node-RED usage
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;Twitter-follower-flow&lt;/em&gt; is an concrete example of following topics ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;... the &lt;strong&gt;implementation&lt;/strong&gt; of Node-RED REST endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Create a very basic authentication to protect each Node-RED endpoint&lt;/li&gt;
&lt;li&gt;Realize the two step authentication &lt;em&gt;(also known as two-factor authentication)&lt;/em&gt; to access the Twitter developer API:
    1. Basic authentication with a key and secret to request a bearer token from Twitter
    2. Use the bearer token for authentication to use the Twitter API &lt;/li&gt;
&lt;li&gt;Get the follower list from Twitter using the bearer token&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;... the &lt;strong&gt;usage&lt;/strong&gt; of the implemented REST endpoints to automate following sequence to get the Twitter follower.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Get the &lt;strong&gt;authorization&lt;/strong&gt; bearer token from Twitter to access the Twitter API&lt;/li&gt;
&lt;li&gt;Get all followers from Twitter using a &lt;strong&gt;bearer token&lt;/strong&gt; ( &lt;em&gt;the challenge is: how implement the paging thought the followers list from Twitter&lt;/em&gt; )&lt;/li&gt;
&lt;li&gt;Extract the names of the follower from the follower list&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;... the &lt;strong&gt;work&lt;/strong&gt; with following Nodes in the Node-RED &lt;em&gt;Twitter-follower-flow&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Function &lt;em&gt;(Do small programming in javascript.)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Inject &lt;em&gt;(Start a flow in Node-RED.)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;HTTP &lt;em&gt;in&lt;/em&gt; &lt;em&gt;(Creates an HTTP end-point for creating web services.)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;HTTP &lt;em&gt;request&lt;/em&gt; &lt;em&gt;(Sends HTTP requests and returns the response.)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;HTTP &lt;em&gt;response&lt;/em&gt; &lt;em&gt;(Sends responses back to requests received from an HTTP Input node.)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Base64 (A function that converts the chosen property (default msg.payload) to and from base64 format.)&lt;/li&gt;
&lt;li&gt;JSON &lt;em&gt;(Converts between a JSON string and its JavaScript object representation, in either direction.)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Switch &lt;em&gt;(Define a decision how to route the payload. Route messages based on their property values or sequence position.)&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;... the &lt;strong&gt;usage&lt;/strong&gt; of flow variables to exchange values between functions in the &lt;em&gt;Twitter-follower-flow&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  3. Setup the Twitter-follower-flow example
&lt;/h2&gt;

&lt;p&gt;That section contains six major steps to setup the &lt;em&gt;Twitter-follower-flow&lt;/em&gt; example on IBM Cloud. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setup Twitter developer application&lt;/li&gt;
&lt;li&gt;Create a Node-RED instance on IBM Cloud&lt;/li&gt;
&lt;li&gt;Install a additional Node to the Node-RED instance&lt;/li&gt;
&lt;li&gt;Import the Node-RED flow&lt;/li&gt;
&lt;li&gt;Configure the Node-RED flow&lt;/li&gt;
&lt;li&gt;Introduction to the Node-RED flow (13 min video)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the image you see the full flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5tSQ5wtO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/twitter-follower-flow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5tSQ5wtO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/twitter-follower-flow.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 1: Setup Twitter developer application
&lt;/h3&gt;

&lt;p&gt;You need a Twitter account and a Twitter developer application.&lt;br&gt;
With your Twitter account can register for the &lt;strong&gt;Twitter developer API&lt;/strong&gt; and create a Twitter developer application. That application provides the needed credentials to access the Twitter API, which is used in that example.&lt;/p&gt;
&lt;h4&gt;
  
  
  a. &lt;a href="https://developer.twitter.com/en/apps"&gt;Link to add a Twitter developer application&lt;/a&gt;.
&lt;/h4&gt;

&lt;p&gt;Here is a blog post with an example how to setup a Twitter application: &lt;a href="https://iag.me/socialmedia/how-to-create-a-twitter-app-in-8-easy-steps/"&gt;How to Register a Twitter App in 8 Easy Steps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a preview, how to get the credentials from your Twitter developer application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g0qAtFPD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/configure-twitter-auth.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g0qAtFPD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/configure-twitter-auth.png%3Fw%3D1024" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list"&gt;b. Twitter API documentation &lt;code&gt;get-followers-list&lt;/code&gt;&lt;/a&gt;
&lt;/h4&gt;


&lt;h3&gt;
  
  
  Step 2: Create a Node-RED instance on IBM Cloud
&lt;/h3&gt;

&lt;p&gt;We use a Node-RED instance on IBM Cloud with an IBM Lite Account.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an IBM Cloud Lite Account just by register &lt;a href="https://ibm.biz/Bdzr7G"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Follow the steps in my blog post to &lt;a href="https://suedbroecker.net/2020/03/09/a-short-introduction-of-the-node-red-starter-kit-on-ibm-cloud-for-hackathons/"&gt;setup a Node-RED instance on IBM Cloud&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;
  
  
  Step 3: Install a additional Node to the Node-RED instance
&lt;/h3&gt;

&lt;p&gt;Install the &lt;code&gt;node-red-node-base64&lt;/code&gt; &lt;strong&gt;Node&lt;/strong&gt; to the Node-RED instance. The gif shows the installation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nAYJbJeY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/install-node.gif%3Fw%3D617%26zoom%3D2" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nAYJbJeY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/install-node.gif%3Fw%3D617%26zoom%3D2" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 4: Import the Node-RED flow
&lt;/h3&gt;

&lt;p&gt;Import the flow from the &lt;a href="//flows/flows.json"&gt;flow.json&lt;/a&gt; file in &lt;code&gt;flows&lt;/code&gt; folder of that project. The gif below shows how to import the flow in the Node-RED.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ey5X1BRM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/import-flow-1.gif%3Fw%3D617%26zoom%3D2" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ey5X1BRM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/import-flow-1.gif%3Fw%3D617%26zoom%3D2" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 5: Configure the Node-RED flow
&lt;/h3&gt;

&lt;p&gt;We need to configure ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;... the Twitter authentication &lt;/li&gt;
&lt;li&gt;... the Twitter username&lt;/li&gt;
&lt;li&gt;... the Node-RED URL &lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;
  
  
  a. Set Twitter API key and secret
&lt;/h4&gt;

&lt;p&gt;Insert the values for the &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;secret&lt;/code&gt; of the Twitter API credentials in the &lt;em&gt;function&lt;/em&gt; &lt;code&gt;set user and secret&lt;/code&gt;. The image shows an example, where you get the credentials information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g0qAtFPD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/configure-twitter-auth.png%3Fw%3D1024" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g0qAtFPD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/configure-twitter-auth.png%3Fw%3D1024" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The mapping for the Node-RED flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;user&lt;/code&gt; = &lt;em&gt;Twitter API&lt;/em&gt; key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;secret&lt;/code&gt; = &lt;em&gt;Twitter API&lt;/em&gt; secret key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nodereduser&lt;/code&gt; = Your own definition to secure the Node-RED REST Endpoints&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;noderedpassword&lt;/code&gt; = Your own definition to secure the Node-RED REST Endpoints&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the source code for the &lt;code&gt;set user and secret&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SECRET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nodereduser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;noderedpassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notreallysecure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nodereduser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nodereduser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noderedpassword&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;noderedpassword&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  b. Set Twitter username
&lt;/h4&gt;

&lt;p&gt;Define &lt;em&gt;"username display name"&lt;/em&gt; you want get the follower list from, by inserting &lt;br&gt;
in function &lt;code&gt;set_basic_auth&lt;/code&gt; the &lt;code&gt;"YOUR_TWITTER_DISPLAY_NAME"&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Set basic auth&lt;/span&gt;
&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Init parameters:&lt;/span&gt;
&lt;span class="c1"&gt;// For more information visit get-followers-list:&lt;/span&gt;
&lt;span class="c1"&gt;// https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list&lt;/span&gt;
&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitterCursor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitterResultCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitterSN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_TWITTER_DISPLAY_NAME&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodereduser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nodereduser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;noderedpassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noderedpassword&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h4&gt;
  
  
  c. Set Node-RED URL
&lt;/h4&gt;

&lt;p&gt;Configure the HTTP request nodes. Replace the &lt;code&gt;https://node-red-my-hackathon.mybluemix.net&lt;/code&gt; URL with your URL in each &lt;em&gt;HTTP request node&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getTwitterFollower-Indicrect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getTwitterToken-Indicrect&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The image shows how you enter the URL in the &lt;em&gt;HTTP requests node&lt;/em&gt; &lt;code&gt;getTwitterFollower-Indicrect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zikOvOi9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/configure-http-node.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zikOvOi9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/configure-http-node.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That image shows &lt;em&gt;HTTP requests nodes&lt;/em&gt; to be change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GHxFQ10_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/request-automation-followers-setup.png%3Fw%3D2196" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GHxFQ10_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/request-automation-followers-setup.png%3Fw%3D2196" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 6: Introduction to the Node-RED flow
&lt;/h3&gt;

&lt;p&gt;The YouTube video gives a 13 min introduction to the &lt;em&gt;Twitter-follower-flow&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4HvBya4Zhn8"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TMeRa9LX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://img.youtube.com/vi/4HvBya4Zhn8/0.jpg" alt="Introduction to the Node-RED flow"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

&lt;p&gt;&lt;a href="https://suedbroecker.net/2020/03/26/a-node-red-twitter-follower-flow/"&gt;Blog post also at www.suedbroecker.net&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nodered</category>
      <category>javascript</category>
      <category>twitterapi</category>
      <category>ibmcloud</category>
    </item>
    <item>
      <title>Write and execute a JUnit test for a Java microservice based on MicroProfile and run both in the OpenLiberty development mode</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Tue, 17 Mar 2020 17:28:02 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/write-and-execute-a-junit-test-for-a-java-microservice-based-on-microprofile-and-run-both-in-the-openliberty-development-mode-47g4</link>
      <guid>https://dev.to/tsuedbroecker/write-and-execute-a-junit-test-for-a-java-microservice-based-on-microprofile-and-run-both-in-the-openliberty-development-mode-47g4</guid>
      <description>&lt;p&gt;That post has the focus on: how to develop a JUnit test for the Authors microservice from the Cloud Native Starter example and run both the Authors microservice and the JUnit test on OpenLiberty in the development mode.&lt;/p&gt;

&lt;p&gt;That post hasn’t the objective to be a blueprint or a ‘how to guide’ for writing JUnit tests,  JUnit test organization, test strategy and so on. The objective is to get technically started along one concrete microservice example from the Cloud Native Starter project.&lt;/p&gt;

&lt;p&gt;The Authors microservice has one RESTful api endpoint called getAuthor. The endpoint provides one parameter for the Author name. The endpoint returns Author data in a JSON format.&lt;/p&gt;

&lt;p&gt;Keep the end in mind: The gif shows a sample JUnit test execution for the Author microservice using OpenLiberty in the Visual Studio Code editor:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/LXVGyHgBibY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Let's start with: What do we need and how do we realize the implementation?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We need to ..&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;invoke&lt;/em&gt; the REST endpoint of the Authors microservice with a REST Client.
  * &lt;em&gt;transform&lt;/em&gt; the JSON response of the REST endpoint to an Author data class
  * &lt;em&gt;handle&lt;/em&gt; different values to invoke the REST Endpoint parameter for the Author name to run tests with variations of the Author name.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;compare&lt;/em&gt; the actual response value with an expected value and document the result.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;And how to ..&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;setup a JUnit test for the development mode of the OpenLiberty server?&lt;/li&gt;
&lt;li&gt;convert JSON Data from a String to an Author Java instance with JSON-B?&lt;/li&gt;
&lt;li&gt;define a REST Client?&lt;/li&gt;
&lt;li&gt;configure a parameterized JUnit test?&lt;/li&gt;
&lt;li&gt;write the concrete parameterized JUnit test?&lt;/li&gt;
&lt;li&gt;execute the JUnit test?&lt;/li&gt;
&lt;li&gt;find the test results?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are the tools and frameworks?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;That are the Tools and frameworks of the sample project:

&lt;ul&gt;
&lt;li&gt;IDE: Visual Studio Code with the Java Development Extension&lt;/li&gt;
&lt;li&gt;Server: Open Liberty&lt;/li&gt;
&lt;li&gt;Frameworks: Eclipse MicroProfile&lt;/li&gt;
&lt;li&gt;Java project organization: Apache Maven&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. How to setup a JUnit test for the development mode of the OpenLiberty server?
&lt;/h2&gt;

&lt;p&gt;To setup and run JUnit tests with the OpenLiberty server in the development mode, we have to provide a test folder in the src folder of our Java project. The image below shows the folders of my sample project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7fK9Dcut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pbvvvyg7ixdh9im0qmil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7fK9Dcut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pbvvvyg7ixdh9im0qmil.png" alt="Folder structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Content of the &lt;code&gt;com.ibm.authors&lt;/code&gt; package for the Authors microservice
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AuthorsApplication&lt;/code&gt; class represents the JAX-RS RESTful web application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Author&lt;/code&gt; class represents the data structure we use for the Author.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GetAuthor&lt;/code&gt; class represents the REST API Endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HealthEndpoint&lt;/code&gt; class represents the support of readiness probes for Kubernetes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Content of the &lt;code&gt;authortests&lt;/code&gt; package for the JUnit test
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AuthorJsonbAdapter&lt;/code&gt; class represents JSON-B adapter for a JSON-B mapping configuration.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AuthorTestClient&lt;/code&gt; class represents the REST Client of the Authors microservice.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Test_GetAuthors&lt;/code&gt; class represents the JUnit test which will be executed as the parameterized test run.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  1.2 The &lt;code&gt;pom.xml&lt;/code&gt; configuration for the JUnit and OpenLiberty
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;junit-jupiter-api&lt;/code&gt; and the &lt;code&gt;junit-jupiter-engine&lt;/code&gt; are the basics for the Unit tests. With the &lt;code&gt;junit-jupiter-params&lt;/code&gt; depencency we can define later a parameterized test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- JUnit Test --&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter-api&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.6.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter-engine&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.6.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter-params&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.6.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt; 
&lt;span class="c"&gt;&amp;lt;!-- JUnit Test --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Build plugins

&lt;ul&gt;
&lt;li&gt;JUnit&lt;/li&gt;
&lt;li&gt;&lt;code&gt;maven-surefire-plugin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maven-failsafe-plugin&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- JUNIT --&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-surefire-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.22.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-failsafe-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.22.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt; 
&lt;span class="c"&gt;&amp;lt;!-- JUNIT --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;OpenLiberty

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;liberty-maven-plugin&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Enable liberty-maven plugin --&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.openliberty.tools&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;liberty-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt; 
 &lt;span class="c"&gt;&amp;lt;!-- libertyMavenConfiguration --&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;serverName&amp;gt;&lt;/span&gt;authorsDevJUnitServer&lt;span class="nt"&gt;&amp;lt;/serverName&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;configFile&amp;gt;&lt;/span&gt;liberty/server.xml&lt;span class="nt"&gt;&amp;lt;/configFile&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt; 
 &lt;span class="c"&gt;&amp;lt;!-- libertyMavenConfiguration --&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt; 
&lt;span class="c"&gt;&amp;lt;!-- Enable liberty-maven-plugin --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. How to convert JSON Data from a String to an Author Java instance with JSON-B?
&lt;/h2&gt;

&lt;p&gt;The response of our endpoint &lt;code&gt;getauthor&lt;/code&gt; is a text in a JSON format, but we want use that data in an instance of an Author class.&lt;/p&gt;

&lt;p&gt;In JSON-B we define a &lt;code&gt;JsonbAdapter&lt;/code&gt; which does the conversion from JSON to an &lt;code&gt;Author&lt;/code&gt; class instance. Therefor we &lt;code&gt;@Override&lt;/code&gt; the operations &lt;code&gt;adaptToJson&lt;/code&gt; and &lt;code&gt;adaptFromJson&lt;/code&gt;. The operation &lt;code&gt;adaptFromJson&lt;/code&gt; defines how to create an Author object from a JsonObject.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Author data class &lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.ibm.authors.Author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="c1"&gt;// JSON-binding &lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.json.bind.adapter.JsonbAdapter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.json.JsonObject&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.json.Json&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthorJsonbAdapter&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;JsonbAdapter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; 
  &lt;span class="nd"&gt;@Override&lt;/span&gt; 
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="nf"&gt;adaptFromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="n"&gt;jsonObject&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
   &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
   &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setBlog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"blog"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; 
   &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; 
   &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTwitter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"twitter"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; 
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
  &lt;span class="o"&gt;}&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the following code of the Test_GetAuthors class you see how to utilize the &lt;code&gt;AuthorJsonbAdapter&lt;/code&gt; to create a new JSON-B configuration. That JSON-B configuration is used to create a JSON-B object. The JSON-B object contains the implemented operation fromJson and knows how to create an instance of an &lt;code&gt;Author&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;JsonbConfig&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JsonbConfig&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;withAdapters&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AuthorJsonbAdapter&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; 
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Jsonb&lt;/span&gt; &lt;span class="n"&gt;jsonb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonbBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="n"&gt;author_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. How to define a REST Client?
&lt;/h2&gt;

&lt;p&gt;The following code shows the interface class &lt;code&gt;AuthorTestClient&lt;/code&gt;. That class contains the REST Client interface definition for the REST Endpoint of the Authors microservice. With the usage of the MicroProfile annotation &lt;code&gt;@RegisterRestClient&lt;/code&gt; a RESTful Client will be created, when the interface is used in the JUnit test.&lt;/p&gt;

&lt;p&gt;The expected return value of getAuthors response type is defined as a String.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.ws.rs.Path&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.ws.rs.GET&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.ws.rs.Produces&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.ws.rs.core.MediaType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.ws.rs.QueryParam&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.eclipse.microprofile.rest.client.inject.RegisterRestClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/getauthor"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
&lt;span class="nd"&gt;@RegisterRestClient&lt;/span&gt; 
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;AuthorTestClient&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
  &lt;span class="nd"&gt;@GET&lt;/span&gt; 
  &lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@QueryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. How to configure the parameterized JUnit test?
&lt;/h2&gt;

&lt;p&gt;The class &lt;code&gt;Test_GetAuthors&lt;/code&gt; implements the JUnit test in the operation &lt;code&gt;testGetAuthor&lt;/code&gt;. The test is defined as a &lt;code&gt;ParameterizedTest&lt;/code&gt; and can be repeated with given values from a &lt;code&gt;CsvSource&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ParameterizedTest&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here you see the annotation &lt;code&gt;@ParameterizedTest&lt;/code&gt; and the configuration of name.&lt;br&gt;
The name contains the count of the parameters, that test has two parameters and can be repeated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ParameterizedTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{index} =&amp;gt; name=''{0},{1}''"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The concrete test implementation itself happens in the operation &lt;code&gt;testGetAuthor&lt;/code&gt;. The operation contains the names for the parameters which were defined before. These parameters we will use in the test implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testGetAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;authorName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;expectedResult&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details visit the &lt;a href="https://junit.org/junit5/docs/5.0.1/api/org/junit/jupiter/params/ParameterizedTest.html"&gt;JUnit documentation&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CsvSource&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The annotation &lt;code&gt;@CsvSource&lt;/code&gt; contains a comma separated list of values for the test execution. The values are in order to fit to parameters &lt;code&gt;nameAuthor&lt;/code&gt; (sample value: Thomas) and &lt;code&gt;expectedResult&lt;/code&gt; (sample value: Thomas Suedbroecker).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@CsvSource&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"Thomas,Thomas Suedbroecker"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
            &lt;span class="s"&gt;"Niklas,Niklas Heidloff"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
            &lt;span class="s"&gt;"Michael,Michael Heinrich"&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details visit the &lt;a href="https://junit.org/junit5/docs/5.0.3/api/org/junit/jupiter/params/provider/CsvSource.html"&gt;JUnit documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. How to write the concrete parameterized JUnit test?
&lt;/h2&gt;




&lt;h3&gt;
  
  
  Step 1: Create a REST Client
&lt;/h3&gt;

&lt;p&gt;To invoke our REST Endpoint &lt;code&gt;getauthor&lt;/code&gt; of the Authors microservice we use the &lt;code&gt;RestClientBuilder&lt;/code&gt; from MicroProfile to create our REST Client.&lt;/p&gt;

&lt;p&gt;We use our defined MicroProfile RestClient Interface &lt;code&gt;AuthorTestClient.class&lt;/code&gt; and the &lt;code&gt;RestClientBuilder&lt;/code&gt; will create for us an object instance for the &lt;code&gt;AuthorTestClient&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;AuthorTestClient&lt;/span&gt; &lt;span class="n"&gt;authorClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RestClientBuilder&lt;/span&gt;
 &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;baseUri&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseURI&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
 &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AuthorTestClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 2: Invoke the REST Client
&lt;/h3&gt;

&lt;p&gt;Now we invoke the REST Client and we use our test parameter nameAuthor as input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;authorClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameAuthor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3: Convert the response to a Author data object
&lt;/h3&gt;

&lt;p&gt;Once more the usage of JSON-B.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;JsonbConfig&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JsonbConfig&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;withAdapters&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AuthorJsonbAdapter&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; 
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Jsonb&lt;/span&gt; &lt;span class="n"&gt;jsonb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonbBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="n"&gt;author_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 4: Compare the actual value of response with the expected value from the test parameter
&lt;/h3&gt;

&lt;p&gt;To compare the actual and expected value we use the assertEquals from JUnit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expectedResult&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author_json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a the values aren't equal, assertEquals throws a &lt;code&gt;AssertionFailedError&lt;/code&gt; exception and document the error in target/surefire-reports/TEST-authortests.Test_GetAuthors.txt file.&lt;/p&gt;

&lt;p&gt;Here is an sample output of the &lt;code&gt;TEST-authortests.Test_GetAuthors.txt&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;org.opentest4j.AssertionFailedError: expected: &amp;lt;Michael Heinrich&amp;gt; but was: &amp;lt;Niklas Heidloff&amp;gt; at authortests.Test_GetAuthors.testGetAuthor&lt;span class="o"&gt;(&lt;/span&gt;Test_GetAuthors.java:60&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details see in the &lt;a href="https://junit.org/junit4/javadoc/latest/org/junit/Assert.html"&gt;JUnit documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8DkLVyOr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w384rh08iu1g2kfcpxma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8DkLVyOr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w384rh08iu1g2kfcpxma.png" alt="test results"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. How to execute the JUnit test?
&lt;/h2&gt;

&lt;p&gt;With the usage of the &lt;code&gt;liberty-maven-plugin&lt;/code&gt; we can start the OpenLiberty server in the development mode with following Maven command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mvn liberty:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we just press return.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;INFO] Press the Enter key to run tests on demand.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. How to find the test results?
&lt;/h2&gt;

&lt;p&gt;The test results are stored in the &lt;code&gt;target/surefire-reports/*&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Y2NHyErZ5Ns"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Here are additional useful blog posts, videos or manuals
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MicroProfile RestClient&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.tomitribe.com/blog/overview-of-microprofile-rest-client/"&gt;Overview MicroProfile REST Client (Tomitribe)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;JUnit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/OpenLiberty/open-liberty/wiki/Unit-Tests"&gt;Setup Unit Tests in OpenLiberty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://junit.org/junit5/docs/5.1.0-M1/user-guide/#dependency-diagram"&gt;JUnit User Guide dependencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.adam-bien.com/roller/abien/entry/using_microprofile_rest_client_for"&gt;Using microprofile rest client for system testing (Adam-Bien)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.petrikainulainen.net/programming/testing/junit-5-tutorial-writing-parameterized-tests/"&gt;Unit 5 tutorial Writing parameterized tests (Petri Kainulainen)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=JPctzdfxeXo"&gt;Create effective tests or create excuses — testing the Java EE way (Sebastian Daschner)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://junit.org/junit5/docs/current/user-guide/#running-tests-ide-vscode"&gt;JUnit user-guide running tests is vscode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Jsonb&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://rieckpil.de/whatis-json-binding-json-b/"&gt;What is JSON binding with JSON-B (RIECKPIL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.java67.com/2016/10/3-ways-to-convert-string-to-json-object-in-java.html"&gt;3 ways to convert String to JSON object in Java?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

&lt;p&gt;PS:  My GitHub project with the source code is &lt;a href="https://github.com/thomassuedbroecker/local-dev-junit"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://suedbroecker.net/2020/03/04/write-and-execute-a-junit-test-for-a-java-microservice-based-on-mircoprofile-and-run-both-in-the-openliberty-development-mode/"&gt;Resource on www.suedbroecker.net&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>junit</category>
      <category>visualstudiocode</category>
      <category>microprofile</category>
    </item>
    <item>
      <title>A short introduction of the Node-RED Starter kit on IBM Cloud for Hackathons</title>
      <dc:creator>Thomas Südbröcker</dc:creator>
      <pubDate>Tue, 17 Mar 2020 15:06:30 +0000</pubDate>
      <link>https://dev.to/tsuedbroecker/a-short-introduction-of-the-node-red-starter-kit-on-ibm-cloud-for-hackathons-187c</link>
      <guid>https://dev.to/tsuedbroecker/a-short-introduction-of-the-node-red-starter-kit-on-ibm-cloud-for-hackathons-187c</guid>
      <description>&lt;p&gt;In that post I want to highlight the new way of the instantiation of a Node-RED application on  IBM Cloud with the Node-RED Starter kit. From my perspective Node-RED is a very helpful tool at hackathons. &lt;a href="https://suedbroecker.net/2019/02/11/how-to-prepare-for-a-hackathon-with-ibm-cloud/"&gt;(just take a look in my blog post  How to prepare for a Hackathon with IBM Cloud?)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Node-RED instantiation has changed and with the Node-RED Starter kit we can take the advantage of the capabilities of IBM Cloud to control the build, deployment and execution of the Node-RED application and we setup automatically all  development tools to work effectively in a small development team in our hackathon.&lt;/p&gt;

&lt;p&gt;I want to provide a short walkthrough from my perspective and created a 13 min YouTube video in addition to that blog post.&lt;a href="https://suedbroecker.net/2019/02/11/how-to-prepare-for-a-hackathon-with-ibm-cloud/"&gt;(just take a look in my blog post  How to prepare for a Hackathon with IBM Cloud?)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/eVHm9UIsbuI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Let's get started with the description of the Node-RED Starter kit in IBM Cloud.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“This starter kit provides a pre-configured Node-RED application, including a Cloudant service to store the application flow configuration. Add services, generate and download the code, use the IBM Cloud Developer Tools CLI to run and debug locally, then deploy to Cloud Foundry or a DevOps Pipeline.“&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With that Node-RED Starter kit we setup all needed development tools to work effectively in a small team at a hackathon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mpQjH6z_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-01.png%3Fw%3D2448" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mpQjH6z_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-01.png%3Fw%3D2448" alt="IBM Node-RED Starter kit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Node-RED Starter kit will create six new service instances in IBM Cloud as you see in the dashboard below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eQ3FaSZn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-02.png%3Fw%3D1548" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eQ3FaSZn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-02.png%3Fw%3D1548" alt="IBM Node-RED Starter kit services"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What are the created resources in the image above:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Foundry apps:&lt;/strong&gt; A Cloud Foundry Node-RED application instance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Foundry services:&lt;/strong&gt; A alias for the Cloudant service to bind that service to the Cloud Foundry Node-RED application. You can find more about the alias topic in my blog post: How to use VCAP with a IAM enabled service in IBM Cloud?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Services:&lt;/strong&gt; Two created services:

&lt;ul&gt;
&lt;li&gt;Cloudant service&lt;/li&gt;
&lt;li&gt;Continuous Delivery service&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apps:&lt;/strong&gt; The App, from my point of view the “App” is technically, a single point of entry to all resources we usually need to build, deploy and run an application on IBM Cloud ("here the App was pre-configured with the Node-RED Starter kit“).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer tools:&lt;/strong&gt; The created toolchain.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Let's have a short walkthrough, how to use the Node-RED Starter kit to create the Node-RED application instance on IBM Cloud
&lt;/h2&gt;

&lt;p&gt;Here are five major steps, I see, when we use the Node-RED Starter kit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YI1aEhMb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-starter.gif%3Fw%3D1460" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YI1aEhMb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-starter.gif%3Fw%3D1460" alt="Here are five major steps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Step 1:&lt;/em&gt; First we will create an App. That App is the single point of entry to all relevant resources for build, deploy and run the Node-RED application instance. In the following image we see the fully deployed App, with links to the related resources as the services, the toolchain, the application URL and the source code repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OXjByhnB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-04.png%3Fw%3D2448" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OXjByhnB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-04.png%3Fw%3D2448" alt="Step 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Step 2:&lt;/em&gt; Then automatically a Cloudant service instance will be instantiated. That instance does contain a Cloudant database which saves configurations and flows and more of the Node-RED application. The image displays the noderedmyhackathon database in the Cloudant service instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4q8u_Ri5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-05.png%3Fw%3D1124" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4q8u_Ri5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-05.png%3Fw%3D1124" alt="Step 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Step 3:&lt;/em&gt; The toolchain will be automatically configured, based on configuration information we will provide. The image shows a example list of toolchains in Dallas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NYjQUSkG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-06.png%3Fw%3D1878" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NYjQUSkG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-06.png%3Fw%3D1878" alt="Step 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Step 4:&lt;/em&gt; The toolchain will create a Continues Delivery service, that service will clone the source code for the Node-RED application from origin Node-RED IBM Cloud GitHub project to our GitLab project in IBM Cloud. We can use the source code to modify the Node-RED application instance later. The GitLab project is the input for the delivery pipeline which does the concrete deployment of the application. The picture displays the configured toolchain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ggwOj2B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-07.png%3Fw%3D1332" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ggwOj2B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-07.png%3Fw%3D1332" alt="Step 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Step 5:&lt;/em&gt;  The deployment pipeline now creates the Cloud Foundry Node-RED application and the needed Cloud Foundry alias to bind the Cloudant service to the Cloud Foundry Node-RED application. The image shows the deployment pipeline.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The gif below shows how to access the running Node-RED application from the App.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ftJTyyRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-11.gif%3Fw%3D2448" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ftJTyyRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://suedbroecker.files.wordpress.com/2020/03/node-red-11.gif%3Fw%3D2448" alt="Access the running Node-RED application from the App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this was useful for you and let’s see what’s next?&lt;/p&gt;

&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;Thomas&lt;/p&gt;

&lt;p&gt;&lt;a href="https://suedbroecker.net/2020/03/09/a-short-introduction-of-the-node-red-starter-kit-on-ibm-cloud-for-hackathons/"&gt;Resource on www.suedbroecker.net&lt;/a&gt; &lt;/p&gt;

</description>
      <category>nodered</category>
      <category>deliverpipeline</category>
      <category>toolchain</category>
      <category>continuesdelivery</category>
    </item>
  </channel>
</rss>
