I am having a number of type conversion issues using the Java DSL with Camel 3.14.3. For a simple example I have a route that uses a direct endpoint to trigger a pollEnrich for a file endpoint.
public class BasicRoute extends RouteBuilder {
#Override
public void configure() {
from("direct:test")
.pollEnrich("file://watchDirectory", 10000)
.to("mock:result");
}
}
When the route starts I get the following exception...
Exception in thread "main" org.apache.camel.FailedToCreateRouteException: Failed to create route route1 at: >>> PollEnrich[constant{file://watchDirectory}] <<< in route: Route(route1)[From[direct:test] -> [PollEnrich[constant{file... because of Error parsing [10000] as a java.time.Duration.
...
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: java.lang.String to the required type: java.time.Duration with value 10000
I am running this within a simple OG java app, so I am sure I am missing something in the context initialization, but I cannot find it.
I'm deploying a Spring Batch job triggered by a Camel route. Here is the Spring Batch config:
#Configuration
#EnableBatchProcessing
public class JobConfig
{
...
#Bean(name = "personJob")
public Job personJob(JobCompletionNotificationListener personListener, Step personStep)
{
return jobBuilderFactory
.get(...)
.incrementer(new RunIdIncrementer())
.listener(...)
.flow(...)
.end()
.build();
}
...
The Camel route looks like this:
#ApplicationScoped
public class MyRouteBuilder extends RouteBuilder
{
#Override
public void configure() throws Exception
{
from("file://...")
...
.to("spring-batch:personJob?jobLauncherRef=jobLauncher");
}
Running the route above raises the following exception:
[ERROR] Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: spring-batch://personJob?jobLauncherRef=jobLauncher due to: No JobLauncher named jobLauncher found in the registry.
[ERROR] Caused by: java.lang.IllegalStateException: No JobLauncher named jobLauncher found in the registry."}}}}
However, the documentation clearly states:
The #EnableBatchProcessing works similarly to the other #Enable*
annotations in the Spring family. In this case, #EnableBatchProcessing
provides a base configuration for building batch jobs. Within this
base configuration, an instance of StepScope is created in addition to
a number of beans made available to be autowired:
JobRepository: bean name "jobRepository"
JobLauncher: bean name "jobLauncher"
...
So, there should be a bean named "jobLauncher" of the type JobLauncher. Why isn't it found in the registry ?
Many thanks in advance,
Seymour
I'm attempting to convert the following Java object initalization with dynamic class casting to camel spring bean syntax. I'm adding my broken spring bean sample as well. I dont have much familiarity with spring beans, so would very much appreciate some input. The Java syntax is:
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
STSAssumeRoleSessionCredentialsProvider credentials = new STSAssumeRoleSessionCredentialsProvider.Builder(
"arn:aws:iam::***:role/myRole-QA", "sessionName").build();
and broken spring bean:
<spring:bean id="sqsCredentials" class="com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider.Builder" >
<spring:constructor-arg index="0" value="arn:aws:iam:***:role/myRole-QA" />
<spring:constructor-arg index="1" value="sessionName" />
<spring:property name="targetMethod">
<spring:value>build</spring:value>
</spring:property>
</spring:bean>
I'm not sure if what I have for method build is correct, but there are two classes at play: .Builder and just STSAssumeRoleSessionCredentialsProvider. So Builder class returns STSAssumeRoleSessionCredentialsProvider. Most likely i have more then one issue to solve here, but the error I think is related to class mismatch ... much appreciate your time:
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'targetMethod' of bean class
[com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider$Builder]: Bean property 'targetMethod' is not writable
or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
I was trying to use the camel-hl7 component to create a hl7 listener in camel. when i used the same in camel-spring, it was working. But when I try to use the same in Java DSL as follows,
HL7MLLPCodec hl7codec = new HL7MLLPCodec();
hl7codec.setCharset("iso-8859-1");
camelContext.addRoutes(new RouteBuilder() {
public void configure() {
from("mina:tcp://localhost:4444?sync=true&codec=hl7codec").to("file://test");
}
});
It throws the exception,
java.lang.IllegalArgumentException: Could not find a suitable setter for property: codec as there isn't a setter method with same type: java.lang.String nor type conversion possible: No type converter available to convert from type: java.lang.String to the required type: org.apache.mina.filter.codec.ProtocolCodecFactory with value hl7codec
! at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:588)
! at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:616)
! at org.apache.camel.util.IntrospectionSupport.setProperties(IntrospectionSupport.java:473)
! at org.apache.camel.util.IntrospectionSupport.setProperties(IntrospectionSupport.java:483)
! at org.apache.camel.util.EndpointHelper.setProperties(EndpointHelper.java:255)
! at org.apache.camel.impl.DefaultComponent.setProperties(DefaultComponent.java:257)
! at org.apache.camel.component.mina.MinaComponent.createEndpoint(MinaComponent.java:92)
! at org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:114)
! at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:568)
! ... 33 common frames omitted
! Causing: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: mina://tcp://localhost:4444?codec=hl7codec&sync=true due to: Could not find a suitable setter for property: codec as there isn't a setter method with same type: java.lang.String nor type conversion possible: No type converter available to convert from type: java.lang.String to the required type: org.apache.mina.filter.codec.ProtocolCodecFactory with value hl7codec
! at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:588)
! at org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:79)
I had to register the hl7codec to the registry for the camel route to use it.
final org.apache.camel.impl.SimpleRegistry registry = new org.apache.camel.impl.SimpleRegistry();
final org.apache.camel.impl.CompositeRegistry compositeRegistry = new org.apache.camel.impl.CompositeRegistry();
compositeRegistry.addRegistry(camelContext.getRegistry());
compositeRegistry.addRegistry(registry);
((org.apache.camel.impl.DefaultCamelContext) camelContext).setRegistry(compositeRegistry);
registry.put("hl7codec", hl7codec);
And now the routes started.
In my Blueprint application deployed in JBoss Fuse 6.1.0-379, I want to secure the password I use for creating a database connection. I read this article and added <enc:property-placeholder> to the blueprint configuration. However my blueprint configuration has many property placeholders, and it seems that the Jasypt Placeholder Resolver is trying to decrypt all the placeholders I define in my Camel Context. When the Blueprint Context starts up, I get the following exception:
11:59:51,233 | ERROR | t-379-dmz/deploy | BlueprintCamelContext | 151 - org.apache.camel.camel-blueprint - 2.12.0.redhat-610379 | Error occurred during starting Camel: CamelContext(camel-5) due Failed to create route route7: Route(route7)[[From[{{uri}}]] -> [Log[logging]]] because of Failed to resolve endpoint: {{uri}} due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException
org.apache.camel.FailedToCreateRouteException: Failed to create route route7: Route(route7)[[From[{{uri}}]] -> [Log[logging]]] because of Failed to resolve endpoint: {{uri}} due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:182)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:778)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:1955)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:1705)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:1579)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:1547)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.blueprint.BlueprintCamelContext.start(BlueprintCamelContext.java:177)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
at org.apache.camel.blueprint.BlueprintCamelContext.maybeStart(BlueprintCamelContext.java:209)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
at org.apache.camel.blueprint.BlueprintCamelContext.serviceChanged(BlueprintCamelContext.java:147)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:934)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:795)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:544)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4666)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.Felix.registerService(Felix.java:3674)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:347)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.aries.blueprint.container.BlueprintContainerImpl.registerService(BlueprintContainerImpl.java:448)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:383)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:261)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
at org.apache.aries.blueprint.container.BlueprintExtender.createContainer(BlueprintExtender.java:270)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
at org.apache.aries.blueprint.container.BlueprintExtender.modifiedBundle(BlueprintExtender.java:233)[9:org.apache.aries.blueprint.core:1.0.1.redhat-610379]
at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$Tracked.customizerModified(BundleHookBundleTracker.java:500)[11:org.apache.aries.util:1.0.1.redhat-610379]
at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$Tracked.customizerModified(BundleHookBundleTracker.java:433)[11:org.apache.aries.util:1.0.1.redhat-610379]
at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$AbstractTracked.track(BundleHookBundleTracker.java:725)[11:org.apache.aries.util:1.0.1.redhat-610379]
at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$Tracked.bundleChanged(BundleHookBundleTracker.java:463)[11:org.apache.aries.util:1.0.1.redhat-610379]
at org.apache.aries.util.tracker.hook.BundleHookBundleTracker$BundleEventHook.event(BundleHookBundleTracker.java:422)[11:org.apache.aries.util:1.0.1.redhat-610379]
at org.apache.felix.framework.util.SecureAction.invokeBundleEventHook(SecureAction.java:1103)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.util.EventDispatcher.createWhitelistFromHooks(EventDispatcher.java:696)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:484)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4650)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.Felix$4.run(Felix.java:2123)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.Felix.runInContext(Felix.java:2147)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.Felix.startBundle(Felix.java:2121)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)[org.apache.felix.framework-4.0.3.redhat-610379.jar:]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1247)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1219)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1208)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:503)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:291)[7:org.apache.felix.fileinstall:3.3.11.redhat-610379]
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: {{uri}} due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:480)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:71)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.model.RouteDefinition.resolveEndpoint(RouteDefinition.java:192)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:106)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:112)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.model.FromDefinition.resolveEndpoint(FromDefinition.java:72)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultRouteContext.getEndpoint(DefaultRouteContext.java:88)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:890)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:177)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
... 38 more
Caused by: org.apache.camel.RuntimeCamelException: org.jasypt.exceptions.EncryptionOperationNotPossibleException
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1363)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1005)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.blueprint.BlueprintPropertiesParser.parseProperty(BlueprintPropertiesParser.java:137)[151:org.apache.camel.camel-blueprint:2.12.0.redhat-610379]
at org.apache.camel.component.properties.DefaultPropertiesParser.createPlaceholderPart(DefaultPropertiesParser.java:201)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.component.properties.DefaultPropertiesParser.doParseUri(DefaultPropertiesParser.java:105)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.component.properties.DefaultPropertiesParser.parseUri(DefaultPropertiesParser.java:51)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.component.properties.PropertiesComponent.parseUri(PropertiesComponent.java:160)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.component.properties.PropertiesComponent.parseUri(PropertiesComponent.java:119)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultCamelContext.resolvePropertyPlaceholders(DefaultCamelContext.java:1155)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:478)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
... 46 more
Caused by: org.jasypt.exceptions.EncryptionOperationNotPossibleException
at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.decrypt(StandardPBEByteEncryptor.java:918)
at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:725)
at org.apache.karaf.jaas.jasypt.handler.EncryptablePropertyPlaceholder.getProperty(EncryptablePropertyPlaceholder.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.7.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[:1.7.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.7.0_25]
at java.lang.reflect.Method.invoke(Method.java:606)[:1.7.0_25]
at org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:1001)[143:org.apache.camel.camel-core:2.12.0.redhat-610379]
... 54 more
I created a test bundle with a Blueprint Context which contains only one placeholder property defined in the Camel Context, without using the encrypted ENC() placeholder syntax. I just added <enc:property-placeholder> and the bundle failed to start with same exception (org.jasypt.exceptions.EncryptionOperationNotPossibleException).
Is this desired behavior?
My Blueprint configuration:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
<cm:property-placeholder persistent-id="encrypt.config" update-strategy="reload" >
<cm:default-properties>
<cm:property name="uri" value="timer://foo?fixedRate=true&period=6000"/>
</cm:default-properties>
</cm:property-placeholder>
<enc:property-placeholder>
<enc:encryptor class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config">
<bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="password" value="password" />
</bean>
</property>
</enc:encryptor>
</enc:property-placeholder>
<camelContext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="http://camel.apache.org/schema/blueprint">
<route>
<from uri="{{uri}}"/>
<log message="logging" loggingLevel="INFO" id="logBeforeService"></log>
</route>
</camelContext>
</blueprint>
EDIT: Response from RedHat Support
So this is a known issue, and theres a couple of Jira issues for it (here and here), and it appears as if the issue has been resolved in newer versions of Camel. I have tested with version 2.12.0.redhat-611412, provided by the patch named jboss-fuse-6.1.0.redhat-379-r1p3, and the exception is no longer being thrown.
Regardless of what I have said previously, im quite happy with this implementation. I would want an exception to be thrown if it couldnt decrypt a value which was actaully encrypted, and that is exactly what happens. I modified the encrypted value to ENC(invalid_and_should_throw_exception), and an exception was thrown exactly like I would expect it to.
Caused by: org.jasypt.exceptions.EncryptionOperationNotPossibleException
EDIT: A more concise Answer
Camel-Blueprint behaves differently to Camel-Core, in regards to the way that it resolves property placeholder values. Camel-Core requires the developer to define a Camel Property Placeholder Resolver, which resolves properties in the Camel Context, for the camel property syntax [1]. Obviously the reasoning behind this is to avoid conflicts between the spring property syntax [2] and the Camel Simple Expression Language syntax [3]. The developer has the choice to optionally bridge the Spring Property Placeholder Resolver with Camel by adding extra configuration.
[1 - Camel Property Syntax]
{{org.my.prop}}
[2 - Spring Property Syntax]
${org.my.prop}
[3 - Simple Expression Language Syntax]
${exchange.body}
In Camel-Blueprint, the bridging between the Blueprint Property Placeholder Resolvers and the Camel Context happens automatically. When a Blueprint Camel Context is created, the Blueprint Bundle Context is injected into it. With the Blueprint Bundle Context, Camel pulls all of the beans out of it and determines if they are assignable to the Apache Aries implementation AbstractPropertyPlaceholder. With each instance of the Property Placeholder Resolvers you have defined, Camel is then capable of calling the resolveProperty method on them, without having to parse the property syntax defined by each of the resolvers.
Because the Jasypt Property Placeholder Resolver expects the placeholder syntax [4], it just ignores everything which dosent match this syntax. Because Camel-Blueprint by-passes that validation which ensures the property syntax, we end up in a scenario where Camel is telling the Jasypt Placeholder Resolver to decrypt every property that we attempt to use in our Camel Context. This of course will throw an exception, because you’re trying to decrypt a property which hasn’t been encrypted.
[4 - Jasypt Blueprint Property Syntax]
ENC(encrypted.value)
Solutions:
Create a class which implements the Jasypt StringEncryptor and holds the StandardPBEStringEncryptor as an attribute. The implemented encrypt and decrypt methods call the encrypt and decrypt methods of the StandardPBEStringEncryptor, but catch any exceptions that are thrown.
This is the solution I gave in my original answer.
This is dangerous, if an encrypted value can’t be decrypted that shouldn’t be ignored. The bundle should not start up, to prevent e.g. your database account from getting locked.
Decrypt values manually before passing them to the Placeholder Resolver.
You could create a configuration service, where you compaile all your configuration from your various sources, decrypt all the encrypted values manually, then expose the properties as an OSGi service to be shared accross bundles.
I’ve gone off this design, it’s basically re-implementing the ConfigurationAdmin service which is provided natively by Karaf (with the addition of decryption which Karaf doesn’t provide), it’s just not as good as the one Karaf provides as it is not capable of detecting when application configuration has changed.
Decrypt values at runtime.
Not a fan of this either, requires your application to be aware of which application properties are expected to be encrypted.
I have raised a support ticket with Redhat through our support contract, I'll keep you updated if anything comes of it.
Original Answer:
I think I figured this one out. According to the camel documentation, in blueprint camel is capable of detecting that a blueprint placeholder resolver is present, and attempts to use that to resolve its properties.
The problem with this is that it does not care what the placeholder prefix and suffix is, it just goes ahead and uses it regarless. The Jasypt placeholder resolver has been desgined so that it is only even invoked if the placeholder prefix is "ENC(" and the suffix is ")", remember Camel dosent care about this. Camel passes its unresolved properties to the Jasypt property resolver, which of course attempts to decrypt them. Because they are not encrypted, an exception is thrown.
To get around this, I have created a custom encryptor which implements the Jasypt StringEncryptor. The custom encryptor contains an instance of the StandardPBEStingEncryptor, and uses that to do the actual encryption/ decryption. The key difference is that Exceptions are caught and ignored, so if an Exception is thrown trying to decrypt a camel property which isnt encrypted, then it is ignored and the application continues as normal.
The Java Class:
package uk.co.test;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CustomEncryptor implements StringEncryptor {
private StandardPBEStringEncryptor encryptor;
private static final Logger LOG = LoggerFactory.getLogger(CustomEncryptor.class);
public CustomEncryptor(String password) {
encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword(password);
}
#Override
public String decrypt(String value) {
String ret = null;
try {
ret = encryptor.decrypt(value);
} catch (Exception e) {
LOG.error("Failed to decrypt value.");
}
return ret;
}
#Override
public String encrypt(String value) {
String ret = null;
try {
ret = encryptor.encrypt(value);
} catch (Exception e) {
LOG.error("Failed to encrypt value.");
}
return ret;
}
public StandardPBEStringEncryptor getEncryptor() {
return encryptor;
}
public void setEncryptor(StandardPBEStringEncryptor encryptor) {
this.encryptor = encryptor;
}
}
The Blueprint configuration:
<enc:property-placeholder>
<enc:encryptor class="uk.co.test.CustomEncryptor">
<argument value="myPass" />
</enc:encryptor>
</enc:property-placeholder>