SNMP4j Trap Severity - snmp4j

How can I set a trap severity?
Code below
TransportMapping transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
CommunityTarget localtarget = new CommunityTarget();
localtarget.setCommunity(new OctetString("public"));
localtarget.setAddress(new UdpAddress(managerIpAdd + "/162"));
localtarget.setVersion(SnmpConstants.version2c);
localtarget.setRetries(3);
localtarget.setTimeout(2000);
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, targetOID));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapAddress, new IpAddress(ApplicationUtil.getMachineIpAddress())));
// variable binding for Enterprise Specific objects, Severity (should be defined in MIB file)
pdu.add(new VariableBinding(targetOID, new OctetString(message)));
pdu.setType(PDU.TRAP);
snmp.send(pdu, localtarget);
snmp.close();
Thanks,

There is no standard way to specify the severity for a trap. Most agents that send "alarm" traps will define a proprietary MIB that includes a varbind for severity.

Related

Is there a way to programmatically delete an ActiveMQ Job Schedule?

I'm trying to delete a scheduled job in ActiveMQ, and so far no luck.
Schedule is created among with the message using either NMS API or Amqpnetlite (except openwire lib as that one is not updated and can't be used on netstandard/netcore)
Sample code used to create the schedule with NMS, same thing done with AMQP lib:
var factory = new Apache.NMS.ActiveMQ.ConnectionFactory(brokerUri);
IConnection connection = factory.CreateConnection(user, password);
connection.Start();
ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
IDestination dest = session.GetQueue(destination);
IMessageProducer producer = session.CreateProducer(dest);
producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
var msg = session.CreateTextMessage("Sample text message");
msg.Properties.SetString("AMQ_SCHEDULED_CRON", "* * * * *");
producer.Send(msg);
connection.Close();
This part produces the following result in browser console, and that's what I am willing to delete:
I've read this other question and answer, also active mq system constants but no way the schedule gets deleted. Also tried to browse over the documentation but can't find anything useful so far
Does ActiveMQ even supports a programmative way of managing schedules? An AMQP solution would be great, but NMS is also appreciated.
You can manage scheduled jobs in ActiveMQ over STOMP, AMQP or simply from a JMS client. I've written about this before showing how to do it using the ActiveMQ Java client but the principle is the same. You can send messages with specific headers set that will operate on the scheduled messages.
To browse the collection of scheduled message you'd do something like the following:
Connection connection = createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the Browse Destination and the Reply To location
Destination requestBrowse = session.createTopic(ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION);
Destination browseDest = session.createTemporaryQueue();
// Create the "Browser"
MessageConsumer browser = session.createConsumer(browseDest);
connection.start();
// Send the browse request
MessageProducer producer = session.createProducer(requestBrowse);
Message request = session.createMessage();
request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
ScheduledMessage.AMQ_SCHEDULER_ACTION_BROWSE);
request.setJMSReplyTo(browseDest);
producer.send(request);
Message scheduled = browser.receive(5000);
while (scheduled != null) {
// Do something clever...
}
The returned messages contain the information on the actual scheduled message jobs that have been previously added. Obtaining the job Id allows you to completely cancel the delivery of said message.
To remove a scheduled message send that was scheduled using the Java client, AMQP client or other procotol client you'd do the following:
Message remove = session.createMessage();
remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVE);
remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID,
scheduled.getStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID));
producer.send(remove);
The full set of message property values that can be used when working with the scheduler are documented here, in AMQP just use the string literal of each as the Application Property value you set with the job Id to remote, or in the NMS client it'd just be a string key message property with the job Id that you want to remove.
There is one caveat though when doing this over AMQP and that would be that you'd need to ensure that the broker is using the JMS transformer ?transport.transformer=jms"see the AMQP documentation for ActiveMQ 5.
Accepted answer is working and correct. Turns out scheduledMessage.NMSMessageId was not holding the scheduler id.
Here's the clean C# source in case one is interested:
var factory = new Apache.NMS.ActiveMQ.ConnectionFactory(brokerUri);
IConnection connection = factory.CreateConnection(userName, password);
var session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
var requestBrowse = session.GetTopic("ActiveMQ.Scheduler.Management");
var queue = session.GetQueue(queueName);
var consumer = session.CreateConsumer(queue);
connection.Start();
var producer = session.CreateProducer(requestBrowse);
var scheduledMessage = consumer.Receive(TimeSpan.FromSeconds(10));
if (scheduledMessage != null)
{
// do check with persistent storage, if schedule is canceled, remove it:
var remove = session.CreateMessage();
// get prop names from : http://activemq.apache.org/maven/apidocs/constant-values.htm
remove.Properties["AMQ_SCHEDULER_ACTION"] = "REMOVE";
remove.Properties["scheduledJobId"] = scheduledMessage.Properties.GetString("scheduledJobId");
producer.Send(remove);
}
producer.Close();
session.Close();
connection.Close();
Flow is like this: Get messages from some queue, in case some condition is met, drop the schedule entirely.

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.

