Camel DefaultShutdownStrategy logging full url - apache-kafka

I'm having an issue where I cannot prevent the shutdown strategy in camel from logging my full URL. This is a problem because the URL has a password in it.
Neither of the .logMask() calls suppress this log line. How can I go about preventing this from being logged?
context.addRoutes(new RouteBuilder() {
#Override
public void configure() {
from(uriString)
.logMask()
.process(exchange -> {
Message in = exchange.getIn();
// Doing some business logic here
})
.toD("direct:someOtherRoute")
.logMask();
}
});
The line being logged:
kafka://MY-TOPIC-NAME?saslJaasConfig=passwordThatShouldNotBeLogged&otherParams...
Edit: The full url is being logged both on startup and shutdown.

Okay this information is logged by Camel. But we have fixed this for next releases (2.25.0 onwards, and the 3.x branches).
For your current version, you cannot prevent this. However you can configure the logging level for that shutdown class to be WARN level.
You can also patch your Camel version yourself, this is the commit
https://github.com/apache/camel/commit/f60e4a73935bea211eec38823698d73bd1d0bd62

If your sensitive endpoint parameters are for SSL configuration, you can register the SSL configuration in the Camel Context and only reference it in the endpoint parameters.
kafka://MY-TOPIC-NAME?sslContextParameters=#ssl
See the Camel-Kafka Docs (section SSL Configuration) for details.

Related

Spring Cloud Dataflow errorChannel not working

I'm attempting to create a custom exception handler for my Spring Cloud Dataflow stream to route some errors to be requeued and others to be DLQ'd.
To do this I'm utilizing the global Spring Integration "errorChannel" and routing based on exception type.
This is the code for the Spring Integration error router:
package com.acme.error.router;
import com.acme.exceptions.DlqException;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.transformer.MessageTransformationException;
import org.springframework.messaging.Message;
#MessageEndpoint
#EnableBinding({ ErrorMessageChannels.class })
public class ErrorMessageMappingRouter {
private static final Logger LOGGER = LoggerFactory.getLogger(ErrorMessageMappingRouter.class);
public static final String ERROR_CHANNEL = "errorChannel";
#Router(inputChannel = ERROR_CHANNEL)
public String onError(Message<Object> message) {
LOGGER.debug("ERROR ROUTER - onError");
if(message.getPayload() instanceof MessageTransformationException) {
MessageTransformationException exception = (MessageTransformationException) message.getPayload();
Message<?> failedMessage = exception.getFailedMessage();
if(exceptionChainContainsDlq(exception)) {
return ErrorMessageChannels.DLQ_QUEUE_NAME;
}
return ErrorMessageChannels.REQUEUE_CHANNEL;
}
return ErrorMessageChannels.DLQ_QUEUE_NAME;
}
...
}
The error router is picked up by each of the stream apps through a package scan on the Spring Boot App for each:
#ComponentScan(basePackages = { "com.acme.error.router" }
#SpringBootApplication
public class StreamApp {}
When this is deployed and run with the local Spring Cloud Dataflow server (version 1.5.0-RELEASE), and a DlqException is thrown, the message is successfully routed to the onError method in the errorRouter and then placed into the dlq topic.
However, when this is deployed as a docker container with SCDF Kubernetes server (also version 1.5.0-RELEASE), the onError method is never hit. (The log statement at the beginning of the router is never output)
In the startup logs for the stream apps, it looks like the bean is picked up correctly and registers as a listener for the errorChannel, but for some reason, when exceptions are thrown they do not get handled by the onError method in our router.
Startup Logs:
o.s.i.endpoint.EventDrivenConsumer : Adding {router:errorMessageMappingRouter.onError.router} as a subscriber to the 'errorChannel' channel
o.s.i.channel.PublishSubscribeChannel : Channel 'errorChannel' has 1 subscriber(s).
o.s.i.endpoint.EventDrivenConsumer : started errorMessageMappingRouter.onError.router
We are using all default settings for the spring cloud stream and kafka binder configurations:
spring.cloud:
stream:
binders:
kafka:
type: kafka
environment.spring.cloud.stream.kafka.binder.brokers=brokerlist
environment.spring.cloud.stream.kafka.binder.zkNodes=zklist
Edit: Added pod args from kubectl describe <pod>
Args:
--spring.cloud.stream.bindings.input.group=delivery-stream
--spring.cloud.stream.bindings.output.producer.requiredGroups=delivery-stream
--spring.cloud.stream.bindings.output.destination=delivery-stream.enricher
--spring.cloud.stream.binders.xdkafka.environment.spring.cloud.stream.kafka.binder.zkNodes=<zkNodes>
--spring.cloud.stream.binders.xdkafka.type=kafka
--spring.cloud.stream.binders.xdkafka.defaultCandidate=true
--spring.cloud.stream.binders.xdkafka.environment.spring.cloud.stream.kafka.binder.brokers=<brokers>
--spring.cloud.stream.bindings.input.destination=delivery-stream.config-enricher
One other idea we attempted was trying to use the Spring Cloud Stream - spring integration error channel support to send to a broker topic on errors, but since messages don't seem to be landing in the global Spring Integration errorChannel at all, that didn't work either.
Is there anything special we need to do in SCDF Kubernetes to enable the global Spring Integration errorChannel?
What am I missing here?
Update with solution from the comments:
After reviewing your configuration I am now pretty sure I know what
the issue is. You have a multi-binder configuration scenario. Even if
you only deal with a single binder instance the existence of
spring.cloud.stream.binders.... is what's going to make framework
treat it as multi-binder. Basically this a bug -
github.com/spring-cloud/spring-cloud-stream/issues/1384. As you can
see it was fixed but you need to upgrade to Elmhurst.SR2 or grab the
latest snapshot (we're in RC2 and 2.1.0.RELEASE is in few weeks
anyway) – Oleg Zhurakousky
This was indeed the problem with our setup. Instead of upgrading, we just eliminated our multi-binder usage for now and the issue was resolved.
Update with solution from the comments:
After reviewing your configuration I am now pretty sure I know what
the issue is. You have a multi-binder configuration scenario. Even if
you only deal with a single binder instance the existence of
spring.cloud.stream.binders.... is what's going to make framework
treat it as multi-binder. Basically this a bug -
github.com/spring-cloud/spring-cloud-stream/issues/1384. As you can
see it was fixed but you need to upgrade to Elmhurst.SR2 or grab the
latest snapshot (we're in RC2 and 2.1.0.RELEASE is in few weeks
anyway) – Oleg Zhurakousky
This was indeed the problem with our setup. Instead of upgrading, we just eliminated our multi-binder usage for now and the issue was resolved.

