Highlighted
Absent Member.. Absent Member..
Absent Member..
275 views

DDMI/Connect It to UD/UCMDB product integration - Hardware.xml normalization in Asset Manager

Jump to solution
Hello expefrts. I have a client going from DDMi/ConnectIt to UD/UCMDB. This is about the fourth project I have done something similar to this on. Everything in the push to AM adapters seems to be going smoothly, except we did notice that we have some duplicatgion of hardware models. I have seen this issue in past engagements also. Looking at the Hardware.xml mapping and comparing it to the Software.xml mapping, I notice that the software references the InventModel table. That does not exist in the Hardware mapping. I think in the past what I have done to solve this was to copy and past the normalization code into Hardware.xml, tweak it as needed and it worked fine. Does this sound like a feasible approach? I can't recall exactly if that was the solution so any help is greatly appreciated. Thanks.
0 Likes
1 Solution

Accepted Solutions
Highlighted
Outstanding Contributor.
Outstanding Contributor.

Re: DDMI/Connect It to UD/UCMDB product integration - Hardware.xml normalization in Asset Manager

Jump to solution

The Invent Model table is only used for mapping software to a normalized final model in the amModel table. For Hardware what you will want to do is review pushMappingAMComputer.xml and decide how best to enter your models so that they reconcile with what is in the amModel table in HPAM. For instance, whether to use the toSmart() method on model names which will capitalize the first letter of each word (i.e. ProLiant DL360 G2 will change to Proliant Dl360 G2). I also switched the order for populating the variable vModelName to Root['discovered_model'] first and then Root['node_model'] if empty.

 

Do some clean up of your amModel table and move associated records from the duplicate models to the model you want going forward then delete the duplicate model. I use a calculated field called Portfolio Count in the amModel table to see how many portfolio records are associated to each model.

(SELECT Sum(fQty) FROM amPortfolio WHERE lModelId = amModel.lModelId)

I remove any models that have zero portfolio records.

 

 

I also move models so that they are in a logical hierarchy and have a parent model based on the type of device.

 

Creating this structure then enables me to use the model name and model parent as the reconciliation key and link the model by reference to the node.

am-push-mapping.xml:

    <am-mapping ci-type="amModel" primary-key="lModelId" operation-type="insert_else_reference" merge-allowed="true" parallel-push-allowed="true">
        <reconciliation>
            <reconciliation-keys>
                <reconciliation-key>Name</reconciliation-key>
                <reconciliation-key>lParentId</reconciliation-key>
            </reconciliation-keys>
        </reconciliation>
        <reference-attribute ci-name="amBrand" datatype="STRING" name="lBrandId" reference-direction="child"/>
        <reference-attribute ci-name="amNature" datatype="STRING" name="lNatureId" reference-direction="child"/>
        <reference-attribute ci-name="amModel-Parent" datatype="STRING" name="lParentId" reference-direction="child"/>
        <action-on-delete>
            <ignore/>
        </action-on-delete>
    </am-mapping>

 

To get the correct model parent I created a dynamic lookup table in pushMappingAMComputer.xml

            <dynamic_mapping name="ParentBarCodeByModelName" keys-unique="true">
                <map_property property-name="AQLQuery" datatype="STRING"
                              property-value="SELECT Lower(Name), Parent.BarCode FROM amModel WHERE Nature.Code IN ('CPU','CPUVM')"/>                              
            </dynamic_mapping>

I then created a custom method in AMPushFunctions.groovy

 

    public static String getMyModelParentBarCode(boolean iIsComputerAVM, def dynamicMapHolder, String modelName, nodeRole) {
        if(iIsComputerAVM){
            return MODEL_VM_AC50;
        }
        else{     
            def modelParentBarCodeMap = dynamicMapHolder.getMap("ParentBarCodeByModelName");
            if(isNull(modelParentBarCodeMap)){
                throw new MessageOnlyPushMappingException("Model parent map is missing.", WARNING_MAPPING_CI_ERROR_ID);
            }
            else if(isNull(modelParentBarCodeMap.get(modelName))){
                //throw new MessageOnlyPushMappingException("Asset Manager has no parent model for model name ["+modelName+"].", WARNING_MAPPING_CI_ERROR_ID);
                if(fIsEmpty(nodeRole)){
                    return 'UNKCHASSIS';
                } else {
                    if(nodeRole.contains('server') && !nodeRole.contains('desktop')){
                        return SERVER_CODE;
                    } else if(nodeRole.contains('desktop') && !nodeRole.contains('server')){
                        return MODEL_WORKSTATION_AC50;
                    }
                }
                //Unknown model and unknown node role
                return 'UNKCHASSIS';
            }
            return modelParentBarCodeMap.get(modelName);
        }
    }

I then call that custom method in pushMappingAMComputer.xml

 

                    <target_ci_type name="amModel">
                        <target_mapping name="CPUType" datatype="STRING" value="vCpuSpecifier"/>
                        <target_mapping name="Name" datatype="STRING" ignore-on-null="false" value="vModelName"/>
                        <target_ci_type name="amBrand">
                            <target_mapping name="Name" datatype="STRING" value="AMPushFunctions.getBrandName(Root['discovered_vendor'],Root['vendor'])"/>
                        </target_ci_type>
                        <target_ci_type name="amNature">
                            <target_mapping name="Code" datatype="STRING" value="vNatureCode"/>
                        </target_ci_type>
                        <target_ci_type name="amModel-Parent">
                            <target_mapping name="BarCode" datatype="STRING" ignore-on-null="false" value="AMPushFunctions.getMyModelParentBarCode(iIsComputerAVM, DynamicMapHolder, vModelName.toLowerCase(), Root['node_role'])"/>
                        </target_ci_type>
                        <before-mapping>Logger.debug('before')</before-mapping>
                        <after-mapping>Logger.debug('vModelName:'+vModelName)</after-mapping>
                    </target_ci_type>

 

