Category Archives: Technical Stuff

webMethods Integration Server: How to Structure Packages

For the webMethods Integration Server (IS) packages are “containers” that bundle together various assets and get deployed as sort-of atomic units; this makes them more or less comparable to web apps in a servlet container.  So if you are given a certain task to solve, you need to figure out a clever way to organize the various parts of the overall implementation. Unless we talk about something trivial and short-lived (ever seen?), this is more complicated than it might appear at a first glance.

I did my first project on Integration Server 4.6 in early 2002 and can now openly confess, that the result, while working fine from a business perspective, was not something I would still be proud of today. To a small extent, the hardware equipment can be blamed. I was working with a notebook that had 256 MB of RAM, a single-core 800 MHz mobile Pentium III, a 20 GB hard disk with a whopping 4200 RPM, and a 14 inch display with a 1024×768 resolution.

You may now ask, how this can affect code quality. Most important in my case was performance. If pressing the save button literally sends the machine into a 2+ minutes period of frantic disk activity, you think more than twice before do this. (Eventually, I got a memory upgrade to 512 MB.) And this is only the tip of the iceberg. In summary, refactoring is very hard if your concentration is constantly drawn away, because you have to wait for your machine to be ready again. Luckily we are past those issues today.

For the sake of this article let’s work with the following scenario, which is close to something I worked on about two years ago:

The business requirement is to automatically perform modifications to certain sales opportunities in the CRM system and report the result to the account manager.

Of course you can put everything in one package. There will be no need to think about dependency management and much less work for setting up the DEV environment, the CI server, deployment scripts (Chef in my case), etc. And in fact this is how I started. Pretty soon I moved some really generic utility services like data type conversion or date calculation into a separate utilities package. But other than that things stayed quite monolithic.

It didn’t last long, though. When I was half-way through with the initial implementation, the next, more or less separate business scenario that involved the CRM system showed up. Obviously, there was no point in having connection details, services, and other configurations related to the latter multiple times. So I moved all CRM-related stuff to yet another package.

To be clear: I was not taken by surprise when this happened. Instead it was a deliberate decision to be very careful with upfront framework building. This has been one of my personal rules for a while and it has the great advantage of being efficient as well as effective. The efficiency comes from the fact that no time is spent on things that later turn out not to be needed a second time. More importantly, however, is the effectiveness. It means the outcome is useful. If you ever came across an API that is cumbersome to use, you know what I’m talking about.

Coming to an end, here is the abstract description of how I structure my IS packages. There are certainly other ways, but this works really well for me and not once in many years has caused issues or created that gut-feeling, which tells you that something is not right, although you cannot say what it is.

  • Business logic: Here is where specifics of the business side are handled. What are the criteria to select an opportunity for processing? What changes shall be applied? Technical details of the CRM are not in scope here.
  • System details: How to perform a query against the CRM system using the criteria coming from the business logic level above? What are the connection details for a given environment (DEV, TEST, PROD)? Not in scope is e.g. the implementation of auditing.
  • Common topics: How to send notifications (e.g. where is your mail server)? Auditing, dealing with data structures, date manipulation, logging, etc.

In terms of naming conventions I suggest the following


Here are a few examples for the famous Acme Corp.

  • AC_APP_CrmOppCheck   : Application that performs checks on sales opportunities
  • AC_CMN_Audit                     : Auditing
  • AC_CMN_Util                         : Utilities
  • AC_SYS_CRM                         : Connectivity and services for CRM system
  • AC_SYS_ERP                          : Connectivity and services for ERP system

If you have questions, please do not hesitate to ask in the comments.

webMethods Integration Server: Create non-printable characters

It is a common requirement (e.g. for search-replace operations on strings) to create characters that are non-printable, which also means there is no obvious way to type them in. In my case the situation was that I had to convert end-of-line characters  created on a Windows system (CR+LF) to Linux (LF only) for some unit tests to pass.

On webMethods Integration Server you have two options to do this. The first is to create a small Java service, which has the down-side that some people shy away from it. (I have even seen organizations that pretty much forbid them, which is probably a bit extreme.) The second way is to have a Flow service (Integration Server’s graphical programming language), which is what I demonstrate here.

So how do I create a LF character? For this you can use the pub.string:URLDecode service with “%0a” (without double-quotes) as input, which is simply the character with ASCII number 10 (0x0a).

And then you simply perform a replace operation using the pub.string:replace service and tell it to replace all CR+LF occurrences with LF. The search part is done best with a regular expression, in this case “\r\n” (again without the double-quotes). And don’t forget to set useRegex to true.

That’s it.

VLANs with pfSense, Unifi, and VMware ESXi

For setting up VLANs in my home network I basically followed the tutorial from Crosstalk Solution on YouTube:

The result, however, was not working as expected. As it turned out the critical difference was that I have my pfSense firewall running virtualized on VMware ESXi 6.5. By default the latter “removes” VLAN tags.

