How to initialize a node with data - corda

How can I initialize a node with data?
Let's take the bootcamp's application as an example. There you can issue tokens to other parties.
I want to extend that, and check if the sending node, has the tokens in the first place. Only if he has the tokens, he can give them to another party.
The problem is that the sender doesn't have any tokens. How can I set a specific amount of tokens to the sender? Is there any other method besides self-issuing the tokens first?

There is no built-in way to initialise the node with certain transactions already completed.
Instead, you'd have to write a small client that you'd execute after creating the node to automatically perform the transaction(s) you want. In the case of the Bootcamp CorDapp, you might write something like:
public class Client {
private static final Logger logger = LoggerFactory.getLogger(Client.class);
public static void main(String[] args) throws ExecutionException, InterruptedException {
// Create an RPC connection to the node.
if (args.length != 3) throw new IllegalArgumentException("Usage: Client <node address> <rpc username> <rpc password>");
final NetworkHostAndPort nodeAddress = parse(args[0]);
final String rpcUsername = args[1];
final String rpcPassword = args[2];
final CordaRPCClient client = new CordaRPCClient(nodeAddress);
final CordaRPCOps proxy = client.start(rpcUsername, rpcPassword).getProxy();
// Issue the tokens.
Party owner = proxy.nodeInfo().getLegalIdentities().get(0);
int amount = 100;
proxy.startFlowDynamic(TokenIssueFlow.class, owner, amount).getReturnValue().get();
}
}

Related

Azure Function Integration of Serilog with Application Insights, logs visible in Search but are not appearing in Failures events timeline

I am trying to use Serilog with Application Insights sink for logging purposes. I can see the logs in Search bar in Azure Portal (Application Insights) but same logs are not visible if we view the timeline of events in Failures or Performance Tab. Thanks
Below is the code am using for registering Logger in FunctionStartup, which then gets injected in Function for logging:
var logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("ApplicationName", "testApp")
.Enrich.WithProperty("Environment", "Dev")
.WriteTo.ApplicationInsights(GetTelemetryClient("Instrumentationkey"), TelemetryConverter.Traces)
.CreateLogger();
builder.Services.AddSingleton<ILogger>(logger);
Telementory Client is getting fetched from a helper method:
public static TelemetryClient GetTelemetryClient(string key)
{
var teleConfig = new TelemetryConfiguration { InstrumentationKey = key };
var teleClient = new TelemetryClient(teleConfig);
return teleClient;
}
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingExcludedTypes": "Request",
"samplingSettings": {
"isEnabled": true
}
}
}
}
I got your mean, and pls allow me to sum up my testing result here.
First, the failure blade is not designed for providing a timeline which used to trace the details(what happened before the exception take place), but to show all the exceptions, how often the error happened, how many users be affected, etc, it's more likely stand in a high place to see the whole program.
And to achieve your goal, I think you can use this kql query in the Logs blade or watching it in transaction blade.
union traces, requests,exceptions
| where operation_Id == "178845c426975d4eb96ba5f7b5f376e1"
Basically, we may add many logs in the executing chain, e.g. in the controller, log the input parameter, then log the result of data combining or formatting, log the exception information in catch, so here's my testing code. I can't see any other information in failure blade as you, but in the transaction blade, I can see the timeline.
public class HelloController : Controller
{
public string greet(string name)
{
Log.Verbose("come to greet function");
Log.Debug("serilog_debug_info");
Log.Information("greet name input " + name);
int count = int.Parse(name);
Log.Warning("enter greet name is : {0}", count);
return "hello " + name;
}
}
And we can easily find that, the whole chain shares the same operationId, and via all these logs, we can pinpoint the wrong line code. By the way, if I surround the code with try/catch, exception won't be captured in the failure blade.
==================================
Using Serilog integrate app insights, we need to send serilog to application insights, and we will see lots of Traces in transaction search, so it's better to made the MinimumLevel to be information and higher. The sreenshot below is my log details, and we can also use kql query by operationId to see the whole chain.
You can easily solve this by following the solution provided by Azure Application Insights on their GitHub repo, as per this Github Issue, you can either use the DI to configure TelemetryConfiguration, i.e
services.Configure<TelemetryConfiguration>(
(o) => {
o.InstrumentationKey = "123";
o.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
});
or you can configure it manually like this:
var config = TelemetryConfiguration.CreateDefault();
var client = new TelemetryClient(config);
So in your code, you have to change your GetTelemetryClient from
public static TelemetryClient GetTelemetryClient(string key)
{
var teleConfig = new TelemetryConfiguration { InstrumentationKey = key };
var teleClient = new TelemetryClient(teleConfig);
return teleClient;
}
to this
public static TelemetryClient GetTelemetryClient(string key)
{
var teleConfig = TelemetryConfiguration.CreateDefault();
var teleClient = new TelemetryClient(teleConfig);
return teleClient;
}
In order to use logging using Telemetry Configuration as mentioned in the answer above for Azure Functions, we just need to update the function as in below snippet and on deployment it should fetch Instrumentation key itself
public static TelemetryClient GetTelemetryClient()
{
var teleConfig = TelemetryConfiguration.CreateDefault();
var teleClient = new TelemetryClient(teleConfig);
return teleClient;
}
But to run both locally and after deployment on Azure. We need to add something like this in function Startup and get rid of the Function above.
builder.Services.Configure<TelemetryConfiguration>((o) =>
{
o.InstrumentationKey = "KEY";
o.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
});
builder.Services.AddSingleton<ILogger>(sp =>
{
var logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("ApplicationName", "TEST")
.Enrich.WithProperty("Environment", "DEV")
.WriteTo.ApplicationInsights(
sp.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces).CreateLogger();
return logger;
});
After wards we just need to use typical DI in our classes/azure function to use ILogger
public class Test{
public ILogger _log;
public void Test(ILogger log){
_log=log;
}
}

