How to enable multiple consumers for Apache.NMS.AMQP clients? - amqp

Would like to know how to enable multiple consumers for Apache.NMS.AMQP client. Have tried with multiple sessions for same queue with different consumer - but the listener is only getting called for one consumer per queue.
Below is the sample code. Ignore the connection per queue as I thought that might be the cause, but doesn't work. Given consumer one name -ConsumerName to identify consumer being called.
var queueClientLogger = loggerFactory.CreateLogger<QueueClient>();
var queueClient1 = new QueueClient(queueClientLogger, "Q/test1");
await queueClient1.InitializeAsync();
var queueClient2 = new QueueClient(queueClientLogger, "Q/test1");
await queueClient2.InitializeAsync();
var queueClient3 = new QueueClient(queueClientLogger, "Q/test2");
await queueClient3.InitializeAsync();
-----------------------------------------------
internal class QueueClient : IDisposable
{
private readonly ILogger<QueueClient> logger;
private IMessageConsumer consumer;
private bool disposedValue;
#region constructor
public QueueClient(ILogger<QueueClient> logger, string queueName)
{
this.logger = logger;
QueueName = queueName;
ConsumerName = $"{QueueName}-{Guid.NewGuid()}";
}
#endregion
#region Properties
internal string? QueueName { get; private set; }
internal string ConsumerName { get; private set; }
internal Apache.NMS.ISession Session { get; private set; }
internal Apache.NMS.IConnection Connection { get; private set; }
#endregion
#region Methods
internal async Task InitializeAsync()
{
string brokerUri = $"amqp://localhost:5672"; // Default port
NMSConnectionFactory factory = new NMSConnectionFactory(brokerUri);
Connection = await factory.CreateConnectionAsync();
await Connection.StartAsync();
Session = await Connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge);
Apache.NMS.IDestination dest = await Session.GetQueueAsync(QueueName);
consumer = await Session.CreateConsumerAsync(dest);
consumer.Listener += Consumer_Listener;
}
private void Consumer_Listener(Apache.NMS.IMessage message)
{
logger.LogInformation($"{ConsumerName}: Message from queue - {QueueName}");
Thread.Sleep(1000);
string content = string.Empty;
if (message is ITextMessage)
{
ITextMessage? txtMsg = message as ITextMessage;
content = txtMsg?.Text ?? "";
}
else if (message is IBytesMessage)
{
IBytesMessage? bytesMsg = message as IBytesMessage;
if (bytesMsg == null)
{
content = $"NULL message received";
}
else
{
content = Encoding.UTF8.GetString(bytesMsg.Content);
}
}
else
{
content = "Unexpected message type: " + message.GetType().Name;
}
logger.LogInformation($"{content}");
}
//Ignore IDosposable code
}

Related

How to get Auth code in api call post on ruby on rails app from wix api website?

