SQLite v3.26.0 Released

D. Richard Hipp has just released SQLite v3.26.0.
http://www.sqlite.org/news.html

SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. SQLite is the most widely deployed SQL database engine in the world. The source code for SQLite is in the public domain.

Regards,
Roger Lacroix
Capitalware Inc.

C, Database, IBM i (OS/400), Linux, macOS (Mac OS X), Open Source, Programming, Unix, Windows, z/OS Comments Off on SQLite v3.26.0 Released

New: MQ Channel Monitor v1.2.0

Capitalware is pleased to announce the release of MQ Channel Monitor v1.2.0. It is a free open source project.

MQ Channel Monitor (MQCM) application is a software package that is designed to gather and to display the status of MQ channels of the queue manager. MQCM displays 16 columns of channel status information. The display is automatically refreshed. The user can define filters so that only particular channels will have their status displayed.

    Changes:

  • Added code so that the MQ DTD will be embedded in the MQCM.jar file.
  • Updated code to support the latest release of IBM MQ.
  • Updated code to support Java i18n – I included 55 language property files.

For more information on MQ Channel Monitor, please go to:
https://www.capitalware.com/mqcm_overview.html

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM MQ, IBM MQ Appliance, Java, Linux, macOS (Mac OS X), Open Source, PCF, Programming, Unix, Windows Comments Off on New: MQ Channel Monitor v1.2.0

IBM MQ V9.1.1 Announced

IBM has announced IBM MQ V9.1.1:
https://www.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/1/897/ENUS218-511/index.html

    Highlights:

  • MQ V9.1.1 base provides the following:
    • Support for running applications on Microsoft™ .NET Core
    • Provision for a list of acceptable Transport Layer Security (TLS) CipherSpecs
    • Dynamic TLS CipherSpec negotiation
    • More effective integration with IBM WebSphere® Liberty
    • Improved queue manager restart and client reconnect times
  • MQ Advanced V9.1.1 includes the capabilities in MQ V9.1.1 base and new REST API calls for MQ Managed File Transfer (MQ MFT) administration.
  • MQ Appliance V9.1.1 firmware includes the capabilities in MQ V9.1.1 and is available for the following appliances:
    • MQ Appliance M2000
    • MQ Appliance M2001
    • MQ Appliance M2002

Planned availability for IBM MQ V9.1.1 is November 30, 2018 for Electronic software delivery.

IBM MQ (aka WebSphere MQ) homepage
https://www.ibm.com/products/mq

Regards,
Roger Lacroix
Capitalware Inc.

Fix Packs for MQ, IBM MQ, IBM MQ Appliance, Linux, Unix, Windows, z/OS Comments Off on IBM MQ V9.1.1 Announced

Capitalware IniFile GUI Tools Updated

If you read my ‘Size Matters’ blog posting, this is just a continuation but for Capitalwre’s IniFile GUI Tools.

Many of Capitalware’s back-end solutions have a lot of keyword/value pairs, so each product has an associated IniFile GUI Tool program to make it easier for the MQAdmin to configure the IniFile rather than using notepad or vi. They are:

When I originally created the first IniFile GUI Tool for MQAUSX, I simply hard-coded (in English) the labels, buttons and menu items, since the important items were the keyword/value pairs that the MQAdmin would be adding/updating/editing. As, I added more back-end solutions, hence more IniFile GUI Tools, I simply cloned the original one (Programmers never write new code unless they have too!!).

When I look at my customer base for Capitalware’s back-end solutions, for non-English customers, it is probably around 33%. Of course, now I’m thinking why didn’t I add multi language support in the begging. D’Oh!

    So, for each IniFile GUI Tool:

  • I added language support for 55 languages for button, menu items and section titles but NOT for the product keywords.
  • I added code to get the font width of each label, button text, etc. and calculating the necessary width of the component and setting the size.

Note: The product keywords were NOT translated because I don’t want to add 55 different language processors to each product to when it is reading/processing the keyword/value pairs.

