The Tideway Foundation model, and TPL, has been designed to be easy to do the common tasks with the minimum of TPL. There are a number of sections of TPL that assist this in having additional behaviour. In particular as the majority of custom pattern writing is to understand bespoke software and business applications there is a lot of additional behaviour in these areas and around the way those nodekinds are used.
In particular the call model.SoftwareInstane() does more than just find or create the node. Behind the scenes the TPL execution is tracking the triggers and data access in order to build the inference relationships for you. When you ask it to create an SI it uses this information to also find the Host.
When creating a First Order SI (that is one triggered directly off DDD) then it detects this through seeing that the trigger is to a DDD node. TPL then builds the InferredElement:Inference:Primary inference relationship for you, the InferredElement:Inference:Contributor(s) if you used any data from nodes other than the one you triggered on, supersedes the old inferences if it is an update, and also builds the RunningSoftware:HostedSoftware:Host:Host relationship. It can do this as the DDD is already related to the Host and TPL knows how to do the navigation needed. This saves you having to understand this navigation and writing many lines of TPL over and over in each pattern. Note that this works for any DDD node though by far the most frequent will be the DiscoveredProcess node.
When it comes to building a second order node (i.e. one triggered off an inferred node) then the situation is a little different. This is because the Foundation Model expects a BAI to be composed of one or many SIs. So when you call model.BusinessApplicationInstance() the TPL execution detects that in this case the trigger is an SI and knows to build the primary inference relationship for you, but does not build the InferredElement:Inference:Primary relationship. Instead you have to tell TPL which SI nodes this BAI contains using the call model.addContainment(bai, si). The TPL execution will at this point know to build the required ContainedSoftware:SoftwareContainment:SoftwareContainer:BusinessApplicationInstance relationship. It will also traverse down the hierarchy to find the Host nodes that all the component parts are running on and build the required RunningSoftware:HostedSoftware:Host:Host relationships. Thus a BAI that has component SIs across more than one host will be linked to each of the Host nodes.
Worthwhile reading would be the example application models in the Application Modelling Guide, in particular the BAI pattern. These examples are a condensed version of what we teach in our 2 day application modelling workshop.
I do recommend that as you try extending TPL you might find it easier to use a BAI rather than a SI to represent the business use of the website.
However if you want to use a second order SI then you need to build the pattern in the same way as a BAI using addContainment(). Once you are confident you have the basic pattern working you will also need to consider the maintenance of the model you are building; such that if websites are removed from the webservers the pattern also removes the node that represents them in the inferred model.
The best way to do this is in a single pattern triggered off the webserver SI to avoid any race conditions.
Then derive a list of the websites that you know are running now from the IIS SI, in fact you can simply copy the list version of the attribute it’s there for this reason.
Next search for the existing set of related SIs representing the website in the inferred model.
You can now iterate through the derived list of websites creating or updating the website SI as appropriate.
If you then correlate the two lists you will be able to determine which of the existing SIs you now need to call model.destroy() for to remove them from the inferred model.
In order to assist you in the searching I’d recommend that you set a specific type on the SIs representing the websites, maybe type = “IIS website”. This will mean that if in future you relate other types of SI to the webserver your search will not accidentally include them and remove them.
For a example of correlating two lists like this have a look at the Sun.Virtualization.Zones.SolarisZoneContainer pattern – around line 130 (I can post it if you don’t have a TKU handy)