SNMP4j - sned(pdu, target) method always returning null - snmp4j

I am using MIB browser engine as SNMP manager and sending trap from Java application as follow
Scenario 1 -( Valid IP address)
Scenario 2 -( Invalid IP address)
In both scenario getting null as a Response
public class TrapSenderVersion2 {
public static void main(String[] args) {
TrapSenderVersion2 trapV2 = new TrapSenderVersion2();
trapV2.sendTrap_Version2();
}
public void sendTrap_Version2() {
try {
// Create Transport Mapping
TransportMapping transport = new DefaultUdpTransportMapping();
transport.listen();
// Create Target
CommunityTarget cTarget = new CommunityTarget();
cTarget.setCommunity(new OctetString("public"));
cTarget.setVersion(SnmpConstants.version1);
cTarget.setAddress(new UdpAddress("10.133.14.35/162"));
cTarget.setRetries(2);
cTarget.setTimeout(5000);
// Create PDU for V2
PDU pdu = new PDU();
// need to specify the system up time
pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new OctetString(new Date().toString())));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(TrapOid)));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.6.0"), new OctetString("23b77493-74dd-489a-9c99-61db6c97a2e1")));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.7.0"), new OctetString("EventType")));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.8.0"), new OctetString("ServiceType")));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.9.0"), new OctetString("inp44vpdl002-COLLECTOR")));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.10.0"), new OctetString("14.140.156.15")));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.11.0"), new OctetString("Collector")));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.12.0"), new OctetString("Pune")));
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.30450.1.9.1.1.13.0"), new OctetString("This is a addtional info text")));
pdu.setType(PDU.NOTIFICATION);
// Send the PDU
Snmp snmp = new Snmp(transport);
System.out.println("Sending V2 Trap... Check Wheather NMS is Listening or not? ");
ResponseEvent re = snmp.send(pdu, cTarget);
System.out.println("ResponseEvent " + re);
snmp.close();
} catch (Exception e) {
e.printStackTrace();
}
}

Following line solved my problem
pdu.setType(PDU.INFORM);
I got the answer by debugging snmp4j source code, that its all depend upon PDU type.
When we set PDU type as Trap, Notificationm then response will alway return as null.
So there is type called "INFORM" which acknowledge to request with ResponseEvent.

Related

spring amqp message CorrelationIdString is null

