Playing with ODI and Groovy – Part 4 – Exporting/Importing ODI Scenarios with SDK


Hi all, I’m back with the continuation of this Groovy and ODI series. Last post we saw how to find the different scenarios between two environments. Today we will look on how we may export those different scenarios from our source repository and how to import them in our target repository. We will do a two-step operation: first we will export the different ODI objects from our source repository as XML files into a folder and then we will import those xml files into our target repository.
Our code is very similar to the one that we did for post 3, but we will need to enhance it a little bit. First thing that we will have to change in our code is the function that creates the list of objects. In the previous post, we were just adding the name of the scenarios to the list. Now we will need to store the object itself in the list, since we will need to have the ODI object (scenario) to have it exported.

def listObjects (odiInstance,odiClass,listOfObjects) {
	odiObjects = odiInstance.getTransactionalEntityManager().getFinder(odiClass).findAll().sort{it.name}
	for (Object odiSingleObject: odiObjects)
		listOfObjects.add(odiSingleObject)
}

Also, we will need to create a variable that will indicate the path where the objects will be temporarily exported.

exportPath = "C:\\Odi"

One import thing that we will need to change is how to compare the objects. In the previous post, we were simply comparing them, as they were strings, which was ok for our propose there. However, now we cannot simple compare the java objects because they will be different even if they represent the same scenario name/version. They are considered “different” because they came from different environments and logically, they represent different ODI entities.

diffScenarios = []
	for (Object odiSingleObject: sourceScenarios)
		if (targetScenarios.find {targetScenarios -> targetScenarios.getName() == odiSingleObject.getName() && targetScenarios.getVersion() == odiSingleObject.getVersion()}.equals(null))
			if (odiSingleObject.getName().startsWith('TEST'))
				diffScenarios.add(odiSingleObject)

I’m basically doing three tests to see if the source scenario will be migrated or not: first I compare its name, than its version and finally if its name starts with TEST (this last step does not need to be done if you want to get the complete scenario list). Next step I just print the scenarios names and versions that will be exported/imported:

println("List of ODI Scenarios that will be migrated")
		for (Object singObject: diffScenarios)
			println(singObject.getName() + "_" + singObject.getVersion())

Now comes the new code:

encode = new EncodingOptions();
transSource = sourceOdiInstance.getTransactionManager().getTransaction(new DefaultTransactionDefinition());
	exportService = new ExportServiceImpl(sourceOdiInstance);
	for (Object singObject: diffScenarios)
		exportService.exportToXml(singObject, exportPath, true, false, encode)

Export objects in ODI SDK is very straight forward: you need to inform which scenarios you want to export (in our case, all objects that were stored in diffScenarios array), the path where the object will be exported and the encode option that will be used. In this case, I just went ahead with the default encode options.

Importing objects is also easy, but similarly to a database, you need to explicitly commit your actions to make it effective in the target repository. Also, for the sake of simplicity, we will import all new scenarios under “root”, but we could explicitly say under which ODI objects we would want to have it imported to:

tm = targetOdiInstance.getTransactionManager()
	transTarget = tm.getTransaction(new DefaultTransactionDefinition());
	importService = new ImportServiceImpl(targetOdiInstance);
	for (Object singObject: diffScenarios)
	{
		println(exportPath+"\\SCEN_"+singObject.getName() + "_Version_" + singObject.getVersion()+".xml")
		importService.importObjectFromXml(ImportServiceImpl.IMPORT_MODE_SYNONYM_INSERT_UPDATE,exportPath+"\\SCEN_"+singObject.getName() + "_Version_" + singObject.getVersion()+".xml", true, null, true)
	}
	tm.commit(transTarget)

Once you run the job, you will get the following:

1

Our target repository already had TEST2, so that’s why its not in the list. When the user connects to the target repository, he will see the following:

2

That’s it for today folks! Hope you like it! See you soon! The code for part 4 can be found here.

14 Responses to “Playing with ODI and Groovy – Part 4 – Exporting/Importing ODI Scenarios with SDK”

  1. Can you help me with the code where i can export the scenarios separately and put them all on a location and a another groovy script which import all the scenarios placed on that location . i need these two scripts separately. email id:rajeshsaini47@gmail.com

    • Hi Rajesh! You may get part4.groovy script and duplicate it. Inside of it you have two objects: exportService and importService. Just use one of them in each file and you will be good to go.

      Thanks!

  2. Ulf Jonsson Says:

    Hi, do you have scripts to do smart export and smart import with SDK?

    Regards
    /Ulf

    • No, we didnt play with smart import/export yet. We generally use the SDK to export/import only scenarios between environments.

  3. Hello,
    Here my environments have different IDs and the import / update does not work because of the different workrep id, we use manual import through Import Substitution.

    Do you know if this command exists in sdk?

    • Hi Paulo, not sure if I understood what you mean by “Import Substitution”, but you may select which import to use by using one of the following parameters in importObjectFromXml function:

      IMPORT_MODE_DUPLICATION, IMPORT_MODE_SYNONYM_INSERT, IMPORT_MODE_SYNONYM_INSERT_UPDATE, IMPORT_MODE_SYNONYM_UPDATE

  4. If I use the option to import UPDATE I get the error “ODI-10035: SNP_SCEN:” XXXX 001 “(with internal id: 10178101) violates the alternative key constraint AK_SNP_SCEN (SCEN_NAME, SCEN_VERSION) for the values ​​…”

    My solution is to go one by one, right click on the stage and “import replacement/substituition”

    but I would like to automate this step of importing

    • Got it. I dont know if this option exists in the SDK, I would need to do some research. Just to confirm, you are trying to update one ODI scenario with the same version number correct? In other words, you already have ODI scenario 001 and you want to import/replace the same 001 in the other environment, correct? I had so many issues with those kind of imports in the past that right now I’m a very big fan of increasing version numbers. In all my projects I increase the version number anytime that I need to migrate something (like 1_00_00, 1_00_01 and so on), so I never run on this AK constraints situations.

  5. Thank you for your help.
    Just one more thing, looking for the documentation I found this class: importReplaceScenario

    In theory it should work with 3 parameters: Scenario, File directory, and true. However in my test I’m taking this error: No signature of method: odi.importReplaceScenario () is applicable for argument types: (java.lang.String, java.lang.String) values: [TESTE1 001, C: \ BIARQ \ TESTE2 \ SCEN_TESTE1001.xml]

    Have you used this class? Could it be a problem in my version to accept only 2 parameters?

    • radk00 Says:

      I never used, but I checked the documentation and it says three input parameters. Please be aware that it is not strings. It is a OdiScenario object, a String and a Boolean. Maybe you are trying to pass only the String instead of the OdiScenario object.

  6. How do I import the scenario in a scenario folder in ODI 11G and not in root? I tried to implement some solutions but without success.

  7. Thankks for this blog post

Leave a comment