As we have started moving to a service based architecture, we have been developing processes to create and configure our infrastructure in a predictable and repeatable way using Vagrant and Chef. One challenge that we have faced is trying to replicate a production Wildfly server on a dev box, including the applications are installed on it and their correct versions.
Ideally, we’d like the developer to be able to specify which server they want to clone when kicking off the Chef process. Chef would then create a new Wildfly instance and download and install all the web applications running on the specified instance.
The first question Chef will need to know, is “what what Wildfly servers are running on the network?” The next question is then, “which applications, and what versions are installed on those servers?”
In order to answer these questions, we developed a “WildflyMonitor” web application which is installed on each of our Wildfly instances. The application will collect information about the local Wildfly instance that it’s running on, including the names and versions of the hosted apps, and publish that information to our messaging system. This information eventually makes it into our Wildfly Registry DB, where it is collected and organized by Wildfly instance.
A rough diagram of the architecture appears below.
In the example, there are 3 Wildfly instances, lisprod01, 02, and 03, which are reporting their applications to the registry. The table below the DB illustrates how the data is organized by server, and then by applications, with each Wildfly instance is running 2 applications. The WildflyRegistry REST service then makes this information available to any client on the network, including Chef recipes.
The next step is then to modify the Chef script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/http' | |
require 'json' | |
url = 'http://lweb.lynden.com/WildflyRegistry/registry/services' | |
webapps = [] | |
resp = Net::HTTP.get_response(URI.parse(url)) | |
resp_text = resp.body | |
data =JSON.parse(resp_text) | |
servers = data | |
# Loop through each Wildfly server that was found | |
servers.each do |server| | |
serverName = server["serverName"] | |
#Is this the server we want to clone? | |
if serverName == cloneServer then | |
wildFlyApps = server["wildflyApp"] | |
#Loop through app on the server | |
wildFlyApps.each do |app| | |
#Create a hash of app name to app version | |
if app["appRuntimeName"].end_with? ".war" then | |
appTokens = app["appName"].split("-") | |
myHash = Hash[ :name, appTokens[0], :version, appTokens[1]] | |
webapps.push(myHash) | |
end | |
end | |
end |
The snippet above shows the script contacting the REST service, looping through all the servers that were returned until the desired server to clone is found. Once the server is found, the script loops through that server’s list of applications and creates a list of hashes with the app name mapped to its version number.
Next, the script loops through each of the apps which were discovered in the previous snippet.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
webapps.each do |app| | |
url = "http://nexus.lynden.com/repo/com/lynden/" + app[:name] + "/" + app[:version] + "/" + app[:name] + "-" + app[:version] + ".war" | |
puts "deploying " + app[:name] + "-" + app[:version] | |
fullFileNameNew = app[:name] + "-" + app[:version] | |
fullPath = "/tmp/" + app[:name] + "-" + app[:version] | |
fullPath = fullPath + ".war" | |
puts "Full path to apps " + fullPath | |
remote_file fullPath do | |
source url | |
action :create_if_missing | |
end | |
bash 'deploy_app' do | |
cwd '/usr/local/wildfly/bin' | |
command = '/tmp/deployWildfly.sh ' + fullPath | |
code <<-EOH | |
echo COMMAND #{command} | |
#{command} | |
EOH | |
end | |
end |
First the script constructs the URL to the web app in our Nexus repository. The script then downloads each web app to the tmp folder on the server. The script then calls a shell script which deploys the applications to Wildfly utilizing the Wildfly command line interface.
The shell script which is called by Chef to perform the actual deployment to Wildfly is fairly straightforward and appears below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!/bin/sh | |
FILENAME=$1 | |
PATH=$PATH:/usr/local/java/bin | |
cd /usr/local/wildfly/bin | |
./jboss-cli.sh -c –user=myUser –password=myPassword –command="deploy $FILENAME" |
That’s it, based on the data in our WildflyRegistry we are able to use this Chef script and shell script to create a clone of an existing Wildfly instance running on our network.
This is a great blog, thanks for referencing our Nexus product! We’d like to publish this on our community page. If you’re interested, let’s get in touch. Hope to hear from you soon!
Sure, I’d have no problem if you would like to publish this on your community page. Let me know what info you would need.
Thanks,
-Rob