Getting all possible values for a key in Firebase's Remote Config

I'm trying to build a settings screen in developer mode in which we can test toggling the different values for a remote config setting using Firebase.
I have been able to get all the keys from Firebase's remoteConfig but can only manage to get the value applied for the current client.
Anyone knows if it's possible to check for all possible values from Firebase?
Manage your configs with something like this:
public class RemoteConfig {
public final static String CONFIG_X = "CONFIG_X";
public final static String CONFIG_Y = "CONFIG_Y";
private final static List<String> keys = new ArrayList<String>(0);
static {
values.add(CONFIG_X);
values.add(CONFIG_Y);
}
public static List<String> getKeys(){
return values;
}
}
And Getting All with this;
FirebaseRemoteConfig mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
List<String> remoteConfigs = new ArrayList<>();
for (String key : RemoteConfig.getKeys()) {
String keyValue = String.format("%s: %s", key, mFirebaseRemoteConfig.getString(key));
remoteConfigs.add(keyValue);
}

Can`t get GPS location in map point via microsoft health API

I want get my run activity location data and use the data in my android app,so I use the Microsoft health cloud API. I can login by using my live ID, and I can read my activity data,include MapPoints, but I can`t get any GPS location information. ‘latitude’ and ‘longitude’ value is 0.
I have set the scope of oauth2.0 to "offline_access mshealth.ReadProfile mshealth.ReadActivityHistory mshealth.ReadActivityLocation mshealth.ReadDevices",but it still doesn't work.
I use android async httpclient to get data.
String msToken = "MSTOKEN...";
String profileUrl = ConstValue.getMSHealthURL(ConstValue.MS_API_HEALTH_URL_ACTIVITIES);
RequestParams params = new RequestParams();
params.add("activityIds","2519604437250480855");
params.add("activityIncludes","Details,MapPoints");
AsyncHttpClient client = new AsyncHttpClient(true, 80, 443);
msToken = String.format("bearer %s", msToken);
client.addHeader("Authorization",msToken);
Log.v("mstoken",msToken);
client.get(profileUrl,params, new TextHttpResponseHandler() {
#Override
public void onFailure(int i, Header[] headers, String s, Throwable throwable) {
}
#Override
public void onSuccess(int i, Header[] headers, String s) {
Log.v("activity",s);
}
});
Microsoft said they have been fix the bug,and I tested it,it's ok now.

