SOAP UI multiple hosts

Posted in Uncategorized with tags , , on June 30, 2016 by Shaun Elliott

Here’s a quick tip: If you use SOAP UI, you can have multiple environments\URLs setup by using placeholder properties.

On the project, go to properties -> custom properties. From there, you can add a property like “host” for example. You can then have a “qaHost” and “prodHost” properties, which can reference other properties. For example, you might set qaHost=qa.foo.com and prodHost=foo.com. You can then set host=#{#Project#qaHost}. You then set your endpoint URL to http://#{Project#host}/service/foo/bar. Now when you want to test out multiple hosts, you can just toggle the property, instead of needing a project for each, allowing you to keep the same requests and setup for each.

I hope this helps someone.

Adding a column to a data frame in R

Posted in Uncategorized with tags on October 2, 2014 by Shaun Elliott

Ok, this should be pretty simple. I’ve found R to be both simultaneously elegant and infuriating. This particular instance for example.

I wanted to add a new column to an existing data frame. My intuition led me down the path of lapply. I was wrong. It is far more simple than that.

Given the canonical R data.frame example:

n <- c(2, 3, 5) 
s <- c("aa", "bb", "cc") 
b <- c(TRUE, FALSE, TRUE) 
df <- data.frame(n, s, b) 
To use a function to add a new column, you have several ways. First, define the function, then you can just add it in one of 3 ways:
something <- function(x,y){
 paste(x,y,sep="--")
}

df[,4] <- something(df[,1],df[,2])
df["foo"] <- something(df[,1],df[,2])
df$bar <- something(df$n,df$b)

CXF WS Client With Fluent Builders and More!

Posted in Uncategorized with tags , , on December 18, 2013 by Shaun Elliott

Alright, I’ve been using SoapUI to generated my CXF WS clients for a little while now. It’s a pretty good tool, but ultimately if you’re using it to generate CXF, you might be able to skip SoapUI if you’re willing to indulge in some maven goodness. I started down the maven path with this because I wanted to use xjc plugins for the generated jaxb classes. Specifically, I wanted to use the fluent builders.

I ran SoapUI and collected the arguments. I then converted them over to the maven form, giving me this:

<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf-version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/wsdl/client.wsdl</wsdl>
<extraargs>
<extraarg>-p</extraarg>
<extraarg>${project.groupId}.${project.artifactId}.gen</extraarg>
<extraarg>-b</extraarg>
<extraarg>${basedir}/src/main/resources/wsdl/bindings.xml</extraarg>
<extraarg>-client</extraarg>
<extraarg>-exsh</extraarg>
<extraarg>false</extraarg>
<extraarg>-dns</extraarg>
<extraarg>true</extraarg>
<extraarg>-dex</extraarg>
<extraarg>true</extraarg>
<extraarg>-verbose</extraarg>
<extraarg>-xjc-npa</extraarg>
<!-- OPTIONAL: generate toString methods -->
<extraarg>-xjc-Xts</extraarg>
<!-- OPTIONAL: use the fluent API -->
<extraarg>-xjc-Xfluent-api</extraarg>
<!-- OPTIONAL: create value constructors -->
<extraarg>-xjc-Xvalue-constructor</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-ts</artifactId>
<version>2.2.12</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-value-constructor</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-fluent-api</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.4</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<copy todir="src/main/java">
<fileset dir="${project.build.directory}/generated-sources/cxf" />
</copy>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

I know that’s alot of pasta, but what you get is a single command run that will (re)generate your CXF WS client, putting them back in to your java source directory.

Here is my bindings file:

<jaxb:bindings version="2.1"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings> 

You’re on your own for your wsdl, just remember to drop it in src/main/resources/wsdl

Reading Tab Delimited Files – H2

Posted in Uncategorized with tags , , on April 23, 2013 by Shaun Elliott

Ok, this is probably easy enough to figure out based on the H2 documentation, but here is an example using java’s H2 embedded database, and a little bit of Spring to query tab delimited files:


public class H2Test {
public static void main( final String[] args ) throws Exception {

File h2Directory = new File( System.getProperty( "user.home" ) + "\\h2" );
if ( h2Directory.exists() ) {
FileUtils.cleanDirectory( h2Directory );
}

// start the TCP Server
Server server = Server.createTcpServer( new String[] {
"-baseDir",
"~/h2/test" } ).start();

try {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName( "org.h2.Driver" );
dataSource.setUrl( "jdbc:h2:~/h2/test" );
dataSource.setUsername( "sa" );
SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate( dataSource );

String fileName = "full path and file name here";
System.out.println( simpleJdbcTemplate.queryForList( "SELECT * FROM CSVREAD('" + fileName + "', null,'UTF-8', chr(9));",
new Object[] {} ) );
}
catch ( Exception e ) {
e.printStackTrace();
}
finally {
// stop the TCP Server
server.stop();
}
}
}

Comparing SQL Logging with Log4j – Default vs. JdbcPlus

Posted in Uncategorized with tags , , , on March 27, 2013 by Shaun Elliott

I was recently playing with logging to jdbc via log4j when I discovered that it isn’t a fully elegant solution. It is fairly raw JDBC, or so it seems. I found this post on stackoverflow that described the same problem I was having. One of the solutions is to use the JDBCPlus appender.

Here is a quick comparison:

log4j.rootLogger=INFO, A1, jdbcPlusJdbcAppender, log4jJdbcAppender

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender

# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

log4j.appender.jdbcPlusJdbcAppender=org.apache.log4j.jdbcplus.JDBCAppender
log4j.appender.jdbcPlusJdbcAppender.url=jdbc:jtds:sqlserver://serverName:1433/databaseName
log4j.appender.jdbcPlusJdbcAppender.dbclass=net.sourceforge.jtds.jdbc.Driver
log4j.appender.jdbcPlusJdbcAppender.username=userName
log4j.appender.jdbcPlusJdbcAppender.password=password
log4j.appender.jdbcPlusJdbcAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.jdbcPlusJdbcAppender.sql=INSERT INTO LOG (log_date, log_level, location, message) VALUES ( '@TIMESTAMP@', '@PRIO@', '@CAT@', '@MSG@' )

log4j.appender.log4jJdbcAppender=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.log4jJdbcAppender.URL=jdbc:jtds:sqlserver://serverName:1433/databaseName
log4j.appender.log4jJdbcAppender.Driver=net.sourceforge.jtds.jdbc.Driver
log4j.appender.log4jJdbcAppender.User=userName
log4j.appender.log4jJdbcAppender.Password=password
log4j.appender.log4jJdbcAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.log4jJdbcAppender.layout.ConversionPattern=INSERT INTO LOG (log_date, log_level, location, message) VALUES ( '%d{yyyy-MMM-dd HH:mm:ss.SSS}','%p', 'Class: %c', '%m')

A couple of obvious points:

  1. This example is based on the JTDS driver. This means you need JTDS on your path. It also means that if you use another driver, you need to change these settings to match the requirements of your alternate driver.
  2. Both appenders are attached to the root logger. This is just to show both in action at the same time.

Here are the differences that I have noticed:

  1. The default JDBC appender uses a conversion pattern to set up it’s insert statement. The conversion params are just standard values used which you can find here. JDBCPlus, on the other hand uses some magic values that are defined for you. I had to look over their examples carefully to figure out which was which.
  2. The properties themselves are slightly different. If you’re converting from one to the other pay attention to things such as Driver\dbclass, URL\url. It is case sensitive.

Hospitality Service Scheduler Kata

Posted in Uncategorized with tags , , on February 27, 2013 by Shaun Elliott

A while back I was introduced to Uncle Bob’s bowling kata. If you’ve never done it before stop reading and go do it before proceeding here. The bowling kata is an excellent exercise in application design, feature creep and overall good OO skills. In the spirit of the bowling kata, here is a new OO design kata, the “Hospitality Service Scheduler Kata”.

Definitions:

“The hospitality industry is a broad category of fields within the service industry that includes lodging, restaurants, event planning, theme parks, transportation, cruise line, and additional fields within the tourism industry.” – Wikipedia

Within the hospitality industry there are many employees that are required to make a business run. Each of these employees have one or more defined jobs that they are capable of doing, for example: cook, janitor, manager. Additionally, each employee is capable of working a certain amount of shifts per day and per week per local laws and restrictions. Lastly, most hospitality business schedule employees by the week, 1-2 weeks in advance.

Suggested Requirements:

Write a class named “Scheduler” with the following methods:

  • getEmployeeSchedule( employee : Employee, duration : DateSpan )
  • getSchedule( duration : DateSpan )

Things to think about:

  • managing employees (crud operations, persistence agnostic)
  • managing jobs, titles, roles
  • ease of use\user stories

Example Use Cases:

Provide a report per employee for a given duration, it might look something like this:

Sally

Monday 9a-3p Server
Tuesday 10a-2p Hostess
Wednesday Off X

Provide a report for a given duration for all employees, it might look something like this:

Week:3/25/13

Monday

Tuesday

Wednesday

Thursday

Friday

Saturday

Sunday

Sally

9a-3p

Server

9a-3p

Server

9a-3p

Server

9a-3p

Server

9a-3p

Server

x

x

Billy

10a-6p

Cook

10a-6p

Cook

10a-6p

Cook

10a-6p

Janitor

10a-6p

Host

x

x

Tommy

1p-9p

Dishes

10a-6p

Dishes

10a-6p

Dishes

x

10a-6p

Dishes

x

x

Google Calendar Sync – End of Life? How about a work around.

Posted in Uncategorized with tags , , on February 14, 2013 by Shaun Elliott

After installing the OS on my new PC I figured out I was missing something: google calendar sync. If you don’t know what this is, it was an app that Google put out to sync your exchange and gmail calendar events. This was a very handy little app. However, to my dismay, I found that it has entered end of life. I explored other options, but none seemed to be as easy or free. What’s a nerd to do?

Well, I decided to muck around with my old PC and see what I could figure out. It turns out that the app itself can just be zipped up, moved over to another machine and ran…. for the most part. When I ran it on my new box it did prompt me for credentials, but it threw up an error dialog. A quick google search lead me down the direction of investigating the Outlook plugins. I took a look at my Outlook instance on my old dev box and found that you just need to add the plugin explicitly. To do this you just go (in Outlook) to options -> add-ins -> manage (go) -> add. Pick the GoogleCalendarSync.x64 or GoogleCalendarSync dll file you zipped up from your old copy and enable it (the 64 one on 64 bit machines, and the other one for 32). Voila!

After restarting Outlook all was kosher and things were syncing again, yay!

Follow

Get every new post delivered to your Inbox.

Join 117 other followers