I'm trying to developing a dashboard website for a wix application and I need to connect the website to the wix application.
I have a problem with an api (post) call. I have to fill in several information including the auth code that I don't know where to find.
Here is an image to illustrate the process :
I don't really know what is the wix app marker install, but for the authorization request I did this
$url_oauth = "https://www.wix.com/oauth/access"
response = RestClient::Request.execute(url: $url_oauth, method: :post, body:{grant_type: "authorization_code",client_id:"APP_ID", client_secret:"Secret_key", code:"{Can not find what is this value}"})
#data = JSON.parse(response)
render json: response
Here is the documentation :
Could you help how and where to find this Auth code ?
You will need to make an intermediate web service that will accept webhooks from WIX.
I'll show you the example of C# ASP.Net Core.
STEP 1:
We are waiting for a token from WIX and if it is received, we make a redirect.
private const string AppID = "";
private const string ApiKey = "";
private const string UrlAccess = "https://www.wix.com/oauth/access";
HttpGet("WaitToken")]
public ActionResult GetToken([FromQuery] string token = "")
{
try
{
if (string.IsNullOrWhiteSpace(token))
{
string message = "Your message";
ModelState.AddModelError("TokenNotCorrect", message);
return BadRequest(ModelState);
}
string paramUrl = #"https://your web service/OAuth/api/check/WaitAuthCode";
string urlRedirect = $#"https://www.wix.com/installer/install?token={token}&appId={AppID}&redirectUrl={paramUrl}";
return RedirectPermanent(urlRedirect);
}
catch (WebException ex)
{
ModelState.AddModelError("GetTokenException", ex.Message);
return BadRequest(ModelState);
}
}
STEP 2:
We are waiting for the Auth Code to be received, provided that the user has confirmed the installation of the application.
[HttpGet("WaitAuthCode")]
public async Task<ActionResult> GetAuthCodeAsync([FromQuery] string code = "", string state = "", string instanceId = "")
{
try
{
if (string.IsNullOrWhiteSpace(code))
{
string message = "your message";
ModelState.AddModelError("AuthCodeNotCorrect", message);
return BadRequest(ModelState);
}
var token = new Token(code);
if (!GetAccessToken(ref token))
return BadRequest("your message RefreshToken");
var tokenBase = new TokenBase
{
AppID = instanceId,
Token = token.RefreshToken
};
db.Tokens.Add(tokenBase);
if(await db.SaveChangesAsync() == 0)
return BadRequest("your message");
string urlRedirect = $"https://www.wix.com/installer/token-received?access_token={token.AccessToken}";
return RedirectPermanent(urlRedirect);
}
catch (WebException ex)
{
ModelState.AddModelError("GetAuthCodeException", ex.Message);
return BadRequest(ModelState);
}
}
The AuthCode is valid for 10 minutes, we send a request to receive a Refresh Token. This token must be kept at home, as it will be required in the future to obtain an Access Token.
private bool GetAccessToken(ref Token token)
{
try
{
string json = JsonConvert.SerializeObject(token, Formatting.Indented);
var client = new RestClient(UrlAccess);
var request = new RestRequest();
request.Method = Method.POST;
request.AddHeader("Content-Type", "application/json");
request.AddParameter(string.Empty, json, "application/json", ParameterType.RequestBody);
var response = client.Post(request);
if (response == null)
return false;
token = JsonConvert.DeserializeObject<Token>(response.Content);
if (string.IsNullOrWhiteSpace(token.RefreshToken))
return false;
return !string.IsNullOrWhiteSpace(token.AccessToken);
}
catch (Exception ex)
{
return false;
}
}
Getting an Access Token from a client application:
[HttpGet("WaitAccessToken")]
public async Task<ActionResult<string>> GetAccessToken([FromQuery] string instance = "", string apiKey = "")
{
string message;
var tokenBase = await db.Tokens.FirstOrDefaultAsync(x => x.AppID == instance);
if (tokenBase == null)
{
message = "Your message";
ModelState.AddModelError("AppIdNotFound", message);
return NotFound(ModelState);
}
var token = new Token
{
GrantType = "refresh_token",
RefreshToken = tokenBase.Token
};
if (!GetAccessToken(ref token))
{
message = $"Your message";
ModelState.AddModelError("NotCorrectAccessToken", message);
return BadRequest(ModelState);
}
return new ObjectResult(token.AccessToken);
}
Model Token:
public class Token
{
public Token() { }
public Token(string code) { Code = code; }
[JsonProperty("grant_type")]
public string GrantType { get; set; } = "authorization_code";
[JsonProperty("client_id")]
public string ClientID { get; set; } = "";
[JsonProperty("client_secret")]
public string ClientSecret { get; set; } = "";
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("refresh_token", NullValueHandling = NullValueHandling.Ignore)]
public string RefreshToken { get; set; }
[JsonProperty("access_token", NullValueHandling = NullValueHandling.Ignore)]
public string AccessToken { get; set; }
}
Model Instance:
public class Instance
{
[JsonProperty("instanceId")]
public string InstanceId { get; set; }
[JsonProperty("appDefId")]
public string AppDefId { get; set; }
[JsonProperty("signDate")]
public DateTime SignDate { get; set; }
[JsonProperty("uid")]
public string Uid { get; set; }
[JsonProperty("permissions")]
public string Permissions { get; set; }
[JsonProperty("demoMode")]
public bool DemoMode { get; set; }
[JsonProperty("siteOwnerId")]
public string SiteOwnerId { get; set; }
[JsonProperty("siteMemberId")]
public string SiteMemberId { get; set; }
[JsonProperty("expirationDate")]
public DateTime ExpirationDate { get; set; }
[JsonProperty("loginAccountId")]
public string LoginAccountId { get; set; }
}
Don't forget that to get an Access Token, you will need the application ID on the site where it is installed.
[HttpGet("WixInfo")]
public ActionResult GetWixInfo([FromQuery] string instance = "")
{
try
{
string message;
var base64 = instance.Split(".");
if (base64.Length != 2)
{
message = "Your message";
ModelState.AddModelError("InstanceNotCorrect", message);
return BadRequest(ModelState);
}
var base64EncodedBytes = Convert.FromBase64String(base64[1]);
string json = Encoding.Default.GetString(base64EncodedBytes);
var info = JsonConvert.DeserializeObject<Instance>(json);
message = $"Your message.AppID: {info.InstanceId}";
return Ok(message);
}
catch (Exception ex)
{
ModelState.AddModelError("GetWixInfoException", ex.Message);
return BadRequest(ModelState);
}
}
When a WIX application is launched by a user, you can get the ID of the running application.

