{"id":1040,"date":"2022-05-31T12:20:46","date_gmt":"2022-05-31T16:20:46","guid":{"rendered":"https:\/\/richrijnders.com\/?p=1040"},"modified":"2022-06-24T09:41:53","modified_gmt":"2022-06-24T13:41:53","slug":"soapui-common-library-framework-for-datapower","status":"publish","type":"post","link":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/","title":{"rendered":"SoapUI for DataPower 01: A Common Library Framework"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Header Image and Title&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; background_enable_image=&#8221;off&#8221; background_size=&#8221;contain&#8221; min_height=&#8221;229px&#8221; custom_padding=&#8221;4px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;140px&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/soapui-datapower-framework-01-banner.jpg&#8221; alt=&#8221;SoapUI DataPower Framework Banner&#8221; title_text=&#8221;soapui-datapower-framework-01-banner&#8221; align=&#8221;center&#8221; _builder_version=&#8221;4.16.0&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;178px&#8221; custom_margin=&#8221;-25px|||||&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Introduction&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;3px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;481px&#8221; custom_padding=&#8221;||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text ol_item_indent=&#8221;5px&#8221; _builder_version=&#8221;4.17.0&#8243; _module_preset=&#8221;default&#8221; text_orientation=&#8221;justified&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Overview<\/h2>\n<p>We all know that IBM DataPower is a very powerful edge platform for the deployment, management, protection, and execution of cloud and on-prem API&#8217;s. The most ubiquitous method of managing the appliances (and now instances) is the provided Web Management Console. As its name implies, this is the provided browser-based management interface with menus and utilities to perform management functions in DataPower. \u00a0If you have one DataPower or, more typically, two (one DMZ and one Internal) then this management interface is probably all you need. \u00a0But if you are in an environment with thousands or millions of transactions per minute, then you probably have four, eight, a dozen, or more appliances or instances redundantly grouped across multiple datacenters. \u00a0In such cases, logging on to each via individual browser tabs to perform similar functions or check status can get very tedius very quickly.<\/p>\n<p>IBM provides another interface in DataPower called the XML Management Interface. \u00a0This interface services a set of API&#8217;s called SOMA (SOap MAnagement) and AMP (App Management Protocol) services. These are SOAP services defined by a WSDLs (more on that later). You can execute these calls with any SOAP tool, or even from a command line with CURL. But we are going to use these SOMA and AMP API&#8217;s to create toolbox of reusable utilities and reports using <a href=\"https:\/\/www.soapui.org\/downloads\/soapui\/\" target=\"_blank\" rel=\"noopener\">SoapUI<\/a>.\u00a0Our toolbox will have a common library of API calls that we can use in multiple utilities without having to re-define them and have redundant code everywhere they are used.<\/p>\n<p>What&#8217;s the big deal about that, you ask?\u00a0 You probably create common functions all the time and copy them into different programs with various types of <em>include() <\/em>functions or statements. Yeah, about that. SoapUI has a testing facility with limited scripting capabilities. It&#8217;s not really an HLL so it doesn&#8217;t support things like copybooks or includes.\u00a0 So this tutorial is going to show you an object based method to set up common libraries and functions within the confines of soapUI&#8217;s TestSuites and scripting.<\/p>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;The Pieces&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;3_5,2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;253px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;3_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text ol_position=&#8221;outside&#8221; ol_item_indent=&#8221;20px&#8221; admin_label=&#8221;Text&#8221; _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;default&#8221; text_orientation=&#8221;justified&#8221; width=&#8221;94.4%&#8221; custom_padding=&#8221;25px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>The Pieces<\/h2>\n<p>As you may have surmised, the pieces needed for this turorial are:<\/p>\n<ol>\n<li>IBM DataPower<\/li>\n<li>SoapUI<\/li>\n<li>Apache Groovy Programming Language<\/li>\n<li>IBM SOMA and AMP API WSDL&#8217;s and XSD&#8217;s<\/li>\n<\/ol>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2020\/12\/puzzle-pieces-shopping-cart.jpg&#8221; title_text=&#8221;puzzle-pieces-shopping-cart&#8221; admin_label=&#8221;Image: Puzzle Pieces in Shopping Cart&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;||-1px|||&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;0px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text ol_position=&#8221;outside&#8221; ol_item_indent=&#8221;20px&#8221; _builder_version=&#8221;4.17.0&#8243; _module_preset=&#8221;default&#8221; text_orientation=&#8221;justified&#8221; min_height=&#8221;360px&#8221; custom_padding=&#8221;||33px|||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h3>IBM DataPower<\/h3>\n<p>For the purposes of this tutorial I will assume that you have access to at least one DataPower appliance or instance and that you have administrative rights to it.<\/p>\n<h3>SoapUI<\/h3>\n<p>SoapUI is a great program for easily importing WSDL&#8217;s and running the API&#8217;s. It also has a testing facility that allows you (with scripting) to string together multiple API calls in order to perform more complete testing or, in our case, to create complex utilities and reports. If you don&#8217;t have it, you can <a href=\"https:\/\/www.soapui.org\/downloads\/latest-release\/\" target=\"_blank\" rel=\"noopener\">download the open source version of SoapUI here<\/a>. For the remainder of this tutorial I will assume that you already have it installed on your computer.<\/p>\n<h3>Apache Groovy<\/h3>\n<p>The Apache Groovy language is what SoapUI uses for its test scripting facilities, so you will need to know at least the basics of the language. You don&#8217;t need to download anything as it is already included in SoapUI. You can <a href=\"https:\/\/www.tutorialspoint.com\/groovy\/index.htm\" target=\"_blank\" rel=\"noopener\">learn the basics of the groovy language here<\/a>.<\/p>\n<h3>IBM SOMA and AMP WSDL&#8217;s<\/h3>\n<p>You will be downloading the SOMA and AMP wsdl and XSD files from your DataPower appliance and then importing those into your SoapUI workspace. \u00a0We will be covering those steps in detail later in the tutorial.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Enable The XML Mgmt Interface on DataPower&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;105px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;||0px|||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Enabling the XML Mgmt Interface on DataPower<\/h2>\n<p>Obviously we cannot use the XML Management interface if it&#8217;s not enabled. You enable the interface via the Web Management console. Here are the steps to accomplish this:<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;23px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/04\/framework_00_enable_xml-mgmt-interface.png&#8221; alt=&#8221;Screenshot: Enable XML Mgmt&#8221; title_text=&#8221;framework_00_Enable_xml-mgmt-interface&#8221; show_in_lightbox=&#8221;on&#8221; align=&#8221;center&#8221; _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;22px&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<ol>\n<li>Log on to DataPower as an Administrator and into the <em>default<\/em> domain.\u00a0Here I am using the Blueprint Console of the Web Management interface.<\/li>\n<li>Click on the &#8220;Network&#8221; icon in the left-side menu<\/li>\n<li>Expand the &#8220;Management&#8221; drop-down menu<\/li>\n<li>Select the &#8220;XML Management Interface&#8221; option<\/li>\n<li>Check the &#8220;Enable Administrative State&#8221; box<\/li>\n<li>Enter the\u00a0<em>host alias<\/em> for your DataPower Management Interface IP or the IP address directly<\/li>\n<li>Click the &#8220;Apply&#8221; button at the top-right or top-left of the page<\/li>\n<li>Save your configuration<\/li>\n<\/ol>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Those are the basics required, but there are some other options on that screen that we will briefly cover here so you don&#8217;t obsess over them.<\/p>\n<p><strong><em>Port Number:\u00a0<\/em><\/strong>The default port for the XML Management Interface is 5550. \u00a0You can change this to another available port number if you wish. For the purposes of this tutorial I am using the default.<\/p>\n<p><em><strong>Access Control List (ACL):<\/strong> <\/em> You can choose to secure the use of this interface by specifying which IP addresses (via CIDR notation) are allowed to connect to it and\/or specify which IP addresses or ranges are denied access.\u00a0<\/p>\n<p><strong><em>Enabled Services:<\/em>\u00a0<\/strong>I normally only enable SOAP and AMP interfaces, but you can leave the defaults if you want to experiment with or use the other mentioned services.<\/p>\n<p><em><strong>Advanced:\u00a0<\/strong><\/em> You can use SSL to secure this interface. You can do so using all of the options available in an SSL Server\/Client profile. This is an advanced feature of DataPower configuration which we will not delve into here. \u00a0If left at the defaults, the interface will still be secured via HTTPS using the appliances global SSL certificate.\u00a0<\/p>\n<p><em><strong>SLM:<\/strong><\/em><strong>\u00a0<\/strong>If your DataPower is part of an SLM group, you would configure the update interval here. This is another advanced feature of the DataPower platform which we will not cover here.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Setup SoapUI&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;3_5,2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;3_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Setup SoapUI Workspace<\/h2>\n<p>Create a new workspace in SoapUI and name it something creative like &#8220;DataPowerTools&#8221;.<\/p>\n<ol>\n<li>Right-click on the workspace name and select &#8220;New SOAP Project&#8221;. Enter a project name of &#8220;DP_Tools&#8221;<\/li>\n<li>Right-click on the project and select &#8220;New TestSuite&#8221;. Name it &#8220;DP_Utils&#8221;<\/li>\n<li>Create another new TestSuite and name it &#8220;DP_Reports&#8221;<\/li>\n<li>Create another new TestSuite and name it &#8220;DP_APIs&#8221;<\/li>\n<li>Create another new TestSuite and name it &#8220;DP_Common&#8221;<\/li>\n<\/ol>\n<p>When you are done with these steps, your workspace should look like this and we are ready to get busy!<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/04\/framework_00_Setup-SoapUI-Workspace_2.png&#8221; title_text=&#8221;framework_00_Setup-SoapUI-Workspace_2&#8243; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.0&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;242px&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Download SOMA WSDL&#8217;s&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|-21px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.0&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Download SOMA and AMP WSDL&#8217;s<\/h2>\n<p>You can download the SOMA and AMP WSDL&#8217;s directly from the DataPower appliance or instance. Log onto DataPower and navigate to the <em>Administration<\/em> menu. Under the\u00a0<em>Main<\/em> submenu, select the\u00a0<em>File Management<\/em> option.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;23px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.0&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Scroll down to the &#8220;store&#8221; folder and expand it.\u00a0Near the top of the folder you will find the &#8220;app-mgmt-protocol-v3*&#8221;\u00a0files and near bottom of that folder you will find the &#8220;xml-mgmt*&#8221; files. These are the WSDL&#8217;s and XSD files you will need:<\/p>\n<ul>\n<li>app-mgmt-protocol-v3.wsld<\/li>\n<li>app-mgmt-protocol-v3.xsd<\/li>\n<li>xml-mgmt.wsdl<\/li>\n<li>xml-mgmt.xsd<\/li>\n<li>xml-mgmt-b2b.xsd<\/li>\n<li>xml-mgmt-base.xsd<\/li>\n<li>xml-mgmt-ops.xsd<\/li>\n<\/ul>\n<p>You can download them by right-clicking the file name and selecting &#8220;save link as&#8221;. \u00a0Save them somewhere on your computer. A good place is wherever you are saving your SoapUI workspace and project files (the default is your user&#8217;s\u00a0<em>home<\/em> directory &#8220;C:\\Users\\youruserid&#8221;).<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/framework_01_download_xml-mgmt-wsdl.png&#8221; title_text=&#8221;framework_01_download_xml-mgmt-wsdl&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Import SOMA WSDL&#8217;s to SoapUI&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;3_5,2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;3_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Import SOMA and AMP WSDL&#8217;s Into SoapUI<\/h2>\n<p>Now it&#8217;s time to add the actual service WSDL&#8217;s to SoapUI. You do this by right-clicking on\u00a0the<em> workspace<\/em> name and selecting\u00a0<em>New Soap Project<\/em>. Be sure to right-click on the\u00a0<em>workspace<\/em> name &#8220;DataPowerTools&#8221; and not the project &#8220;DP_Tools&#8221;.\u00a0 This is because we are going to import the full WSDL&#8217;s as their own projects and select which API&#8217;s we will be using as we need them.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/04\/framework_03_add-wsdl.png&#8221; alt=&#8221;import_project&#8221; title_text=&#8221;framework_03_Add-WSDL&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;23px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/04\/framework_03_add-wsdls.png&#8221; alt=&#8221;importing_wsdls&#8221; title_text=&#8221;framework_03_Add-WSDLs&#8221; show_in_lightbox=&#8221;on&#8221; align=&#8221;center&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;22px&#8221; custom_margin=&#8221;88px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>In the &#8220;New Soap Project&#8221; window, click the <em>browse<\/em> button next to the\u00a0<em>initial WSDL<\/em> box and navigate to the folder where you saved the DataPower WSDL files. Select the &#8220;xml-mgmt.wsdl&#8221; file and then click &#8220;OK&#8221;.\u00a0 Don&#8217;t worry about the\u00a0<em>Project Name\u00a0<\/em>field, it will be filled in by the WSDL.<\/p>\n<p>After the WSDL is added as a new project, do the same with the &#8220;app-mgmt-protocol-v3.wsdl&#8221;.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;95px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>After adding both of the WSDL&#8217;s as new projects to your workspace, your screen should look something like this.<\/p>\n<p>At this point our base structure is done and we are ready to start developing our first utility, &#8220;ShowActiveUsers&#8221;<\/p>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/04\/framework_04_after-wsdls-added.png&#8221; alt=&#8221;workspace_with_wsdls&#8221; title_text=&#8221;framework_04_after-wsdls-added&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;List Active Users SOAP Request&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row admin_label=&#8221;Intro&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>List Active Users SOAP Request<\/h2>\n<p>We will build out our reusable API framework while simultaneously building our first utility, &#8220;Show Active Users&#8221;.\u00a0 This utility will cycle through some or all of our appliances and list all user accounts that are currently logged in to the device. This relatively simple utility will use one IBM API that we will put into our common &#8220;DP_APIs&#8221; test suite, and one common function that we will put into our &#8220;DP_Common&#8221; test suite. Once created, these functions will be available to be easily reused by any future utility we create.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;2_5,3_5&#8243; admin_label=&#8221;Open SOMA Request&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;23px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/04\/framework_06_open-request1-e1650333365576.png&#8221; alt=&#8221;Screenshot: Enable XML Mgmt&#8221; title_text=&#8221;framework_06_open-request1&#8243; show_in_lightbox=&#8221;on&#8221; align=&#8221;center&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;3_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;22px&#8221; custom_margin=&#8221;|||-49px||&#8221; custom_padding=&#8221;|||5px||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>The first thing we need to do is identify the SOMA API that will retrieve for us the list of active users on our DataPower appliances. To do this, expand the &#8220;xml-mgmt&#8221; project, then the &#8220;xml-mgmt-soap&#8221; interface, then the &#8220;operation&#8221; mock service, and finally double-click &#8220;Request1&#8221;. When you do this, SoapUI opens the request XML in the left-side pane of the editor window.\u00a0The first thing you will notice is that the request XML is HUGE. Every function that the SOMA API supports is in this one request XML!\u00a0 But don&#8217;t get intimidated, you only need a small part of this request for any given action.\u00a0 \u00a0<\/p>\n<p>To get the list of all active users, we are only interested in the &#8220;get-status&#8221; operation, as shown below:<\/p>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Pare Down Monster Request&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/framework_06_open-raw-request.png&#8221; title_text=&#8221;framework_06_open-raw-request&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Remove all the other operations from the request. When you are done paring it down, it should like the image below:<\/p>\n<p>[\/et_pb_text][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/framework_07_trimmed-down-request.png&#8221; title_text=&#8221;framework_07_trimmed-down-request&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Modify Request Parms&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Now that we have an API that will return the list ofactive users, we had better test it out and make sure that it will do just that.\u00a0 So the first thing we need to do is modify the request with the parameters it needs to its job.\u00a0 First, modify the request URL so the request goes to one of your DataPower appliances or instances. Leave the port nunber and URI\/endpoint unchanged. Next, set the\u00a0<em>domain\u00a0<\/em>attribute equal to &#8220;default&#8221; and set the\u00a0<em>class<\/em> attribute equal to &#8220;ActiveUsers&#8221;. Be sure your letter case is accurate, it matters. You can delete the &#8220;object-class&#8221; and &#8220;object-name&#8221; attributes &#8211; we don&#8217;t need them for this action.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/framework_08_modify-request-for-call.png&#8221; title_text=&#8221;framework_08_modify-request-for-call&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;27px|||||&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Add Basic Auth Header&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/framework_09_create-auth-header.png&#8221; title_text=&#8221;framework_09_create-auth-header&#8221; show_in_lightbox=&#8221;on&#8221; admin_label=&#8221;Add Basicauth&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;15px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Before you can actually execute your request you need to be able to log into the DataPower.\u00a0 To do this, we are going to add our base 64 encoded user id and password as a\u00a0<em>basic auth<\/em> header to our request.\u00a0 Yes, I know you can do this using the &#8220;Auth&#8221; panel directly, but adding it manually as a header will allow us to soft-code it later when we turn it into re-usable module.<\/p>\n<ol>\n<li>Click the &#8220;Headers&#8221; button to open the Header panel<\/li>\n<li>Click the &#8220;+&#8221; sign at the top-left of the Header panel<\/li>\n<li>Enter the word &#8220;Authorization&#8221; for the header name and click &#8220;OK&#8221;\u00a0<\/li>\n<\/ol>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Add Base64 String&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Now you see the &#8220;Authorization&#8221; header in the Header list. Click the box to the right of the &#8220;Authorization&#8221; header name and paste\/enter the word &#8220;Basic&#8221; followed by a space and then the base 64 encoded string of your DataPower user id and password.\u00a0 If you don&#8217;t know what this is, it&#8217;s basically your userid and password in the form &#8220;myuserid:mypassword&#8221; and then base 64 encoded (there are plenty of free tools on the Internet to do this). When done, your header should look like the one in this image.\u00a0 You can click the &#8220;Headers&#8221; button again to close the panel.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/framework_10_paste-basic-auth-string.png&#8221; title_text=&#8221;framework_10_paste-basic-auth-string&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;26px|||||&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Test Run Soap Request&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/03\/framework_11_active-users-soap-response.png&#8221; title_text=&#8221;framework_11_active-users-soap-response&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.1&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Click the &#8220;Run&#8221; button on the request.<\/p>\n<p>If you did everything correctly, then the request will return a response that looks something like the image to the left. Looking at the response, you can clearly see id&#8217;s of the users currently logged into the device.\u00a0 You will note that\u00a0<em>your own id<\/em> also shows up since you <em>did<\/em> just log in to run this API!\u00a0 Keep this in mind for later.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Rename Soap Request&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;58px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Now that we have a working and pared down SOAP call, let&#8217;s give it a name that reflects what it actually does.\u00a0 Right-click on the soap operation name and select &#8220;Rename&#8221; from the pop-up menu. Rename it to &#8220;ListActiveUsersSoap&#8221;.<\/p>\n<p>\u00a0We&#8217;re doing great so far. But even though we have a working SOAP call, it is still in its own soapUI project (xml-mgmt).\u00a0 So now, we are going to create a new\u00a0<em>test case<\/em> under the &#8220;DP_APIs&#8221;\u00a0<em>test suite<\/em> in our &#8220;DataPowerTools&#8221; project.\u00a0 This is where all of our re-usable api calls will live.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_12_rename-soap-request.png&#8221; title_text=&#8221;framework_12_rename-soap-request&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Drag Soap Request to Test Steps&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_13_drag-and-drop-soap-request-onto-test-case.png&#8221; title_text=&#8221;framework_13_drag-and-drop-soap-request-onto-test-case&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;79px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Right-click on the &#8220;DP_APIs&#8221; test suite and select &#8220;New Test Case&#8221; from the pop-up menu.\u00a0 Enter &#8220;ListActiveUsers&#8221; for the name and press &#8220;OK&#8221;.<\/p>\n<p>Now expand the new test case until you see the &#8220;Test Steps&#8221; section. It should say (0) test steps currently.<\/p>\n<p>Now drag-and-drop your ListActiveUsersSoap request and drop it onto the new &#8220;Test Steps&#8221; section as shown in the image to the left.<\/p>\n<p>You will get a prompt window asking you to confirm that you want to add the request to the test case. Click &#8220;Yes&#8221;.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;3_5,2_5&#8243; admin_label=&#8221;Missing Interfaces Prompt&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;3_5&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_13_add-missing-interfaces-prompt.png&#8221; title_text=&#8221;framework_13_add-missing-interfaces-prompt&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;23px|||||&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;2_5&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>The first time you copy a request from the SOMA project (xml-mgmt) to your DataPowerTools project, you will be notified that your project is missing the necessary\u00a0<em>interfaces<\/em> for the SOMA request and it will prompt you to add them. Click &#8220;Yes&#8221;.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Add Request Window&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_13_add-request-to-test-case-window.png&#8221; title_text=&#8221;framework_13_add-request-to-test-case-window&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;55px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>You will then be presented with the &#8220;Add Request to TestCase&#8221; window.\u00a0 You will note how it adds &#8220;operation -&#8221; to the front of the request name.\u00a0 You can remove that so the name remains &#8220;ListActiveUsersSoap&#8221;. Uncheck any of the other boxes that may be checked by default (some you cannot uncheck, that&#8217;s OK) and press &#8220;OK&#8221;.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Current Project State&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_13_after-copy-request-to-dp-apis.png&#8221; title_text=&#8221;framework_13_after-copy-request-to-dp-apis&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;38px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>The request will be added to the TestCase and the request will be opened in a window in the editing pane.\u00a0<\/p>\n<p>At this point, your project\u00a0<em>should<\/em> look similar to the image to the left.<\/p>\n<p>Now it&#8217;s time to create a\u00a0<em>groovy<\/em> wrapper around this request that will make it into a reusable resource for your utilities.<\/p>\n<p>Time to code!<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;ListActiveUsers Object&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row admin_label=&#8221;Intro&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>ListActiveUsers Reusable Object<\/h2>\n<p>So far we only have a usable SOAP request. You can certainly open up this request and <em>run <\/em>it for each of your DataPower devices and look at the SOAP response for each invokation and see who is logged in. But we want to <em>use and execute<\/em> this soap request for each DataPower device in a single operation and output readable messages to the soapUI <em>log<\/em> window so we can quickly and easily check all of our devices at the same time and know who is logged in.<\/p>\n<p>In order to write such a utility that will live in our &#8220;DP_Utils&#8221; TestSuite (are you seeing a pattern yet?) we will first put our <em>ListActiveUsersSoap<\/em> SOAP request into an object wrapper that we can instaniate and use easily from any utility or report we write. This <em>object wrapper<\/em> will be created as a\u00a0<em>Test Script<\/em> and written in the\u00a0<em>Groovy<\/em> language.<\/p>\n<p>Let&#8217;s begin.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Add Groovy Script&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;23px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_14_add-groovy-script.png&#8221; alt=&#8221;Screenshot: Enable XML Mgmt&#8221; title_text=&#8221;framework_14_add-groovy-script&#8221; show_in_lightbox=&#8221;on&#8221; align=&#8221;center&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;22px&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>The first thing we are going to do is add a\u00a0<em>Groovy<\/em> script along side our\u00a0<em>ListActiveUsersSoap<\/em> request.<\/p>\n<ol>\n<li>Expand <em>DP_Tools<\/em><\/li>\n<li>Expand\u00a0<em>DP_APIs<\/em><\/li>\n<li>Epand <em>ListActiveUsers<\/em><\/li>\n<li>Expand <em>Test Steps<\/em><\/li>\n<\/ol>\n<p>Right-Click on <em>Test Steps<\/em> and select\u00a0<em>Add Step -&gt; Groovy Script <\/em>as shown in the screenshot to the left.<\/p>\n<p>Name the new script\u00a0<em>ListActiveUsers<\/em> and click &#8220;OK&#8221;. The\u00a0<em>ListActiveUsers<\/em> groovy script will be added below the\u00a0<em>ListActiveUsersSoap\u00a0<\/em>request in your\u00a0<em>Test Steps\u00a0<\/em>and a blank groovy editor window will be opened.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; admin_label=&#8221;Object Class Construct&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;||-22px|||&#8221; custom_padding=&#8221;||0px|||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>So let&#8217;s first take a look at the groovy code that defines our basic reusable api object. This will be the same for all of our reusable api&#8217;s so you will become very familiar with it. After we understand this construct we will go back and add in the code that actually executes the <em>ListActiveUsersSoap<\/em> SOAP request and returns the results.<\/p>\n<p><strong><span style=\"color: #e02b20;\">(a)<\/span><\/strong> Standard program headers and footers &#8211; let&#8217;s not be lazy.<\/p>\n<p><span style=\"color: #e02b20;\"><strong>(b)<\/strong><\/span> Import some standard utilities and definitions. They both do exactly what they say.<\/p>\n<p><span style=\"color: #e02b20;\"><strong>(c)<\/strong><\/span> Here is where we define the reusable\u00a0<em>object class\u00a0<\/em>and its properties. Later api&#8217;s may have additional properties, but they will <em>*ALL<\/em> have these three properties at a minimum. In short, because the utilities we create will be scripts that will instantiate this object and execute its methods, we need to pass references to the calling script&#8217;s <em>log, context, and testrunner<\/em> in order for our class to function as part of the callers run scope.<\/p>\n<p><span style=\"color: #e02b20;\"><strong>(d)<\/strong><\/span> Class Constructor.\u00a0 When the class is instantiated we set the object&#8217;s properties to the values passed in as arguments.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_15_list-active-users-object-framework.png&#8221; title_text=&#8221;framework_15_list-active-users-object-framework&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;178.8px&#8221; custom_padding=&#8221;8px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p><span style=\"color: #e02b20;\"><strong>(e)<\/strong><\/span> <em>runAPI()<\/em> method.\u00a0 This is where we actually execute the SOAP call. IE: the utility or report script will invoke this method each time it wants to make the <em>ListActiveUsersSoap<\/em> call. We will add the required code for that in a moment, but you can immediately see that we will need to pass in a DataPower device name as the argument for each execution. You can also see that we need to instantiate a <em>GroovyUtils<\/em> object based on the current context of the script that is calling this method. GroovyUtils is necessary in order to pass the SOAP response XML back to the calling script as an object.<\/p>\n<p><span style=\"color: #e02b20;\"><strong>(f)<\/strong><\/span>\u00a0<strong><em>important! <\/em><\/strong>You will note that this last line of code is <em>outside of the class definition<\/em>.\u00a0 The reason for this is because utilities and reports that use this object will actually execute (run) <em>this<\/em> script in order to both define and instantiate the class &#8211; they will not instantiate the object directly with the <em>new()<\/em> operator.\u00a0 So running this script from any utility will load the class definition and then this single line at the end actually instantiates the object using the <em>new() <\/em>operator, and assigns it to a <em>context property <\/em>named &#8220;ListActiveUsers&#8221;. This property is then used by the utility or report script to access the methods of the class (as we will see later).<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Executing the SOAP Call&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text admin_label=&#8221;Intro&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Executing the SOAP Call<\/h2>\n<p>In order for our class to execute the\u00a0<em>ListActiveUsersSoap<\/em> request we need it to do three things first:<\/p>\n<ol>\n<li>We need to instantate the SOAP request as a <em>testRequest\u00a0<\/em>object.<\/li>\n<li>We need to set the Basic Auth header of the request with our base64 credentials, like we did when we tested the request, only this time we will get the value from a property we set at the <em>test suite\u00a0<\/em>level.<\/li>\n<li>We need to set the API Endpoint for the request so it goes to the DataPower device that we need it to.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row admin_label=&#8221;Create Request Object&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_15_code-create-request-object.png&#8221; title_text=&#8221;framework_15_code-create-request-object&#8221; show_in_lightbox=&#8221;on&#8221; admin_label=&#8221;Request Object Code&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>So right below the line where we instantiate <em>GroovyUtils,\u00a0<\/em>add the three lines of code as shown.\u00a0\u00a0<\/p>\n<p>The first line,\u00a0<em>def dp_apis<\/em>, creates a variable that points to our common API library, <em>DP_APIs<\/em>.\u00a0\u00a0<\/p>\n<p>The next line,\u00a0<em>def api,<\/em> creates a variable that points to the actual\u00a0<em>test step<\/em> that is our\u00a0<em>ListActiveUsersSoap<\/em> request. You could do these two lines in one single step, but the line of code would be really long and I like to keep my code readable.\u00a0<\/p>\n<p>Now that we have a variable that points to the soap request, the next line uses the\u00a0<em>.testRequest<\/em> method to instantiate a request object that we can execute in our code.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_15_auth-value-at-suite-level.png&#8221; title_text=&#8221;framework_15_auth-value-at-suite-level&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>The next thing we need to do is add a\u00a0<em>basic auth<\/em> header to our request.\u00a0 We did this back when we were testing the SOAP call so it should be familiar to you. Now, we <em>could<\/em> just do as we did before and add the header to the SOAP request, itself. But if we ever change our password or credentials then we have to go back to\u00a0<em>all<\/em> the SOAP requests in our common library and change them. For this reason, I prefer to save my basic auth credentials in a property at the\u00a0<em>Test Suite<\/em> level and use code to add it dynamically to the request object at execution time.\u00a0<\/p>\n<p>So go ahead and double-click the\u00a0<em>DP_Utils<\/em> Test Suite. When the window opens, click on the\u00a0<em>Properties<\/em> button towards the bottom and the click the &#8220;+&#8221; sign to add a property. Enter &#8220;__Authorization&#8221; for the property name and then add your basic auth base64 credentials for the value.\u00a0<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_15_code-auth-header.png&#8221; title_text=&#8221;framework_15_code-auth-header&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Go ahead and add these four lines of code just below where we created the request object.\u00a0 The first line defines a variable named\u00a0<em>authHeader<\/em> that points to the property at the TestSuite level where you just stored your basic auth string.\u00a0 The next line creates a temporary object from the headers of the request object we just instantiated above on line 40. This is necessary in order to manipulate the headers.\u00a0 The third line adds a header named <em>Authorization<\/em> to our temporary object and assigns to it the basic auth value we just retrieved from the test suite property.\u00a0 The last line creates a string map of the temporary object and assigns that back to the headers of the actual request object. Four lines of code are not a bad trade-off for the convenience of soft-coding our basic auth credentials.\u00a0<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_15_code-set-soap-endpoint.png&#8221; title_text=&#8221;framework_15_code-set-soap-endpoint&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>So the last thing we need to do before executing the SOAP call is to override the SOAP request endpoint to send the request to the right DataPower device.\u00a0 This is the equivalent of the drop-down endpoint box at the top of the SOAP request test step.\u00a0 We use the string that is passed in as an argument to concatenate the connection string.\u00a0 The argument can be the DNS name of the device, the IP address of the device, or the name you associated with the devices IP address in your <em>hosts<\/em> file (more on this later). After we have the connection string, we use the\u00a0<em>.setEndpoint()<\/em> method of the request object to assign the string as the endpoint for the call.<\/p>\n<p>Now that we have done all the preliminary work, it&#8217;s time to execute the\u00a0<em>ListActiveUsersSoap<\/em> SOAP call.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_15_execute-soap-call-1.png&#8221; title_text=&#8221;framework_15_execute-soap-call&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>We will put the execution of the SOAP call into a standard try\/catch construct.\u00a0 If an error occurs the catch block will print the error to the running\u00a0<em>log<\/em> output. This is why we pass the calling scripts log object into the constructor of our class. Without that we cannot write messages to the log output of the running script.<\/p>\n<p>To execute the SOAP call, we use the\u00a0<em>.run()<\/em> method of the <em>ListActiveUsersSoap<\/em> test step object (the one we instantiated as the &#8220;api&#8221; variable).\u00a0 We pass the method the\u00a0<em>testRunner<\/em> and\u00a0<em>context<\/em> objects that were passed in the constructor from the calling script.\u00a0 This ensures that the call is executed in the same scope as the calling script.<\/p>\n<p>Next, we create a pointer to the SOAP response and place it into an XML Holder (remember that GroovyUtils thingy?).\u00a0 Although we can get the SOAP response and save it as an XML object, we no longer have the benefit of having the namespaces defined by the request so the next line of code manually defines that namespace and adds it to the XML Holder.\u00a0<\/p>\n<p>And the last bit of business is to return that XML Holder to the calling script.\u00a0\u00a0<\/p>\n<p>With that, we have completed the coding of the reusable api object. We can now execute this api call from any utility or report that we create without having to copy\/paste a good chunk of this same code into every one of them.\u00a0<\/p>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;getDataPowerDeviceList&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>A Non-API Reusable Function<\/h2>\n<p>One of the most common things that we will be doing with our utilities and reports is looping through groups of our DataPower devices to either perform the same function on all the devices in a group or to gather similar information from all the devices in the group.\u00a0 In the case of checking for logged-in users, we will be doing the latter &#8211; checking all our devices or a subset of them to see who is logged in. Most likely, we will be using a loop that iterates through a list of the device names and calls our api for each one.\u00a0 We can always create a list of our devices and manipulate it each time we use our utility in order to target the desired subset of devices, and that will work. Or&#8230;\u00a0<em>or&#8230;\u00a0<\/em>we can create a common function that each utility or report can call to get the correct list of devices on-the-fly!\u00a0<\/p>\n<p>Lo and behold, we have already created a place to put such non-api reusable functions: The &#8220;DP_Common&#8221; test suite.\u00a0<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;23px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_16_common-functions.png&#8221; alt=&#8221;Screenshot: Enable XML Mgmt&#8221; title_text=&#8221;framework_16_common-functions&#8221; show_in_lightbox=&#8221;on&#8221; align=&#8221;center&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;22px&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<ol>\n<li>Right-click &#8220;DP_Common&#8221; and select &#8220;New TestCase&#8221;<\/li>\n<li>Enter &#8220;CommonFunc&#8221; for the new test case name<\/li>\n<li>Expand the new TestCase<\/li>\n<li>Right-click on &#8220;Test Steps&#8221; and select &#8220;Add Step &#8211;&gt; Groovy Script&#8221;<\/li>\n<li>Let&#8217;s name our new common function &#8220;GetDataPowerDeviceList&#8221;<\/li>\n<\/ol>\n<p>When you hit enter, a blank editor window will appear so you can begin coding your groovy script. The Test Suite structure should look similar to the screenshot to the left.<\/p>\n<p>Let&#8217;s see what that the structure of our common functions will look like.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,2_3&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Right away we can see that the structure for common functions is going to be almost identical to that we used for our reusable api&#8217;s.\u00a0 We create a class definition with our three required properties (log, context, and testRunner) and we create a constructor method that sets those properties to the arguments passed. We also have the single line of code outside of and below the class definition that instantiates the class and assigns it to a context property so it can be used by the calling utility or report.<\/p>\n<p>The difference here is that instead of a\u00a0<em>runAPI()<\/em> method, we create a method that is our common function <span style=\"color: #e02b20;\"><strong>(a)<\/strong><\/span>.<\/p>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_3&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_16_get-device-list.png&#8221; title_text=&#8221;framework_16_get-device-list&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>There is nothing that stops us from creating multiple methods in the class. If you wanted, you can create a single class containing multiple methods, one for each common function. But for our example, we will create one class with one common function, <em>getList()<\/em>.\u00a0<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>As you can see, the function will return a\u00a0<em>list[]<\/em> holding the names of DataPower devices <span style=\"color: #e02b20;\"><strong>(a)<\/strong><\/span>.\u00a0 We first create separate lists holding the names of the devices in our most oft used groupings <span style=\"color: #e02b20;\"><strong>(b)<\/strong><\/span>. If those names confuse you, check out my other tutorial on <a href=\"https:\/\/richrijnders.com\/better-soapui-endpoints-for-datapower-soma-amp\/\" target=\"_blank\" rel=\"noopener\">setting up better soapUI endpoints<\/a>. Or you can just put in the IP Addresses of your DataPower devices in similar groupings.\u00a0<\/p>\n<p>Next we use a switch statement to return the correct list or combine different lists together based on the desired\u00a0<em>group name<\/em> as input argument <span style=\"color: #e02b20;\"><strong>(c)<\/strong><\/span>. The\u00a0<em>default<\/em> clause will just return the same string that was passed in as the group name. This allows the calling utility to pass in just the name of a single device if they wish and we will return it as a list so that the rest of the utility can function just on that one device. A good enhancement would be to validate the input argument string to make sure it is a valid device name or group name.<\/p>\n<p>And then we just return the list object to the calling script (d).\u00a0<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_16_get-list-method.png&#8221; title_text=&#8221;framework_16_get-list-method&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;ShowActiveUsers&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_margin=&#8221;2px|||||&#8221; custom_padding=&#8221;4px||12px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text admin_label=&#8221;intro&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Utility: ShowActiveUsers<\/h2>\n<p>So now that we have examples of a reusable api and a reusable common function, let&#8217;s create a utility that puts them to good use.\u00a0 We are going to create a utility named\u00a0<em>ShowActiveUsers.\u00a0<\/em>I named it <em>ShowActiveUsers <\/em>in order to distinguish the utility from the reusable api\u00a0<em>ListActiveUsers<\/em> that it will be using. This utility will allow us to specify what group of DataPower devices to check (or all of them) and will write information about all the active (logged in) users to the soapUI log output.\u00a0<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;10px||4px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_create-showactiveusers.png&#8221; alt=&#8221;Screenshot: Enable XML Mgmt&#8221; title_text=&#8221;framework_17_create-showactiveusers&#8221; show_in_lightbox=&#8221;on&#8221; align=&#8221;center&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;22px&#8221; custom_padding=&#8221;51px|||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>You should be familiar with this process by now, so go ahead and create the <em>ShowActiveUsers<\/em> test case and test step under &#8220;DP_Utils&#8221;.<\/p>\n<ol>\n<li>Right-click &#8220;DP_Utils&#8221; and select &#8220;New TestCase&#8221;.\u00a0<\/li>\n<li>Name the TestCase &#8220;ShowActiveUsers&#8221;.<\/li>\n<li>Expand the TestCase and then Right-Click on &#8220;TestSteps&#8221; and select &#8220;Add Step &#8211;&gt; Groovy Script&#8221;.<\/li>\n<li>Name the script &#8220;ShowActiveUsers&#8221;.\u00a0<\/li>\n<\/ol>\n<p>An empty editor will open so you can add your groovy code.<\/p>\n<p>Your project navigator should now look similar to the screenshot here.\u00a0<\/p>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>We will start our new utility with the standard header and import the XmlHolder object definition. Recall this is needed in order to get back the SOAP response as an XML object.<\/p>\n<p>I always add a debugging flag that will trigger additional outputs that I add to my code <span style=\"color: #ff0000;\"><strong>(a)<\/strong><\/span>.\u00a0<\/p>\n<p>We can set the name of the device group that we want to run the check against here <span style=\"color: #ff0000;\"><strong>(b)<\/strong><\/span>.<\/p>\n<p>Along with your own user ID, there are usually other user ID&#8217;s, created for logging and monitoring accessing the device. These will also be returned every time you run the API. we are not interested in those usually, so we add a list of user ID&#8217;s that will be ignored when generating the output <span style=\"color: #ff0000;\"><strong>(c)<\/strong><\/span>.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_code-showactiveusers-1.png&#8221; title_text=&#8221;framework_17_code-showactiveusers-1&#8243; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_code-showactiveusers-2.png&#8221; title_text=&#8221;framework_17_code-showactiveusers-2&#8243; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Next is where we define and instantiate our common API and function.\u00a0 First, we define variables that point to the common API and common function TestSuites, &#8220;DP_APIs&#8221; and &#8220;DP_Common&#8221; respectively <strong><span style=\"color: #ff0000;\">(d)<\/span><\/strong>.<\/p>\n<p>Then <span style=\"color: #ff0000;\"><strong>(e)<\/strong><\/span> we set a variable to the common function TestStep\u00a0<em>GetDataPowerDeviceList\u00a0<\/em>and execute it using the <em>run()<\/em> method. This instantiates the object and sets a context variable pointing to it so that the following line can set a program variable to the same so we can access it directly.\u00a0<\/p>\n<p>The next block does the same things, but for the\u00a0<em>ListActiveUsers<\/em> API <span style=\"color: #ff0000;\"><strong>(f)<\/strong><\/span>.\u00a0 Now our common function and common API are fired up and ready to use.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Here we get to the where the action is.\u00a0 Most of your utilities and reports will be some variation of this basic construct.\u00a0<\/p>\n<p>First <span style=\"color: #ff0000;\"><strong>(g)<\/strong><\/span> we execute the common function method to retrieve the list of DataPower devices we want to execute our utility against.\u00a0<\/p>\n<p><span style=\"color: #ff0000;\"><strong>(h)<\/strong><\/span> We initalize a simple counter variable so that later we can output a total number of active users. We also write out a preamble to the log to remind us what this utility is for.\u00a0<\/p>\n<p><span style=\"color: #ff0000;\"><strong>(i)<\/strong><\/span> This is where most of our work takes place. This loop iterates through the list of DataPower device names that we retrieved from our common function. This is where we will execute the common API to check for active users on all of desired devices. We will insert and discuss that code next.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_code-showactiveusers-3.png&#8221; title_text=&#8221;framework_17_code-showactiveusers-3&#8243; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>So let&#8217;s add some code inside this loop that will execute for each DataPower device.\u00a0 First we just initialize some working variables <span style=\"color: #ff0000;\"><strong>(j)<\/strong><\/span>.\u00a0 The first one is just a counter to keep track of how many active users we found on this device. The second is just a flag to let my code know if I have output a header message for this device yet.\u00a0<\/p>\n<p>Next <span style=\"color: #ff0000;\"><strong>(k)<\/strong><\/span> we output a message (if the debugOn flag is true) so we know what iteration of the loop is executing.<\/p>\n<p><span style=\"color: #ff0000;\"><strong>(L)<\/strong><\/span> And here we go ahead and execute the common API, passing in the device name as an argument. The result XML is directly assigned to the &#8220;xml_ListActiveUsers&#8221; variable.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_code-showactiveusers-4.png&#8221; title_text=&#8221;framework_17_code-showactiveusers-4&#8243; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Having executed the API request and received the response, we now need to loop through the xml elements for each active user ID on the device <span style=\"color: #ff0000;\"><strong>(m)<\/strong><\/span>. <a href=\"https:\/\/richrijnders.com\/iterate-through-soap-response-nodes-in-soapui-and-groovy\/\" target=\"_blank\" rel=\"noopener\">Read this for an in-depth explanation<\/a> of how this works.<\/p>\n<p>Note here <span style=\"color: #ff0000;\"><strong>(n)<\/strong><\/span> that we are skipping any user ID&#8217;s if they are found in our\u00a0<em>skipUsers[]<\/em> list.\u00a0\u00a0<\/p>\n<p>Finally, we output the user ID details to the log <span style=\"color: #ff0000;\"><strong>(o)<\/strong><\/span>.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_3&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_code-showactiveusers-5.png&#8221; title_text=&#8221;framework_17_code-showactiveusers-5&#8243; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>For completeness, we add some code to increment the counter for the number of active users and output that information to the log, as well.<\/p>\n<p>And that completes the\u00a0<em>ShowActiveUsers<\/em> utility!\u00a0 You can specify a group of DataPower devices and quickly run this utility to see who is currently logged in to those devices. When you run this, it will output information to the log similar to the output below. Play around with the run options and debugOn flag to see how it changes the expected output.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_code-showactiveusers-6.png&#8221; title_text=&#8221;framework_17_code-showactiveusers-6&#8243; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2022\/05\/framework_17_showactiveusers-output.png&#8221; title_text=&#8221;framework_17_showactiveusers-output&#8221; show_in_lightbox=&#8221;on&#8221; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row admin_label=&#8221;Summary&#8221; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; min_height=&#8221;122px&#8221; custom_margin=&#8221;0px|auto|9px|auto||&#8221; custom_padding=&#8221;10px||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h3>Summary<\/h3>\n<p>In this tutorail we outlined a how you can use soapUI and the IBM DataPower API&#8217;s to set up a framework for developing utilites and reports to help you manage your DataPower platform. We created a soapUI TestSuite structure for creating common library functions and reusable API&#8217;s to be used in those utilities and reports. We developed one common function that can be used in all of your Utilities and Reports to return a list of DataPower devices to run the API&#8217;s against. We developed one such reusable API to check a DataPower device to see what users are currently active on it.\u00a0 Finally, we created a sample utility,\u00a0<em>ShowActiveUsers<\/em> that will quickly check a grouping of DataPower devices and display which users are active on those devices.\u00a0<\/p>\n<p>In future tutorials, we will develop more complex utilities to do things like upload files and security certificates, and reports that generate Excel spreadsheets with information retrieved from the DataPower devices. Be sure to check back for those and other tips and tutorials.<\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We will develop a generic framework within SoapUI for executing DataPower XML Management Interface API&#8217;s with common and reusable libraries and API&#8217;s.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[27],"tags":[42,51,33,7,52,37,53,36,41,50],"class_list":["post-1040","post","type-post","status-publish","format-standard","hentry","category-rich-rijnders-tutorials","tag-amp","tag-api","tag-code","tag-datapower","tag-framework","tag-groovy","tag-reusable","tag-soapui","tag-soma","tag-xml-management-2"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SoapUI for DataPower 01: A Common Library Framework - Rich Rijnders<\/title>\n<meta name=\"description\" content=\"We will develop a generic framework within SoapUI for executing DataPower XML Management Interface API&#039;s with common and reusable libraries and API&#039;s.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SoapUI for DataPower 01: A Common Library Framework - Rich Rijnders\" \/>\n<meta property=\"og:description\" content=\"We will develop a generic framework within SoapUI for executing DataPower XML Management Interface API&#039;s with common and reusable libraries and API&#039;s.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/\" \/>\n<meta property=\"og:site_name\" content=\"Rich Rijnders\" \/>\n<meta property=\"article:published_time\" content=\"2022-05-31T16:20:46+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-06-24T13:41:53+00:00\" \/>\n<meta name=\"author\" content=\"rich\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"rich\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"29 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/\"},\"author\":{\"name\":\"rich\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#\\\/schema\\\/person\\\/186c2ab9e139d2ed4065ce4a70046eff\"},\"headline\":\"SoapUI for DataPower 01: A Common Library Framework\",\"datePublished\":\"2022-05-31T16:20:46+00:00\",\"dateModified\":\"2022-06-24T13:41:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/\"},\"wordCount\":10181,\"commentCount\":0,\"keywords\":[\"AMP\",\"API\",\"code\",\"DataPower\",\"Framework\",\"Groovy\",\"Reusable\",\"soapui\",\"SOMA\",\"xml management\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/\",\"url\":\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/\",\"name\":\"SoapUI for DataPower 01: A Common Library Framework - Rich Rijnders\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#website\"},\"datePublished\":\"2022-05-31T16:20:46+00:00\",\"dateModified\":\"2022-06-24T13:41:53+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#\\\/schema\\\/person\\\/186c2ab9e139d2ed4065ce4a70046eff\"},\"description\":\"We will develop a generic framework within SoapUI for executing DataPower XML Management Interface API's with common and reusable libraries and API's.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/soapui-common-library-framework-for-datapower\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/richrijnders.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SoapUI for DataPower 01: A Common Library Framework\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#website\",\"url\":\"https:\\\/\\\/richrijnders.com\\\/\",\"name\":\"Rich Rijnders\",\"description\":\"Cloud and SOA Integration Architect\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/richrijnders.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#\\\/schema\\\/person\\\/186c2ab9e139d2ed4065ce4a70046eff\",\"name\":\"rich\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g\",\"caption\":\"rich\"},\"url\":\"https:\\\/\\\/richrijnders.com\\\/profile\\\/rich\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SoapUI for DataPower 01: A Common Library Framework - Rich Rijnders","description":"We will develop a generic framework within SoapUI for executing DataPower XML Management Interface API's with common and reusable libraries and API's.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/","og_locale":"en_US","og_type":"article","og_title":"SoapUI for DataPower 01: A Common Library Framework - Rich Rijnders","og_description":"We will develop a generic framework within SoapUI for executing DataPower XML Management Interface API's with common and reusable libraries and API's.","og_url":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/","og_site_name":"Rich Rijnders","article_published_time":"2022-05-31T16:20:46+00:00","article_modified_time":"2022-06-24T13:41:53+00:00","author":"rich","twitter_card":"summary_large_image","twitter_misc":{"Written by":"rich","Est. reading time":"29 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/#article","isPartOf":{"@id":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/"},"author":{"name":"rich","@id":"https:\/\/richrijnders.com\/#\/schema\/person\/186c2ab9e139d2ed4065ce4a70046eff"},"headline":"SoapUI for DataPower 01: A Common Library Framework","datePublished":"2022-05-31T16:20:46+00:00","dateModified":"2022-06-24T13:41:53+00:00","mainEntityOfPage":{"@id":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/"},"wordCount":10181,"commentCount":0,"keywords":["AMP","API","code","DataPower","Framework","Groovy","Reusable","soapui","SOMA","xml management"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/","url":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/","name":"SoapUI for DataPower 01: A Common Library Framework - Rich Rijnders","isPartOf":{"@id":"https:\/\/richrijnders.com\/#website"},"datePublished":"2022-05-31T16:20:46+00:00","dateModified":"2022-06-24T13:41:53+00:00","author":{"@id":"https:\/\/richrijnders.com\/#\/schema\/person\/186c2ab9e139d2ed4065ce4a70046eff"},"description":"We will develop a generic framework within SoapUI for executing DataPower XML Management Interface API's with common and reusable libraries and API's.","breadcrumb":{"@id":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/richrijnders.com\/soapui-common-library-framework-for-datapower\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/richrijnders.com\/"},{"@type":"ListItem","position":2,"name":"SoapUI for DataPower 01: A Common Library Framework"}]},{"@type":"WebSite","@id":"https:\/\/richrijnders.com\/#website","url":"https:\/\/richrijnders.com\/","name":"Rich Rijnders","description":"Cloud and SOA Integration Architect","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/richrijnders.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/richrijnders.com\/#\/schema\/person\/186c2ab9e139d2ed4065ce4a70046eff","name":"rich","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g","caption":"rich"},"url":"https:\/\/richrijnders.com\/profile\/rich\/"}]}},"_links":{"self":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts\/1040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/comments?post=1040"}],"version-history":[{"count":5,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts\/1040\/revisions"}],"predecessor-version":[{"id":1320,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts\/1040\/revisions\/1320"}],"wp:attachment":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/media?parent=1040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/categories?post=1040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/tags?post=1040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}