a) uses information from TEMPLATE XML b) to create CTS SEED c) containing
SOURCE SENSOR RESULT DATA d) and runs CTS SENSOR using created ...
IBM Tivoli Application Dependency Discovery Manager TADDM
How to create Custom Template Sensor (CTS), through the example of WebSphere Server hash code generator
© 2013 IBM Corporation
INTRODUCTION
What this White Paper contains: ●
Custom Template Sensor (CTS) technology introduction
●
Working CTS example resolving a real business problem
What this White Paper is intended to provide: ●
Understanding of CTS idea
●
Basic understanding of CTS capabilities
●
Basic CTS development guidelines
What this White Paper is NOT intended to provide: ●
2
Detailed and comprehensive CTS development guide © 2013 IBM Corporation
Example Sensor – what it will do?
THE PROBLEM One of the WebSphere Server Application jar files was replaced with the new version – but no changes in configuration files were made. Because TADDM does not check Application files content, it is unaware about the change. THE SOLUTION Create Custom WAS Sensor calculating hash codes for every Application file. Hash codes will be saved in TADDM database (as WebSphere Server extended attribute) and therefore every file change will be visible in TADDM Change History. 3
© 2013 IBM Corporation
Custom Template Sensor (CTS) – what is it? ●
Technology allowing customer to create new sensors ● also ideal for extending existing sensors functionality
●
Simple configuration, just define: Sensor name Triggering source sensor name Scripts names and locations ● ● ●
4
●
Uses source sensor result data as a seed
●
Uses well-known Jython© (Python© for Java©) language
●
Plug and play – no need to restart TADDM
●
Available in TADDM from version 7.2.2 © 2013 IBM Corporation
CTS workflow schema
REGULAR SENSOR
Custom Template Sensor ENGINE: a) uses information from TEMPLATE XML b) to create CTS SEED c) containing SOURCE SENSOR RESULT DATA d) and runs CTS SENSOR using created seed
REGULAR SENSOR
5
REGULAR SENSOR
TEMPLATE.XML
CUSTOM TEMPLATE SENSOR: matcher.py sensor.py
CREATED BY CUSTOMER
SEEDS:
© 2013 IBM Corporation
Example WAS Sensor workflow 1. WebSphere Cell Senor runs and gathers information about WebSphere Cell Servers 2. CTS ENGINE checks all CTS configuration files and finds out that there is custom WAS sensor intended to run after WebSphere Cell Sensor 3. CTS ENGINE runs matcher.py script passing to it WebSphere Cell Sensor result data. Matcher.py chooses data for WAS sensor seed 4. Sensor.py performs discovery: connects to each WebSphere Server and calculates hash codes for every server application files. 5. Sensor.py put discovered hash codes into Server extended attributes. Data will be automatically persisted in TADDM Database 6
WebSphere Cell Sensor WAS TEMPLATE.XML
WAS matcher.py
WAS sensor.py
DB © 2013 IBM Corporation
Development first step – make some place for your sensor
first: determine your sensor name and create folder for it /opt/IBM/taddm/dist/etc/templates/cts/was It should be here /opt/IBM/taddm/dist/etc/templates/cts/was/template.xml matcher.py sensor.py second: create empty files for your sensor (we will fill them soon) note: it should be done on Domain Server or Discovery Server 7
© 2013 IBM Corporation
Filling template.xml template.xml is your sensor configuration file
was, matcher.py, sensor.py – see previous slide
was com.ibm.cdb.discover.result.app.j2ee.WebSphereCellSensorResult com.ibm.cdb.discover.sensor.app.j2ee.webspherecell_7.2.2 matcher.py sensor.py
Here put your source sensor info. Every time your source sensor discovers data, your custom sensor is executed with source sensor result data provided. - for see pluggable sensor folder name in /opt/IBM/taddm/dist/osgi/plugins - for see plugin.xml file in plugin folder 8
© 2013 IBM Corporation
Filling matcher.py import sys
standard configuration
from java.lang import System from java.util import HashMap coll_home = System.getProperty("com.collation.home") System.setProperty("jython.home",coll_home + "/external/jython-2.1") System.setProperty("python.home",coll_home + "/external/jython-2.1") jython_home = System.getProperty("jython.home") sys.path.append(jython_home + "/Lib") sys.path.append(coll_home + "/lib/sensor-tools") sys.prefix = jython_home + "/Lib" import sensorhelper (resultMap,returnList,log) = sensorhelper.init(targets)#@UndefinedVariable log.info("CTS WAS result matcher script running") try: if resultMap['domain'].getName().contains("test"): return initValue = HashMap() initValue.put('appServer', resultMap['appServer']) initValue.put('cell', resultMap['domain']) returnList.add(resultMap['domain'].getName() + " " \ + resultMap['appServer'].getName(), initValue)
load source sensor result data filter unwanted servers create input data pass input data to seed
#returnList.add("fullResult", resultMap) except: log.error("Error occured.") 9
alternatively just pass all data using one line © 2013 IBM Corporation
Filling sensor.py ... def addVariables(variables, toAdd): for var in toAdd: if var.hasValue(): variables[var.getSymbolicName()] = var.getValue() else: variables[var.getSymbolicName()] = "" def hashcode(os, fileName): return sensorhelper.executeCommandWithTimeout("tar c " + fileName + " | md5sum", 100000, os) (ctsResult,ctsSeed,log) = sensorhelper.init(targets)#@UndefinedVariable initValue = ctsSeed.getSeedInitiator().getValue() appServer = initValue.get('appServer') cell = initValue.get('cell') if appServer.hasNode(): node = appServer.getNode() for n in cell.getNodes(): if n.getName() == node.getName(): node = n variables = {'CELL': cell.getName()} if cell.hasVariables(): addVariables(variables, cell.getVariables()) if appServer.hasNode(): if node.hasVariables(): addVariables(variables, node.getVariables()) if appServer.hasVariables(): addVariables(variables, appServer.getVariables())
10
standard configuration, copy from matcher.py some helper method main discovery method executing code on discovered server load seed data get WebSphere node data gather all WebSphere variables
© 2013 IBM Corporation
Filling sensor.py (continuation) ... os = sensorhelper.getNewOsHandle(cell.getAdminHost().getContextIp()) resultMap = {} if appServer.hasDeployedObjectsRaw(): for module in appServer.getDeployedObjectsRaw(): fileName = module.getFileName() for k, v in variables.items(): fileName = fileName.replace("${" + k + "}", v) fileName = fileName.replace("$(" + k + ")", v) try: moduleHash = hashcode(os, fileName) log.debug(fileName + " : " + moduleHash) resultMap[fileName] = moduleHash except: resultMap[module.getFileName()] = \ "Hashcode determining error" resultString = "" for k, v in resultMap.items(): resultString = resultString + k + ": " + v + "\n" sensorhelper.setExtendedAttributes(appServer, {'hash': resultString}) ctsResult.addExtendedResult(appServer)
!
target server handler read application modules file names replace variables identifiers with values generating hash codes prepare result text attach result text to WAS return updated WAS
! – “hash” extended attribute must be created manually in TADDM Data Management Portal – described later 11
© 2013 IBM Corporation
Summary: creating CTS in one picture
12
TEMPLATE.XML − sensor name − source sensor info − matcher script name − sensor script name
... was com.ibm.cdb.discover.result.app.j2ee. WebSphereCellSensorResult com.ibm.cdb.discover.sensor.app.j2ee. webspherecell_7.2.2 matcher.py sensor.py
Matcher jython© script − gets source sensor result data − decides whether to proceed or not − if so chooses some or all data and passes it to sensor
... (resultMap,returnList,log) = sensorhelper.init(targets) if resultMap['domain'].getName().contains("test"): return initValue = HashMap() initValue.put('appServer', resultMap['appServer']) initValue.put('cell', resultMap['domain']) returnList.add(resultMap['domain'].getName() + " " + resultMap['appServer'].getName(), initValue)
Sensor jython© script − performs discovery − prepares result data for TADDM database
... for module in appServer.getDeployedObjectsRaw(): moduleHash = sensorhelper.executeCommandWithTimeout( "tar c " + module.getFileName() + " | md5sum", 100000, os) resultMap[fileName] = moduleHash ... for k, v in resultMap.items(): result = result + k + ": " + v + "\n" sensorhelper.setExtendedAttributes(appServer, {'hash': result}) ctsResult.addExtendedResult(appServer)
© 2013 IBM Corporation
Additional information – Extended Attributes
Before using Extended Attribute, it must be created in TADDM Data Management Portal:
CI's type – here is the base type for all Application Servers
chosen name 13
© 2013 IBM Corporation
Additional information – Discovery Management Console configuration
Create new Discovery Profile and enable Custom Template Sensor:
14
© 2013 IBM Corporation
Additional information – Discovery Management Console configuration (continuation)
WebSphere Cell Sensor needs to be run in Deep discovery Level:
15
© 2013 IBM Corporation
Additional information – The Result
If any Application file content was changed on WebSphere Server it can be seen in TADDM (i.e. in Change History report):
16
© 2013 IBM Corporation
Additional information – The Code
Complete, ready for install, example WAS Sensor is available for download here: https://www.ibm.com/developerworks/community/wikis/home?
lang=en#!/wiki/Tivoli%20Application%20Dependency%20Discovery%20Manager/page/Custom %20Template%20Sensor%20introduction
TADDM_CTS_Was_Sensor.zip file needs to be decompressed here:
[TADDM_HOME]/dist/etc/templates/cts i.e.: /opt/IBM/taddm/dist/etc/templates/cts Notes: ● ● ●
17
create cts folder if it does not exist it should be done on Domain Server or Discovery Server make sure that sensor files and folders have proper permissions – they must be available for TADDM user (i.e. taddmusr) © 2013 IBM Corporation
18
© 2013 IBM Corporation