Wednesday, June 27, 2018

Just Announced: IBM Cloud App Management

Here's the announcement, with architecture details:

https://developer.ibm.com/apm/2018/06/26/introducing-ibms-new-service-management-cloud-native-offering-ibm-cloud-app-management/

Some of the highlights are that it runs on IBM Cloud Private (so it runs in containers orchestrated by Kubernetes) and supports both ITM v6 and APM v8 agents.

Monday, June 25, 2018

Reading and writing files in a Maximo automation script

Background

All of the product documentation tells you to use the product provided logging for debugging automation scripts (see here, for example: https://www.ibm.com/support/knowledgecenter/SSZRHJ/com.ibm.mbs.doc/autoscript/c_ctr_auto_script_debug.html ). For quick debugging, however, I thought that was cumbersome, so I decided to figure out how to access files directly from within an automation script. This post goes over exactly what's required to do that. Maximo supports Jython and Rhino-JavaScript for automation scripting, and I'll cover both of those here.

Jython

This one was straightforward, since the Python documentation can be followed exactly. Jython is simply an implementation of Python written completely in Java. All you need to open a file is:

my_file = open('c:/tmp/outfile.txt','a')

where 'a' specifies that we're appending to the file (and creating it if it doesn't exist). You then do need to flush and close the file, and this is my function to do that:

def logit(mytext):
  my_file = open('c:/tmp/jout.txt','a')
  my_file.write(mytext + '\n')
  my_file.flush()
  my_file.close()

So to log a string, just run:

logit("this is my string")

Reading from a file is just as easy:

my_read = open('c:/tmp/computers.json')
my_json = my_read.readline()
my_read.close()

In my case, the file contains one long line of JSON data, so readline() works great to store all of the text of the file into the string named my_json.

Rhino-JavaScript

This one is quite a bit more painful than Jython, which is really just one more reason that all of your automation scripts should be written in Jython. Specifically, the Rhino implementation in Maximo doesn't seem to completely adhere to the documentation you'll fine online. For example, there is no "ReadFile()" method available in Maximo. There are also other limitations, and the only way I found to get over them was to use Java classes. I thought that would make it easy, but then you have to deal with the fact that Java objects (specifically Array objects) are absolutely not the same as JavaScript objects. 

So, writing a file isn't too difficult once you realize that you need to use Java. Here's how you open and write a file:

var outFile = new java.io.FileWriter("c:/tmp/autoscriptout.txt");
outfile.write("my string");
outfile.close();

The hard part is actually reading data from the file. Using the same JSON file as above with one long line of JSON, the following is required to read that data into a JavaScript string that can then be parsed:

var 
  thefile = new java.io.File("c:/tmp/computers.json"),
  filelength = thefile.length(),
  thefilereader = new java.io.FileReader(thefile),
  jsonData = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE,filelength),
  res = thefilereader.read(jsonData,0,filelength),
  jsonString = new java.lang.String(jsonData);

And now all of the JSON data is in the string named jsonString.

Enjoy.

Friday, June 15, 2018

ICD 7.6 Fresh install and config with LDAP authentication configured will fail

We found a problem when installing IBM Control Desk 7.6 on WebSphere and MSSQL where it fails every time if you enable LDAP/AD authentication during the configuration phase of the install. Specifically, you'll see this error in the ConfigTool window:

Apply Deployment Operations-CTGIN5013E: The reconfiguration action deployDatabaseConfiguration failed. Refer to messages in the console for more information.

And if you look in the CTGConfigurationTrace<datetime>.log file, you'll see this error:

