Be Glad I Didn’t Write Apache Camel

appwriter_logo
If I had written Apache Camel, instead of my personal heroes – James Strachan, and Claus Isben – I would have completely screwed it up.

A nightmare. Allow me to clarify:

Explicit Everything – a Religious Belief:

In my world, the very word “implicit” is synonymous with Evil.

Implicit languages, implicit conversations, implicit meanings – these are all destined to confuse and sometimes even disrespect people. Or at least, disrespect their time.

Everything implicit, to me, is like an “in group” where only the initiates know the secret language. You can join the group, but only after you learn some implicit meanings. To heck with that.

Implicit languages, for example, are a little faster to code in, harder to tool, and much harder to learn than explicit languages. Or at least, that’s my perspective. Java is dumb as a box of rocks, compared to JavaScript – and that’s why I like it better. A reasonable example that favors the explicit.

I could go on and on, but it would only be more of the same. Law, governance, politics, culture, implicit vs explicit is a key issue everywhere, and a vast source of mischief.

Camel Works. Because of Generics. Implicit everything…

My worst nightmare is projects like Camel, where I cannot use explicit hierarchical topologies to walk a tree of types or functional options.

Camel uses generics, casting, and “type converters” to allow what amounts to an “any to any to any” kind of message passing. All without your explicit knowledge. If implicit was evil, this is evil on steroids.

But instead of being evil, it just works! Implicit is what allows the vast, and growing, array of Camel components and other usages to just work. It may make me appear lazy, (I am), but the extra work of testing at runtime really isn’t that bad, after making the mental adjustment.

Topologies as a Police State

Compare that to my chosen approach: Everything is a finite, known, hierarchical topology.

Except who makes the topology? Is it me, you, or ??? Now, we have a classic case of the Police State to the rescue.  I would probably have installed myself as the policeman, and Camel would never have grown beyond my ability to police the topology of types and functions. That would be amount to 1% of it’s current scope.

But that’s OK, because it would never have grown anyway.  Nobody even likes participating, where a police state is involved.

Conclusion

I have ragged on and on about Apache Camel and how needlessly hard it is to learn. I am not completely off, in this assessment.

But the point is that there is some magic to this design. It’s difficulty is in it’s brilliance. And it isn’t even that hard, you just have to get used to testing well at the runtime level.

No. That isn’t so hard.

 

Camel CXF – X__project Supplement

appwriter_logo

Who:

This blog should be interesting only to someone actively attempting to get their first camel-cxf project working. It is a companion piece to a progression of 4 example projects, and the docs on each.

  1. Code first CXF – simple.
  2. WSDL first CXF – simple.
  3. Code first CXF – complex objects.
  4. WSDL first CXF – complex objects.

It is notable that none of the previous Camel example projects required anything close to this kind of documentation, or explanation.

Main Points:

If you are impatient, like me, you may find that getting to number 4, above, is needlessly difficult, the first time. Especially aggravating, given that number 4 is the only variant that commercial/corporate applications might accept.

Then, when you get it all done, you might wonder what the fuss was about. Maybe this blog and these projects will get you there without spending much time.

The idea is to be able to blast through each of these very quickly, picking up additional steps/dependencies with each one.

The Sequence:

  1. Code first simple – basic dependencies, server, testing, tooling.
  2. WSDL first simple – add WSDL first steps, code.
  3. Code first complex – adds objects for input and output, processing, and testing variants.
  4. WSDL first complex – adds a merge with your own entity code.

Again, once you know the above steps you’ll wonder what all the fuss was about. Until then I found lots of ways to guess wrong and waste lots of time.

Specific to WSDL-First:

If you are new to SOAP and WSDL first in general, there may be some confusion about the generated code step. Since there may be some options, here is what I found successful.

  • Just running mvn compile is enough to generate the wsdl2java step. It’s will place it wherever you told it to in your pom, or in this case target/generated/src/main/java.
  • Wasn’t sure if I should be making this a legit source folder? Or copy the code to my src/main/java? I chose the latter, see next step.
  • When you copy it to your source folder, there still may be plenty of changes you have to make by hand. For example, your complex input and output object entities may already be in your codebase, and the wsdl2java generates you new entities. So in that case, you would have to merge the generated into the previous entities and then modify the rest of the generated code to point to those, and not the generated. You then delete the generated.
  • You may also have to comment out your wsdl2java plugin code in the pom.xml as soon as you have copied over and modified any generated code. This may or may not be obvious, but will make itself quite obvious if it becomes an issue.