But it is very easy to change this and not even a reboot is required. So here are the steps you need to perform:

  • Log in to the admin web UI of ESXi
  • Go to the network port groups and open your internal network
  • Open settings for internal network
  • Change VLAN to 4095
  • Save change

That’s all 🙂

pfSense Upgrade to 2.4.4 p1

Just a few short lines to let you know that for me the upgrade from plain 2.4.4 to p1 went really smooth.

I have the following plugins installed:

  • bandwidthd (0.7.4_1)
  • iftop (0.17_2)
  • net-snmp (0.1.5_2)
  • ntopng (0.8.13_3)
  • Open-VM-Tools (10.1.0,1)
  • suricata (4.0.13_11)

All plugins had been updated some time ago and thus prior to the pfSense core, which is not recommended. In my case, though, it did not cause any issues. This was a pleasant difference to the upgrade from 2.4.3 to 2.4.4 (also see this video on YouTube), where the fact that plugins had been installed was cause for a completely broken system after the upgrade.

It’s Not Beautifying but Reduction of Complexity

I am writing this on a Saturday afternoon after having spent several hours going over Java code that is about a year old,  needed only occasionally, and has not caused issues for quite a while. Still I spent personal time to improve or, shame on me, even add the Javdocs. Also, some additional error checks were added and the code structure simplified.

None of this had been asked for by anyone else. And probably quite a few people would call it a terrible waste time, given the various new features still needed so badly. So why did I do it?

It was an experiment, a successful one  from where I stand. In the beginning I merely wanted to see in how many ways the code could be improved with sufficient time gone by after the initial writing. I ended up doing the following things:

  • Renamed class ServiceWrapper to ServiceWrapperManager, because the class is not an actual wrapper but creates and deletes them.
  • Renamed variable adapterServiceNode to node, because via a wrong user input it could point to a node object of a different type and not an adapter service. (The same was done in two other cases.)
  • Added multiple checks that would throw an IllegalArgumentException, if the user had provided wrong input. So rather than having to wonder why the creation of a wrapper had failed, I would be “shouted” at early in the process.
  • Added and improved multiple Javadoc entries. This, in turn, made me look at the code more closely where I discovered multiple things to improve or even fix.

When I look at the code now, it is cleaner, more robust, and easier to read. And the latter is the most important aspect on my case, because it reduces technical debt. So here you have your argument.

And for business people this means that I “keep my head above water level”. Or in other words: It is an absolute prerequisite for fast time-to-market that my code base is tidy and well-structured. Only then can I react quickly and change things without having to think hours what might break in other places, should I now add this or that new feature.

Installing Pi-hole on top of dnsmasq

Pi-hole is a great and easy addition to security. The automated installation is a nice thing, but did not work on my system. The core of the problem was that I wanted to install it on a Rasperry Pi that already had dnsmasq running  on it. And of course that dnsmasq was configured to provide DNS services to the Pi. What then happened was that, as an early step of the installation, the dnsmasq daemon was stopped. Logically, the Pi-hole download that was supposed to to take place, did not work.

After a few tests the following approach showed to work

  • Disable dnsmasq via sudo systemctl stop dnsmasq.service
  • Update /etc/resolv.conf to point to the DNS server in my router or something like (dnsmasq sets it to on every start or stop)
  • Start the Pi-hole installation normally


Displaying Your Terminal Sessions

We are used to terminal sessions displayed like any other content, i.e. as a video of some kind. The latter comes with two caveats, though. It uses a lot of bandwidth (compared to the actual terminal session) and is often difficult to read. Because many people do not bother to magnify the terminal either during the actual presentation or as part of the post-processing.

A very interesting alternative, especially for blog posts, is asciinema. It works on Linux, macOS and various BSD flavors. What it basically does is open a special shell (Bash-like) that simply records all keystrokes (plus the responses) in a VT-100 compatible format. So you end up with a small text file that can be replayed using a JavaScript snippet.

In addition to using the hosted instance, that supports sharing in multiple ways, you can also run your own server via Docker. For all the details, please go to the website.

Visual Studio Code and Bash on Windows

A while ago I started using Visual Studio Code and it is a great tool for many things. Primary use-cases for me are Chef recipes and SFDX at the moment, for both of which there are extensions in the VS Code marketplace. Also, I like to use Bash (the one that came with Git for Windows) in the terminal .

But at least on Windows (this seems to be different on Mac OS) some of the standard keyboard shortcuts for Bash are used by VS Code itself. Relevant for me personally were Ctrl-A, Ctrl-E, and Ctrl-K. To make bash usable for me, I had to “undefine” those shortcuts in VS Code, but only for the terminal.

Here are the necessary additions to  keybindings.json :

// Place your key bindings in this file to overwrite the defaults

 { "key": "ctrl+a",
   "command": "",
   "when": "terminalFocus" },
 { "key": "ctrl+e",
   "command": "",
   "when": "terminalFocus" },
 { "key": "ctrl+k",
   "command": "",
   "when": "terminalFocus" },
Hope that helps!