As an added bonus, I thought I would also include 6 of the “other tools” that are in MQ Visual Edit to each IniFile GUI Tool. Here are the 6 “other tools” that were added:

  • Hex Converter tool can convert a hexadecimal number to its corresponding string representation and vice versa. i.e. 0x’3132333041424344′ to ‘1230ABCD’.
  • Hex Editor is a simple multi-purpose HEX editor. The Hex Editor supports multi-file editing.
  • Text Editor is a simple multi-purpose plain-text editor. The Text Editor supports multi-file editing.
  • Tail File is a simple multi-purpose file monitoring viewer. The Tail File supports monitoring of multiple files at the same time.
  • XML Editor is a simple multi-purpose XML editor. The XML Editor supports multi-file editing.
  • Visual Difference is a simple file to file comparison tool. It visually displays differences between 2 files.

These IniFile GUI Tool updates are available for download. Send the email to support@capitalware.com if you want to use the latest release.

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Auditor, MQ Authenticate User Security Exit, MQ Channel Connection Inspector, MQ Enterprise Security Suite, MQ Message Encryption, MQ Message Replication, MQ Standard Security Exit, Unix, Windows Comments Off on Capitalware IniFile GUI Tools Updated

IBM MQ Fix Pack 9.1.0.1 Released

IBM has just released Fix Pack 9.1.0.1 for IBM MQ V9.1 LTS:
https://www.ibm.com/support/docview.wss?uid=ibm10738815

and for IBM i:
https://www.ibm.com/support/docview.wss?uid=ibm10740195

Regards,
Roger Lacroix
Capitalware Inc.

Fix Packs for MQ, IBM i (OS/400), IBM MQ, Linux, Unix, Windows Comments Off on IBM MQ Fix Pack 9.1.0.1 Released

Size Matters

Ha! Got your attention. 🙂 This posting is not what you think it is about! So, get your mind out of the gutter. 🙂

A couple of weeks ago, a customer using MQ Visual Edit sent me a screenshot of an issue they were having. The column label on one of the windows was truncated. He was using it on Windows, so I did a quick test on my Windows desktop PC and everything looked normal. I scratched my head and as I was starring at the screenshot and my running copy of MQ Visual Edit, I noticed that his font appeared larger.

After an email exchange with the end-user, I found out that he had set his PC’s screen resolution at “125% of normal” (i.e. DPI of 120).

Now I do have some code in MQ Visual Edit to make the docks larger so that the text would fit but it was more of some simple coding. I had previously tested MQ Visual Edit on Windows, macOS and Linux (desktop) to make sure everything fit in the windows, column labels and buttons but I never thought about testing it for users who might have issue with normal screen resolution. My bad.

It occurred to me that MQ Visual Edit may have the same issue with non English languages even at normal resolution. I have tested non English languages at normal resolution and never noticed an issue but that does not mean end-users might not be having an issue.

So, I have spent the last 2 weeks adding code to MQ Visual Edit to get the font width of each label, button text, etc. and calculating the necessary width of the component and setting the size. It has been a whole lot of tedious work but I am happy to say everything is looking good. I even set my laptop’s screen resolution to “125% of normal” and been using it to test all of the screens.

I have also made the changes to MQ Visual Browse and MQTT Message Viewer.

If you are having an issue with truncated text, labels, buttons, etc. then send me an email and I will send you the latest release of MQ Visual Edit, MQ Visual Browse or MQTT Message Viewer. Send the email to support@capitalware.com

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM MQ, Linux, macOS (Mac OS X), MQ Visual Browse, MQ Visual Edit, MQTT Message Viewer, Windows Comments Off on Size Matters

Java Code to Open a Web Page

Some times the simplest things drive you nuts. 🙂

The Desktop class (java.awt.Desktop) was introduced in Java v1.6. There are occasions when you are running a Java application in JVM 1.6 or higher that the Desktop class is not available or fails to load.

It is just weird and very frustrating. Its not just me. If you do an internet search, you will find lots of people with the same problem and weirdly, Ubuntu is an operating system that has this problem a lot.

I decided to create a simple “wrapper” class to open a web page (URL). First, it will attempt to load the Java Desktop class and if it fails or is not available then it will use the Runtime class to open the web page. My Java class should be able to run in any release of Java (JVM) and on pretty much any platform.

You can download the source code from here. Enjoy. 🙂

/**
 * A simple class to open a web page (URL) in the default web browser.
 * First, it will attempt to use the Desktop class that is available in
 * Java 1.6 or higher.  If it fails or is not available then it will attempt
 * to open the web page using the Runtime class.
 *
 * @author Roger Lacroix
 * @version 1.0.0
 * @license Apache 2 License
 */
