Guvnor Dependency Management

Use Case

 

1. Create a workspace.

 

2. Create a module called "mortgage".

 

3. Create an asset under the module.

 

Every asset in the repository has a URL which serves as the permanent link to uniquely identify itself. The URL is version-aware. For example,

 

URL /repository/mortgage/myasset?version=LATEST and /repository/assets/myasset is the latest version

of myasset.

 

URL /repository/mortgage/myasset?version=3 is the version 3 of myasset.

 

4. Create an asset under the Global Area.

 

5. Open Module editor to editor "mortgage" module


5.1. Add dependency /repository/mortgage/myasset?version=LATEST to mortgage module.

5.2. Add dependency /repository/globalarea/myasset?version=LATEST to mortgage module.

 

6. View dependency graph. In Guvnor editor, module editor (and asset editor) displays following info under the DependencyManagement sections:

 

a. WhatDependsOnMe:

b. Dependencies:

 

This allows drawing out a dependency graph so that the potential impact of a change can be evaluated. Users who are interested in the change of certain assets can subscribe to the feed.

 

This also enables multi version graph support. i.e,  a rule of version 12 could depend on a function of version 7.  so I can have a package that has a rule that rule could use a function. Each one of those is a version artifact. So package version 8 references rule version 2 and the rule references function version 1. the numbers are for instance. Lets say I update a class to version 9, a wizard will then tell me all the rules that depend on that class and ask if any of them should be updated to use that version. updating the rule increases it's version. so then any packages that depend on that will also be asked if you want to update them to the latest version. so there is this sort of chain reaction from an update. and also reporting to show you lists of things not running on latest version of an artifact.

 

 

7. Build "mortgage" module.

 

 

 

Features:

 

1. Dependency types:


a. Explicit dependency (Hard dependency): Presume we have a, b, c services, they all depend on inmessage.xsd. The user has to open service editor for service a,b,c then add a dependency of inmessage.xsd explicitly. Once this is done, inmessage.xsd's service editor will display the URL of a,b,c under the whatDependsOnMe section. This information will help to analyze the potential impact if inmessage.xsd is changed. This is called hard dependency because the build of service a,b,c will break if inmessage.xsd is missing or becomes invalid.

 

b. Implicit dependency (soft dependency).

 

2. Build the Module based on the dependency mechanism.

 

A module (for the time being, a module is a Package) must declare all its dependencies explicitly, even when the dependency is under the same module. I.e., like below:

 

       |-- mortgages

       |        |        |---jcr:content:

       |        |              |-- title

       |        |              |-- desc

       |        |              |-- lastModified

       |        |              |-- checkInComment

       |        |              |-- content: empty

       |        |              |-- content_binary: mortgages.jar, this is generated by building mortgages module.

       |        |              |-- DefaultLifeCycle: created

       |        |              |-- dependency (multi-value-property)

       |        |                     --/ROOT/REPOSITORY_AREA/mortgages/BankruptcyHistory.drl

       |        |                     --/ROOT/REPOSITORY_AREA/mortgages/Pricingloans.xls

       |        |                     --/ROOT/REPOSITORY_AREA/mortgages/MortgageModel.jar

       |        |                     --/ROOT/REPOSITORY_AREA/mortgages/Aretheyoldenough

       |        |              |-- moduleType: drools

       |        |              |-- workspace: WorkSpace1

 

 

This way we don't need Package Snapshot anymore. We tag the module, then all its components (and the version of the components) are tagged.

 

 

Some random thoughts:

 

The more I think about dependency management, the more I get confused. We already started to talk about a dependency system that potentially can get very complicated. A module can depend a module, a module can depend on an asset (either depends on the asset directly, or depend on the asset through a module wrapper indirectly). An asset can also depend on an asset. Then we will have to worry about cyclic dependency etc. Further more, all dependencies are versioned, i.e., a module can depend on a certain version of asset. But hold on a minute, do we really need these fancy features? Do we really need a dependency system that is as complicated as maven?

 

Take the Guvnor as an example. Currently Guvnor does not have any so called dependency management, but aren't we just fine? I am not aware of any feature request related to dependencies from the community or from customers. I can only think of three things if there is anything we need to add related to dependency support:

 

1. Change impact analysis:

Generally speaking, if one asset gets changed, we do want to know what impact this change may have. This can be done by analyzing the dependencies. There are two levels of change impact analysis here:

 

