Big fat red warning!


This is intended for educational purposes only!

 

This post is about installing ThingWorx on a highly unsupported environment. It's neither recommended nor encouraged to set up a system like this any other than strictly educational purposes or for creating a mobile mockup that can easily be taken on the road. Any system experiencing errors, performance issues or other kind of weird errors based on this installation guide is not supported at all by PTC / ThingWorx and has neither been blessed by R&D nor QA.

 

Installing ThingWorx on a Raspberry Pi

 

This blog post holds information on installing ThingWorx in a highly unsupported environment (Raspberry Pi, Tomcat 8.5.3, 32-Bit). If you have not read the warning above, now is the time to read it!

 

Though the environment is not supported, ThingWorx can be used utilizing a Raspberry Pi as a server to receive either information from the Raspberry Pi itself or from other connected Things and Sensors. This can be used for small demonstration applications where memory and CPU are not of utmost importance.

 

Configuring the Raspberry Pi as a WIFI hotspot / access point will even allow to connect to the server directly without utilizing e.g. the PTC- or a customer-network infrastructure.

 

Warning

 

This project is not a typical setup for ThingWorx and is neither intended for any real environments nor for any actual usage. It's purely designed as a demonstration environment to explore the ThingWorx user interface and connect a minimal amount of devices / sensors. The typical use case would be to set up an Edge MicroServer (EMS) or a Java Edge SDK on the Raspberry Pi and send data to a ThingWorx instance hosted on a proper server with more capable hardware and resources.

 

And because this scenario is highly unsupported anyway, we're not even looking into securing the system (e.g. through firewalls).

 

Common Sense Warning

 

It is assumed that all commands are executed correctly and without an error message.

Should any errors show up during the installation / configuration, don't just continue with the rest of the commands - it won't work.

Troubleshoot and fix the immediate issue before continuing with the rest of guide.

 

Performance Warning

 

Due to the lean resource design of the Raspberry Pi, this guide purely focuses on deploying the Neo4J version of ThingWorx (only).

 

 

You've been warned four times now (just saying...)

 

 

 

 

About

 

This is the first part of a ThingBerry related blog post series.

 

thingberry_small.png

 

ThingBerry is ThingWorx installed on a RaspBerry Pi, which can be used for portable demonstrations without the need of utilizing e.g. customer networks. Instead the ThingBerry provides its own custom WIFI hotspot and allows Things to connect and send / receive demo data on a small scale.

 

In this particual blog post we'll discuss on how to setup the Raspberry Pi and how to install ThingWorx on it.

Other parts will cover topics like setting up the ThingBerry as a WIFI hotspot, federation or using TLS to secure the connections.

 

Installing the Raspberry Pi

 

This installation is going to use a command line version of Raspbian Jesse Light.

Download and install it from https://www.raspberrypi.org/downloads/raspbian/

The installation guide over there is quite straight forward...

 

The command line version will have less strain on resources but will provide no graphical user interface.

This blog post is based on the 2017-01-11 release - things might be different with newer versions.

 

When working with the ThingBerry it's recommended to connect via SSH (e.g. using PuTTY).

