Glen Mazza's Weblog

Main | Next page » Tuesday November 24, 2015

TightBlog: November 2015 update

Since my update last month, I've been able to pull out an additional 35 Java source files, dropping TightBlog to 297 total compared to Roller's 493. The GitHub Issues List notes 114 issues closed and 21 still open. The application still isn't ready until the open issues are closed, but I'll keep working on zeroing out the remaining open issues.

The code simplification/shrinkage comes from normal refactoring and code modernization, embracing the Spring framework, using JAXB over JDOM, and having a higher threshold than Apache Roller of which functionality to retain. Generally speaking, any functionality that fewer than say 3% of bloggers would use gets tossed out, and functionality that perhaps up to 8% would use but would not be a deal-breaker if TightBlog didn't provide has also been removed. This threshold has dropped me to perhaps about 20-30 features that I can focus on making solid for bloggers. When there is too much seldom-used functionality to maintain, core functionality starts to suffer, causing people who might have liked the extended functionality to turn away from the product anyway due to its substandard core, a situation I'm trying to avoid with TightBlog. Sunday November 15, 2015

Pink Slips at Disney. But First, Training Foreign Replacements.

Sold Out Book

Journalist Michelle Malkin and Center for Immigration Studies fellow John Miano have teamed together to offer a new book Sold Out. It offers a critique of the various foreign worker visas offered by the federal government and its consequences on American workers. I just got the book yesterday and am still in its early stages but would highly recommend it for American IT professionals wishing to learn more about the consequences of these programs or (for those already well aware) just wanting to thank and support the authors for raising publicity about this issue during an election year. Happy to note at the time of this writing that the book is #1 on Amazon's Government and Management bestseller list. Thursday November 05, 2015

Letter to the Arlington County board via fitness membership fees

My county has a website form residents can use to submit questions, comments and concerns, which I've used three times in the past five years. The county runs fitness centers of which I'm a member. This morning I submitted the below concern (slightly polished for grammar :) about the reduced cost passes for non-county residents 55 and over:

Hello, I'm [in my mid-40's] and a long-time taxpaying Arlington County resident as well as an Arlington County gym member. When I buy my annual County fitness center pass, I pay the $195 rate as a county resident, much less than the $558 charged to non-residents because residents pay Arlington County taxes and as much of Parks & Rec is supported by taxpayer dollars we should be discounted. No problems there, neighboring jurisdictions do the same thing.

The county, via its 55+ Gold Pass program, has recently dropped the qualification age from 62 to 55, any resident 55 or over needs to just pay $60. OK. But non-residents 55+ who aren't paying Arlington taxes have to pay just $90, a mere $30 more and less than half the $195 that I need to pay. That benefit seems too disproportionate to be giving to non-taxpaying non-county residents--should I really have to be paying $195 while a relatively youthful 55-year old Fairfax County resident just has to pay $90?

55 is hardly retirement age, many of those people are at the top of their financial situation at that time, and giving such a benefit to 55+ county residents must come at a significant price both to county taxpayers who have to subsidize the shortfall in fees and paying county members whose memberships would be cheaper if they didn't have to cover this subsidy. So be it, though, we take care of our senior residents. But asking taxpayers and gym members to pay more to be subsidizing *non-county* residents as young as 55 seems an unfair burden to ask. I'd like the county to raise the minimum age for non-county residents back to 62, and/or alternatively retain the same $195/$558 resident/non-resident ratio for the senior passes ($60 for residents, $172 for non-residents.) Gyms cost money to run, and non-residents should be expected to pay more to cover the difference that they're not paying in county taxes.

I've checked the Fairfax County Parks and Recreation website and they give no senior discount to people outside of their jurisdiction, they just take care of their own and then only when they reach 65. Alexandria does cover at age 55, but only a 20% discount and again only for city residents. Likewise, Arlington County reduced fee memberships correctly just cover Arlington residents, taxpayers don't have to support non-residents for that.

This rate is also bad for the County for another reason -- each of the fitness centers have a limited number of aerobic machines, the more you fill up those machines due to heavy subsidies of non-county residents, the $195 payers get upset because the machines are never available and instead go to private gyms that aren't that much more expensive for them. The percentage of those using the gym being full payers is going to drop as a result, with the lost gym revenue requiring more county subsidies in order to be supporting people who live outside the county's jurisdiction. Saturday October 31, 2015

"Monster Mash" Will Get You

From The Miami News, October 6, 1962:

Rock 'n' roll and the twist have finally come to grips with Horror and the result is a startling eruption in the record-buying field. Now it's spreading to the screen and television.