public class WebPage
{
   public static void main(String[] args)
   {
        String url = "https://www.google.com";
        WebPage.open(url);
   }

   /**
    * Open a URL in the default web browser.
    * @param url
    * @return true/false
    */
   public static boolean open(String url)
   {
      boolean flag = false;

      try
      {
         /**
          *  Try to load the Desktop Class - only available in Java 1.6 or higher
          *  The code performs the following call:
          *  <code>java.awt.Desktop.getDesktop().browse(url)</code>
          */
         Class<?> cc = Class.forName("java.awt.Desktop");
         cc.getDeclaredMethod("browse", new Class[] { java.net.URI.class }).invoke(
               cc.getDeclaredMethod("getDesktop").invoke(null),
               new Object[] { java.net.URI.create(url) } );

         flag = true;
      }
      catch (Exception skip)
      {  // The Desktop Class either failed to load or is not available.
         String OS = System.getProperty("os.name").toLowerCase();
         Runtime rt = Runtime.getRuntime();
         try
         {
            if (OS.contains("win"))
            {
               rt.exec("rundll32 url.dll,FileProtocolHandler " + url).waitFor();
               flag = true;
            }
            else if (OS.contains("mac"))
            {
               String[] cmd = { "open", url };
               rt.exec(cmd).waitFor();
               flag = true;
            }
            else if (OS.contains("nix") || OS.contains("nux"))
            {
               String[] cmd = { "xdg-open", url };
               rt.exec(cmd).waitFor();
               flag = true;
            }
            else
            {
               System.out.println("Unknown operating system: "+ OS + " : cannot open web page.");
            }
         }
         catch (Exception e)
         {
            e.printStackTrace();
         }
      }

      return flag;
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

Java, Linux, macOS (Mac OS X), Open Source, Programming, Raspberry Pi, Unix, Windows Comments Off on Java Code to Open a Web Page

Java MQ Code to List Channel Status

I thought I posted this code sample but I guess I forgot to do it. 😉

If you have done the runmqsc command for Channel Status for all channels of a queue manager as follows:

DIS CHS(*) ALL

And you wanted to do the same thing via a program, here is a fully functioning Java MQ example that will connect to a remote queue manager, issue a PCF “Inquire Channel Status” command, get the PCF response messages, loop through the PCF responses and output the information. You can download the source code from here.

For more information about the PCF “Inquire Channel Status” command, go to MQ KnowLedge Center here.

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import com.ibm.mq.MQException;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.CMQCFC;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;

/**
 * Program Name
 *  MQListChannelStatus01
 *
 * Description
 *  This java class issues a PCF "inquire channel status" request message for all ("*") channels 
 *  of a remote queue manager. 
 *
 * Sample Command Line Parameters
 *  -m MQA1 -h 127.0.0.1 -p 1414 -c TEST.CHL -q TEST.Q1 -u UserID -x Password
 *
 * @author Roger Lacroix
 */
public class MQListChannelStatus01
{
   private static final SimpleDateFormat  LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");

   private Hashtable<String,String> params;
   private Hashtable<String,Object> mqht;
   private String qMgrName;

   public MQListChannelStatus01()
   {
      super();
      params = new Hashtable<String,String>();
      mqht = new Hashtable<String,Object>();
   }

   /**
    * Make sure the required parameters are present.
    * @return true/false
    */
   private boolean allParamsPresent()
   {
      boolean b = params.containsKey("-h") && params.containsKey("-p") &&
                  params.containsKey("-c") && params.containsKey("-m") &&
                  params.containsKey("-u") && params.containsKey("-x");
      if (b)
      {
         try
         {
            Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            b = false;
         }
      }

      return b;
   }

   /**
    * Extract the command-line parameters and initialize the MQ HashTable.
    * @param args
    * @throws IllegalArgumentException
    */
   private void init(String[] args) throws IllegalArgumentException
   {
      int port = 1414;
      if (args.length > 0 && (args.length % 2) == 0)
      {
         for (int i = 0; i < args.length; i += 2)
         {
            params.put(args[i], args[i + 1]);
         }
      }
      else
      {
         throw new IllegalArgumentException();
      }

      if (allParamsPresent())
      {
         qMgrName = (String) params.get("-m");
         
         try
         {
            port = Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            port = 1414;
         }
         
         mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
         mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));
         mqht.put(CMQC.PORT_PROPERTY, new Integer(port));
         mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
         mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));

