As a first step towards including Oracle Service Bus projects into our Continuous Integration environment, let’s look at how to script exporting some project(s) from Oracle Enterprise Pack for Eclipse (the IDE for OSB) and deploying those project(s) to an OSB server. Later, we will include this into the Maven/Hudson environment we have been constructing in this series of posts on continuous integration.
Here is our script, right up front, then we will discuss it:
@echo Export project from eclipse java ^ -Dweblogic.home=c:\oracle\middleware\wlserver_10.3 ^ -Dosb.home=c:\oracle\middleware\Oracle_OSB1 ^ -Dosgi.bundlefile.limit=500 ^ -Dharvester.home=c:\oracle\middleware\Oracle_OSB1\harvester ^ -Dosgi.nl=en_US ^ -Dsun.lang.ClassLoader.allowArraySyntax=true ^ -jar c:\Oracle\OEPE\oepe_11gR1PS4\plugins\org.eclipse.equinox.launcher_1.1.1.R36x_v20101122_1400.jar ^ -data c:\src\osb\notsvn ^ -application com.bea.alsb.core.ConfigExport ^ -configProject "OSB Configuration 1" ^ -configJar c:\src\osb\test_sbconfig.jar ^ -configSubProjects "OSB Project 1" ^ -includeDependencies true @echo Deploy 'import' to Service Bus c:\oracle\middleware\oracle_common\common\bin\wlst import.py import.properties
First of all, if you have not seen them before, the ‘^’ is a continuation character in Windows CMD files, such as this one, so that we can spread a command over many lines in our script, but it is executed as if it were all typed in on a single line.
This script has not been made generic yet – it has a bunch of stuff hardcoded. Let’s take a look.
First, we run java with a bunch of properties. You will need to set weblogic.home, osb.home and harvester.home to suit your environment. You can just include the others as they are.
Following the properties, you see we point to a JAR file, this allows us to run eclipse in headless mode. The remainder of the parameters are passed to eclipse. You can see we need to specify the location of the workspace to use (in data) – this can also be the Subversion trunk (or similar). The application tells it to run the OSB exporter.
The other important parameters are configProject which names the OSB Configuration project in the workspace you want to use, configSubProjects which is a comma separated list of the OSB projects you want to export, and configJar which is the name of the JAR file you want to create.
If you want to know more about this command, take a look in the online help in your OSB IDE. Look under the OSB help topic, then ‘Tasks,’ ‘Working with projects, folders, resources & configurations,’ ‘exporting resources,’ ‘using command line,’ and then the ANT topic.
When this command has run, we will have an OSB configuration JAR file (test_sbconfig.jar in this case) which is ready to import into (deploy to) an OSB server.
The second part is to perform the deployment (import). We will do this using a WLST script from Oracle, import.py (see below). This script also expects a properties file. We need to set up some details in the properties file so the script knows what to do.
Let’s take a look at the properties file:
################################################################## # OSB Admin Security Configuration # ################################################################## adminUrl=t3://localhost:7001 importUser=weblogic importPassword=welcome1 ################################################################## # OSB Jar to be exported, optional customization file # ################################################################## importJar=test_sbconfig.jar #customizationFile=OSBCustomizationFile.xml ################################################################## # Optional passphrase and project name # ################################################################## #passphrase=osb #project=default
You can see we have provided the URL for the Administration Server, and also the name of the OSB configuration JAR file (that we just created in the previous step).
Here is the import.py sciript that WLST will run:
from java.util import HashMap from java.util import HashSet from java.util import ArrayList from java.io import FileInputStream from com.bea.wli.sb.util import Refs from com.bea.wli.config.customization import Customization from com.bea.wli.sb.management.importexport import ALSBImportOperation import sys #======================================================================================= # Entry function to deploy project configuration and resources # into a ALSB domain #======================================================================================= def importToALSBDomain(importConfigFile): try: SessionMBean = None print 'Loading Deployment config from :', importConfigFile exportConfigProp = loadProps(importConfigFile) adminUrl = exportConfigProp.get("adminUrl") importUser = exportConfigProp.get("importUser") importPassword = exportConfigProp.get("importPassword") importJar = exportConfigProp.get("importJar") customFile = exportConfigProp.get("customizationFile") passphrase = exportConfigProp.get("passphrase") project = exportConfigProp.get("project") connectToServer(importUser, importPassword, adminUrl) print 'Attempting to import :', importJar, "on ALSB Admin Server listening on :", adminUrl theBytes = readBinaryFile(importJar) print 'Read file', importJar sessionName = createSessionName() print 'Created session', sessionName SessionMBean = getSessionManagementMBean(sessionName) print 'SessionMBean started session' ALSBConfigurationMBean = findService(String("ALSBConfiguration.").concat(sessionName), "com.bea.wli.sb.management.configuration.ALSBConfigurationMBean") print "ALSBConfiguration MBean found", ALSBConfigurationMBean ALSBConfigurationMBean.uploadJarFile(theBytes) print 'Jar Uploaded' if project == None: print 'No project specified, additive deployment performed' alsbJarInfo = ALSBConfigurationMBean.getImportJarInfo() alsbImportPlan = alsbJarInfo.getDefaultImportPlan() alsbImportPlan.setPassphrase(passphrase) alsbImportPlan.setPreserveExistingEnvValues(true) importResult = ALSBConfigurationMBean.importUploaded(alsbImportPlan) SessionMBean.activateSession(sessionName, "Complete test import with customization using wlst") else: print 'ALSB project', project, 'will get overlaid' alsbJarInfo = ALSBConfigurationMBean.getImportJarInfo() alsbImportPlan = alsbJarInfo.getDefaultImportPlan() alsbImportPlan.setPassphrase(passphrase) operationMap=HashMap() operationMap = alsbImportPlan.getOperations() print print 'Default importPlan' printOpMap(operationMap) set = operationMap.entrySet() alsbImportPlan.setPreserveExistingEnvValues(true) #boolean abort = false #list of created ref createdRef = ArrayList() for entry in set: ref = entry.getKey() op = entry.getValue() #set different logic based on the resource type type = ref.getTypeId if type == Refs.SERVICE_ACCOUNT_TYPE or type == Refs.SERVICE_PROVIDER_TYPE: if op.getOperation() == ALSBImportOperation.Operation.Create: print 'Unable to import a service account or a service provider on a target system', ref abort = true elif op.getOperation() == ALSBImportOperation.Operation.Create: #keep the list of created resources createdRef.add(ref) if abort == true : print 'This jar must be imported manually to resolve the service account and service provider dependencies' SessionMBean.discardSession(sessionName) raise print print 'Modified importPlan' printOpMap(operationMap) importResult = ALSBConfigurationMBean.importUploaded(alsbImportPlan) printDiagMap(importResult.getImportDiagnostics()) if importResult.getFailed().isEmpty() == false: print 'One or more resources could not be imported properly' raise #customize if a customization file is specified #affects only the created resources if customFile != None : print 'Loading customization File', customFile print 'Customization applied to the created resources only', createdRef iStream = FileInputStream(customFile) customizationList = Customization.fromXML(iStream) filteredCustomizationList = ArrayList() setRef = HashSet(createdRef) # apply a filter to all the customizations to narrow the target to the created resources for customization in customizationList: print customization newcustomization = customization.clone(setRef) filteredCustomizationList.add(newcustomization) ALSBConfigurationMBean.customize(filteredCustomizationList) SessionMBean.activateSession(sessionName, "Complete test import with customization using wlst") print "Deployment of : " + importJar + " successful" except: print "Unexpected error:", sys.exc_info()[0] if SessionMBean != None: SessionMBean.discardSession(sessionName) raise #======================================================================================= # Utility function to print the list of operations #======================================================================================= def printOpMap(map): set = map.entrySet() for entry in set: op = entry.getValue() print op.getOperation(), ref = entry.getKey() print ref print #======================================================================================= # Utility function to print the diagnostics #======================================================================================= def printDiagMap(map): set = map.entrySet() for entry in set: diag = entry.getValue().toString() print diag print #======================================================================================= # Utility function to load properties from a config file #======================================================================================= def loadProps(configPropFile): propInputStream = FileInputStream(configPropFile) configProps = Properties() configProps.load(propInputStream) return configProps #======================================================================================= # Connect to the Admin Server #======================================================================================= def connectToServer(username, password, url): connect(username, password, url) domainRuntime() #======================================================================================= # Utility function to read a binary file #======================================================================================= def readBinaryFile(fileName): file = open(fileName, 'rb') bytes = file.read() return bytes #======================================================================================= # Utility function to create an arbitrary session name #======================================================================================= def createSessionName(): sessionName = String("SessionScript"+Long(System.currentTimeMillis()).toString()) return sessionName #======================================================================================= # Utility function to load a session MBeans #======================================================================================= def getSessionManagementMBean(sessionName): SessionMBean = findService("SessionManagement", "com.bea.wli.sb.management.configuration.SessionManagementMBean") SessionMBean.createSession(sessionName) return SessionMBean # IMPORT script init try: # import the service bus configuration # argv[1] is the export config properties file importToALSBDomain(sys.argv[1]) except: print "Unexpected error: ", sys.exc_info()[0] dumpStack() raise
You need to put the original script, import.py and import.properties all in to the same directory. Now you can run our original script and it will perform the export from eclipse and the deployment to OSB.
In a future post, we will be parameterizing this and folding it into our Hudson/Maven oriented continuous integration environment.
Mark, I’m going to try and implement CI for OSB on Hudson/Jenkins, and was wondering if you were going to do a followup post covering that topic.
Hi Rob,
Yes I am planning to do a follow up post around the time that OSB PS6 is released…
Mark
Pingback: Building OSB projects with Maven and removing the eclipse dependency | RedStack
Pingback: Building OSB projects with Maven and removing the eclipse dependency by Mark Nelson | SOA Community Blog
Hi Mark,
very good article, I am going to experiment with this topic in these days. Keep going and thank you.
Ladislav