A little .45 disc titled "Monster Mash," rocketing within a few weeks into a spot among the top 10 sellers, seizes upon weird species from the Frankenstein laboratory, man-made creatures who shake off their electrodes and, to the tune of a shudder-packed production number, stomp around the graveyard in a wild new dance.

The "Monster Mash" has become an overnight hit in Los Angeles ballrooms, and two film studios and at least one TV network are angling for rights to its use for specialty insertions in movies and air shows.

Chief proponent of the new order is Bobby (Boris) Pickett who, like his recording sponsor, Gary Paxton, is bewildered by the smash reception the record has won. Hurriedly, they have marshaled a musical troupe for an invasion of eastern cities, with Boston scheduled as the first stop.

To a set of frightening Karloff-toned lyrics ("I was working in my lab late one night when my eyes beheld an eerie Monster from his slab began to rise...and suddenly to my surprise...he did the mash. He did the Monster Mash!") dancers the country over may soon be stomping and flailing their arms into a new epidemic--a slow-beat dance which Pickett feels will come as a welcome relief from the swift torturous movements of the twist.

How did Pickett happen on horror as the stepping stone to a new dance madness?

"The door was wide open," replied the young singer, who leads the song and dancers himself. "Horror pictures always have been popular and it seemed funny no one hit upon them for a dance until now. We just drove into a red-hot vacuum." Sunday October 25, 2015

Tightblog taking shape

I forked Apache Roller last May after about two-and-a-half years volunteering on the project, calling my fork "Tightblog" to emphasize the amount of streamlining I wished to do to it. As of today, Tightblog still isn't ready, the GitHub issues list reports 97 issues closed and 23 open. Although there have been a few enhancements added (a notes field for blog entries, configurable anchor, alt text and title for media files, and much easier to set up planet functionality), I'm still pretty much cleaning out the old before I can move on to modernizing the remaining core.

Since forking Roller, I've been able to reduce the number of Java source files from 493 to 332--with more to go!--while keeping average file size about the same. The running application feels zippier. The number of database tables has fallen from 33 to 18 plus one view. The data model is fairly stable now, I don't see any more tables being added or removed, although a few columns may still be adjusted here and there. A table-by-table comparison between Tightblog and present production Apache Roller 5.1.2:

Tightblog (column list)Apache Roller 5.1.2 (column list)



weblog_entry_tag_agg (view)




I believe that the streamlined data model I settled on for Tightblog will provide a reliable, wobble-free foundation for upper layers of the application without sacrificing important functionality. As you can see from the table names, I'm taking care not to make references to the project name within the data model as I'd like to make it smoother for others to rebrand and/or incorporate this Apache-licensed work into their own projects. Saturday June 27, 2015