         // I don't want to see MQ exceptions at the console.
         MQException.log = null;
      }
      else
      {
         throw new IllegalArgumentException();
      }
   }
   
   private void doPCF()
   {
      MQQueueManager qMgr = null;
      PCFMessageAgent agent = null;
      PCFMessage   request = null;
      PCFMessage[] responses = null;
      String chlStatus = "Inactive"; 

      try
      {
         qMgr = new MQQueueManager(qMgrName, mqht);
         MQListChannelStatus01.logger("successfully connected to "+ qMgrName);

         agent = new PCFMessageAgent(qMgr);
         MQListChannelStatus01.logger("successfully created agent");
      
         // https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.ref.adm.doc/q087540_.htm
         request = new PCFMessage(CMQCFC.MQCMD_INQUIRE_CHANNEL_STATUS);
         
         /**
          * You can explicitly set a channel name like "TEST.CHL" or
          * use a wild card like "TEST.*"
          */
         request.addParameter(CMQCFC.MQCACH_CHANNEL_NAME, "*");
         
         // Add a parameter to select the instance type (current)
         request.addParameter(CMQCFC.MQIACH_CHANNEL_INSTANCE_TYPE, CMQC.MQOT_CURRENT_CHANNEL);

         // Add a parameter that selects all of the attributes we want
         request.addParameter(CMQCFC.MQIACH_CHANNEL_INSTANCE_ATTRS, 
                              new int [] { CMQCFC.MQCACH_CHANNEL_NAME,
                                           CMQCFC.MQCACH_CONNECTION_NAME,
                                           CMQCFC.MQIACH_MSGS,
                                           CMQCFC.MQCACH_LAST_MSG_DATE,
                                           CMQCFC.MQCACH_LAST_MSG_TIME,
                                           CMQCFC.MQIACH_CHANNEL_STATUS
                              });

         responses = agent.send(request);
         
         for (int i = 0; i < responses.length; i++)
         {
            if ( ((responses[i]).getCompCode() == CMQC.MQCC_OK) &&
                 ((responses[i]).getParameterValue(CMQCFC.MQCACH_CHANNEL_NAME) != null) )
            {
               //  get the channel name and trim the spaces               
               String name = responses[i].getStringParameterValue(CMQCFC.MQCACH_CHANNEL_NAME);
               if (name != null)
                  name = name.trim();
               
               //  get the channel name and trim the spaces
               String connName = responses[i].getStringParameterValue(CMQCFC.MQCACH_CONNECTION_NAME);
               if (connName != null)
                  connName = connName.trim();
               
               //  get the channel last message date/time
               String lastMsgDate = responses[i].getStringParameterValue(CMQCFC.MQCACH_LAST_MSG_DATE);
               if (lastMsgDate != null)
                  lastMsgDate = lastMsgDate.trim();
               
               String lastMsgTime = responses[i].getStringParameterValue(CMQCFC.MQCACH_LAST_MSG_TIME);
               if (lastMsgTime != null)
                  lastMsgTime = lastMsgTime.trim();

               //  get the channel current messages total
               int totalMsgs = responses [i].getIntParameterValue(CMQCFC.MQIACH_MSGS);

               //  get the channel status
               chlStatus = getChannelStatus(responses [i].getIntParameterValue(CMQCFC.MQIACH_CHANNEL_STATUS));
               
               MQListChannelStatus01.logger("Name=" + name + " : Connection Name=" + connName  + " : Total Messages=" + totalMsgs +  
                                            " : Last Message Date='" + lastMsgDate +  "' : Last Message Time='" + lastMsgTime +
                                          "' : Status='" + chlStatus+"'");
            }
         }
      }
      catch (MQException e)
      {
         MQListChannelStatus01.logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
      }
      catch (IOException e)
      {
         MQListChannelStatus01.logger("IOException:" +e.getLocalizedMessage());
      }
      catch (MQDataException e)
      {
         MQListChannelStatus01.logger("MQDataException:" +e.getLocalizedMessage());
      }
      finally
      {
         try
         {
            if (agent != null)
            {
               agent.disconnect();
               MQListChannelStatus01.logger("disconnected from agent");
            }
         }
         catch (MQDataException e)
         {
            MQListChannelStatus01.logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }

         try
         {
            if (qMgr != null)
            {
               qMgr.disconnect();
               MQListChannelStatus01.logger("disconnected from "+ qMgrName);
            }
         }
         catch (MQException e)
         {
            MQListChannelStatus01.logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }
      }
   }
   
   private String getChannelStatus(int cs)
   {
      String chlStatus = "Inactive"; 

      switch (cs)
      {
         case CMQCFC.MQCHS_INACTIVE:
            chlStatus = "Inactive";
            break;
         case CMQCFC.MQCHS_BINDING:
            chlStatus = "Binding";
            break;
         case CMQCFC.MQCHS_STARTING:
            chlStatus = "Starting";
            break;
         case CMQCFC.MQCHS_RUNNING:
            chlStatus = "Running";
            break;
         case CMQCFC.MQCHS_STOPPING:
            chlStatus = "Stopping";
            break;
         case CMQCFC.MQCHS_RETRYING:
            chlStatus = "Retrying";
            break;
         case CMQCFC.MQCHS_STOPPED:
            chlStatus = "Stopped";
            break;
         case CMQCFC.MQCHS_REQUESTING:
            chlStatus = "Requesting";
            break;
         case CMQCFC.MQCHS_PAUSED:
            chlStatus = "Paused";
            break;
         case CMQCFC.MQCHS_DISCONNECTED:
            chlStatus = "Disconnected";
            break;
         case CMQCFC.MQCHS_INITIALIZING:
            chlStatus = "Initializing";
            break;
         case CMQCFC.MQCHS_SWITCHING:
            chlStatus = "Switching";
            break;
         default:
            chlStatus = "Unknown ["+cs+"]";
            break;
      }
      
      return chlStatus;
   }

   /**
    * A simple logger method
    * @param data
    */
   public static void logger(String data)
   {
      String className = Thread.currentThread().getStackTrace()[2].getClassName();

      // Remove the package info.
      if ( (className != null) && (className.lastIndexOf('.') != -1) )
         className = className.substring(className.lastIndexOf('.')+1);

      System.out.println(LOGGER_TIMESTAMP.format(new Date())+" "+className+": "+Thread.currentThread().getStackTrace()[2].getMethodName()+": "+data);
   }

   public static void main(String[] args)
   {
      MQListChannelStatus01 mqlqs = new MQListChannelStatus01();
      
      try
      {
         mqlqs.init(args);
         mqlqs.doPCF();
      }
      catch (IllegalArgumentException e)
      {
         MQListChannelStatus01.logger("Usage: java MQListChannelStatus01 -m QueueManagerName -h host -p port -c channel -u UserID -x Password");
         System.exit(1);
      }

      System.exit(0);
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, HPE NonStop, IBM i (OS/400), IBM MQ, Java, Linux, macOS (Mac OS X), Open Source, PCF, Programming, Unix, Windows 3 Comments

Red Hat Enterprise Linux 7.6 Released

Red Hat has just released Red Hat Enterprise Linux 7.6.
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/7.6_release_notes/

Red Hat Enterprise Linux (RHEL) is a Linux distribution developed by Red Hat and targeted toward the commercial market. Red Hat Enterprise Linux is released in server versions for x86, x86-64, Itanium, PowerPC and IBM Z, and desktop versions for x86 and x86-64. All of the Red Hat’s official support and training, together with the Red Hat Certification Program, focuses on the Red Hat Enterprise Linux platform. Red Hat Enterprise Linux is often abbreviated to RHEL, although this is not an official designation.

Regards,
Roger Lacroix
Capitalware Inc.

Linux, Open Source, Operating Systems Comments Off on Red Hat Enterprise Linux 7.6 Released

Fedora 29 Released

Fedora Project has just released Fedora 29.
https://fedoramagazine.org/announcing-fedora-29/

Fedora is a Linux distribution developed by the community-supported Fedora Project and sponsored by Red Hat. Fedora contains software distributed under various free and open-source licenses and aims to be on the leading edge of such technologies. Fedora is the upstream source of the commercial Red Hat Enterprise Linux distribution.

Regards,
Roger Lacroix
Capitalware Inc.

Linux, Open Source, Operating Systems Comments Off on Fedora 29 Released