Xamarin Forms consuming Web Service

I'm new in mobile apps and now developing an app with xamarin forms. There is a website which i developed with django (sqlite3 db), and now i'am trying to consume data from it and display in my mobile app in listvew. Any thoughts how to achieve it. I've tried this but it doesn't work. Should i use rest api?
public class LandingViewModel : INotifyPropertyChanged
{
private List<Dishes> _menuList { set; get; }
public List<Dishes> MenuList
{
get
{
return _menuList;
}
set
{
if(value != _menuList)
{
_menuList = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public LandingViewModel()
{
GetDataAsync();
}
private async void GetDataAsync()
{
HttpClient client = new HttpClient();
var response = await client.GetAsync("https://mysite.ru/project/");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var menu = JsonConvert.DeserializeObject<List<Dishes>>(content);
MenuList = new List<Dishes>(menu);
}
}
models:
public class Dishes
{
public int id { get; set; }
public string description { get; set; }
public string image { get; set; }
public DateTime published { get; set; }
}
my database in django:
operations = [
migrations.CreateModel(
name='Post',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('description', models.TextField(blank=True)),
('image', models.ImageField(blank=True, upload_to='pictures/')),
('published', models.DateTimeField(verbose_name='publishing date')),
],
),
]
i solved the problem
in postgresql database allowed remote connection: in postgresql.conf replaced line listen_addresses = 'localhost' with listen_addresses = '*'
allowed tcp\ip connection on port 5432
in my web api established connection width db
NpgsqlConnection connection;
public string _name;
public string _description;
public string _image;
private readonly MenuContext _context;
public MenuController(MenuContext context)
{
_context = context;
string connectionString = "Server=server; Port=5432; User Id=user;
Password=password; Database=database";
try
{
connection = new NpgsqlConnection(connectionString);
connection.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
NpgsqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM table";
try
{
NpgsqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
_name = reader[1].ToString();
_image = reader[2].ToString();
_description = reader[3].ToString();
_context.Menus.Add(new Menu { name = _name, description =
_description, image = "https://mysite.ru/media/" + _image });
_context.SaveChanges();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
// GET: api/Menu
[HttpGet]
public async Task<ActionResult<IEnumerable<Menu>>> GetMenus()
{
return await _context.Menus.ToListAsync();
}
code in my app:
private async void GetDataAsync()
{
HttpClient httpClient = new HttpClient();
var content = await httpClient.GetStringAsync("https://locahost/api/Menu");
var menu = JsonConvert.DeserializeObject<List<Dishes>>(content);
MenuList = new ObservableCollection<Dishes>(menu);
}
and then displayed it in listview

How to invoke async activity in UIPath

I am trying to execute custom asyncCodeActivity in UIPath. Added the package, passing all data, however UIPath just hangs when it reaches custom activity and does not throw any exceptions/or stops. I tried to create Class Library using CodeActivity and AsyncCodeActivity - my activity should make several APICalls but I get result it just stops when it reaches my custom activity and does not go to the next one. Is there any example how to create async custom activity for UIPath? My class library worked ok when I tried to test it outside of UIpath. Will appreciate any help.
My class library using CodeActivity:
public class AddInvoice : CodeActivity
{
[Category("Input")]
[RequiredArgument]
public InArgument<string> PickupZip { get; set; }
[Category("Output")]
[RequiredArgument]
public OutArgument<String> Output { get; set; }
public async Task<string> ApiTest(CodeActivityContext context)
{
try
{
var origin = await GoogleAPIWrapper.GetAddressByZip(PickupZip.Get(context));
string PickupAddress;
string DeliveryAddress;
var inv = new IList();
if (origin.StatusId >= 0)
{
invoice.PickupCity = origin.Locality;
invoice.PickupState = origin.AdminLevel1;
}
else
{
invoice.PickupCity = null;
invoice.PickupState = null;
}
var tkn = token.Get(context);
var client = new HttpClient();
HttpClientHandler handler = new HttpClientHandler();
client = new HttpClient(handler, false);
client.BaseAddress = new Uri("http://test.test.com/");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + tkn);
StringContent content = new StringContent(JsonConvert.SerializeObject(inv), Encoding.UTF8, "application/json");
var response = await client.PostAsync("api/insert/", content);
var resultContent = response.StatusCode;
Output.Set(context, resultContent.ToString());
}
catch (Exception e)
{
Output.Set(context, e.ToString());
}
return "ok";
}
protected override void Execute(CodeActivityContext context)
{
try
{
string result = ApiTest(context).GetAwaiter().GetResult();
}
catch (Exception e)
{
Output.Set(context, e.ToString());
}
}
public class IList
{
public string PickupState { get; set; }
public string PickupCity { get; set; }
}
}
Classes that derive from CodeActivity are synchronous by default. Since UiPath is based on Windows Workflow, deriving from an AsyncCodeActivity class should work.
You didn't ask explicitly for it, but since you're essentially calling a web service, have a look at the Web Activities package, the HTTP Request in particular. This also comes with JSON deserialization. You can find more information about web service integration here, for example (disclaimer: I am the author).

Prism Event Aggregator Not Working With Async/Await

I am working with prism in a client server app with sql server. I have a loading screen after login screen in which I've fetch the main data in async task for main windows and publish it and subscribe in main windows like customers, Users and etc. But the problem is that subscriber not updated. But If I sign out and sign in again then subscriber updated.
Subscriber not updated first time.
Here is the code of loading screen
public class StartPageViewModel : ViewModelBase
{
private readonly IUnitOfWork _unitOfWork;
private readonly IEventAggregator _eventAggregator;
private readonly IRegionManager _regionManager;
public List<Customer> Customers { get; set; }
private List<Models.User> Users { get; set; }
private List<Invoice> Invoices { get; set; }
public List<Vehicle> Vehicles { get; set; }
public List<Tax> Taxes { get; set; }
private Models.User _user;
private object _userId;
public StartPageViewModel(IRegionManager regionManager, Models.User user,
IUnitOfWork unitOfWork, IEventAggregator eventAggregator)
{
_regionManager = regionManager;
_user = user;
_unitOfWork = unitOfWork;
_eventAggregator = eventAggregator;
Customers = new List<Customer>();
Users = new List<Models.User>();
Invoices = new List<Invoice>();
Vehicles = new List<Vehicle>();
Taxes = new List<Tax>();
}
[OnCommand("InitializeStartPage")]
public async void InitializeStartPage()
{
if (!InternetCs.IsConnectedToInternet())
_regionManager.RequestNavigate(RegionNames.ShellRegion, "InternetConnection");
else
{
await Task.WhenAll(CheckUser(), Preloading()).ContinueWith(async(t, _) =>
{
_eventAggregator.GetEvent<AllCustomersEvent>().Publish(Customers);
_eventAggregator.GetEvent<AllInvoicesEvent>().Publish(Invoices);
_eventAggregator.GetEvent<CurrentUserEvent>().Publish(_user);
_eventAggregator.GetEvent<AllUsersEvent>().Publish(Users);
_eventAggregator.GetEvent<AllVehiclesEvent>().Publish(Vehicles);
_eventAggregator.GetEvent<AllTaxesEvent>().Publish(Taxes);
if (_user != null && _user.Status)
{
_user.LastLogin = DateTime.Now;
_user.LoginStatus = true;
_unitOfWork.UserRepository.Update(_user);
await _unitOfWork.SaveAsync();
_regionManager.RequestNavigate(RegionNames.MainContentRegion, "Home");
_regionManager.RequestNavigate(RegionNames.ShellRegion, "MainWindow");
}
else
{
_regionManager.RequestNavigate(RegionNames.ShellRegion, "LoginWindow");
}
}, null, TaskScheduler.FromCurrentSynchronizationContext());
}
}
private async Task<Models.User> CheckUser()
{
IsoStorage.Instance.TryGetValue("UserId", out _userId);
_user = await _unitOfWork.UserRepository.GetAsync((int)_userId);
return _user;
}
private async Task Preloading()
{
Customers = await _unitOfWork.CustomerRepository.GetAsync();
Invoices = await _unitOfWork.InvoiceRepository.GetAsync();
Users = await _unitOfWork.UserRepository.GetAsync();
Vehicles = await _unitOfWork.VehicleRepository.GetAsync();
Taxes = await _unitOfWork.TaxRepository.GetAsync();
}
}
and here is example subscriber
public AdminProfileViewModel(IEventAggregator eventAggregator)
{
Users = new List<Models.User>();
eventAggregator.GetEvent<AllUsersEvent>().Subscribe(AdminAllUsers, ThreadOption.PublisherThread);
}
private void AdminAllUsers(List<Models.User> obj)
{
Users = obj;
}

Not able to send the Toast Push notification in wp7

I always get the 404 error.Below is my complete code for sending the push notification of type Toast from the wcf service.Anything wrong with the message ?
string channelURI = "http://db3.notify.live.net/throttledthirdparty/01.00/AgAAAAQUZm52OjBEMTRBNDEzQjc4RUFBRTY";
HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(channelURI);
//Indicate that you'll send toast notifications!
sendNotificationRequest.ContentType = "text/xml";
sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
sendNotificationRequest.Method = "POST";
sendNotificationRequest.Headers.Add("X-MessageID",Guid.NewGuid().ToString());
if (string.IsNullOrEmpty(message)) return "empty cannot be sent";
//send it
var msg = string.Format("sample toast message", "Toast Message", "This is from server");
byte[] notificationMessage = Encoding.UTF8.GetBytes(msg);
sendNotificationRequest.ContentLength = notificationMessage.Length;
//Push data to stream
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
//Get reponse for message sending
HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
return notificationStatus;
this code may help you
private static byte[] prepareToastPayload(string text1, string text2)
{
MemoryStream stream = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings() { Indent = true, Encoding = Encoding.UTF8 };
XmlWriter writer = XmlTextWriter.Create(stream, settings);
writer.WriteStartDocument();
writer.WriteStartElement("wp", "Notification", "WPNotification");
writer.WriteStartElement("wp", "Toast", "WPNotification");
writer.WriteStartElement("wp", "Text1", "WPNotification");
writer.WriteValue(text1);
writer.WriteEndElement();
writer.WriteStartElement("wp", "Text2", "WPNotification");
writer.WriteValue(text2);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
byte[] payload = stream.ToArray();
return payload;
}
private void SendMessage(Uri channelUri, byte[] payload, NotificationType notificationType, SendNotificationToMPNSCompleted callback)
{
//Check the length of the payload and reject it if too long
if (payload.Length > MAX_PAYLOAD_LENGTH)
throw new ArgumentOutOfRangeException(
"Payload is too long. Maximum payload size shouldn't exceed " + MAX_PAYLOAD_LENGTH.ToString() + " bytes");
try
{
//Create and initialize the request object
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(channelUri);
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "text/xml; charset=utf-8";
request.ContentLength = payload.Length;
request.Headers[MESSAGE_ID_HEADER] = Guid.NewGuid().ToString();
request.Headers[NOTIFICATION_CLASS_HEADER] = ((int)notificationType).ToString();
if (notificationType == NotificationType.Toast)
request.Headers[WINDOWSPHONE_TARGET_HEADER] = "toast";
else if (notificationType == NotificationType.Token)
request.Headers[WINDOWSPHONE_TARGET_HEADER] = "token";
request.BeginGetRequestStream((ar) =>
{
//Once async call returns get the Stream object
Stream requestStream = request.EndGetRequestStream(ar);
//and start to write the payload to the stream asynchronously
requestStream.BeginWrite(payload, 0, payload.Length, (iar) =>
{
//When the writing is done, close the stream
requestStream.EndWrite(iar);
requestStream.Close();
//and switch to receiving the response from MPNS
request.BeginGetResponse((iarr) =>
{
using (WebResponse response = request.EndGetResponse(iarr))
{
//Notify the caller with the MPNS results
OnNotified(notificationType, (HttpWebResponse)response, callback);
}
},
null);
},
null);
},
null);
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
//Notify client on exception
OnNotified(notificationType, (HttpWebResponse)ex.Response, callback);
}
throw;
}
}
protected void OnNotified(NotificationType notificationType, HttpWebResponse response, SendNotificationToMPNSCompleted callback)
{
CallbackArgs args = new CallbackArgs(notificationType, response);
if (null != callback)
callback(args);
}
public class CallbackArgs
{
public CallbackArgs(NotificationType notificationType, HttpWebResponse response)
{
this.Timestamp = DateTimeOffset.Now;
this.MessageId = response.Headers[NotificationSenderUtility.MESSAGE_ID_HEADER];
this.ChannelUri = response.ResponseUri.ToString();
this.NotificationType = notificationType;
this.StatusCode = response.StatusCode;
this.NotificationStatus = response.Headers[NotificationSenderUtility.NOTIFICATION_STATUS_HEADER];
this.DeviceConnectionStatus = response.Headers[NotificationSenderUtility.DEVICE_CONNECTION_STATUS_HEADER];
this.SubscriptionStatus = response.Headers[NotificationSenderUtility.SUBSCRIPTION_STATUS_HEADER];
}
public DateTimeOffset Timestamp { get; private set; }
public string MessageId { get; private set; }
public string ChannelUri { get; private set; }
public NotificationType NotificationType { get; private set; }
public HttpStatusCode StatusCode { get; private set; }
public string NotificationStatus { get; private set; }
public string DeviceConnectionStatus { get; private set; }
public string SubscriptionStatus { get; private set; }
}
public enum NotificationType
{
Token = 1,
Toast = 2,
Raw = 3
}

Resources