May i subscribe multiple hosts (and clusters) with one subscriber pattern in Redis? - redis

I am implementing a feature which integrating redis published messages to mongodb that i made the project and working perfect on testing environment.
But I'm concerning about the production environment, that i have 3 master server and they exist 12 slave cluster. if i publish message from them to a channel pattern may i subscribe all messages in one place

Yes it is possible by stackexchange redis settings, i had done my general structure like below
public class RedisSubscriber: IRedisSubscriber
{
private readonly RedisConfigurationManager _config;
private readonly IMongoDbRepository _mongoDbRepository;
private readonly ILogger<RedisSubscriber> _logger;
private readonly IConnectionMultiplexer _connectionMultiplexer;
public RedisSubscriber(IServiceProvider serviceLocator, ILogger<RedisSubscriber> logger, IConnectionMultiplexer conn)
{
_config = (RedisConfigurationManager)serviceLocator.GetService(typeof(RedisConfigurationManager));
_mongoDbRepository = (IMongoDbRepository)serviceLocator.GetService(typeof(IMongoDbRepository));
_connectionMultiplexer = conn;
_logger = logger;
}
public void SubScribeChannel()
{
_logger.LogInformation("!SubScribeChannel started!!");
string channelName = _config.ActiveChannelName;
var pubSub = _connectionMultiplexer.GetSubscriber();
try
{
pubSub.Subscribe(channelName, async (channel, message) => await MessageActionAsync(message, channel));
}
catch(Exception ex)
{
_logger.LogInformation(String.Format("!error: {0}", ex.Message));
}
Debug.WriteLine("EOF");
}
private async Task MessageActionAsync(RedisValue message, string channel)
{
try
{
Transformer t = new Transformer(_logger);
_logger.LogInformation(String.Format("!SubScribeChannel message received on message!! channel: {0}, message: {1}", channel, message));
string transformedMessage = Transformer.TransformJsonStringData2Message(message);
List<Document> documents = Transformer.Deserialize<List<Document>>(transformedMessage);
await MergeToMongoDb(documents, channel);
_logger.LogInformation("!Merged");
}
catch (Exception ex)
{
_logger.LogInformation(String.Format("!error: {0}", ex.Message));
}
}
private async Task MergeToMongoDb(IList<Document> documents, string channelName)
{
try
{
foreach (Document doc in documents)
{
TurSysPartitionedDocument td = JsonConvert.DeserializeObject<TurSysPartitionedDocument>(JsonConvert.SerializeObject(doc));
td.DepartureDate = td.DepartureDate.ToLocalTime();
td.PartitionKey = channelName;
TurSysPartitionedDocument isExist = await _mongoDbRepository.GetOneAsync<TurSysPartitionedDocument>(k =>
k.ProductCode == td.ProductCode &&
k.ProviderCode == td.ProviderCode &&
k.CabinClassName == td.CabinClassName &&
k.OriginAirport == td.OriginAirport &&
k.DestinationAirport == td.DestinationAirport &&
k.Adult >= td.Adult &&
k.DepartureDate == td.DepartureDate,
td.PartitionKey);
if (isExist != null)
{
//_logger.LogInformation(String.Format("!isExist departure date: {0}", isExist.DepartureDate));
isExist.SearchCount++;
await _mongoDbRepository.UpdateOneAsync(isExist, k => k.Adult, td.Adult);
await _mongoDbRepository.UpdateOneAsync(isExist, k => k.SearchCount, isExist.SearchCount);
}
else
{
//_logger.LogInformation(String.Format("!last ToLocalTime td departure date: {0}", td.DepartureDate));
td.SearchCount = 1;
await _mongoDbRepository.AddOneAsync(td);
//_logger.LogInformation(String.Format("!last ToLocalTime result td departure date: {0}", td.DepartureDate));
}
}
}
catch(Exception ex)
{
_logger.LogInformation(String.Format("!error: {0}", ex.Message));
}
}
}

