在 ODI 中使用 Groovy 为数据源设置订阅服务器

Using Groovy in ODI to set the Subscriber for a data source

我们需要在许多映射上批量更改订阅者,但我发现构建正确的方法调用很困难。我正在遍历我的映射列表,但不确定如何更改每个映射的订阅者。我的 Groovy 脚本中有这个代码结构:

//Created with ODI Studio

import groovy.swing.SwingBuilder

import java.awt.FlowLayout as FL
import javax.swing.DefaultComboBoxModel
import javax.swing.BoxLayout as BXL

import oracle.odi.domain.project.finder.IOdiProjectFinder;
import oracle.odi.domain.project.OdiProject;
import oracle.odi.domain.adapter.project.IKnowledgeModule.ProcessingType;
import oracle.odi.domain.project.finder.IOdiFolderFinder;
import oracle.odi.domain.project.OdiFolder;
import oracle.odi.domain.mapping.finder.IMappingFinder;
import oracle.odi.domain.mapping.Mapping;
import oracle.odi.domain.mapping.component.Dataset;
import oracle.odi.domain.mapping.component.DatastoreComponent;
import oracle.odi.interfaces.interactive.support.InteractiveInterfaceHelperWithActions;
import oracle.odi.interfaces.interactive.IInteractiveInterfaceHelperWithActions;
import oracle.odi.core.persistence.transaction.ITransactionStatus;
import oracle.odi.core.persistence.transaction.support.DefaultTransactionDefinition;
import oracle.odi.domain.mapping.physical.MapPhysicalNode;

//**********************************************************

// Careful, this is the project CODE, not the project name (all caps, no spaces)
myProject = "PROJECT"  // CODE of the ODI project where subscribers have to be replaced 
myFolder = "TEST FOLDER" // Folder where subscribers have to be replaced 
NewSubscriberName="TEST_SUBSCRIBER"  // Name of the new Subscriber that will replace the old one
MappingNamePattern="MAP_"  // Any part of the mapping name, if there is a pattern. Leave blank to process all mappings. 
// Example for patterns: "LOAD_" will process mapping LOAD_CUSTOMERS and PRELOAD_CUSTOMER but not LOADER_PRECURSOR

//--------------------------------------
// Build the list of available Folders

def getFoldersList(projectCode){
  folders = []
  foldersList = ff.findByProject(projectCode)

  for (folder in foldersList){
    folders.add(folder.getName())
    //println(folder.getName())
  }

  folders.sort()

  return folders
}

//-------------------------------------------------------------
// Main processing 
// First, retrieve the ODI studio connection to the repository
txnDef = new DefaultTransactionDefinition();
tm = odiInstance.getTransactionManager();
tme = odiInstance.getTransactionalEntityManager()
txnStatus = tm.getTransaction(txnDef);

// Create a few shortcuts for the finders
pf = (IOdiProjectFinder)odiInstance.getTransactionalEntityManager().getFinder(OdiProject.class);
ff = (IOdiFolderFinder)odiInstance.getTransactionalEntityManager().getFinder(OdiFolder.class);
mapf = (IMappingFinder) odiInstance.getTransactionalEntityManager().getFinder(Mapping.class); 

// Locate the folder in the project
OdiFolder folder = null;
folderColl = ff.findByName(myFolder, myProject)
if (folderColl.size() == 1)
  folder = folderColl.iterator().next();

if (folder == null) {
   println("*** Could not find folder named\""+myFolder+"\"")
   exit
}

//--------------------------------------
// Retrieve all mappings in that folder
def OdiMappingsList = mapf.findByProject(myProject, folder.getFolderId())
println("*** Processing mappings for Project \""+myProject+"\", Folder \"" + myFolder+"\"")

//--------------------------------------
// For each mapping, do the folowing:
// - print mapping name
// - check if mapping name matched search string. If not, print 'no action' and get to the next mapping
// - if we have a name match, replace Subscriber with the new value.

for (map in OdiMappingsList){
    println("*******\nMapping: " + map.getName())
    bSubscriberChanged=false        
    // Make sure that the mapping matches the names we are looking for 
    if (map.getName().contains(MappingNamePattern)){
        // Set the subscriber
        sources = map.getSources()
        for (sourceDS in sources) {
           --- I NEED TO SET THE SUBSCRIBER HERE ---
           bSubscriberChanged=true
        }
    } else {// No match on mapping name
        println ("Skipped mapping: name does not contain \"" + MappingNamePattern +"\"")
    }
    if (bSubscriberChanged){
        // Persist the changes in the cache
        tme.persist(map);
    }
}//Mapping

// Commit the changes in the repository
tm.commit(txnStatus);

如有任何帮助,我们将不胜感激。

您可以使用 getSources 从 IMapComponentOwner(由 Mapping 实现)中检索映射的源组件列表。 这些源组件应该是 DatastoreComponent 类型,它具有设置 JournalizedFiler 的方法。

应该是这样的(还不能测试):

srcComps = map.getSources()
srcComps.each() { srcComp ->
    if (srcComp.isJournalized()) {
        srcComp.setJournalizedFilter("JRN_SUBSCRIBER = '"+NewSubscriberName+"'")
    }
}

请注意,如果组件设置为日记化,此代码只会更改过滤器。

如果您当前的日记化过滤器比这更复杂(例如,包括日期过滤器),您将需要使用 getJournalizedFilter() 并解析结果以仅替换订阅者名称而不是覆盖整个过滤器。