Camel Restlet - Context Path Ambiquity

I have Spring Boot Camel application where rest apis are exposed using camel-restlet
Sample route
#Component
public class AppRoute extends RouteBuilder{
public void configure(CamelContext context){
from("restlet:employee?restletMethods=GET").log("${body}");
}
}
The App runs perfect ( spring-boot:run ). but am unable to locate under which path the API is exposed. Log has no information.
Every API i hit returns 404. Log shows the route has been started. Under which path is it running. And how do I change it?
Note: Please dont suggest any XML based configuration. Anything that I can put under #Configuration would be perfect
I would go with the Rest DSL which is supported by the camel-restlet component like this
restConfiguration().component("restlet").port(8080);
rest("/rest")
.get("employee")
.route().log("${body}")
.endRest();
And this route will listen to the following url
http://localhost:8080/rest/employee
EDIT:
I guess you could do something like without using the Rest DSL
String host = InetAddress.getLocalHost().getHostName();
from("restlet:http://" + host + contextPath + "/employee?restletMethods=GET").log("${body}")
The port and context path are configurable with the following properties
camel.component.restlet.port=8686
server.servlet.context-path=/my-path
The context path can be injected in the routeBuilder with
#Value("${server.servlet.context-path}")
private String contextPath;
According to the documentation, the format of the URI in a restlet endpoint definition should be the following:
restlet:restletUrl[?options]
Where restletUrl should have the following format:
protocol://hostname[:port][/resourcePattern]
So in your case you could define the URI in the following way:
from("restlet:http://localhost/employee?restletMethods=GET")
This should make the endpoint available under the following URL:
http://localhost/employee
Which you can test e.g. in a web browser.
Use the first of the three configuration methods described here:
https://restlet.com/open-source/documentation/javadocs/2.0/jee/ext/org/restlet/ext/servlet/ServerServlet.html
You should be able to customize it using the Component:
https://restlet.com/open-source/documentation/javadocs/2.0/jee/api/org/restlet/Component.html?is-external=true
See in particular setServers() methods (or XML equivalent) to change the hostname and port.

JavaMail crashes after build/deploy on Glassfish 4

My current project includes using of a JavaMail for confirming an user email. The problem I have is that, using eclipse, every time I build & deploy my web application on the local Glassfish server the JavaMail crashes with the following exception:
Severe: java.lang.SecurityException: Access to default session denied
at javax.mail.Session.getDefaultInstance(Session.java:333)
at utils.MailService.sendEmailSSL(MailService.java:58)
And here the code snipped where I'm obtaining the session and which is throwing the above exception:
Session session = Session.getDefaultInstance(
props,
new javax.mail.Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(usr, pwd);
}
});
The workaround I've found so far is restarting Glassfish and after that JavaMail functions properly again. The problem is it is very annoying and time consuming doing a restart even after the smallest change in my code.
My question: Is there a possibility to reset only the JavaMail service and bind this with the build event?
Off course any other suggestions are welcome too :)
If you can avoid using Session.getDefaultInstance. Use Session.getInstance and fix some of the common mistakes.