Consuming WSDL from CodeFirst

One possible source of confusion can be quickly clarified by acknowledging a cheat that was used on the two WsdlFirst projects.

One of the most significant challenges to a WSDL first project of any type is the creation of the initial WSDL. This file is a complex 5 part file with many cross-referencing parts. Not for sissies like me, putting together silly example projects.

What was done on these example projects was to create the WSDL using the code first project, which creates a wsdl and publishes it to the browser as part of it’s functionality set.

This WSDL was then hand copied to the correct folder in the WsdlFirst projects.

A side benefit was that the WsdlFirstComplex and CodeFirstComplex projects could then also share entity classes, but that is just a side effect. In this case, the shared entities were placed in the jammazwan.shared project. Both WsdlFirst and CodeFirst projects share the same test code, using this approach.

Running Your Test as a Server (WTH?)

Problem: Jammazwan example projects are for learning Camel, not production deployments. Server and deployment code is intentionally excluded so you can isolate only what you are learning. So what happens in a case like this, where we actually need a running server to test with during development?

Solution: A quick, and ugly, manual hack is provided in our test code. I cringe, but it works great for the learning process.

A more realistic solution begins to outline itself in my Camel Microservices blog, though that is a bit off topic for this article.

Sequence:

  • Write your project to test with a normal test, such as template.requestBody(), like any other camel route.
  • Once it’s working, test it in the real world using something like SoapUI. To do this, uncomment the hack line

    Thread.sleep(Long.MAX_VALUE); Ugh.

  • You may now run the test, and the test basically hangs. Whola! Your server is operating. Even if you are wincing in disgust.
  • From your camel-ctx.xml file, copy the url. Such as http://localhost:9876/passThru/
  • Append ‘?wsdl‘ to this line. You now have a wsdl url of http://localhost:9876/passThru/?wsdl
  • Open the wsdl url in your browser. My chrome browser shows the xml from the wsdl file.
  • Now you can take this same wsdl url to your SoapUI tool, and test the actual working server with actual working xml. I won’t cover this here, as it’s assumed you already have this skillset.
  • Now you can kill your running test, which never finished, and comment back out the Thread.sleep(). Your manual dev test is complete.

Remaining Documentation:

Each of the 4 cxf example projects is documented in their respective NOTES.md

The NOTES.md files each focus on a diff between that, and previous artifacts. So 4 isn’t so much of a standalone, as a diff between it’s artifacts, and the previous. Etc. Other x__projects are standalone, not these 4.

  1. Code first CXF – simple –  NOTES.md
  2. WSDL first CXF – simple-  NOTES.md
  3. Code first CXF – complex objects –  NOTES.md
  4. WSDL first CXF – complex objects – NOTES.md

 

Jammazwan FAQ

appwriter_logo

  • You said my x_project was complete working software! How do I deploy it?
  • How to import into my IDE?
  • Are goals of example projects contradictory?
  • Why is my x_project written with spring/java configuration?
  • What is an x_project?
  • Why the jammazwan.shared dependency?
  • What is this x… prefix?
  • Generated or not? README.md vs NOTES.md
  • What does jammazwan.maker have to do with any of this?
  • Complex project warnings WTH?
  • Local v Remote JMS, DB, FTP
  • X__Projects vs jammazwan.100? WTH?
  • Uh, this isn’t a comprehensive list of example projects.

You said my x_project was working software! How do I deploy it?

x__projects are designed to isolate routing functionality and protect the user from confusing, deployment related code. They are run with unit tests. “Working,” in this context, is not intended to imply that it is deployable on a server.

 

The routes you would learn about from these isolated examples may be deployed into any server or service as appropriate. One such approach is outlined in another blog, but there are also vertical stack approaches such as Fuse which are amply documented by Red Hat.

Fabric8 or Openshift are also great deployment options, but again, provide their own learning curves.

How to import into my IDE?

You are encouraged – but not required – to open up your IDE into a new workspace and do all jammazwan work in a fresh workspace. This has nothing to do with jammazwan specifically, but is helpful practice whenever experimenting with new tech.