SignalR - sending parameter to OnConnected?

I have the following JS working:
var chat = $.connection.appHub;
My app has a single hub, AppHub, that handles two types of notifications - Chat and Other. I'm using a single hub because I need access to all connections at all times.
I need to be able to tell OnConnected which type it is via something like the following:
[Authorize]
public class AppHub : Hub {
private readonly static ConnectionMapping<string> _chatConnections =
new ConnectionMapping<string>();
private readonly static ConnectionMapping<string> _navbarConnections =
new ConnectionMapping<string>();
public override Task OnConnected(bool isChat) { // here
string user = Context.User.Identity.Name;
if (isChat){
_chatConnections.Add(user, Context.ConnectionId);
_navbarConnections.Add(user, Context.ConnectionId);
} else{
_navbarConnections.Add(user, Context.ConnectionId);
}
}
}
Usage would ideally be something like this:
var chat = $.connection.appHub(true);
How can I pass that parameter to the hub from javascript?
Update:
SendMessage:
// will have another for OtherMessage
public void SendChatMessage(string who, ChatMessageViewModel message) {
message.HtmlContent = _compiler.Transform(message.HtmlContent);
foreach (var connectionId in _chatConnections.GetConnections(who)) {
Clients.Client(connectionId).addChatMessage(JsonConvert.SerializeObject(message).SanitizeData());
}
}
I would rather add a method to the hub that you call from the client to subscribe to the type. E.g.
public void Subscribe(bool isChat) {
string user = Context.User.Identity.Name;
if (isChat){
_chatConnections.Add(user, Context.ConnectionId);
} else{
_otherConnections.Add(user, Context.ConnectionId);
}
}
You call this method after the hub is connected. It is more flexible in terms that it is then possible to change the notification type without having to reconnect. (Unsubscribe and Subscribe)
Alternative
If you don't want the extra roundtrip/flexibility. You can send QueryString parameters when connecting to the hub. Stackoverflow answer: Signalr persistent connection with query params.
$.connection.hub.qs = 'isChat=true';
And in OnConnected:
var isChat = bool.Parse(Context.QueryString["isChat"]);
Hallvar's answer is useful in most cases. But sometimes you could also use headers to send data to the OnConnected method.
Code example for Asp .Net Framework:
var myParameter = HttpContext.Current.Request.Headers["HeaderName"];
For .NET 5+ you may need Dependency Injection to access HttpContext, as shown here

SignalR Adding/Removing Connections from a dictionary and finding Group values from dictionary

