{"id":2052,"date":"2024-10-22T14:30:31","date_gmt":"2024-10-22T13:30:31","guid":{"rendered":"https:\/\/thomas-kopton.de\/vblog\/?p=2052"},"modified":"2024-10-22T16:18:50","modified_gmt":"2024-10-22T15:18:50","slug":"vmware-aria-operations-integration-sdk-part-2-demo-project","status":"publish","type":"post","link":"https:\/\/thomas-kopton.de\/vblog\/?p=2052","title":{"rendered":"VMware Aria Operations Integration SDK &#8211; Part 2 &#8211; Demo Project"},"content":{"rendered":"\n<p>In the <a href=\"https:\/\/thomas-kopton.de\/vblog\/?p=1872\">first post<\/a> on the topic of <strong>VMware Operations Integration SDK<\/strong>, I showed how I prepared my development environment and how a demo project is created using the triad of <code>mp-init<\/code>, <code>mp-test<\/code>, and <code>mp-build<\/code>.<\/p>\n\n\n\n<p>In this post, we&#8217;ll take a closer look at which files a simple, <strong>REST API-based project<\/strong> consists of, as well as how the structure of the actual app (Python code) looks like.<br>Using the example of my SmartHome central unit, I will show how the demo code needs to be adapted to build a simple, functional, and expandable Management Pack.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Project Initialization<\/h5>\n\n\n\n<p>As already shown in the first part, a project begins with us calling <code>mp-init<\/code> and thereby creating the project structure. Of course, we enter appropriate values for names, description, etc. After all, it should become a proper Management Pack.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"511\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1024x511.png\" alt=\"\" class=\"wp-image-2059\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1024x511.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-300x150.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-768x384.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1536x767.png 1536w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image.png 2006w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 01: mp-init SDK command.<\/em><\/figcaption><\/figure>\n\n\n\n<p>At this point, we have created our project structure, and we&#8217;ll now quickly take a look at it. The next screenshot shows the folder and files two levels down of the project folder creates by <code>mp-init<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"517\" height=\"1024\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1-517x1024.png\" alt=\"\" class=\"wp-image-2062\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1-517x1024.png 517w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1-151x300.png 151w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1-768x1521.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1-776x1536.png 776w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-1.png 1034w\" sizes=\"auto, (max-width: 517px) 100vw, 517px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 02: Folder structure and files after new project initialization.<\/em><\/figcaption><\/figure>\n\n\n\n<p>The files outlined in <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">red<\/mark> are the ones we will need to modify during the development of the Management Pack. It&#8217;s obvious that we will be working with the Python files, but the <code>adapter_requirements.txt<\/code> will also be adjusted so that we get all the necessary libraries for our own code included. The <code>connections.json<\/code> contains all the data needed for the development environment to actually communicate with a real endpoint when <code>mp-test<\/code> is called, in this case with my SmartHome central unit.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Adapter Logic<\/h5>\n\n\n\n<p>Broadly speaking, and this is indeed sufficient for a basic framework, we can summarize the necessary work steps in three points:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Modify the <strong>adapter definition<\/strong> to add fields for connecting to the SmartHome endpoint.<\/li>\n\n\n\n<li>Modify the <strong>test method <\/strong>to create a SmartHome connection and run a test query.<\/li>\n\n\n\n<li>Modify the <strong>collect method<\/strong> to collect objects, metrics, properties, and relationships.<\/li>\n<\/ol>\n\n\n\n<h6 class=\"wp-block-heading\">Adapter Definition<\/h6>\n\n\n\n<p>The adapter definition, typically implemented in the <code>get_adapter_definition()<\/code> method, which is later on reflected in <code>conf\/describe.xml<\/code> file of the Management Pack, serves several crucial purposes, like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It defines the <strong>configuration parameters <\/strong>and<strong> credentials<\/strong> needed to connect to the target endpoint (e.g., <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">host<\/mark>, <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">port<\/mark>, <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">username<\/mark>, <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">password<\/mark>).<\/li>\n\n\n\n<li>It specifies the <strong>object types<\/strong> and <strong>attribute<\/strong> types that will be present in a collection.<\/li>\n<\/ul>\n\n\n\n<p>In essence, the adapter definition is a crucial step in creating a Management Pack, as it establishes the foundation for how the <strong>adapter<\/strong> will <strong>interact<\/strong> with both the target system and VMware Aria Operations.<\/p>\n\n\n\n<p>Of course, I can&#8217;t present the entire code in one post; that would be beyond the scope. That&#8217;s what the official <a href=\"https:\/\/vmware.github.io\/vmware-aria-operations-integration-sdk\/\">documentation<\/a> is for, and I will also post my code on <a href=\"https:\/\/github.com\/tkopton\/smarthome-mp\">GitHub<\/a> and try to keep it up to date. At least up-to-date enough that one can learn from it. Here, I will only present the essential and abbreviated code snippets. It&#8217;s unlikely that anyone would want to exactly replicate my Management Pack; it&#8217;s more about the <strong>concepts<\/strong> behind it.<\/p>\n\n\n\n<p>At the beginning, I outsourced a few constants; the file can be seen here:<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>ADAPTER_KIND = \"tkSmartHome\"\nADAPTER_NAME = \"tk-SmartHome\"\nHOST_IDENTIFIER = \"host\"\nPORT_IDENTIFIER = \"port\"\nUSER_CREDENTIAL = \"user\"\nPASSWORD_CREDENTIAL = \"password\"<\/code><\/pre>\n\n\n\n<p>Lets start with the <code>get_adapter_definition()<\/code> method.<\/p>\n\n\n\n<p>Once again, to make absolutely sure that no one tries to copy the code here 1:1. The snippets are heavily abbreviated and show what I consider to be essential.The <code>get_adapter_definition()<\/code> method defines what a SmartHome Adapter instance will look like. That is, which <strong>parameters<\/strong>, both string and number, are queried during configuration to connect to the endpoint, are there default values, what other <strong>options<\/strong> could there be, etc. It defines how the <strong>authentication<\/strong> should proceed. This is also where all <strong>object types<\/strong> with their associated <strong>metrics<\/strong> and <strong>properties<\/strong> are defined. It&#8217;s practically a basic framework of every Management Pack. We don&#8217;t need more than this at the beginning.<\/p>\n\n\n\n<p>Please don&#8217;t be surprised by the strange method of authentication. The SmartHome system specifically requires a POST request with the user and password in the body and an additional Authorization header, which, when Base64 decoded, is nothing other than the string <code>Basic clientId:clientPass<\/code>. That&#8217;s just how it is \ud83d\ude09<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>def get_adapter_definition() -&gt; AdapterDefinition: # type: ignore\n    definition = AdapterDefinition(ADAPTER_KIND, ADAPTER_NAME) \n\n    definition.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_string_parameter<\/mark>(\n        \"ID\",\n        label=\"ID\",\n        description=\"Example identifier. Using a value of 'bad' will cause test connection to fail; any other value will pass.\",\n        required=True,\n    )\n\n    definition.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_int_parameter<\/mark>(\n        \"container_memory_limit\",\n        label=\"Adapter Memory Limit (MB)\",\n        description=\"Sets the maximum amount of memory VMware Aria Operations can allocate to the container running this adapter instance.\",\n        required=True,\n        advanced=True,\n        default=1024,\n    )\n\n    definition.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_string_parameter<\/mark>(\n        constants.HOST_IDENTIFIER,\n        label=\"Host\",\n        description=\"FQDN or IP of the SmartHome Central Unit.\",\n        required=True,\n        default=\"192.168.0.116\",\n    )\n\n    definition.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_int_parameter<\/mark>(\n        constants.PORT_IDENTIFIER,\n        label=\"TCP Port\",\n        description=\"TCP Port SmartHome is listening on.\",\n        required=True,\n        advanced=True,\n        default=8080,\n    )\n\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">credential<\/mark> = definition.define_credential_type(\"smarthome_user\", \"Credential\")\n    credential.define_string_parameter(constants.USER_CREDENTIAL, \"User Name\") \n    credential.define_password_parameter(constants.PASSWORD_CREDENTIAL, \"Password\") \n\n  <strong>  <mark style=\"background-color:#fcb900\" class=\"has-inline-color has-vivid-red-color\"># Object types definition section<\/mark><\/strong>\n\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">system<\/mark> = definition.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_object_type<\/mark>(\"system\", \"System\")\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\">system<\/mark>.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_string_property<\/mark>(\"systemid\", \"SystemID\")\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">device<\/mark> = definition.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_object_type<\/mark>(\"device\", \"Device\")\n    device.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_string_property<\/mark>(\"id\", \"ID\")\n    device.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_string_property<\/mark>(\"serialnumber\", \"Serial Number\")\n    device.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_string_property<\/mark>(\"name\", \"Name\")\n    device.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">define_metric<\/mark>(\"version\", \"Version\")\n\n    return definition<\/code><\/pre>\n\n\n\n<h6 class=\"wp-block-heading\">Test Method<\/h6>\n\n\n\n<p>Now, let&#8217;s inspect the <code>test(adapter_instance: AdapterInstance)<\/code> method.<\/p>\n\n\n\n<p>The test method is usually relatively simple, as it is primarily used to <strong>check<\/strong> the <strong>connection<\/strong> to the endpoint. That is, whether the FQDN or IP address is correct, the port is right, the authentication works, etc.<br>My test method establishes <strong>two<\/strong> <strong>connections<\/strong>. First, I need to <strong>obtain<\/strong> a <strong>token<\/strong>, which is required for all other API calls; this is marked in blue. With this token, I can perform the second call, which is the green code.<br>The details, of course, depend on the endpoint. The SmartHome API provides tokens via <code>auth\/token<\/code>, and the test calls the <code>status<\/code> REST method.<br>To make my work easier, I have outsourced the creation of a REST client to a separate class.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>def test(adapter_instance: AdapterInstance) -&gt; TestResult:\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">result = TestResult()\n    host = adapter_instance.get_identifier_value(constants.HOST_IDENTIFIER)\n    port = adapter_instance.get_identifier_value(constants.PORT_IDENTIFIER)\n    base_url = \"http:\/\/\" + str(host) + \":\" + str(port)\n    user = adapter_instance.get_credential_value(constants.USER_CREDENTIAL)\n    password = adapter_instance.get_credential_value(constants.PASSWORD_CREDENTIAL)\n    payload = {\n        \"username\": user,\n        \"password\": password,\n        \"grant_type\": \"password\"\n    }\n\n    headers = {\n        'Authorization': 'Basic Y*****=',  # Replace YOUR_ACCESS_TOKEN with your actual access token\n        'Content-Type': 'application\/json',\n        'Accept': '*\/*',\n        'Accept-Encoding': 'gzip, deflate'\n    }\n    json_payload = json.dumps(payload)\n\n    client = RestClient(base_url)\n    status_code, response_data = client.post(\"auth\/token\", headers, json_payload)\n    if status_code == 200:\n        sh_token = response_data.get(\"access_token\")\n    else:\n        logger.error(\"Error:\", status_code)<\/mark>\n\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">client = None\n    headers = None\n    headers = {\n        'Authorization': 'Bearer ' + sh_token,\n        'Content-Type': 'application\/json',\n        'Accept': '*\/*',\n        'Accept-Encoding': 'gzip, deflate'\n    }\n    client = RestClient(base_url)\n    status_code, response_data = client.get(\"status\", headers)<\/mark>\n\n    return result<\/code><\/pre>\n\n\n\n<p>And here is the code of my <code>RestClient<\/code> class. As for now, I have defined a <code><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">get<\/mark><\/code> and a <code><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">post<\/mark><\/code> method.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>import requests\n\nclass RestClient:\n    def __init__(self, base_url):\n        self.base_url = base_url\n\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">def get(self, endpoint, headers):\n        url = f\"{self.base_url}\/{endpoint}\"\n        response = requests.get(url, headers=headers)\n        status_code = response.status_code\n\n        if response.ok:\n            try:\n                json_data = response.json()\n                return status_code, json_data\n            except ValueError:\n                return status_code, None\n        else:\n            return status_code, None<\/mark>\n\n    <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">def post(self, endpoint, headers, payload):\n        url = f\"{self.base_url}\/{endpoint}\"\n        response = requests.post(url, headers=headers, data=payload)\n        status_code = response.status_code\n\n        if response.ok:\n            try:\n                json_data = response.json()\n                return status_code, json_data\n            except ValueError:\n                return status_code, \"VALUE ERROR\"\n        else:\n            return status_code, \"ERROR\"<\/mark><\/code><\/pre>\n\n\n\n<h6 class=\"wp-block-heading\">Collect Method<\/h6>\n\n\n\n<p>The <code>collect(adapter_instance: AdapterInstance)<\/code> method is the actual heart of the adapter. As the name suggests, this method ensures that we get data from the endpoint and use this data to build our objects and assign metrics and properties to them. In my code, for example, I manually created two instances of the <code><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">system<\/mark><\/code> object type, not based on a response from SmartHome, simply to show how an instance is built and how, for example, a property is assigned a value.<\/p>\n\n\n\n<p>On the other hand, the instances of the <code><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\">device<\/mark><\/code> object type are built from the responses of the appropriate REST call. I have outsourced this functionality to a separate <code>DeviceCollector<\/code> class.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>def collect(adapter_instance: AdapterInstance) -> CollectResult:\n    with Timer(logger, \"Collection\"):\n        result = CollectResult()\n        try:\n            host = adapter_instance.get_identifier_value(constants.HOST_IDENTIFIER)\n            port = adapter_instance.get_identifier_value(constants.PORT_IDENTIFIER)\n            base_url = \"http:\/\/\" + str(host) + \":\" + str(port)\n            logger.info(base_url)\n\n            user = adapter_instance.get_credential_value(constants.USER_CREDENTIAL)\n            password = adapter_instance.get_credential_value(constants.PASSWORD_CREDENTIAL)\n            payload = {\n                \"username\": user,\n                \"password\": password,\n                \"grant_type\": \"password\"\n            }\n\n            headers = {\n                'Authorization': 'Basic xxxx=',\n                # Replace YOUR_ACCESS_TOKEN with your actual access token\n                'Content-Type': 'application\/json',\n                'Accept': '*\/*',\n                'Accept-Encoding': 'gzip, deflate'\n            }\n\n            json_payload = json.dumps(payload)\n\n            client = RestClient(base_url)\n            status_code, response_data = client.post(\"auth\/token\", headers, json_payload)\n            if status_code == 200:\n                sh_token = response_data.get(\"access_token\")\n            else:\n                logger.error(\"Error:\", status_code)\n\n            <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">system01 = result.object(ADAPTER_KIND, \"system\", \"System\")\n            system01.with_property(\"systemid\", \"SH-Manager01\")\n            system02 = result.object(ADAPTER_KIND, \"system\", \"NewSystem\")\n            system02.with_property(\"systemid\", \"SH-Manager02\")<\/mark>\n\n            <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\">devicecollector = DeviceCollector(adapter_instance, sh_token, host, result, logger)<\/mark>\n\n            result = devicecollector.collect()\n\n        except Exception as e:\n            logger.error(\"Unexpected collection error\")\n            logger.exception(e)\n            result.with_error(\"Unexpected collection error: \" + repr(e))\n        finally:\n            # TODO: If any connections are still open, make sure they are closed before returning\n            logger.debug(f\"Returning collection result {result.get_json()}\")\n            return result<\/code><\/pre>\n\n\n\n<p>Of course, the code is far from finished. All metrics are still missing, and the object type <code>device<\/code> is not specific enough; these are just the first simple steps. The following two screenshots show how the result will look later in <strong>Aria Operations Inventory<\/strong>.&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"455\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-4-1024x455.png\" alt=\"\" class=\"wp-image-2100\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-4-1024x455.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-4-300x133.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-4-768x341.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-4-1536x682.png 1536w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-4-2048x909.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 03: System object type instance.<\/em><\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-5.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"397\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-5-1024x397.png\" alt=\"\" class=\"wp-image-2102\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-5-1024x397.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-5-300x116.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-5-768x298.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-5-1536x595.png 1536w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-5-2048x793.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 04: Device object type instance.<\/em><\/figcaption><\/figure>\n\n\n\n<p>The DeviceCollector method is structured very simply. A REST call is executed to get data about all devices, then the received JSON is iterated over, and for each device in the JSON, an instance of the object type &#8216;device&#8217; is created. Each instance is then assigned a few properties and a metric (yes, I know, it&#8217;s not a real property, this is just for demonstration purposes). The whole thing is passed back to collect(), and voila, we&#8217;re done.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>class DeviceCollector:\n    def __init__(self, adapter_instance, token, fqdn, result, logger):\n        self.fqdn = fqdn\n        self.token = token\n        self.result = result\n        self.logger = logger\n        self.adapter_instance = adapter_instance\n\n    def collect(self):\n        host = self.adapter_instance.get_identifier_value(constants.HOST_IDENTIFIER)\n        port = self.adapter_instance.get_identifier_value(constants.PORT_IDENTIFIER)\n        base_url = \"http:\/\/\" + str(host) + \":\" + str(port)\n        headers = {\n            'Authorization': 'Bearer ' + self.token,\n            'Content-Type': 'application\/json',\n            'Accept': '*\/*',\n            'Accept-Encoding': 'gzip, deflate'\n        }\n        client = RestClient(base_url)\n        # Make a GET request to the device endpoint\n        status_code, response_data = client.get(\"device\", headers)\n        if status_code == 200:\n            for obj in response_data:\n                self.logger.info(\"Device ID:\" + obj&#91;\"id\"])\n                self.logger.info(\"Serial Number:\" + obj&#91;\"serialNumber\"])\n                self.logger.info(\"Device Name:\" + obj&#91;\"config\"]&#91;\"name\"])\n                <mark style=\"background-color:#fcb900\" class=\"has-inline-color has-vivid-red-color\"><strong># creating object and adding it to the result set<\/strong><\/mark>\n                <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">device_obj = self.result.object(ADAPTER_KIND, \"device\", obj&#91;\"config\"]&#91;\"name\"])\n                device_obj.with_property(\n                    \"id\", obj&#91;\"id\"]\n                )\n                device_obj.with_property(\n                    \"serialnumber\", obj&#91;\"serialNumber\"]\n                )\n                device_obj.with_metric(\n                    \"version\", obj&#91;\"version\"]\n                )<\/mark>\n        else:\n            self.logger.error(\"Error:\", status_code)\n\n        return self.result<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Testing<\/h5>\n\n\n\n<p>Now it&#8217;s time to test the whole thing. For this purpose, we have our <code>mp-test<\/code> command, and first, I&#8217;m using it to test the connection to my SmartHome central unit. For this, I select the <strong>Test Connection<\/strong> option from the <code>mp-test<\/code> menu.<\/p>\n\n\n\n<p>As can be seen in the following screenshot, the connection works flawlessly, which means that the <code>test<\/code> method is performing its job as desired.&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"370\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8-1024x370.png\" alt=\"\" class=\"wp-image-2111\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8-1024x370.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8-300x108.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8-768x277.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8-1536x555.png 1536w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8-2048x740.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 05: SDK command mp-test run with Test Connection option selected.<\/em><\/figcaption><\/figure>\n\n\n\n<p>The next test checks whether we also receive data and if the <code>collect<\/code> method creates the instances of the object types along with their metrics and properties as intended. For this, the <strong>Collect<\/strong> option is selected from the <code>mp-test<\/code> menu. The following two screenshots show it; I have shortened the JSON output so that the screenshot doesn&#8217;t become too long.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1017\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10-1024x1017.png\" alt=\"\" class=\"wp-image-2115\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10-1024x1017.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10-300x298.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10-150x150.png 150w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10-768x763.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10-1536x1525.png 1536w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-10.png 1966w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 06: SDK command mp-test run with Collect option selected.<\/em><\/figcaption><\/figure>\n\n\n\n<h5 class=\"wp-block-heading\">Building<\/h5>\n\n\n\n<p>Obviously, everything is working, we&#8217;re not getting any error messages, so let&#8217;s move on to the last step within the SDK &#8211; building the Management Pack, which is the actual <strong>.pak<\/strong> <strong>file<\/strong> for VMware Aria Operations. For this, we use the <code>mp-build<\/code> command as seen in the next image.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-11.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"550\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-11-1024x550.png\" alt=\"\" class=\"wp-image-2118\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-11-1024x550.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-11-300x161.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-11-768x412.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-11-1536x825.png 1536w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-11.png 1948w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 07: SDK command mp-build run.<\/em><\/figcaption><\/figure>\n\n\n\n<p>We now find the finished file in the Docker repository, which was specified when configuring the development environment, or, what is much quicker for us, in the <code>build<\/code> folder.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-12.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"117\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-12-1024x117.png\" alt=\"\" class=\"wp-image-2120\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-12-1024x117.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-12-300x34.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-12-768x88.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-12.png 1348w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 08: Management Pack -pak file.<\/em><\/figcaption><\/figure>\n\n\n\n<h5 class=\"wp-block-heading\">Deployment<\/h5>\n\n\n\n<p>Now we just need to install the Management Pack in the usual way into the <strong>Aria Operations Integrations Inventory<\/strong>, as shown in the next image, so that we can immediately create an adapter instance.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-13.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"821\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-13-1024x821.png\" alt=\"\" class=\"wp-image-2122\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-13-1024x821.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-13-300x241.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-13-768x616.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-13.png 1454w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 09: Management Pack in Aria Operations Inventory.<\/em><\/figcaption><\/figure>\n\n\n\n<p>In the adapter settings, we can beautifully see the options that were defined in the <code>get_adapter_definition()<\/code> method.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-14.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"994\" src=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-14-1024x994.png\" alt=\"\" class=\"wp-image-2123\" srcset=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-14-1024x994.png 1024w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-14-300x291.png 300w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-14-768x746.png 768w, https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-14.png 1514w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\"><em>Figure 10: Adapter Instance configuration.<\/em><\/figcaption><\/figure>\n\n\n\n<h5 class=\"wp-block-heading\">Outlook<\/h5>\n\n\n\n<p>That&#8217;s it for now. There are still many open construction sites in my Management Pack, but since I&#8217;m not a programmer and have practically no extensive experience with Python, it will take a while before the results are really presentable. Next, I&#8217;ll look at how to create relationships in the code.<br><\/p>\n\n\n\n<p>If you&#8217;re more interested in the topic and happen to be visiting <a href=\"https:\/\/www.vmware.com\/explore\/eu?utm_source=google&amp;utm_medium=ppc&amp;utm_campaign=vmware_explore&amp;utm_term=barcelona&amp;utm_content=eu_phrase&amp;gad_source=1&amp;gclid=Cj0KCQjwmt24BhDPARIsAJFYKk1ENxpgxewvIaJWTt-nzfCms5ILSEzmjbCg47K8ViJMPWnGV_7kqIoaAvxtEALw_wcB\">VMware Explore Barcelona 2024<\/a>, come to my session Building Solutions: <a href=\"https:\/\/event.vmware.com\/flow\/vmware\/explore2024bcn\/content\/page\/catalog?search=%22Thomas%20Kopton%22&amp;tab.contentcatalogtabs=1627421929827001vRXW#:~:text=Step%2Dby%2DStep-,Guide,-with%20Aria%20Operations\" data-type=\"link\" data-id=\"https:\/\/event.vmware.com\/flow\/vmware\/explore2024bcn\/content\/page\/catalog?search=%22Thomas%20Kopton%22&amp;tab.contentcatalogtabs=1627421929827001vRXW#:~:text=Step%2Dby%2DStep-,Guide,-with%20Aria%20Operations\">Step-by-Step Guide with Aria Operations Integration SDK [CODE1376BCN]<\/a> and ask questions \ud83d\ude42<\/p>\n\n\n\n<p><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">Stay<\/mark><\/strong> <strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#f5d800\" class=\"has-inline-color\">safe<\/mark><\/strong>.<\/p>\n\n\n\n<p>Thomas \u2013&nbsp;<a href=\"https:\/\/twitter.com\/ThomasKopton\">https:\/\/twitter.com\/ThomasKopton<\/a><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the first post on the topic of VMware Operations Integration SDK, I showed how I prepared my development environment and how a demo project is created using the triad of mp-init, mp-test, and mp-build. In this post, we&#8217;ll take a closer look at which files a simple, REST API-based project consists of, as well &#8230;<\/p>\n","protected":false},"author":1,"featured_media":2111,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57,81],"tags":[58,82,85,83,84],"class_list":["post-2052","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aria-operations","category-integration-sdk","tag-aria-operations","tag-integration-sdk","tag-integrations","tag-management-pack","tag-solutions"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>VMware Aria Operations Integration SDK - Part 2 - Demo Project - TOMsOps<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thomas-kopton.de\/vblog\/?p=2052\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"VMware Aria Operations Integration SDK - Part 2 - Demo Project - TOMsOps\" \/>\n<meta property=\"og:description\" content=\"In the first post on the topic of VMware Operations Integration SDK, I showed how I prepared my development environment and how a demo project is created using the triad of mp-init, mp-test, and mp-build. In this post, we&#8217;ll take a closer look at which files a simple, REST API-based project consists of, as well ...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/thomas-kopton.de\/vblog\/?p=2052\" \/>\n<meta property=\"og:site_name\" content=\"TOMsOps\" \/>\n<meta property=\"article:published_time\" content=\"2024-10-22T13:30:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-22T15:18:50+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2220\" \/>\n\t<meta property=\"og:image:height\" content=\"802\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Thomas Kopton\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Thomas Kopton\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#article\",\"isPartOf\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052\"},\"author\":{\"name\":\"Thomas Kopton\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/892d6b96c66b1dd4b75c6e32fdbfea82\"},\"headline\":\"VMware Aria Operations Integration SDK &#8211; Part 2 &#8211; Demo Project\",\"datePublished\":\"2024-10-22T13:30:31+00:00\",\"dateModified\":\"2024-10-22T15:18:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052\"},\"wordCount\":1465,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage\"},\"thumbnailUrl\":\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png\",\"keywords\":[\"Aria Operations\",\"integration sdk\",\"integrations\",\"management pack\",\"solutions\"],\"articleSection\":[\"Aria Operations\",\"Integration SDK\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052\",\"url\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052\",\"name\":\"VMware Aria Operations Integration SDK - Part 2 - Demo Project - TOMsOps\",\"isPartOf\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage\"},\"image\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage\"},\"thumbnailUrl\":\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png\",\"datePublished\":\"2024-10-22T13:30:31+00:00\",\"dateModified\":\"2024-10-22T15:18:50+00:00\",\"author\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/892d6b96c66b1dd4b75c6e32fdbfea82\"},\"breadcrumb\":{\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/thomas-kopton.de\/vblog\/?p=2052\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage\",\"url\":\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png\",\"contentUrl\":\"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png\",\"width\":2220,\"height\":802},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/?p=2052#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/thomas-kopton.de\/vblog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"VMware Aria Operations Integration SDK &#8211; Part 2 &#8211; Demo Project\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/#website\",\"url\":\"https:\/\/thomas-kopton.de\/vblog\/\",\"name\":\"TOMsOps\",\"description\":\"Just another VMware Cloud Management Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/thomas-kopton.de\/vblog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/892d6b96c66b1dd4b75c6e32fdbfea82\",\"name\":\"Thomas Kopton\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e746aafbd3733172ceb4d600ba1feda61bc87cd3b70f5a9dfb581907cc7973b1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e746aafbd3733172ceb4d600ba1feda61bc87cd3b70f5a9dfb581907cc7973b1?s=96&d=mm&r=g\",\"caption\":\"Thomas Kopton\"},\"url\":\"https:\/\/thomas-kopton.de\/vblog\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"VMware Aria Operations Integration SDK - Part 2 - Demo Project - TOMsOps","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:\/\/thomas-kopton.de\/vblog\/?p=2052","og_locale":"en_US","og_type":"article","og_title":"VMware Aria Operations Integration SDK - Part 2 - Demo Project - TOMsOps","og_description":"In the first post on the topic of VMware Operations Integration SDK, I showed how I prepared my development environment and how a demo project is created using the triad of mp-init, mp-test, and mp-build. In this post, we&#8217;ll take a closer look at which files a simple, REST API-based project consists of, as well ...","og_url":"https:\/\/thomas-kopton.de\/vblog\/?p=2052","og_site_name":"TOMsOps","article_published_time":"2024-10-22T13:30:31+00:00","article_modified_time":"2024-10-22T15:18:50+00:00","og_image":[{"width":2220,"height":802,"url":"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png","type":"image\/png"}],"author":"Thomas Kopton","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Thomas Kopton","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052#article","isPartOf":{"@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052"},"author":{"name":"Thomas Kopton","@id":"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/892d6b96c66b1dd4b75c6e32fdbfea82"},"headline":"VMware Aria Operations Integration SDK &#8211; Part 2 &#8211; Demo Project","datePublished":"2024-10-22T13:30:31+00:00","dateModified":"2024-10-22T15:18:50+00:00","mainEntityOfPage":{"@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052"},"wordCount":1465,"commentCount":0,"image":{"@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage"},"thumbnailUrl":"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png","keywords":["Aria Operations","integration sdk","integrations","management pack","solutions"],"articleSection":["Aria Operations","Integration SDK"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/thomas-kopton.de\/vblog\/?p=2052#respond"]}]},{"@type":"WebPage","@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052","url":"https:\/\/thomas-kopton.de\/vblog\/?p=2052","name":"VMware Aria Operations Integration SDK - Part 2 - Demo Project - TOMsOps","isPartOf":{"@id":"https:\/\/thomas-kopton.de\/vblog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage"},"image":{"@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage"},"thumbnailUrl":"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png","datePublished":"2024-10-22T13:30:31+00:00","dateModified":"2024-10-22T15:18:50+00:00","author":{"@id":"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/892d6b96c66b1dd4b75c6e32fdbfea82"},"breadcrumb":{"@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thomas-kopton.de\/vblog\/?p=2052"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052#primaryimage","url":"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png","contentUrl":"https:\/\/thomas-kopton.de\/vblog\/wp-content\/uploads\/2024\/10\/image-8.png","width":2220,"height":802},{"@type":"BreadcrumbList","@id":"https:\/\/thomas-kopton.de\/vblog\/?p=2052#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/thomas-kopton.de\/vblog"},{"@type":"ListItem","position":2,"name":"VMware Aria Operations Integration SDK &#8211; Part 2 &#8211; Demo Project"}]},{"@type":"WebSite","@id":"https:\/\/thomas-kopton.de\/vblog\/#website","url":"https:\/\/thomas-kopton.de\/vblog\/","name":"TOMsOps","description":"Just another VMware Cloud Management Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/thomas-kopton.de\/vblog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/892d6b96c66b1dd4b75c6e32fdbfea82","name":"Thomas Kopton","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/thomas-kopton.de\/vblog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e746aafbd3733172ceb4d600ba1feda61bc87cd3b70f5a9dfb581907cc7973b1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e746aafbd3733172ceb4d600ba1feda61bc87cd3b70f5a9dfb581907cc7973b1?s=96&d=mm&r=g","caption":"Thomas Kopton"},"url":"https:\/\/thomas-kopton.de\/vblog\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=\/wp\/v2\/posts\/2052","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2052"}],"version-history":[{"count":61,"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=\/wp\/v2\/posts\/2052\/revisions"}],"predecessor-version":[{"id":2130,"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=\/wp\/v2\/posts\/2052\/revisions\/2130"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=\/wp\/v2\/media\/2111"}],"wp:attachment":[{"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2052"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2052"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thomas-kopton.de\/vblog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2052"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}