Related

Azure Redis Cache - add_ServerMaintenanceEvent from StackExchange.Redis ConnectionMultiplexer pool does not have an implementation

I was creating a library in .net core 6 for using with other projects.I am trying to add cache pooling using StackExchange.Redis.MultiplexerPool in that library.
public class Library1 : ILibrary1
{
public Library1(IConfiguration configuration, string azureOptionsKey)
{
configuration.Bind(azureOptionsKey, azureOptions);
//redis client
_redisClient = new LibraryRedisCacheService();
}
}
below is my CacheService
public class LibraryRedisCacheService
{
private readonly IConnectionMultiplexerPool _connectionMultiplexerPool;
private readonly int[] _connectionsErrorCount;
public LibraryRedisCacheService()
{
var configureOptions = ConfigurationOptions.Parse("Cache connection string");
configureOptions.AllowAdmin = true;
configureOptions.AsyncTimeout = 10000;
_connectionMultiplexerPool = ConnectionMultiplexerPoolFactory.Create(
poolSize: 10,
configurationOptions: configureOptions,
connectionSelectionStrategy: ConnectionSelectionStrategy.RoundRobin);
_connectionsErrorCount = new int[_connectionMultiplexerPool.PoolSize];
}
public async Task<TResult> QueryRedisAsync<TResult>(Func<IDatabase, Task<TResult>> op)
{
var connection = await _connectionMultiplexerPool.GetAsync();
try
{
return await op(connection.Connection.GetDatabase());
}
catch (RedisConnectionException)
{
_connectionsErrorCount[connection.ConnectionIndex]++;
if (_connectionsErrorCount[connection.ConnectionIndex] < 3)
{
throw;
}
await connection.ReconnectAsync();
return await op(connection.Connection.GetDatabase());
}
}
public async Task SetCacheAsync<T>(string key, T value, TimeSpan? expiry = null, int retryCount = 0)
{
try
{
await QueryRedisAsync(async db => await db.StringSetAsync(key, JsonConvert.SerializeObject(value), expiry ?? TimeSpan.FromHours(12)));
}
catch (Exception)
{
if (retryCount < 3)
{
await Task.Delay(3000);
await SetCacheAsync(key, value, expiry, retryCount + 1);
}
}
}
public async Task<T?> GetCacheAsync<T>(string key, int retryCount = 0)
{
try
{
var value = await QueryRedisAsync(async db => await db.StringGetAsync(key));
return !value.HasValue ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
catch (Exception)
{
if (retryCount < 3)
{
await Task.Delay(3000);
await GetCacheAsync<T>(key, retryCount + 1);
}
}
return default;
}
public async Task<TResult> RetryCachConnectAsync<TResult>(Func<IConnectionMultiplexer, TResult> op)
{
var connection = await _connectionMultiplexerPool.GetAsync();
try
{
return op(connection.Connection);
}
catch (RedisConnectionException)
{
_connectionsErrorCount[connection.ConnectionIndex]++;
if (_connectionsErrorCount[connection.ConnectionIndex] < 3)
{
throw;
}
await connection.ReconnectAsync();
return op(connection.Connection);
}
}
}
}
and in my project startup i am adding this library like this
services.AddSingleton<ILibrary1, Library1>(
_ => new Library1(Configuration, "KeyvaultReference"));
after that i am getting run time exception in my application like below
Unable to load one or more of the requested types.
Method 'add_ServerMaintenanceEvent' in type 'StackExchange.Redis.MultiplexerPool.Multiplexers.InternalDisposableConnectionMultiplexer' from assembly 'StackExchange.Redis.MultiplexerPool, Version=1.0.2.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
How to add this method implementation, Or I am doing something wrong in the library implementation

Using MQTT ManagedClient with ASP NET API, how to?