code like below i send a message and set it messageid and CorrelationIdString
rabbitTemplate.send(RabbitMQConfig.EXCHANGE_NAME, "aaa.orange.bbb",new Message(messageBody, MessagePropertiesBuilder.newInstance().setCorrelationIdString(uuid3).
setMessageId(uuid3).setContentType("text/x-json").build()),
new CorrelationData(uuid3)
);
and the receiver code
public void processMessage (Message msg) throws Exception {
// Thread.sleep(100000);
System.out.println("Receiver1 got message" + msg);
and the log
Receiver1 got message(Body:'hello,world1 2' MessageProperties [headers={spring_listener_return_correlation=93fbcc71-b0eb-4d33-a187-d4b27122a663}, timestamp=null, messageId=5f779051-12c5-43f1-a589-6d14430d3a52, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=text/x-json, contentEncoding=null, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=first_exchange, receivedRoutingKey=aaa.orange.bbb, receivedDelay=null, deliveryTag=1, messageCount=0, consumerTag=amq.ctag-JbtjvUYYqlWOIsgKkOe-8A, consumerQueue=queue_a])
my question is why CorrelationIdString is null is that a problem or not
We migrated away from a byte[] for correlationId to String in 1.6 and 1.7 but we had to stick with byte[] by default for backwards compatibility; the migration is complete in 2.0 (currently 2.0.2) and correlationIdString is not longer a property.
I suggest moving to 2.0.
Alternatively, if you must use an older version, see CorrelationIdPolicy here to switch from byte[] to String or BOTH.
For me I was forced to override createContainerInstance method to change the policy on the listener side.
final DefaultMessagePropertiesConverter messagePropertiesConverter = new DefaultMessagePropertiesConverter();
messagePropertiesConverter.setCorrelationIdPolicy(DefaultMessagePropertiesConverter.CorrelationIdPolicy.STRING);
return new SimpleRabbitListenerContainerFactory() {
#Override
protected SimpleMessageListenerContainer createContainerInstance() {
final SimpleMessageListenerContainer result = new SimpleMessageListenerContainer();
result.setMessagePropertiesConverter(messagePropertiesConverter);
return result;
}
};

ConcurrentConsumers not created using DefaultMessageListenerContainer but using maximumActiveSessionsPerConnection on PooledConnectionFactory

I have following Java class. When used with CachingConnectionFactory it creates configured number of ConcurrentConsumers set on DefaultMessageListenerContainer. However if PooledConnectionFactory is used instead of CachingConnectionFactory, it just creates concurrentConsumers equals to maximumActiveSessionPerConnection set on PooledConnectionFactory instead of number of concurrentConsumers set on DefaultMessageListenerContainer.
How can I make sure the DefaultMessageListenerContainer uses multiple connections/Sessions provided by PooledConnectionFactory and create configured number of concurrentConsumer provided to DefaultMessageListenerContainer. Below is the simple example to check the same.
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.jms.pool.PooledConnectionFactory;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
public class ActiveMQMainTest {
public static void main(String[] args) {
String queueUrl = "tcp://localhost:61616";
ActiveMQQueue queue = new ActiveMQQueue("request.queue");
final ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(queueUrl);
PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory();
pooledConnectionFactory.setConnectionFactory(connectionFactory);
pooledConnectionFactory.setCreateConnectionOnStartup(false);
pooledConnectionFactory.setMaxConnections(5);
pooledConnectionFactory.setMaximumActiveSessionPerConnection(100);
pooledConnectionFactory.start();
// CachingConnectionFactory pooledConnectionFactory = new CachingConnectionFactory(connectionFactory);
DefaultMessageListenerContainer defaultMessageListenerContainer = new DefaultMessageListenerContainer();
defaultMessageListenerContainer.setConnectionFactory(pooledConnectionFactory);
defaultMessageListenerContainer.setDestination(queue);
defaultMessageListenerContainer.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
defaultMessageListenerContainer.setConcurrentConsumers(5);
defaultMessageListenerContainer.setMaxConcurrentConsumers(5 * 2);
defaultMessageListenerContainer.setCacheLevel(DefaultMessageListenerContainer.CACHE_NONE);
defaultMessageListenerContainer.setSessionTransacted(true);
JmsMessageListener messageListener = new JmsMessageListener();
defaultMessageListenerContainer.setMessageListener(messageListener);
defaultMessageListenerContainer.afterPropertiesSet();
defaultMessageListenerContainer.start();
try {
Thread.sleep(1000 * 60 * 10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The DMLC uses a shared connection by default (when there's no transaction manager). It can be disabled using:
dmlc.setCacheLevel(DefaultMessageListenerContainer.CACHE_NONE);
You should also normally have setSessionTransacted(true) with the DMLC, to avoid the possibility of losing messages (with the DMLC, messages are ack'd before the listener is invoked), using local transactions, the ack won't go to the broker until the listener exits normally.

Spring & RabbitMQ - register queue at runtime

How can I create new queue bound to Fanout exchange and run it during runtime? So far I have this:
Map<String, Object> arguments = new HashMap<>();
arguments.put("x-message-ttl", 600000L);
GenericBeanDefinition runtimeQueueBean = new GenericBeanDefinition();
runtimeQueueBean.setBeanClass(Queue.class);
runtimeQueueBean.setLazyInit(false);
runtimeQueueBean.setAbstract(false);
runtimeQueueBean.setAutowireCandidate(true);
ConstructorArgumentValues queueConstrArgs = new ConstructorArgumentValues();
queueConstrArgs.addIndexedArgumentValue(0, queueName);
queueConstrArgs.addIndexedArgumentValue(1, true);
queueConstrArgs.addIndexedArgumentValue(2, false);
queueConstrArgs.addIndexedArgumentValue(3, false);
queueConstrArgs.addIndexedArgumentValue(4, arguments);
runtimeQueueBean.setConstructorArgumentValues(queueConstrArgs);
this.context.registerBeanDefinition("nejm", runtimeQueueBean);
GenericBeanDefinition runtimeFanoutExchange = new GenericBeanDefinition();
runtimeFanoutExchange.setBeanClass(FanoutExchange.class);
runtimeFanoutExchange.setLazyInit(false);
runtimeFanoutExchange.setAbstract(false);
runtimeFanoutExchange.setAutowireCandidate(true);
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0, "staticCache");
runtimeFanoutExchange.setConstructorArgumentValues(constructorArgumentValues);
this.context.registerBeanDefinition("staticCache", runtimeFanoutExchange);
GenericBeanDefinition runtimeBinding = new GenericBeanDefinition();
runtimeBinding.setBeanClass(Binding.class);
runtimeBinding.setLazyInit(false);
runtimeBinding.setAbstract(false);
runtimeBinding.setAutowireCandidate(true);
constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0, queueName);
constructorArgumentValues.addIndexedArgumentValue(1, Binding.DestinationType.QUEUE);
constructorArgumentValues.addIndexedArgumentValue(2, "staticCache");
constructorArgumentValues.addIndexedArgumentValue(3, "");
runtimeBinding.setConstructorArgumentValues(constructorArgumentValues);
this.context.registerBeanDefinition("bajnding", runtimeBinding);
GenericBeanDefinition runtimeMessageListenerAdapter = new GenericBeanDefinition();
runtimeMessageListenerAdapter.setBeanClass(MessageListenerAdapter.class);
runtimeMessageListenerAdapter.setLazyInit(false);
runtimeMessageListenerAdapter.setAbstract(false);
runtimeMessageListenerAdapter.setAutowireCandidate(true);
constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0, this);
constructorArgumentValues.addIndexedArgumentValue(1, new RuntimeBeanReference("jackson2JsonMessageConverter"));
runtimeMessageListenerAdapter.setConstructorArgumentValues(constructorArgumentValues);
this.context.registerBeanDefinition("mla2", runtimeMessageListenerAdapter);
GenericBeanDefinition runtimeContainerExchange = new GenericBeanDefinition();
runtimeContainerExchange.setBeanClass(SimpleMessageListenerContainer.class);
runtimeContainerExchange.setLazyInit(false);
runtimeContainerExchange.setAbstract(false);
runtimeContainerExchange.setAutowireCandidate(true);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("connectionFactory", new RuntimeBeanReference("connectionFactory"));
propertyValues.addPropertyValue("queues", new RuntimeBeanReference("nejm"));
propertyValues.addPropertyValue("messageListener", new RuntimeBeanReference("mla2"));
runtimeContainerExchange.setPropertyValues(propertyValues);
this.context.registerBeanDefinition("defqueue", runtimeContainerExchange);
The problem is that queue/exchange is not created at the runtime, and I have to manually start the listener (unless I call this.context.start() - but I don't know if this is correct approach).
My question - is there some way to magically start all generated beans in runtime (something like this.context.refresh() - this exists but doesn't work or similar)?
UPDATE:
This is how I do it currently (this approach works, but don't know if correct one)
Map<String, Object> arguments = new HashMap<>();
arguments.put("x-message-ttl", 600000L);
Queue queue = new Queue(queueName, true, false, false, arguments);
FanoutExchange exchange = new FanoutExchange("staticCache");
Binding binding = new Binding(queueName, Binding.DestinationType.QUEUE, "staticCache", "", null);
rabbitAdmin.declareQueue(queue);
rabbitAdmin.declareExchange(exchange);
rabbitAdmin.declareBinding(binding);
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(this.connectionFactory);
container.setQueues(queue);
container.setMessageListener(new MessageListenerAdapter(this, this.converter));
container.start();
You can't do that way. BeanDefinition and this.context.registerBeanDefinition are for parsing phase of your application context lifecycle.
If you app is already there, the application context won't accepts any BeanDefinition.
Yes, you can declare Queue and its Binding to the exchange manually at runtime. And also you even can create SimpleMessageListenerContainer manually and make it worked.
And what is good for you that you just need to use their classes manually to instantiate. There is just need to supply container environment (e.g. inject this.applicationContext to the listenerContainer object).
For the declaration on the Broker you must use RabbitAdmin bean from your applicationContext.
From other side there is no reason to start a new listenerContainer manually. The existing one can supplied with your new Queue at runtime.

Apache Directory adding partition programmatically

I'm trying to create a partition programmatically. I've tried following the example on the ApacheDS website (https://directory.apache.org/apacheds/basic-ug/1.4.3-adding-partition.html#adding-a-partition-programmatically) , but this example is definitely not correct.
Here is my code:
LdapConnection connection = new LdapNetworkConnection(host, port);
connection.bind(admin, password);
connection.loadSchema();
SchemaManager schemaManager = connection.getSchemaManager();
Dn suffixDn = new Dn(schemaManager, "dc=newParition,dc=com");
JdbmPartition newPartition = new JdbmPartition(schemaManager);
newPartition.setId("newParition");
newPartition.setSuffixDn(suffixDn);
newPartition.setCacheSize(1000);
newPartition.setPartitionPath(new URI("file:///var/lib/apacheds-2.0.0-M15/default/partitions/newParition"));
newPartition.addIndex(new JdbmIndex("objectClass", false));
newPartition.addIndex(new JdbmIndex("dc", false));
Entry contextEntry = new DefaultEntry(schemaManager, suffixDn);
contextEntry.put("objectClass", "domain", "top");
contextEntry.put("dc", "newParition");
newPartition.initialize();
newPartition.add(new AddOperationContext(null, contextEntry));
I'm seeing the following error when I try to add the contextEntry to the partition:
org.apache.directory.api.ldap.model.exception.LdapSchemaViolationException: ERR_219 Entry dc=newParition,dc=com contains no entryCsn attribute: Entry …
It doesn't even look like the partition is being added to my server (when I restart my apacheds server, I don't see any new namingContexts under the Root DSE). I think I'm missing some steps here, but not sure what they are.
An advice from the Apache DS dev's mailing list:
"// ALWAYS add an entry using CoreSession's API". Check http://apaste.info/KHX for a nearly complete example of how to add a partition. The missing class EmbeddedServer is as follows:
private static final class EmbeddedServer {
private DirectoryService directoryService;
private LdapServer ldapService;
public EmbeddedServer(final String host, final int port) throws Exception {
init(host, port);
}
private void init(final String host, final int port) throws Exception {
DefaultDirectoryServiceFactory factory = new DefaultDirectoryServiceFactory();
factory.init("Test");
this.directoryService = factory.getDirectoryService();
this.directoryService.getChangeLog().setEnabled(false);
this.directoryService.setShutdownHookEnabled(true);
this.directoryService.setInstanceLayout(new InstanceLayout("/tmp/ldapServer"));
this.ldapService = new LdapServer();
this.ldapService.setTransports(new TcpTransport(host, port));
this.ldapService.setDirectoryService(this.directoryService);
}
public void start() throws Exception {
this.directoryService.startup();
this.ldapService.start();
}
public void stop() throws Exception {
this.ldapService.stop();
this.directoryService.shutdown();
}
}

WCF EndpointNotFoundException

I am working on a simple WCF service, MiniCalcService which has only one operation Add. The client and host are both console applications. The client application takes in the operands necessary for each operation and passes them over to the service. The service returns the result which would be displayed on the client console.
Host is running
I am doing everything in code so far and there is no app.config.
There is no large data being passed, just two or three numbers
This worked for me yesterday. Today when I tried the same thing, it throws the following exception:
There was no endpoint listening at http://localhost:8091/MiniCalcService that could accept the message.
Here is the Stack Trace. Not that it might matter, but MiniCalcClient is developed in Visual Studio and MiniCalcService and MiniCalcHost are developed in SharpDevelop.
MiniCalcHost:
using(ServiceHost host = new ServiceHost(typeof(MiniCalcService.Service), new Uri("http://localhost:8091/MiniCalcService")))
{
host.AddServiceEndpoint(typeof(MiniCalcService.IService),new BasicHttpBinding(),"Service");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("Serving MiniCalcService since {0}", DateTime.Now);
Console.Write("Press ENTER key to terminate the MiniCalcHost . . . ");
Console.ReadKey(true);
}
MiniCalcClient:
static string Calculator(string operation, params string[] strOperands)
{
EndpointAddress ep = new EndpointAddress("http://localhost:8091/MiniCalcService");
IService proxy = ChannelFactory<IService>.CreateChannel(new BasicHttpBinding(), ep);
int[] operands;
string result = string.Empty;
try { operands = Array.ConvertAll(strOperands, int.Parse); }
catch (ArgumentException) { throw; }
switch (operation)
{
case "add":
result = Convert.ToString(proxy.Add(operands));//<---EXCEPTION
break;
default:
Console.WriteLine("Why was this reachable again?");
break;
}
return result;
}
Service Contract IService:
[ServiceContract(Namespace="learning.wcf.MiniCalc")]
public interface IService
{
[OperationContract]
double Add(params int[] operands);
}
Can you please help me identify what's causing this exception?
Solution: I changed this line:
EndpointAddress ep = new EndpointAddress("http://localhost:8091/MiniCalcService");
to this:
EndpointAddress ep = new EndpointAddress("http://localhost:8091/MiniCalcService/Service");
and it worked.
I'm not sure if you can use the params in a WCF service call.... seems unnecessary, anyway....
Could you try these two service contracts instead, just to see if those would work:
[ServiceContract(Namespace="learning.wcf.MiniCalc")]
public interface IService2
{
[OperationContract]
int Add(int op1, int op2);
}
and
[ServiceContract(Namespace="learning.wcf.MiniCalc")]
public interface IService3
{
[OperationContract]
int Add(List<int> operands);
}
I'm just wondering if removing the params from your service contract might make it run - everything seems fine at first glance...
OK, so it wasn't this first attempt ......
Well - quite obvious, really: you're using a using block around the service host instantiation:
using(ServiceHost host = new ServiceHost(typeof(MiniCalcService.Service), new Uri("http://localhost:8091/MiniCalcService")))
{
host.AddServiceEndpoint(typeof(MiniCalcService.IService),new BasicHttpBinding(),"Service");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("Serving MiniCalcService since {0}", DateTime.Now);
Console.Write("Press ENTER key to terminate the MiniCalcHost . . . ");
}
So by the time the code reaches the closing bracket }, the ServiceHost instance will be disposed and thus the service host closed. There's no running service host anymore!
You need to stop the code execution somewhere after the call to host.Open() by e.g.
Console.ReadLine();
or something else.
So your first claim that Host is running really doesn't hold up - it's running briefly and then is terminated again right away.....