Since the model is linked by reference I don't have to worry about the model names getting duplicated or changing case.

View solution in original post

2 Replies
Highlighted
Outstanding Contributor.
Outstanding Contributor.

Re: DDMI/Connect It to UD/UCMDB product integration - Hardware.xml normalization in Asset Manager

Jump to solution

The Invent Model table is only used for mapping software to a normalized final model in the amModel table. For Hardware what you will want to do is review pushMappingAMComputer.xml and decide how best to enter your models so that they reconcile with what is in the amModel table in HPAM. For instance, whether to use the toSmart() method on model names which will capitalize the first letter of each word (i.e. ProLiant DL360 G2 will change to Proliant Dl360 G2). I also switched the order for populating the variable vModelName to Root['discovered_model'] first and then Root['node_model'] if empty.

 

Do some clean up of your amModel table and move associated records from the duplicate models to the model you want going forward then delete the duplicate model. I use a calculated field called Portfolio Count in the amModel table to see how many portfolio records are associated to each model.

(SELECT Sum(fQty) FROM amPortfolio WHERE lModelId = amModel.lModelId)

I remove any models that have zero portfolio records.

 

 

I also move models so that they are in a logical hierarchy and have a parent model based on the type of device.

 

Creating this structure then enables me to use the model name and model parent as the reconciliation key and link the model by reference to the node.

am-push-mapping.xml:

    <am-mapping ci-type="amModel" primary-key="lModelId" operation-type="insert_else_reference" merge-allowed="true" parallel-push-allowed="true">
        <reconciliation>
            <reconciliation-keys>
                <reconciliation-key>Name</reconciliation-key>
                <reconciliation-key>lParentId</reconciliation-key>
            </reconciliation-keys>
        </reconciliation>
        <reference-attribute ci-name="amBrand" datatype="STRING" name="lBrandId" reference-direction="child"/>
        <reference-attribute ci-name="amNature" datatype="STRING" name="lNatureId" reference-direction="child"/>
        <reference-attribute ci-name="amModel-Parent" datatype="STRING" name="lParentId" reference-direction="child"/>
        <action-on-delete>
            <ignore/>
        </action-on-delete>
    </am-mapping>

 

To get the correct model parent I created a dynamic lookup table in pushMappingAMComputer.xml

            <dynamic_mapping name="ParentBarCodeByModelName" keys-unique="true">
                <map_property property-name="AQLQuery" datatype="STRING"
                              property-value="SELECT Lower(Name), Parent.BarCode FROM amModel WHERE Nature.Code IN ('CPU','CPUVM')"/>                              
            </dynamic_mapping>

I then created a custom method in AMPushFunctions.groovy

 

    public static String getMyModelParentBarCode(boolean iIsComputerAVM, def dynamicMapHolder, String modelName, nodeRole) {
        if(iIsComputerAVM){
            return MODEL_VM_AC50;
        }
        else{     
            def modelParentBarCodeMap = dynamicMapHolder.getMap("ParentBarCodeByModelName");
            if(isNull(modelParentBarCodeMap)){
                throw new MessageOnlyPushMappingException("Model parent map is missing.", WARNING_MAPPING_CI_ERROR_ID);
            }
            else if(isNull(modelParentBarCodeMap.get(modelName))){
                //throw new MessageOnlyPushMappingException("Asset Manager has no parent model for model name ["+modelName+"].", WARNING_MAPPING_CI_ERROR_ID);
                if(fIsEmpty(nodeRole)){
                    return 'UNKCHASSIS';
                } else {
                    if(nodeRole.contains('server') && !nodeRole.contains('desktop')){
                        return SERVER_CODE;
                    } else if(nodeRole.contains('desktop') && !nodeRole.contains('server')){
                        return MODEL_WORKSTATION_AC50;
                    }
                }
                //Unknown model and unknown node role
                return 'UNKCHASSIS';
            }
            return modelParentBarCodeMap.get(modelName);
        }
    }

I then call that custom method in pushMappingAMComputer.xml

 

                    <target_ci_type name="amModel">
                        <target_mapping name="CPUType" datatype="STRING" value="vCpuSpecifier"/>
                        <target_mapping name="Name" datatype="STRING" ignore-on-null="false" value="vModelName"/>
                        <target_ci_type name="amBrand">
                            <target_mapping name="Name" datatype="STRING" value="AMPushFunctions.getBrandName(Root['discovered_vendor'],Root['vendor'])"/>
                        </target_ci_type>
                        <target_ci_type name="amNature">
                            <target_mapping name="Code" datatype="STRING" value="vNatureCode"/>
                        </target_ci_type>
                        <target_ci_type name="amModel-Parent">
                            <target_mapping name="BarCode" datatype="STRING" ignore-on-null="false" value="AMPushFunctions.getMyModelParentBarCode(iIsComputerAVM, DynamicMapHolder, vModelName.toLowerCase(), Root['node_role'])"/>
                        </target_ci_type>
                        <before-mapping>Logger.debug('before')</before-mapping>
                        <after-mapping>Logger.debug('vModelName:'+vModelName)</after-mapping>
                    </target_ci_type>

 

Since the model is linked by reference I don't have to worry about the model names getting duplicated or changing case.

View solution in original post

Highlighted
Absent Member.. Absent Member..
Absent Member..

Re: DDMI/Connect It to UD/UCMDB product integration - Hardware.xml normalization in Asset Manager

Jump to solution
This is wonderful John. THANK YOU MUCH!
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.