I'm currently working on a project that has to rely heavily on MQTT - one of the parts that needs to utilize MQTT is a ASP Net API, but I'm having difficulties receiving messages.
Here is my MQTTHandler:
public MQTTHandler()
{
_mqttUrl = Properties.Resources.mqttURL ?? "";
_mqttPort = Properties.Resources.mqttPort ?? "";
_mqttUsername = Properties.Resources.mqttUsername ?? "";
_mqttPassword = Properties.Resources.mqttUsername ?? "";
_mqttFactory = new MqttFactory();
_tls = false;
}
public async Task<IManagedMqttClient> ConnectClientAsync()
{
var clientID = Guid.NewGuid().ToString();
var messageBuilder = new MqttClientOptionsBuilder()
.WithClientId(clientID)
.WithCredentials(_mqttUsername, _mqttPassword)
.WithTcpServer(_mqttUrl, Convert.ToInt32(_mqttPort));
var options = _tls ? messageBuilder.WithTls().Build() : messageBuilder.Build();
var managedOptions = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(options)
.Build();
_mqttClient = new MqttFactory().CreateManagedMqttClient();
await _mqttClient.StartAsync(managedOptions);
Console.WriteLine("Klient startet");
return _mqttClient;
}
public async Task PublishAsync(string topic, string payload, bool retainFlag = true, int qos = 1)
{
await _mqttClient.EnqueueAsync(new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel((MQTTnet.Protocol.MqttQualityOfServiceLevel)qos)
.WithRetainFlag(retainFlag)
.Build());
Console.WriteLine("Besked published");
}
public async Task SubscribeAsync(string topic, int qos = 1)
{
var topicFilters = new List<MQTTnet.Packets.MqttTopicFilter>
{
new MqttTopicFilterBuilder()
.WithTopic(topic)
.WithQualityOfServiceLevel((MQTTnet.Protocol.MqttQualityOfServiceLevel)(qos))
.Build()
};
await _mqttClient.SubscribeAsync(topicFilters);
}
public Status GetSystemStatus(MqttApplicationMessageReceivedEventArgs e)
{
try
{
var json = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
var status = JsonSerializer.Deserialize<Status>(json);
if (status != null)
{
return status;
}
else
{
return null;
}
}
catch (Exception)
{
throw;
}
}
The above has been tested with a console app and works as it should.
The reason I need MQTT in the APi is that a POST method has to act on the value of a topic;
In particular I need to check a systems status before allowing the post;
[HttpPost]
public async Task<ActionResult<Order>> PostOrder(Order order)
{
if (_lastStatus != null)
{
if (_lastStatus.OpStatus)
{
return StatusCode(400, "System is busy!");
}
else
{
var response = await _orderManager.AddOrder(order);
return StatusCode(response.StatusCode, response.Message);
}
}
return StatusCode(400, "Something went wrong");
}
So I will need to set up a subscriber for this controller, and set the value of _lastStatus on received messages:
private readonly MQTTHandler _mqttHandler;
private IManagedMqttClient _mqttClient;
private Status _lastStatus;
public OrdersController(OrderManager orderManager)
{
_orderManager = orderManager;
_mqttHandler = new MQTTHandler();
_mqttClient = _mqttHandler.ConnectClientAsync().Result;
_mqttHandler.SubscribeAsync("JSON/Status");
_mqttClient.ApplicationMessageReceivedAsync += e =>
{
_lastStatus = _mqttHandler.GetSystemStatus(e);
return Task.CompletedTask;
};
}
However, it's behaving a little odd and I'm not experienced enough to know why.
The first time I make a POST request, _lastStatus is null - every following POST request seem to have the last retained message.
I'm guessing that I am struggling due to stuff being asynchronous, but not sure, and every attempt I've attempted to make it synchronous have failed.
Anyone have a clue about what I'm doing wrong?

onMessageReceived method is not called, when app is not open