ArgumentNull Exception: Parameter name: ServerConnection

I have implemented WCF service for the database synchronization of Microsoft Sync Framework since the databases are not on the same network.
However when I call Sychronize() method on my SyncOrchestrator I get an error ArgumentNull Exception: Parameter name: ServerConnection.
I am not sure what parameter I have missed in my SyncOrchestrator setup. I cannot find a good help on the internet either. Can you please advise what could be the wrong
Code follows:
SyncOperationStatistics status = null;
//Creating proxy and Local sqlsync Provider to create scope on remote based on Locle table description
SqlSyncProvider localProvider = new SqlSyncProvider(scopeName, new System.Data.SqlClient.SqlConnection(localConnString), null, "sync");
PSHInternetSyncOrchestrator syncOrchestrator = new PSHInternetSyncOrchestrator(localProvider, remoteProvider, syncTable);
//Setting up batch size
localProvider.MemoryDataCacheSize = 4096;
status = syncOrchestrator.Synchronize();

How to read the System.ServiceModel.Message?

I came across this situation.
Main Function:
Message msg = Message.CreateMessage(MessageVersion.Default, "Process");
String xmlData ="<Name>Navin</Name>";
Byte[] ba = Encoding.ASCII.GetBytes(xmlData);
MemoryStream ms = new MemoryStream(ba);
XmlWriter xw = XmlWriter.Create(ms);
msg.WriteBody(xw);
readMessage(msg);
In readMessage(Message msg):
XmlDictionaryReader xdr = msg.GetReaderAtBodyContents();
WHen i do this i am getting this error.
Unhandled Exception: System.InvalidOperationException: This message cannot suppo
rt the operation because it has been written.
How to overcome this.
Waiting for response.
Thanks in advance.
According to MSDN Message.GetReaderAtBodyContents Method, you can't access the message body once it's been read or written - it can only be accessed once. You need to use 'CreateBufferedCopy' to access a message multiple times.
I didn't find any examples in the MSDN documentation, but it looks like you'd need to create a MessageBuffer instance via Message.CreateBufferedCopy, and then you can use the MessageBuffer's CreateMessage method to gain access to the contents of the buffer.
See:
Message.CreateBufferedCopy Method
MessageBuffer Class
MessageBuffer.CreateMessage Method

WCF Named pipe message size problems

I am trying to get working a WCF named pipe communication between two processes on the same computer (on XP), but I am having trouble with "large" messages disappearing. The messages that disappear contain a largish byte array and I have narrowed the failure down to when the array is around 16k in size. Smaller than that and the message gets through. Larger than that and the sender says it went fine but it is never received. I have tried bumping up the buffer sizes on both sender and receiver as per this code for the server:
PipeServer pipeServer = new PipeServer();
ServiceHost serviceHost = new ServiceHost(pipeServer, new Uri[] { new Uri(baseName) });
NetNamedPipeBinding netNamedPipeBinding = new NetNamedPipeBinding();
netNamedPipeBinding.MaxBufferPoolSize = 5000000;
netNamedPipeBinding.MaxBufferSize = 500000;
netNamedPipeBinding.MaxReceivedMessageSize = 500000;
serviceHost.AddServiceEndpoint(typeof(ISSNPipeServer), netNamedPipeBinding, pipeName);
and this code for the client:
_callbacks = new PipeClientCallbacks();
NetNamedPipeBinding netNamedPipeBinding = new NetNamedPipeBinding();
netNamedPipeBinding.MaxBufferPoolSize = 5000000;
netNamedPipeBinding.MaxBufferSize = 500000;
netNamedPipeBinding.MaxReceivedMessageSize = 500000;
_pipeFactory = new DuplexChannelFactory<ISSNPipeServer>(_callbacks,
netNamedPipeBinding,
new EndpointAddress(_targetPipe));
_pipeProxy = _pipeFactory.CreateChannel();
I am eventually looking to transfer arrays in the 60KB size, but this is my first serious WCF experience and I have no idea even where to really start looking.
You can enable WCF tracing on the server to get more information as to what the failure is. Likely, you still need to increase the reader quotas associated with the binding (NetNamedPipeBinding.ReaderQuotas). Check the MaxArrayLength one in particular.