SEVERE: NOTE ^^T^Incorrect syntax near the keyword 'null'.
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'null'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:285)
at com.ibm.tivoli.ccmdb.install.common.util.CmnEncryptPropertiesUtil.init(CmnEncryptPropertiesUtil.java:187)
at com.ibm.tivoli.ccmdb.install.common.util.CmnEncryptPropertiesUtil.<init>(CmnEncryptPropertiesUtil.java:101)
at com.ibm.tivoli.ccmdb.install.common.util.CmnEncryptPropertiesUtil.getInstance(CmnEncryptPropertiesUtil.java:141)
at com.ibm.tivoli.ccmdb.install.common.config.database.ACfgDatabase.createCronTask(ACfgDatabase.java:1391)
at com.ibm.tivoli.ccmdb.install.common.config.database.CfgEnableVMMSyncTaskAction.performAction(CfgEnableVMMSyncTaskAction.java:140)
at com.ibm.tivoli.ccmdb.install.common.config.database.ACfgDatabase.runConfigurationStep(ACfgDatabase.java:1108)
at com.ibm.tivoli.madt.reconfig.database.DeployDBConfiguration.performAction(DeployDBConfiguration.java:493)
at com.ibm.tivoli.madt.configui.config.ConfigureSQLServer.performConfiguration(ConfigureSQLServer.java:75)
at com.ibm.tivoli.madt.configui.common.config.ConfigurationUtilities.runDatabaseConfiguration(ConfigurationUtilities.java:540)
at com.ibm.tivoli.madt.configui.bsi.panels.deployment.TpaeDeploymentPanel$RunOperations.run(TpaeDeploymentPanel.java:1550)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)


This happens before the EAR files are built.

The way around this is to select "Use Maximo internal authentication" on the "Configure Application Security" screen of the ConfigTool". Once everything is installed, configured and running, you can then go in and enable J2EE application security for authentication.


Wednesday, June 13, 2018

JD-Gui is an invaluable tool for troubleshooting Java applications

If you deal with Java applications, you should get familiar with JD-Gui if you aren't already. JD-Gui (Java Decompile - Graphical User Interface) does exactly what its name states, and it seems downright magical because it shows you source code from compiled Java applications, which can give you amazingly useful insight into how an application is working. Here's a screenshot of it in action, where I'm using it to look at a JAR file that's included with the IBM Control Desk ConfigTool:


All of that information came from just dropping the JAR file onto JD-Gui.

The problem I'm encountering is a SQL error complaining about a syntax error near the keyworkd "null". By looking at the trace file produced and the source code, I've been able to reproduce the exact error message, and I'm 100% confident I know exactly in the code where the error is generated. So instead of just randomly trying different possible solutions, I can focus on the very small number of areas that could be causing this particular problem.

I've been using this tool for years, so I'm not sure what took me so long to write about it.

Monday, June 11, 2018

I definitely recommend installing Linux on Windows

If you've got Windows 10, hopefully you've been able to install a recent update that allows you to enable the Windows System for Linux feature and install a supported Linux distribution from the Microsoft Store. I finally bit the bullet and installed Ubuntu today, and it makes the life of a system administrator MUCH easier. I already had Cygwin installed, but this is just a slightly smoother integration, with many of the tools you need already installed (or available with the normal 'apt' or 'apt-get').

The Ubuntu distribution available in the MS Store even comes with vi with color highlighting for known file types (like html or js), and it's got telnet, ssh, sftp, etc. to make your life easy.

It's been available for a while, and I was hesitant to install it, but now I'm very happy I did.

Friday, June 1, 2018

Amazon Chime is a cheaper and more powerful alternative to WebEx

If you haven't looked at Amazon's different AWS offerings in a while, you definitely should take a look sometime. For example, I stumbled across their Chime web conference service:

https://aws.amazon.com/chime/

and I can report that it's just as reliable and easy as WebEx, but with more capabilities and at a fraction of the cost. Specifically, it's only a maximum of $15 per month per host, with 100 attendees allowed, plus you get a dial-in number (an 800 number is available, but there are additional per-minute charges associated with it).

We had an older WebEx account that was $50 per host per month, so I was very happy to run across this service and to get a minimum of a 70% savings. I say minimum of 70% savings because some of our host accounts were used only at most 2 days per month, which, with Chime, will now only cost a maximum of $6 per month.

High Availability for DB2 on AWS

If you're running an IBM product that requires a DB2 backend, you should really consider running DB2 on AWS. Here's a great article that provides you with the CloudFormation template to set it all up for you very quickly:

https://aws.amazon.com/blogs/database/creating-highly-available-ibm-db2-databases-in-aws/

If you're concerned about running your infrastructure in the cloud, please contact us so we can give you the information you need about the tight security and incredible flexibility that AWS provides.

Update 8/8/2023: One important note: this still uses TSAM for failover. What this means is that if your primary DB2 instance has a problem, the entire VM hosting that instance is rebooted. So if you have multiple databases on that instance, they're all failing over to the backup. If you have any other processes running on that VM, they're all going away. You can definitely architect your application to work fine with this, but it is definitely something you have to keep in mind before simply implementing DB2 HADR.