a. Change impact on the pacakge level: In Guvnor, assets are contained by packages, this already implies a dependency relationship between packages and assets. If you change the bankruptcy rule under the mortgage package, you already know that the change of bankruptcy rule will impact the mortgage package. The only case that we need an explicit dependency is for global area. This is because assets located under the global area might be shared by multiple packages. With the current Guvnor, it is hard to know what the potential impact is if we change the assets under the global area. It will be helpful if the assets under Global area has a section to display who depend on this asset.  BTW, this is hard dependency.

 

b. Change impact on the asset level: If I change the fact module, it will be helpful if Guvnor can pop up a warning window to tell me this change may have impact on rule A. Or even better, Guvnor validates all other rules that depend on this fact module, then tell me if  this change breaks anything. BTW, this is soft dependency.

 

2. Build the package using an old version of the asset other than the latest

At the moment, if we want to build the package using an old version of the asset other than the latest, you can probably achieve this by using asset filter. It will be great if there is an easier way to do this.

 

3. Package depends on package:

Ppl want want package named a.b.c to see all assets from pacakge a.b. This is can be achieved by making package a.b.c depends on package a.b.

 

How about assets depend on assets? For example, rule A depends on rule B, travelService.wsdl depends on address.xsd? My initial reaction is, yes, this is what we need, this is a very generic request. I cant imagine we come out with a dependency system that does not allow assets depending on assets. However I became not so sure when I gave it a second thought. Still use Guvnor as an example, do we currently allow assets depending on assets? No, we don't. But when a rule uses a fact model, doesn't that mean exactly a rule depends on a model? If you change the fact model (in a bad way), then the rule wont validate. Isn't this the exact reason why we want to have a dependency system? For analyzing change impact? How can Guvnor survive without defining an explicit dependency between rule A and a fact model? I think the secret lies in the fact that for assets included by the same package, there is an assumption that every assets depends on every other assets and the package depends on all assets it includes. So if you change one asset, you have to check if all other assets from the same package still validate. Yes this is a bit simplification, but without this simplification, can you imagine how complex a dependency graph you have to draw for assets from the mortgage package.

 

What is my conclusion? There is no need to define a relationship which is assets depend on assets even though its a very common case that rule A depends on rule B and travelService.wsdl depends on address.xsd. As I mentioned above, the dependency management serves two purposes only. One is for analyzing change impact. One is for building the package (module). For the latter, there is no difference between "package A depends on rule B and rule C (and Rule B depends on rule C)" and "package A depends on rule B and rule C" from package builder's point of view. Building a package is different from a maven build. In maven, there is a difference between "parent pom depends on module B and module C (and module B depends on module C)" and "parent pom A depends on module B and module C" because the parent pom needs to know which module to build first. Package builder does not need this info because it already has its own specific knowledge on how to build a drools package, and this knowledge is not captured and should not be captured by dependency management. This assertion can be applied to other projects I believe. For example, if we are going to provide such a feature in Guvnor to build a web service from Guvnor GUI, then the web service builder will have the knowledge on how to build a web service war, eg, where to find the WSDL, where to find java classes etc. I would imagine this is probably done by calling a maven or ant plugin from GUI. Guvnor is designed for content management and governance, it is not a build system, it is not for replacing maven.

 

To summarize:

 

1. Dependency management only serves for two purposes: One is for analyzing  change impact. One is for building the package (module).

 

2. Package can depend on package (or module can depend on module). this is for package (module) reuse.

 

3. We do not explicitly define a dependency relationship between package and assets contained by this package. However for a package to include an asset from global area, this dependency relationship needs to be defined explicitly. The package and the shared asset from global area will have a section to display "dependencies" and "who depends on me". The "dependencies" is for package to optionally depends on an old version of the shared asset. The "who depends on me" is for the shared asset from global to analyz potential change impact.

 

4. We do not explicitly define a dependency relationship between assets. As this information is not needed by package builder. If we really really want, we can define dependencies between assets, for example "Rule B depends on rule C". But this is only there for analyzing change impact, for information only. It has no impact on the package builder (or any module builder) at all. For example, package A depends on rule B, Rule B depends on rule C, Rule C is not included in package A. During the building of package A, the package builder wont  pull the content of Rule C to package A automatically . In another word, the knowledge of how to build a package (module) is not captured by the dependency management (but don't forget, which version of shared asset from global area to be included in the package build, this information is captured by dependency).

 

Reference: https://docs.google.com/document/d/1tdpMmuWDemsfUYIg4eX0rKezeVXVgKpleikpR84WeLk/edit?hl=en_GB#