That eliminates the need of setting up a dedicated monitor / mouse / keyboard etc. and also allows to copy & paste the command lines from this blog post directly into the command line interface (so it's my typo, not yours).

 

The default username is pi with password raspberry - the default startup is with a querty keyboard!

So check your spelling before firing the password...

 

As we're using the ThingBerry as a WIFI hotspot later on, it's recommended to plug it in via an ethernet cable for the installation / configuration part - or for accessing it through your local network infrastructure.

 

Setting up the Raspberry Pi

 

Initial configuration

 

After booting up, adjust the general configuration via the Raspberry Pi Software Configuration Tool

 

sudo raspi-config

 

If you're not sure where to find the - character on an English keyboard, just use the one on the number pad.

 

The following action need to be performed:

 

  • Expand Filesystem (to take full usage of the SD card)
  • Boot Options > Wait for network at boot (to have the network ready directly after startup)
  • Internationalisation Options > Change Timezone (to reflect your timezone)
  • Internationalisation Options > Change Keyboard Layout (to reflect your keyboard = less typos = great!)
  • Internationalisation Options > Change Wi-Fi Country (to enable channels specific to your location)
  • Advanced Options > Hostname (set a specific hostname to talk to this Raspberry Pi, e.g. thingberry)
  • Advanced Options > SSH (to enable remote access)

 

If sensors should be connected to this device directly, the following needs to be enabled as well:

 

  • Advanced Options > SPI
  • Advanced Options > I2C
  • Advanced Options > 1-Wire

 

Finish the configuration and reboot the Thingberry.

 

Updating and installing required software

 

The keyboard layout has changed, so you can now use the regular keys to type the password.

 

From this point forward, you can also connect via SSH using the hostname and the default SSH port 22.

To exit from any current sessions, use the command

 

exit

 

In case the password needs to be changed, this can be done via

 

passwd

 

The installation needs now to be updated and authbind and Java need to be installed.

Java is required for the Tomcat installation and authbind will allow to actually startup services that are using a port that usually requires root access (like port 80).

 

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install authbind
sudo apt-get install oracle-java8-jdk

 

This might take a while - feel free to grab a tea or a beer...

 

After the installation verify that Java is installed via

 

java -version

 

With this, the initial configuration of the ThingBerry is done.

 

Tomcat

 

Download Tomcat

 

To install Tomcat, first a new user needs to be created. We will add the user named tomcat to the system:

 

sudo adduser --system --shell /bin/bash --gecos 'Tomcat Java Servlet and JSP engine' --group --disabled-password --home /home/tomcat tomcat

 

Next step is to create a temporary directory and download the latest version from apache.org

In a web-browser on your desktop / laptop open http://www.eu.apache.org/dist/tomcat/tomcat-8/

Browse through the latest version branches, in my case it's 8.5.11 - go to bin and find the tar.gz file.

On the ThingBerry, download the file via wget, extract the file and delete it.

 

mkdir -p ~/tmp
cd ~/tmp
wget http://www.eu.apache.org/dist/tomcat/tomcat-8/v8.5.11/bin/apache-tomcat-8.5.11.tar.gz
tar xvzf ./apache-tomcat-8.5.11.tar.gz
rm ./apache-tomcat-8.5.11.tar.gz

 

Configure Tomcat

 

The first configuration step is to move Tomcat into the /usr/share folder

Then we can create a link to address it via /usr/share/tomcat

This link allows to dynamically update or swap the Tomcat version later without any impact on any of the configuration / hard wired directory pointers that we're setting up later on.

Nice one, isn't it?

 

Please note, there are two directories here: tomcat8 where we will copy the files to and tomcat which is used for the link

 

cd ~
sudo mkdir -p /usr/share/tomcat8
sudo mv ~/tmp/apache-tomcat-8.5.11 /usr/share/tomcat8
sudo rmdir ~/tmp
sudo rm -f /usr/share/tomcat
sudo ln -s /usr/share/tomcat8/apache-tomcat-8.5.11 /usr/share/tomcat

 

Now that we have the new location, we can set the required environment variables

I prefer the nano editor, but choose whatever you're comfortable with...

Create a new file via

 

sudo nano /etc/environment

 

Paste the following content:

 

export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt
export CATALINA_HOME=/usr/share/tomcat

 

Copy it from here, in PuTTY just right-click the mouse to paste.

CTRL+X to exit and save the changes via "Y" and confirming the filename.

 

To enable the environment variable, reboot the ThingBerry

 

sudo reboot

 

Configure Tomcat in detail

 

Tomcat needs to be prepared make it smoother integrating the ThingWorx.war file.

First step of doing this, is to edit the context and include the manager's pathname.

cd $CATALINA_HOME
sudo nano conf/context.xml

 

Uncomment the line with

 

<Manager pathname="" />

 

close to the end of the file by removing the commenting brackets in the line above and below it.

 

The section as it is now:

 

<Context>

    [...]

    <!-- Uncomment this to disable session persistence across Tomcat restarts -$
    <!--
    <Manager pathname="" />
    -->
</Context>

 

The section as it should be:

 

<Context>

    [...]

    <!-- Uncomment this to disable session persistence across Tomcat restarts -$
    <Manager pathname="" />
</Context>

 

Save and exit.

 

Next step is to set the Tomcat environment variables.

 

sudo nano $CATALINA_HOME/bin/setenv.sh

 

Paste the following content:

 

# Java Options
export JAVA_OPTS="-server -d32 -Djava.security.egd=file:/dev/urandom -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -XX:+UseNUMA -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.hostname=<server_name> -Dfile.encoding=UTF-8 -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
export JRE_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre

 

Ensure to edit <server_name> to match your actual hostname (e.g. thingberry)!

This is quite important... if that change is not made, the rest won't work!

Make it so.

 

We need to use the 32-Bit version of Java as the Raspberry Pi is based on an ARM system which does not support 64-Bit.

 

Save and exit.

 

To be able to monitor Tomcat from remote, a JMX Listener would be helpful.

To learn more about JMX, check out https://en.wikipedia.org/wiki/Java_Management_Extensions

 

sudo nano conf/server.xml

 

In the server.xml there's a section with already configured Listeners. Add the following after the last configured listener:

 

<!-- custom JMX Listener - add after existing Listners -->
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="22222" rmiServerPortPlatform="22223" />

 

Save and exit.

 

For JMX to work, the catalina-jmx-remote.jar is required.

Remember when browsing through the apache.org directories to get the latest Tomcat version?

If not, it's still written somewhere above

Go back to the bin folder and go to extras and locate the catalina-jmx-remote.jar

This file can be wget'ed into Tomcat's lib folder:

 

cd $CATALINA_HOME/lib
sudo wget http://www.apache.org/dist/tomcat/tomcat-8/v8.5.11/bin/extras/catalina-jmx-remote.jar
cd $CATALINA_HOME

 

Finally ownership and permissions need to be adjusted:

 

sudo chmod +x /usr/share/tomcat/bin/*.sh
sudo chmod 775 bin/ lib/ webapps/
sudo chmod 750 logs/ temp/ work/
sudo chmod 640 conf/*
sudo chown -R tomcat:tomcat /usr/share/tomcat8

 

Securing ports and run Tomcat on port 80 with authbind

 

Secure the shutdown port password and configure port 80.

 

sudo nano conf/server.xml

 

Find

 

<Server port="8005" shutdown="SHUTDOWN">

 

and update the password with something more secure, like

 

<Server port="8005" shutdown="TH!nGW0rX">

 

If you're following this guide literally and actually use TH!nGW0rX as a password, it might not be too secure - so choose wisely

 

Comment out the Connector on port 8080

 

<!--
<Connector port="8080" protocol="HTTP/1.1"
          connectionTimeout="20000"
          redirectPort="8443" />
-->

 

Add the <!-- and --> line for commenting it out.

 

Create a new connector on port 80

 

After the port 8080 configuration block, insert a new block with the following content:

 

<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
          maxThreads="150"
          connectionTimeout="20000"
          redirectPort="8443" />

 

This allows listening to port 80 and forwarding any requests to the internal Tomcat port 8443

 

Save and exit.

 

Identify the tomcat user userid with

 

id -u tomcat

 

Let's say the result is 109, therefore the following command needs to be:

 

sudo nano /etc/authbind/byuid/109

 

Opening the nano editor and creating the 109 file (adjust for your usernumber) will allow to configure the port usage that this user can run programs with without having root access. To allow the Tomcat user start services with ports < 1024 insert the following content:

 

0.0.0.0/0:1,1023

 

Save and exit.

 

Finally ownership and permissions need to be adjusted:

 

sudo chmod 700 /etc/authbind/byuid/109
sudo chown tomcat:tomcat /etc/authbind/byuid/109
sudo nano $CATALINA_HOME/bin/startup.sh

 

The last command will open the Tomcat startup file.

To actually run the service within the scope of authbind, the actual execution needs to be adjusted.

 

At the end of the file, adjust the following line

 

exec "$PRGDIR"/"$EXECUTABLE" start "$@"

 

to

 

exec authbind --deep "$PRGDIR"/"$EXECUTABLE" start "$@"

 

Save and exit.

 

The same needs to be done for the Tomcat shutdown file:

 

sudo nano $CATALINA_HOME/bin/shutdown.sh

 

At the end of the file, adjust the following line

 

exec "$PRGDIR"/"$EXECUTABLE" stop "$@"

 

to

 

exec authbind --deep "$PRGDIR"/"$EXECUTABLE" stop "$@"

 

Save and exit.

 

Enable log rotation

 

Log rotation is important to keep log sizes under control and minimize the impact on file size and I/O as well as CPU usage during writing the Tomcat logs.

 

sudo nano /etc/logrotate.d/tomcat

 

Paste the following content:

 

/usr/share/tomcat/logs/catalina.out {
copytruncate
daily
rotate 7
compress
missingok
size 9M
}

 

With this logs will be rotated on a daily bases or once they reach 9 MB.

 

Save and exit.

 

Autostart Tomcat on boot

 

The last step for Tomcat is to automatically start in on boot. This is configured via the init.d files

 

sudo nano /etc/init.d/tomcat

 

In this file we specify a start, stop and restart option. Paste the following content:

 

#!/bin/bash

### BEGIN INIT INFO
# Provides:        tomcat
# Required-Start:  $network
# Required-Stop:  $network
# Default-Start:  2 3 4 5
# Default-Stop:    0 1 6
# Short-Description: Start/Stop Tomcat server
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin

start() {
    /bin/su - tomcat -c /usr/share/tomcat/bin/startup.sh
}

stop() {
    /bin/su - tomcat -c /usr/share/tomcat/bin/shutdown.sh
}

case $1 in
    start|stop) $1;;
    restart) stop; start;;
    *) echo "Run as $0 <start|stop|restart>"; exit 1;;
esac

 

Save and exit.

 

To get this configuration in place, the permissions need to be adjusted:

 

sudo chmod 755 /etc/init.d/tomcat
sudo update-rc.d tomcat defaults
sudo reboot

 

The final reboot will ensure a fresh start of the ThingBerry, with hopefully Tomcat already up and running.

 

If Tomcat is indeed up and running can be verified with

 

ps -ef | grep tomcat

 

which should return information about any running processes / services containing the string "tomcat".

The second process you're seeing is the actual grep, that's also coloring the "tomcat" string.

 

ThingWorx

 

Preparing Tomcat and the environment

 

Now that Tomcat is up and running, we're going to stop it. Not just for fun, but to configure ThingWorx properly and start up Tomcat only if the ThingWorx installation is prepared and fully configured.

 

sudo service tomcat stop

 

Ensure with the ps command above, that Tomcat is indeed no longer running. If it still is, not all the above steps have been deployed correctly and Tomcat can't be stopped due to a configuration issue.

 

We need to provide new directories to actually store ThingWorx related information.

Those can be created with the following commands:

 

sudo mkdir /thingworx
sudo mkdir /thingworx/platform /thingworx/storage /thingworx/backupstorage

 

In a previous step, we already defined the Tomcat environment variables, now we need to update them to include the path to the ThingWorx Platform Settings:

 

sudo nano $CATALINA_HOME/bin/setenv.sh

 

At the end of the file, insert the following content:

 

#THINGWORX OPTIONS
export THINGWORX_PLATFORM_SETTINGS=/thingworx/platform

 

Save and exit.

 

In the just defined directory we're now creating the platform-settings.json and configure the directories we created earlier. Those will hold the Storage and BackupStorage for ThingWorx.

 

sudo nano /thingworx/platform/platform-settings.json

 

Paste the following content:

 

{
    "PlatformSettingsConfig": {
        "BasicSettings": {
            "BackupStorage": "/thingworx/backupstorage",
            "Storage": "/thingworx/storage"
        }
    }
}

 

Save and exit.

 

To give the tomcat user access to this file, ownership and permissions need to be adjusted:

 

sudo chmod -R 755 /thingworx
sudo chown -R tomcat:tomcat /thingworx

 

Deploying Thingworx.war

 

Now things get tricky.

 

As mentioned in the intital "Performance Warning" ensure to deploy the Neo4J version of ThingWorx.

 

There are quite some ways to get the Thingworx.war file into the correct directory.

Here I'm showing how to wget it from a private http server in the local network.

Of course this would also work, copying from a USB stick etc.

 

Never, ever put this file on a public web / ftp server etc.

 

For simplicity, we're just assuming that the Thingworx.war file is available on a http server within your local network environment.

Ensure the path and server is correct, don't just copy & paste!

 

cd $CATALINA_HOME/webapps
sudo wget http://<server>/Thingworx.war
sudo chmod 775 Thingworx.war
sudo chown tomcat:tomcat Thingworx.war
sudo reboot

 

With this, ThingWorx is deployed on the ThingBerry!

 

Check out http://<thingberry>/Thingworx to connect to it from your desktop machine.

The default login is username Administrator and password admin

 

Have fun!

 

What's next

 

ThingWorx is now installed and you should be good to go.

Just keep in mind, it might be kind of slow and is just for demo purposes, as the Raspberry Pi just doesn't provide the power to allow a full blown performance as on other (64-Bit) systems.

 

In upcoming Blog posts we're going to look into actually configuring the ThingBerry as a WIFI hotspot and securing the data transfer with a (self-signed) chain of certificates.