WSO2IS NullPointerException when using step authenticator

Occasionally (?) the WSO2 IS user is unable to authenticate with following exception. When retrying, the user will be authenticated. Any ideas what could be reason / resolution? We set up the session caching.
Using WSO2 Identity Server 5.0.0.SP1 / SAML authentication with the authenticator set to advanced (single step, multiple options). I cannot find the correct source code commit to check out (to match the line number in the exception)
Thank you all in advance
Gabriel
TID: [0] [IS] [2016-02-15 13:07:22,914] ERROR
{org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator}
- Exception in Authentication Framework {org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator}
java.lang.NullPointerException at
org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler.handle(DefaultStepBasedSequenceHandler.java:83)
at
org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:121)
at
org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator.handle(DefaultRequestCoordinator.java:94)
at
org.wso2.carbon.identity.application.authentication.framework.servlet.CommonAuthenticationServlet.doPost(CommonAuthenticationServlet.java:54)
at
org.wso2.carbon.identity.application.authentication.framework.servlet.CommonAuthenticationServlet.doGet(CommonAuthenticationServlet.java:44)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:735) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
Edit:
This exception occurs on the WSO2 IS 5.1.0 too
see the Source code line 105
StepConfig stepConfig = context.getSequenceConfig().getStepMap().get(currentStep);
// if the current step is completed
if (stepConfig.isCompleted()) {
stepConfig.setCompleted(false);
ERROR org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator} - Exception in Authentication Framework
java.lang.NullPointerException
at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler.handle(DefaultStepBasedSequenceHandler.java:105)
at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:115)
it looks like the stepConfig 'dissapeared' from the authentication config. The setup is done on a single node with session persistence into a database.
Apparently it looks like a problem with concurrency.
When multiple concurrent requests are sent to the SSO endpoint while the user is already authenticated, all threads are attempting to process the request modifying the same authentication context object (currentStep counter) so the cached authentication context comes to an invalid state.
Valid use case is that the client should send only a single request to the SSO endpoint, so the team dealing with the UI have to fix it. But - that's only the a quick fix not preventing the issue in long term. We have to really pick it up with WSO2 (and fix the code ourselves maybe) :)
g.

HTTP BasicAuthentication doesn't immediately realize, when a user's role changes. What can I do about it?

I have deployed a Webservice on JBossAS 5.1 GA. To use HTTP Basic Authentication, The SBC class is annotated the following way:
#Stateless
#SecurityDomain(value = "MyWSSecurity")
#RolesAllowed(value = "WebserviceUser")
#WebContext(contextRoot="/MyWS", urlPattern="/*", authMethod="BASIC", transportGuarantee="NONE", secureWSDLAccess=true)
#WebService(endpointInterface = "MyWS")
public class MyWSImpl implements MyWS {
public String doSomething() {
return "something";
}
}
Generally this works fine. But the following szenario bothers me.
User who is in role WebserviceUser calls the service.
The role Webservice is now taken AWAY from the user.
Problem: He still can call the service.
I guess this happens, because user credentials and roles are stored in HttpSession object on the server side. After server restart the user is denied from calling the service.
What can I do about that?
Regards
EDIT: The problem does not apply only to JBOSSWS EJB3 webservices, but to anything using JAAS authentication.
Found 2 solutions that are appropriate for me.
Solution 1) Change the Default timeout for the JAAS Cache
You can do this by editing $JBOSS_HOME/server/default/conf/jboss-service.conf. Locate the part of the file, where JaasSecurityManager MBean is configured and change the attribute DefaultCacheTimeout to an acceptable small value (60 seconds is fine for me). If you want to disable caching of security credentials entirely, set the value to 0.
<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
<!--
skipped some configuration
-->
<!-- DefaultCacheTimeout: Specifies the default timed cache policy timeout
in seconds.
If you want to disable caching of security credentials, set this to 0 to
force authentication to occur every time. This has no affect if the
AuthenticationCacheJndiName has been changed from the default value.
-->
<attribute name="DefaultCacheTimeout">60</attribute>
<!-- DefaultCacheResolution: Specifies the default timed cache policy
resolution in seconds. This controls the interval at which the cache
current timestamp is updated and should be less than the DefaultCacheTimeout
in order for the timeout to be meaningful. This has no affect if the
AuthenticationCacheJndiName has been changed from the default value.
-->
<attribute name="DefaultCacheResolution">30</attribute>
<!--
skipped some configuration
-->
</mbean>
Solution 2: Call method flushAuthenticationCache("MyWSSecurity") on JaasSecurityManager MBean, whenever a user's role changes.
Regards