I have Organizations that login to an asp.net website and when each member logs in I add their ConnectionId and OrganizationId to a static ConcurrentDictionary named OrganizationMembers in a SignalR Hub OnConnected override. I do this so I can send data to a page callback function that contains data relative only to that Organization (SignalR Group). The OrganizationId will represent the SignalR Group that I send data to.
Also in the OnConnnected method, I add the OrganizationId and OrganizationId.ToString() to another ConcurrentDictionary that represents unique Organization Ids. I'll explain later why I store the OrganizationId.ToString(). I store unique Organization Ids so that in a background Task that calls a method and sleeps over and over, I can enumerate the unique Organization Ids and only send each Organization (SignalR Group) data relevant to it.
In the OnDisconnected Hub override, after I remove a Connection, I want to check the OrganizationId values in the OrganizationMembers ConcurrentDictionary to see if that was the last Member with that OrganizationId to disconnect and if so remove it from the UniqueOrganizations dictionary. I know the dictionary Values.Contains() is O(n) so I'd really like to avoid this.
This is so when the task enumerates the UniqueOrganizations, there won't be Organizations (SignalR Groups) that I'm attempting to send data to needlessly in the case that say for example 5 Members from the same Organization log in but all later close their browser, I won't be attempting to send that Group data via the SignalR callback.
Admittedly I don't know the internal workings of the SignalR Hub so it may be the case that it won't matter if I try to send data needlessly to Members of Organizations (SignalR Groups) that have all disconnected.
Is this over-thinking the SignalR Hub? Should I not worry about determining if the last Organization (SignalR Group) Member has disconnected from the Hub and not remove the OrganizationId from the UniqueOrganizations?
If this is OK to do, how can I avoid the dictionary Values.Contains() since it's O(n)?
// the key is the ConnectionId of an Organization Member
// the value is the OrganizationId of the Member
protected static ConcurrentDictionary<string, int> _organizationMembers;
public static ConcurrentDictionary<string, int> OrganizationMembers {
get {
if(_organizationMembers == null) {
_organizationMembers = new ConcurrentDictionary<string, int>();
}
return _organizationMembers;
}
}
// the key is the OrganizationId to send the specific data to
// the value is the OrganizationId converted to string
protected static ConcurrentDictionary<int, string> _uniqueOrganizations;
public static ConcurrentDictionary<int, string> UniqueOrganizations {
get {
if(_uniqueOrganizations == null) {
_uniqueOrganizations = new ConcurrentDictionary<int, string>();
}
return _uniqueOrganizations;
}
}
// Hub Code
public override Task OnConnected() {
string connectionId = Context.ConnectionId;
string organizationId = Context.Request.QueryString["organizationId"];
int organizationIdValue = int.Parse(organizationId);
OrganizationMembers.TryAdd(connectionId, organizationIdValue);
UniqueOrganizations.TryAdd(organizationIdValue, organizationId);
// the organizationId represents the SignalR group
Groups.Add(connectionId, organizationId);
return base.OnConnected();
}
public override Task OnDisconnected() {
string organizationId = string.Empty;
int organizationIdValue;
string connectionId = Context.ConnectionId;
OrganizationMembers.TryRemove(connectionId, out organizationIdValue);
// if that happens to be the last Member connection to be removed
// then remove the OrganizationId from the unique OrganizationIds
// so it won't be a wasted enumeration and useless callback
// I want to avoid this O(n) Contains()
if(!OrganizationMembers.Values.Contains(organizationIdValue)) {
UniqueOrganizations.TryRemove(organizationIdValue, out organizationId);
}
Groups.Remove(connectionId, organizationId);
return base.OnDisconnected();
}
// Task code
foreach(int organizationIdValue in DataCache.UniqueOrganizations.Keys) {
// this is why I also stored the OrganizationId as a string so I wouldn't have to
// convert it to a string each time the dictionary is enumerated.
// I can just have the organizationId string ready to use as the SignalR Group.
string organizationId = UniqueOrganizations[organizationIdValue];
try {
string organizationData = GetOrganizationData(organizationIdValue);
_clients.Group(organizationId).sendToOrganizationData(organizationData);
}
catch(Exception ex) {
_clients.Group(organizationId).sendToOrganizationError();
}
}
First of all, SignalR is pretty smart about not wasting resources when sending to groups without any subscriptions, so you should be fine sending to groups without any members as long as it's OK to waste a few cycles doing that.
If you don't have too many organizations you can have a ConcurrentDictionary<int,int> with all your organization ids as your keys and the number of connected members as your value. In OnConnected and OnDisconnected in could use Interlocked.Increment and Interlocked.Decrement respectively to keep track of the currently connected members. Then in your task could loop over the keys and skip any organization with zero connected members.
This new ConcurrentDictionary could replace _uniqueOrganizations if you don't mind calling key.ToString(CultureInfo.InvariantCulture) to get the group name.

Resources