If you use Eclipse, then Import > General > Existing Projects into Workspace > Next > Browse > … then follow the prompts.

Other IDEs, or even Eclipse as an alternative to above, will import any project which has a pom.xml file. You may follow this normal process to import your jammazwan project into your IDE.

Are goals of example projects contradictory?

Jammazwan example projects are all about:

  • Driving adoption to increase learning speed.
  • Isolation of functionality to increase learning speed.

Isn’t that a contradiction? Don’t you need to pick one, instead?

Yes, it’s a contradiction. Maximizing the tension between the two is where learning gets real. Drive adoption and you create a huge desire to learn more, really fast. Isolate functionality and you make Camel easy to learn. Together, it’s a magical combination.

The tension between the two does create other problems, though. These are great problems to have.

Why is my x_project written with spring/java configuration?

There are so many language and configuration combinations available to the author of a Camel project, there could be no canonical, or even “best” choice.

Instead I opted for what seems to be the most common and powerful configuration choices. The choice of Java for it’s fluent API is the most important, because it is the most powerful.

What is this x__project naming convention?

One of the major challenges of isolating functionality in example projects is that now you have too many of them.

x__project is often used in the docs as a name for

see below: “What is this x… prefix?” if you need more info on this.

Why the jammazwan.shared dependency?

Some, but not all, x__projects require jammazwan.shared as a dependency, as indicated in their respective README.md

X__project design tries to include only what is unique to this example, so you can focus only on what is required to demo the MyCoolCamelComponent feature in isolation. The single shared project includes dumb artifacts that shouldn’t be unique to a single x__project, such as:

  • Beans used as value objects for all example projects
  • pom.xml dependencies of a more general nature
  • .csv and other source files for use as data sources
  • generic utility functions not specific to a single project

So you sometimes have to git clone jammazwan.shared as a sibling first, then run mvn install, before installing your project.

If you want to replicate the functionality of your project into your own stand-alone project, you will need to pull some dependencies and code from each.

Another pattern I could have followed would be to create jammazwan.shared as a parent project. This pattern has been horribly abused in recent years, (IMO), creating insanely nested and hard to decipher project structures, so I just avoided it entirely.

What is this x… prefix?

The prefix x__ is used for maintaining sort order in a directory, providing packaging, and is otherwise meaningless. The x stands for example.

A side benefit is that I do a lot of work in a bash shell, so being able to type cd ../xao [tab] saves me a lot of time, and is easier to remember than a lot of project names.

Generated or not? README.md vs NOTES.md

Every project has a README.md which is generated from here, and never hand modified.

Some projects also have a NOTES.md which is entirely created by hand, and contains information which is not in the metadata. Go there first if you have any needs that are not answered in the opening page README.

What does jammazwan.maker have to do with any of this?

All x__projects are created with a generator. Interesting notes about the generator, if you care:

  • Written entirely in Camel
  • Can create, and update, any project.
  • Uses Velocity component
  • Open source, use it for anything you wish.
  • Not in any way documented or supported.

Complex project warnings WTH?

Xab and at least one other project start out by advising you to go away. Kind of silly.

The whole point of x__projects is isolation of just one small thing. These projects break that implicit contract. So instead of learning just one thing you are confronted with way more than you can absorb, possibly doing more harm than good.

I’m still not sure why they are here, but some day I might come up with a better strategy and explanation.

Local v Remote JMS, DB, FTP

to be documented later, if ever.

X__Projects vs jammazwan.100?  WTH?

Is Jammazwan about x__projects or jammazwan.100? Don’t they have different goals in mind?

  • jammazwan is 90% about example projects
  • jammazwan.100 is for advanced work

Uh, this isn’t exactly a comprehensive list of example projects.

 

Pull requests welcomed.

Jammazwan – For Hire

appwriter_logo

Camel Keeper: Jammazwan

“Jammazwan” is Hindi for “camel keeper”.

Me, a jammazwan? another Camel Keeper: TL DR?     about:
pete jammazwanPhotoSmall jamzVid1

You may have already read my post on making Camel easier to learn.

Contract Camel Work

Please contact me to supplement the work that your own team might be doing with Apache Camel or JBoss Fuse.

I can bring an official Red Hat consulting shop with me as your go-between,  even a larger team – if required.

Smaller contracts by 1099, or even W2.

pete dot carapetyan at gmail dot com