Git & GitHub Notes

  1. For ease, fork the repo on GitHub and clone your fork rather than the main repo, then

    git remote add upstream
    to link to main repo.

  2. git push origin branchName -- "origin" refers to the fork (here, one's own, else can be upstream or any other created via git remote)

  3. To switch between branches locally, git checkout <branch name> (use git branch to see a list); to check out a new branch based on the one you're currently in, git checkout -b <new branch name>

  4. git fetch upstream [branch or remote branch:local branch] - update pointers to latest code, git merge afterwards (or git pull to do both) to update local code. If any automated merge failures, right-click Git->Resolve Conflicts from IntelliJ to resolve manually.

  5. To place your changes on one branch above those from another: (from your branch): git fetch as above, then

    git rebase [branch name to retrieve from]
    , then
    git push origin brname -f
    to update GitHub fork.
  6. Recovering from an accidental pull: SO #1, SO #2. Another possibility: git rebase -i HEAD~xxx to supposedly squash the commits, but I instead removed all unwanted commits from the pull. Then git rebase to bring in actual wanted branch.

  7. To pull a different branch to your local machine:

    git remote add upstream
    git fetch upstream
    git co upstream/release/branchname
    git co -b [newBranchNameHere]
  8. To checkout a tag.

  9. To check out a coworker's branch:

    git remote add coworkerFork
    git fetch coworkerFork hisBranch:newNameForYourLocalBranch
  10. In GitHub pull requests, use ``` or ```json to format code (JSON)

  11. In PR reviews, use : to bring up icons.

  12. Deleting a branch:

    git branch -D branchnames...

  13. List of repos presently watching:

  14. Squashing commits:

    git log
    to find number of commits to squash,
    git rebase -i HEAD~X
    (X is number of commits). 1st page: mark all but first commit "s" for squash, 2nd page, edit common commit message. Standard editor: Ctrl-K to remove lines, Ctrl-X to save. Then
    git push origin brName -f
    to update remote.

  15. git cherry-pick to copy commits from one place to another. Applying a commit from one branch to another:

    git log to copy sha of commit you want to merge
    git fetch upstream to download all available branches
    git co -b mynewbranch
    git pull upstream {branchYouWantToAddPRTo}
    git cherry-pick { sha value} -m 1
    git push origin mynewbranch
  16. How to merge a PR against one fork into your own
  17. Wanting to create a new branch without committing changes first:
    git stash, git checkout -b newBranch, git stash pop
  18. Undoing changes:
    git checkout <branch_copying_from> -- <file_to_reset>
  19. branch rewinding - another method for combining commits when the work was not done on a separate branch.
  20. JQuery Commits and Pull Requests Guide
  21. Checking out an older git version (snapshot)
  22. Adding Git Aliases -- simplify terminal window commands
  23. Efficient way to do commits:
    git log --oneline --decorate
  24. Which release contains a commit? git fetch --all followed by git tag --contains (hash)
  25. Amending commit messages Monday November 24, 2014

Using UsernameToken security with Apache CXF

This tutorial modifies the CXF version of the WSDL-first DoubleIt web service to include WS-Security with UsernameTokens. This profile should be used with transport-layer encryption (i.e., SSL) as a minimum to ensure the username and password are encrypted at least between the client and the first recipient node. Note the X.509 or SAML token approach would be more appropriate instead if any of cases below apply:

  • Clients need to sign the request to guard against it being altered in transit
  • There are intermediary nodes between client and service that would be unencrypting the message (and hence able to read its contents) before forwarding it on to the next node
  • The web service provider has incomplete nonce and timestamp support necessary to guard against replay attacks. CXF has implemented such caching since version 2.6, and it also appears supported with Metro.

CXF provides two main options for adding UsernameToken security headers, both of which will be covered below: WS-SecurityPolicy and manual CXF interceptors. The former relies on the WSDL already having WS-SecurityPolicy elements defined within it to obtain the security requirements. Use the manual CXF interceptor approach when security is not defined in the WSDL or more customized control of the security header construction is desired.

Note one difference between CXF's UsernameToken implementation and Metro's is that the former requires explicit service-side callback handlers to validate passwords while the latter, for the Tomcat and the GlassFish server, will validate against container usernames and passwords if no service-side callback handler is declared. However, CXF provides a JAASLoginInterceptor for container-based authentication.

The finished tutorial source code can be obtained from GitHub by using either the download ZIP button or git clone -v git:// command. The download is configured to use WS-SecurityPolicy, if desired make the adjustments specified below to switch to the CXF interceptor approach.

  1. Implement SSL without basic authentication for the web service. This is the same as Step #1 of the Metro/UsernameToken guide.

  2. Include additional Maven dependencies to handle security processing. The following dependency will need to be added to the project-level pom.xml to activate security processing.


    Also, since we'll be adding a Spring cxf.xml configuration file to the client to declare the security parameters, we'll need to add a Spring dependency to the client/pom.xml. (See notes at the bottom for a non-Spring way of doing client configuration.) While CXF is relatively flexible with the version of Spring that you use, to determine the optimal (tested) version of Spring for your version of CXF, go to the tags folder of the CXF source repository, select your version of CXF, and under that folder select the folder named "parent" and open its pom.xml. Search for the cxf.spring.version variable to determine the version to use.

  3. Configure the client to provide the user and password. We'll be introducing a Spring-based cxf.xml configuration file, presently configured for the WS-SecurityPolicy approach but can be switched over to the CXF interceptor approach by following the comments given below in this source file.

    Next supply the password CallbackHandler that was listed in the SOAP client above. Place this class in the same package as the SOAP client:

    package client;
    import org.apache.wss4j.common.ext.WSPasswordCallback;
    public class ClientPasswordCallback implements CallbackHandler {
        public void handle(Callback[] callbacks) throws IOException, 
                UnsupportedCallbackException {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            if ("joe".equals(pc.getIdentifier())) {
            } // else {...} - can add more users, access DB, etc.
  4. Add the WS-SecurityPolicy statements to the WSDL. This has already been done in the Service WSDL in the source code download, which uses the WS-Policy statements created in the Metro UsernameToken tutorial. CXF interceptor method only: We'll need to use a Policy-free WSDL, so remove this DoubleIt.wsdl and rename the Policy-free DoubleItInterceptorMethod.txt found in the service submodule resources folder to DoubleIt.wsdl (it's the same WSDL from the standard DoubleIt tutorial.)

  5. Configure the service provider to authenticate the username and password tokens. Here we'll need to modify the cxf-servlet.xml configuration file from Step #6 of the WSDL-first tutorial to add either the CXF inbound interceptor or WS-SecurityPolicy configuration information (not both.) Replace the previous cxf-servlet.xml file with the following, after modifying it based on your security implementation preference:

    Once done we'll need to add the new server-side password callback class referenced above, which provides the correct password for a user, which the CXF framework uses to compare with what is supplied in the client request. Place the following ServerPasswordCallback class to the same package as the service's DoubleItPortTypeImpl SEI implementation class:

    package service;
    import org.apache.wss4j.common.ext.WSPasswordCallback;
    public class ServerPasswordCallback implements CallbackHandler {
        public void handle(Callback[] callbacks) throws IOException,
                UnsupportedCallbackException {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            if ("joe".equals(pc.getIdentifier())) {

    You can now compile and redeploy the web service from the DoubleIt base folder.

  6. Test the client. Run the client as shown in the DoubleIt tutorial. Best to test also with incorrect usernames and passwords to ensure the web service provider is catching these errors.

    You can view the headers being added to the SOAP request if you temporarily switch your web service back to non-SSL usage. This can be done by updating the web.xml and URL within the WSDL, and additionally if you're using WS-SecurityPolicy, removing any WSDL element declaring a requirement for SSL. Once done you can either use Wireshark or activate logging within your WSClient class to see the unencrypted SOAP messages. Running the client from a terminal window will show results similar to the following:

    Oct 1, 2011 7:47:34 PM
    org.apache.cxf.interceptor.AbstractLoggingInterceptor log
    INFO: Outbound
    ID: 1
    Encoding: UTF-8
    Content-Type: text/xml
    Headers: {Accept=[*/*], SOAPAction=[""]}
    <soap:Envelope xmlns:soap="">
                <wsse:UsernameToken wsu:Id="UsernameToken-1">
            <ns2:DoubleIt xmlns:ns2="">
    Oct 1, 2011 7:47:34 PM
    org.apache.cxf.interceptor.AbstractLoggingInterceptor log
    INFO: Inbound
    ID: 1
    Response-Code: 200
    Content-Type: text/xml;charset=UTF-8
    Headers: {Content-Length=[238],
    content-type=[text/xml;charset=UTF-8], Date=[Sat, 01 Oct 2011 23:47:34
    GMT], Server=[Apache-Coyote/1.1]}
    <soap:Envelope xmlns:soap="">
            <ns2:DoubleItResponse xmlns:ns2="">
    The number 10 doubled is 20

    If you do this, remember to switch back to SSL for production usage.


If desired, you can avoid introducing a Spring dependency in the client by not using a cxf.xml configuration file and instead declaring security using the Java API in the client's WSClient class. A sample alteration demonstrating both the WS-SecurityPolicy and CXF interceptor approaches is as follows:

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;

public class WSClient {
    public static void main(String[] args) {
        DoubleItService service = new DoubleItService();
        DoubleItPortType port = service.getDoubleItPort();

        // WS-SecurityPolicy configuration method
        Map ctx = ((BindingProvider)port).getRequestContext();
        ctx.put("ws-security.username", "joe");
        ctx.put("ws-security.callback-handler", ClientPasswordCallback.class.getName());
        // instead of above line can also do:
        // ctx.put("ws-security.password", "joespassword");
        // Alternative CXF interceptor config method
        Client client = org.apache.cxf.frontend.ClientProxy.getClient(port);
        Endpoint cxfEndpoint = client.getEndpoint();
        Map outProps = new HashMap();
        outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
        outProps.put(WSHandlerConstants.USER, "joe");
        outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
        WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
        ... Monday October 06, 2014

Returning PDFs from Web Services using MTOM and Apache FOP

Summary: Use MTOM and Apache FOP within your Apache CXF- or Metro-based web services to send PDFs to and from SOAP clients.

[Read More] Monday September 29, 2014

Activating Transport Layer Security (SSL) for web services

See how to implement SOAP web services over SSL.

[Read More] Monday September 22, 2014

Creating a Java-first web service using CXF or Metro

Summary: This article shows the changes needed to the WSDL-first DoubleIt tutorial to convert it to a start-from-Java (no WSDL) process.

[Read More]

Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.