I have implemented FCM in my app, and I need to pass some data from Firebase service to Activity. I have implemented the following code, which works fine, when the app is in foreground(open). When the app is killed or in background, onMessageReceived method is not called, and the launcher activity is loaded while click on the push notification. Also, when the app is open, push message is blank. Kindly advise what I have done wrong. FYI, from backend, they are sending data payload, not notification.
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
public FirebaseMessagingService() {
}
private static final String TAG = com.google.firebase.messaging.FirebaseMessagingService.class.getSimpleName();
public static String CHAT_PUSH_NOTIFICATION_INTENT = "chatPushNotificationIntent";
private PreferencesManager preferencesManager;
#Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.e("push token >>", s);
String reliableIdentifier = FirebaseInstanceId.getInstance().getId();
FCMPreferencesManager pref = FCMPreferencesManager.getInstance(this);
if (pref != null) {
pref.setStringValue(FCMPreferencesManager.FCM_KEY_VALUE, s);
pref.setStringValue(FCMPreferencesManager.DEVICE_ID, reliableIdentifier);
}
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
try {
preferencesManager = PreferencesManager.getInstance(this);
int userId = preferencesManager.getIntValue(PreferencesManager.LOGIN_USER_ID);
Log.e("onMessage received >>", "inside service");
Log.e("userId >>", userId + "");
if (userId > 0) {
Log.e("remote message >>", remoteMessage.getNotification().getBody() + "");
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void classApprovedNotification(int jobId, String stage) {
if (!Utils.isAppIsInBackground(getApplicationContext())) {
Intent pushNotification = new Intent(Constants.PUSH_NOTIFICATION_INTENT);
pushNotification.putExtra("jobId", jobId);
pushNotification.putExtra("stage", stage);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
}
}
private void handleDataMessage(JSONObject json) {
try {
Log.e("total json >> ", json.toString());
JSONObject data = json.optJSONObject("data");
Log.e("data >> ", data.toString());
String title = data.optString("title");
String message = data.optString("message");
Log.e("title >>", title);
Log.e("message >>", message);
localNotification(data, title, message, false);
} catch (Exception e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
}
}
private void localNotification(JSONObject data, String title, String message, boolean isSendBird) {
int type = 0, groupId = 0, classId = 0, jobId = 0;
String stage = "";
int notificationId = (int) System.currentTimeMillis();
int userId = preferencesManager.getIntValue(PreferencesManager.LOGIN_USER_ID);
String className = "", fileName = "";
if (data != null) {
jobId = data.optInt("job_id");
stage = data.optString("stage", "");
}
Log.e("jobId in service >>", jobId + "");
Log.e("stage in service >>", stage);
Intent intent = new Intent(FirebaseMessagingService.this, VendorHomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("jobId", jobId);
intent.putExtra("stage","stage");
int requestID = (int) System.currentTimeMillis();
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
requestID,
intent,
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
);
String channelId = "";
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.fyxt_logo)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
/* NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(this);*/
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(notificationId /* ID of notification */, notificationBuilder.build());
try {
PowerManager.WakeLock screenLock = null;
if ((getSystemService(POWER_SERVICE)) != null) {
screenLock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "OOTUSER:WAKE");
screenLock.acquire(10 * 60 * 1000L /*10 minutes*/);
screenLock.release();
}
} catch (Exception e) {
e.printStackTrace();
}
classApprovedNotification(jobId, stage);
}
}
In my Activity, I have the following code.
private BroadcastReceiver notificationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
jobIdFromNotification = intent.getIntExtra("jobId", 0);
stageFromNotification = intent.getStringExtra("stage");
Log.e("jobIdFromNotification >>", jobIdFromNotification + "");
Log.e("stageFromNotification >>", stageFromNotification);
prefManager.setIntValue(PreferencesManager.JOB_ID_IN_PREF, jobIdFromNotification);
prefManager.setStringValue(PreferencesManager.JOB_STAGE_IN_PREF, stageFromNotification);
classApprovedViewUpdate();
}
};
private void classApprovedViewUpdate() {
if (jobIdFromNotification > 0) {
fragmentInteractionCallback = (BaseFragment.FragmentInteractionCallback) this;
Log.e("inside push receiver update ", "sfs");
if (stageFromNotification.trim().equalsIgnoreCase(Constants.STAGE_TICKET_APPROVAL)) {
sendActionToActivity(ACTION_CREATE_MAINTENANCE_REQUEST, currentTab, true, fragmentInteractionCallback);
}
}
}
Edit:
data payload:
{
"data": {
"type": 0,
"job_id": 123,
"stage": "STAGE_TICKET_APPROVAL",
}

org.apache.fop.fo.flow.ExternalGraphic catches and logs ImageException I want to handle myself

I am transforming an Image into pdf for test purposes.
To ensure that the Image is compatible with the printing process later on, I'm running a quick test print during the upload.
I'm creating a simple Test-PDF with a transformer. When I try to print an image with an incompatible format, the ImageManager of the transformer throws an ImageException, starting in the preloadImage() function:
public ImageInfo preloadImage(String uri, Source src)
throws ImageException, IOException {
Iterator iter = registry.getPreloaderIterator();
while (iter.hasNext()) {
ImagePreloader preloader = (ImagePreloader)iter.next();
ImageInfo info = preloader.preloadImage(uri, src, imageContext);
if (info != null) {
return info;
}
}
throw new ImageException("The file format is not supported. No ImagePreloader found for "
+ uri);
}
throwing it to:
public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager)
throws ImageException, IOException {
//Fetch unique version of the URI and use it for synchronization so we have some sort of
//"row-level" locking instead of "table-level" locking (to use a database analogy).
//The fine locking strategy is necessary since preloading an image is a potentially long
//operation.
if (isInvalidURI(uri)) {
throw new FileNotFoundException("Image not found: " + uri);
}
String lockURI = uri.intern();
synchronized (lockURI) {
ImageInfo info = getImageInfo(uri);
if (info == null) {
try {
Source src = session.needSource(uri);
if (src == null) {
registerInvalidURI(uri);
throw new FileNotFoundException("Image not found: " + uri);
}
info = manager.preloadImage(uri, src);
session.returnSource(uri, src);
} catch (IOException ioe) {
registerInvalidURI(uri);
throw ioe;
} catch (ImageException e) {
registerInvalidURI(uri);
throw e;
}
putImageInfo(info);
}
return info;
}
}
throwing it to :
public ImageInfo getImageInfo(String uri, ImageSessionContext session)
throws ImageException, IOException {
if (getCache() != null) {
return getCache().needImageInfo(uri, session, this);
} else {
return preloadImage(uri, session);
}
}
Finally it gets caught and logged in the ExternalGraphic.class:
/** {#inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
src = pList.get(PR_SRC).getString();
//Additional processing: obtain the image's intrinsic size and baseline information
url = URISpecification.getURL(src);
FOUserAgent userAgent = getUserAgent();
ImageManager manager = userAgent.getFactory().getImageManager();
ImageInfo info = null;
try {
info = manager.getImageInfo(url, userAgent.getImageSessionContext());
} catch (ImageException e) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageError(this, url, e, getLocator());
} catch (FileNotFoundException fnfe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageNotFound(this, url, fnfe, getLocator());
} catch (IOException ioe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageIOError(this, url, ioe, getLocator());
}
if (info != null) {
this.intrinsicWidth = info.getSize().getWidthMpt();
this.intrinsicHeight = info.getSize().getHeightMpt();
int baseline = info.getSize().getBaselinePositionFromBottom();
if (baseline != 0) {
this.intrinsicAlignmentAdjust
= FixedLength.getInstance(-baseline);
}
}
}
That way it isn't accessible for me in my code that uses the transformer.
I tried to use a custom ErrorListener, but the transformer only registers fatalErrors to the ErrorListener.
Is there any way to access the Exception and handle it myself without changing the code of the library?
It was easier than I thought. Before I call the transformation I register a costum EventListener to the User Agent of the Fop I'm using. This Listener just stores the Information what kind of Event was triggered, so I can throw an Exception if it's an ImageError.
My Listener:
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
public class ImageErrorListener implements EventListener
{
private String eventKey = "";
private boolean imageError = false;
#Override
public void processEvent(Event event)
{
eventKey = event.getEventKey();
if(eventKey.equals("imageError")) {
imageError = true;
}
}
public String getEventKey()
{
return eventKey;
}
public void setEventKey(String eventKey)
{
this.eventKey = eventKey;
}
public boolean isImageError()
{
return imageError;
}
public void setImageError(boolean imageError)
{
this.imageError = imageError;
}
}
Use of the Listener:
// Start XSLT transformation and FOP processing
ImageErrorListener imageListener = new ImageErrorListener();
fop.getUserAgent().getEventBroadcaster().addEventListener(imageListener);
if (res != null)
{
transformer.transform(xmlDomStreamSource, res);
}
if(imageListener.isImageError()) {
throw new ImageException("");
}
fop is of the type Fop ,xmlDomStreamSource ist the xml-Source I want to transform and res is my SAXResult.

how to access the activemq statistics plugin in .net

I am trying to access the activemq statistics information http://activemq.apache.org/statisticsplugin.html in c#
This is what i have so far. I am not able to get a reply from the consumer. I can the count increase in monitor website for the queue.
public class Statistics
{
private readonly string queueName = string.Empty;
private readonly string queueToMonitor = string.Empty;
private readonly IConnectionFactory connectionFactory;
private readonly IConnection connection;
private readonly ISession session;
private readonly IMessageProducer producer;
private readonly ActiveMQQueue queue;
public Statistics(string qName, string brokerUri, string queueToMon)
{
this.queueName = qName;
this.queueToMonitor = "ActiveMQ.Statistics.Destination." + queueToMon;
this.connectionFactory = new ConnectionFactory(brokerUri);
this.connection = connectionFactory.CreateConnection();
this.connection.Start();
this.session = connection.CreateSession();
queue = new ActiveMQQueue(qName);
producer = session.CreateProducer(queue);
}
public void GetStats()
{
try
{
var statusQueue = session.CreateTemporaryQueue();
var consumer = session.CreateConsumer(statusQueue);
ActiveMQQueue query = new ActiveMQQueue(queueToMonitor);
var msg = session.CreateMessage();
msg.NMSReplyTo = statusQueue;
producer.Send(queue, msg);
var reply = (ActiveMQMapMessage)consumer.Receive();
if (reply != null)
{
var test = reply.Content.ToString();
}
}
catch (Exception e)
{
var t = e.Message + " " + e.StackTrace;
}
}
}
You are sending the message to the wrong queue. You need to send the message to the ActiveMQ.Statistics.Destination.QueueToMonitor destination. I re-wrote your GetStats() function to show that it works. The critical change is which destination the producer sends the message to.
public void GetStats()
{
try
{
IDestination statusQueue = session.CreateTemporaryQueue();
IMessageConsumer consumer = session.CreateConsumer(statusQueue);
IDestination query = session.GetQueue(queueToMonitor);
IMessage msg = session.CreateMessage();
IMessageProducer producer = session.CreateProducer(query);
msg.NMSReplyTo = statusQueue;
producer.Send(msg);
IMapMessage reply = (IMapMessage) consumer.Receive();
if(reply != null)
{
IPrimitiveMap statsMap = reply.Body;
foreach(string statKey in statsMap.Keys)
{
Console.WriteLine("{0} = {1}", statKey, statsMap[statKey]);
}
}
}
catch(Exception e)
{
var t = e.Message + " " + e.StackTrace;
}
}