camel snmp can't resive snmpversion=3 info - apache-camel

When I use came-snmp resive snmp info which version is 3, it can't go to the process method.
#Component
public class SnmpCollect extends RouteBuilder {
#Override
public void configure() throws Exception {
from("snmp:0.0.0.0:162?protocol=udp&type=TRAP&snmpVersion=3&securityName=test").process(new Processor() {
#Override
public void process(Exchange arg0) throws Exception {
}
}
}
Camel xml config:
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="snmpCollect"/>
</camelContext>
But when the snmp info which version is 1 or 2 is coming, it can go to the process method.
What's wrong with it, and how to make it work for "snmpVersion=3" info?
Camel Version is 2.20.1

Let me try to answer your question by providing some info based in what I've found.
Seems that he requirements and interfaces from v1 and v2 version differ from v3, so it doesn't like to work just updating the version. The mainly difference, from what I've seen, is that you need to provide a security model to v3. I saw that you are passing it via parameters, but have you got the chance to check the security requirements?
When I use the TrapTest where is on the camel-snmp github “github.com/apache/camel/blob/master/components/camel-snmp/s‌​rc/…”,it‘s ok.But when I change the snmpVersion to SnmpConstants.version3,it's also error
That's because the interface changed and the test should rely on ScopedPDU model instead of the base class PDU. Also the security model isn't set up in this test:
org.snmp4j.MessageException: Message processing model 3 returned error: Unsupported security model
Unfortunately there isn't any example using camel-snmp with v3, but you could take a look into this example using the inner component snmp4j.

Related

Apache camel pollEnrich strangeness

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.

FailedToStartRouteException exception while using camel-spring-boot, amqp and kafka starters with SpringBoot, unable to find connectionFactory bean

I am creating an application using Apache Camel to transfer messages from AMQP to Kafka. Code can also be seen here - https://github.com/prashantbhardwaj/qpid-to-kafka-using-camel
I thought of creating it as standalone SpringBoot app using spring, amqp and kafka starters. Created a route like
#Component
public class QpidToKafkaRoute extends RouteBuilder {
public void configure() throws Exception {
from("amqp:queue:destinationName")
.to("kafka:topic");
}
}
And SpringBoot application configuration is
#SpringBootApplication
public class CamelSpringJmsKafkaApplication {
public static void main(String[] args) {
SpringApplication.run(CamelSpringJmsKafkaApplication.class, args);
}
#Bean
public JmsConnectionFactory jmsConnectionFactory(#Value("${qpidUser}") String qpidUser, #Value("${qpidPassword}") String qpidPassword, #Value("${qpidBrokerUrl}") String qpidBrokerUrl) {
JmsConnectionFactory jmsConnectionFactory = new JmsConnectionFactory(qpidPassword, qpidPassword, qpidBrokerUrl);
return jmsConnectionFactory;
}
#Bean
#Primary
public CachingConnectionFactory jmsCachingConnectionFactory(JmsConnectionFactory jmsConnectionFactory) {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(jmsConnectionFactory);
return cachingConnectionFactory;
}
jmsConnectionFactory bean which is created using Spring Bean annotation should be picked by amqp starter and should be injected into the route. But it is not happening. When I started this application, I got following exception -
org.apache.camel.FailedToStartRouteException: Failed to start route route1 because of Route(route1)[From[amqp:queue:destinationName] -> [To[kafka:.
Caused by: java.lang.IllegalArgumentException: connectionFactory must be specified
If I am not wrong connectionFactory should be created automatically if I pass right properties in application.properties file.
My application.properties file looks like :
camel.springboot.main-run-controller = true
camel.component.amqp.enabled = true
camel.component.amqp.connection-factory = jmsCachingConnectionFactory
camel.component.amqp.async-consumer = true
camel.component.amqp.concurrent-consumers = 1
camel.component.amqp.map-jms-message = true
camel.component.amqp.test-connection-on-startup = true
camel.component.kafka.brokers = localhost:9092
qpidBrokerUrl = amqp://localhost:5672?jms.username=guest&jms.password=guest&jms.clientID=clientid2&amqp.vhost=default
qpidUser = guest
qpidPassword = guest
Could you please help suggest why during autoconfiguring connectionFactory object is not being used? When I debug this code, I can clearly see that connectionFactory bean is getting created.
I can even see one more log line -
CamelContext has only been running for less than a second. If you intend to run Camel for a longer time then you can set the property camel.springboot.main-run-controller=true in application.properties or add spring-boot-starter-web JAR to the classpath.
however if you see my application.properties file, required property is present at the very first line.
One more log line, I can see at the beginning of application startup -
[main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.camel.spring.boot.CamelAutoConfiguration' of type [org.apache.camel.spring.boot.CamelAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Is this log line suggesting anything?
Note - One interesting fact that exactly same code was running fine last night, just restarted my desktop and there is not even a single word changed and now it is throwing exception.
This just refers to an interface
camel.component.amqp.connection-factory = javax.jms.ConnectionFactory
Instead it should refer to an existing factory instance, such as
camel.component.amqp.connection-factory = #myFactory
Which you can setup via spring boot #Bean annotation style.

How to resolve "You have not started an Objectify context" in JUnit?

I've got some Objectify test code running in JUnit and I'm getting this error:
java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.
at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:44)
at com.googlecode.objectify.impl.ref.LiveRef.<init>(LiveRef.java:31)
at com.googlecode.objectify.Ref.create(Ref.java:26)
at com.googlecode.objectify.Ref.create(Ref.java:32)
at com.netbase.followerdownloader.repository.DownloadTaskRepositoryImpl.create(DownloadTaskRepositoryImpl.java:35)
at com.netbase.followerdownloader.repository.DownloadTaskRepositoryImplTest.setUp(DownloadTaskRepositoryImplTest.java:45)
How do I resolve this for test code?
Jeff Schnitzer answered this here: https://groups.google.com/forum/#!topic/objectify-appengine/8HinahG7irg. That link points to https://groups.google.com/forum/#!topic/objectify-appengine/O4FHC_i7EGk where Jeff suggests the following quick and dirty workaround:
My #BeforeMethod starts an objectify context (ObjectifyService.begin())
My #AfterMethod closes the objectify context
Jeff suggests we use ObjectifyService.run() instead but admits it's more work.
Here's how my implementation looks:
public class DownloadTaskRepositoryImplTest {
// maximum eventual consistency (see https://cloud.google.com/appengine/docs/java/tools/localunittesting)
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()
.setDefaultHighRepJobPolicyUnappliedJobPercentage(100));
private Closeable closeable;
#Before
public void setUp() {
helper.setUp();
ObjectifyRegistrar.registerDataModel();
closeable = ObjectifyService.begin();
}
#After
public void tearDown() {
closeable.close();
helper.tearDown();
}
I also had this issue and noticed that I had not added the ObjectifyFilter to my web.xml
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I also had to include Objectify and guava jars in my WEB-INF>lib directory and include them in my build path.
I was facing the same error and this solusion worked for me
I have an app based on Endpoints that uses Objectify. When I leave it with the default/automatic scaling, everything works great. Once I enable basic scaling, though, I get the following exception when executing the endpoint method:
[INFO] java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.
[INFO] at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:44)
[INFO] at com.myco.myapp.dao.datastore.OfyService.ofy(OfyService.java:62)
The good news is that this goes away when you enable RequestDispatcher
support in the web.xml file like so. I think this is a documentation
issue, then, but I didn't know if everyone would agree if I edited the
Wiki page directly. Here is the proposed web.xml entry, which worked
for me:
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Improving michael-osofsky answer, I add this to my ofy helper class
public static void registerDataModel() {
try {
factory().register(Profile.class);
} catch (Exception e){
e.printStackTrace();
}
}
and remplace
ObjectifyRegistrar.registerDataModel();
for this
OfyService.registerDataModel();
OfyService.java
public static void registerDataModel() {
try {
factory().register(Profile.class);
} catch (Exception e){
e.printStackTrace();
}
}
As Jeff Schnitzer says in the link provided by Michael Osofsky:
In your tests you should have some notion of a 'request' even if it is just conceptual. If "each test is a request by itself", then you can use #Before/#After in conjunction with ObjectifyService.begin() to demarcate the requests. However, this is probably not actually how your tests work - it isn't how my tests work.
He then goes on to say:
This would be prettier with JDK8 closures but the idea is straightforward - you're wrapping some unit of work in a context which represents a request. It would probably be smart to add even more context like authentication in that wrapper too.
I came up with the following implementation of his idea. With the solution below, you can ensure each call to a servlet handler gets a fresh Objectify session while still making your servlet handler calls in a single line of code. It also decouples your tests from explicitly worrying about Objectify, and allows you to add additional non-Objectify context around your servlet handlers.
My solution below works with Objectify 5.1.22. I tried using Objectify 6+, but I had problems that seem to be related to this.
First, define a custom Supplier that is able to capture the exceptions thrown by a servlet handler.
#FunctionalInterface
public interface ServletSupplier<T> {
T get()
throws ServletException, IOException;
}
Next, define a wrapper method that accepts your new custom Supplier as an input, and wrap the call to ServletSupplier.get() in a try-with-resources block that calls ObjectifyService.begin(). You must also register your entity classes before calling ServletSupplier.get().
public <T> T runInServletContext(ServletSupplier<T> servletMethod)
throws ServletException, IOException {
try (Closeable session = ObjectifyService.begin()) {
ObjectifyService.register(MyObj.class);
return servletMethod.get();
}
}
Finally, anywhere in your tests that you call the servlet handler you should do so using the wrapper method.
MyObj myObjPost = runInServletContext(() -> getServlet().doPost(request, response));
// Assert results of doPost call.
MyObj myObjGet = runInServletContext(() -> getServlet().doGet(request, response));
// Assert results of doGet call.
Just in case someone ends up here (as I originally did) looking up the same problem but for the ktor "main.kt" server instead of unit tests...
After looking at the ObjectifyFilter source code, I added
val closer = ObjectifyService.begin()
... real service here ...
closer.close()
around my actual servlet code and that fixed the problem.

log4j2 how to disable "date:" lookup - log4j throws exception

edit seems not to be possible at the moment filed an issue.
i am using log4j2 in my apache camel application. In camel file names can be configured this way "?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz"
if i set log level to debug camel tries to log what it is doing but log4j seems to try to lookup/interpret the string with "date:" and throws an exception:
2014-11-24 11:29:19,218 ERROR Invalid date format: "now:yyyyMMdd-HHmmss", using default java.lang.IllegalArgumentExcepti
on: Illegal pattern character 'n'
at java.text.SimpleDateFormat.compile(Unknown Source)
at java.text.SimpleDateFormat.initialize(Unknown Source)
at java.text.SimpleDateFormat.<init>(Unknown Source)
at java.text.SimpleDateFormat.<init>(Unknown Source)
at org.apache.logging.log4j.core.lookup.DateLookup.formatDate(DateLookup.java:60)
at org.apache.logging.log4j.core.lookup.DateLookup.lookup(DateLookup.java:53)
at org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:144)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1008)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:926)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:816)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(StrSubstitutor.java:385)
at org.apache.logging.log4j.core.pattern.MessagePatternConverter.format(MessagePatternConverter.java:71)
at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:36)
at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:189)
at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:53)
at org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:52)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:
104)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:97)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:428)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:407)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:365)
at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:112)
at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1347)
at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1312)
at org.apache.logging.slf4j.Log4jLogger.debug(Log4jLogger.java:132)
at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:518)
at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:570)
at org.apache.camel.util.IntrospectionSupport.setProperties(IntrospectionSupport.java:454)
at org.apache.camel.util.EndpointHelper.setProperties(EndpointHelper.java:249)
at org.apache.camel.impl.DefaultComponent.setProperties(DefaultComponent.java:272)
at org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:67)
at org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:37)
at org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:123)
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:514)
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:547)
Is there a way to turn off this "date:" lookup? Why does it try to interpret stuff coming from log at all? I think it should not be touched in any way?!
Edit, very easy to reproduce in test:
public class LogTest {
private Logger log = LoggerFactory.getLogger(LogTest.class);
#Test
public void test() {
log.info("${date:now:buhu}");
}
}
It is crucial to us ${date:} - only "data:now" is working.
So this problem is completely independent from camel, but camel uses ${date:...} pattern for several things. Here is a simple route that reproduces the problem - the exception will be thrown on camel set up phase - no test code needed - logging level must be "debug"!:
public class LogTest extends CamelTestSupport{
private Logger log = LoggerFactory.getLogger(LogTest.class);
#Test
public void test() {
//log.info("${date:now:yyyyMMdd-HHmmss}");
}
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:a").to("file:./?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
}
};
}
}
This issue was fixed in 2.7 version of Log4j2.
The solution is to upgrade to that version (or higher) and add in the pattern attribute the option "{nolookups}" to %msg .
%msg{nolookups}
For example
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1} %L %M %t - %msg{nolookups}%n%xEx%n" />
The problem can be avoided, if the simple-Expression is written as $simple{..} instead of ${..}. Then log4j2 won't use his Date-Lookup.
So, if you change your Route from:
from("direct:a").to("file:./?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
to:
from("direct:a").to("file:./?fileName=$simple{date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
it should work, even if you debug Camel.
To disable the date lookup locally, you can add a "$" in front of the expression:
log.info("$${date:now:buhu}");
This will print ${date:now:buhu} instead of throwing an exception printing the stack trace.
As for how to avoid this using Camel, I'm not sure. The cleanest fix would probably be a log4j2 update to disable their DateLookup feature. A temporary fix is to disable DEBUG level logs from the org.apache.camel package:
<loggers>
<logger name="org.apache.camel" level="INFO" />
<root level="debug">
<appender-ref ref="Console" />
</root>
</loggers>
It's not ideal, but we can increase the log level if we ever need to debug Camel context creation since the log statements are not necessary for general everyday development.
The correct solution is now to upgrade the log4j-core library to 2.15.0 or above. At time of writing, the latest and current recommended version is 2.16.0.
The variable substitutions happening in logged messages here are symptoms of the same feature exploited in CVE-2021-44228, aka Log4Shell.
The feature is disabled by default in 2.15.0 and removed in 2.16.0.
It's not news to anyone by now, but it's really important to take steps to disable this feature, as a security measure, even if not using Apache Camel or encountering the issue as described.
As an aside, I found this question when searching for early warning signs of the Log4Shell vulnerability. I've quoted it in my write-up.

Camel CXF throwing AssertionBuilderRegistryImpl exception

cannot figure out what is going on with this - trying to set up a route to just see cxf connect to a soap web service (I don't care about the actual data and don't expect the data to actually 'work', but it keeps throwing an exception I don't understand:
I wonder if I'm configuring it correctly.
I was thinking it might be a missing jar, but strated causing dependency conflicts when I tried to bring in other Jars
I'm using a maven dependency "camel-cxf" to load in all my jar configuration
"Reason: org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl."
The exact error is
"Failed to create Producer for endpoint: Endpoint[cxf://http://wsf.cdyne.com/WeatherWS/Weather.asmx?dataFormat=MESSAGE&portName=WeatherSoap&serviceClass=prototypes.CxfExample%24GetWeatherInformationSoapIn&serviceName=Weather&wsdlURL=http%3A%2F%2Fwsf.cdyne.com%2FWeatherWS%2FWeather.asmx%3FWSDL]. Reason: org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl."
The code I'm using to cause this is
camel.addComponent( "cxf", new CxfComponent() );
camel.addRoutes( new RouteBuilder() {
#Override
public void configure() throws Exception {
from( "timer://sometimer?delay=1s")
.to( "cxf://http://wsf.cdyne.com/WeatherWS/Weather.asmx"
+"?wsdlURL=http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL"
+"&dataFormat=MESSAGE"
+"&serviceClass=prototypes.CxfExample$GetWeatherInformationSoapIn"
+"&serviceName=Weather"
+"&portName=WeatherSoap"
);
}
});
camel.start();
Thread.sleep( 10000 );
camel.stop();
I think I have 'solved' it -
mvn:camel-cfx dependency is not enough
you need mvn:neethi dependency too
the AssertationBuildImpl class extends from a class that is not included in the jar-set for mvn:camel-cfx, which makes AssertationBuildImpl appear listed as a known class in the ide, but doesn't get class-loaded at runtime
this was a horrendous problem to track down, by analysing source-code of third-parties

Resources