Front end of the notary in cordapp-samples - blockchain

I want to set up the UI for the notary in cordApp samples. As the notary's Web port is not configured by default,I am trying to change the client's Gradle file to configure the notary.
Is there any other way to configure the notary's UI ?
I checked,It can be seen through the Node Explorer.Is there any other way to check the notary on web front?

You can configure the notary's webport in a similar way as you would configure for any other node.
Your notary must have an RPC address configured.
Once you have an rpc address configured, you can either use the default corda webserver (which is now deprecated) or you must configure your own webserver or use spring-webserver).
Without specifying the web port you can define your spring boot server, and connect to the node via RPC.
Step 1 Define your Spring boot server
#SpringBootApplication
private open class Starter
/**
* Starts our Spring Boot application.
*/
fun main(args: Array<String>) {
val app = SpringApplication(Starter::class.java)
app.setBannerMode(Banner.Mode.OFF)
app.isWebEnvironment = true
app.run(*args)
}
Step 2 Start your server by defining a starter task in your gradle build file
task runPartyAServer(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'net.corda.server.ServerKt'
}
Step 3 Define the rpc configuration used to connect to the node.
server.port=10055
config.rpc.username=user1
config.rpc.password=test
config.rpc.host=localhost
config.rpc.port=10008
Step 4 Connect to the node using the above config defined.
val rpcAddress = NetworkHostAndPort(host, rpcPort)
val rpcClient = CordaRPCClient(rpcAddress)
val rpcConnection = rpcClient.start(username, password)
proxy = rpcConnection.proxy
Step 5 Use the proxy to connect to the notary node.
You can refer to the complete code here.

Related

Connection to AWS MemoryDB cluster sometimes fails

We have an application that is using AWS MemoryDB for Redis. We have setup a cluster with one shard and two nodes. One of the nodes (named 0001-001) is a primary read/write while the other one is a read replica (named 0001-002).
After deploying the application, connecting to MemoryDB sometimes fails when we use the cluster endpoint connection string to connect. If we restart the application a few times it suddenly starts working. It seems to be random when it succeeds or not. The error we get is the following:
Endpoint Unspecified/ourapp-memorydb-cluster-0001-001.ourapp-memorydb-cluster.xxxxx.memorydb.eu-west-1.amazonaws.com:6379 serving hashslot 6024 is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect. IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=0,Free=32767,Min=2,Max=32767), Local-CPU: n/a
If we connect directly to the primary read/write node we get no such errors.
If we connect directly to the read replica it always fails. It even gets the error above, compaining about the "0001-001" node.
We use .NET Core 6
We use Microsoft.Extensions.Caching.StackExchangeRedis 6.0.4 which depends on StackExchange.Redis 2.2.4
The application is hosted in AWS ECS
StackExchangeRedisCache is added to the service collection in a startup file :
services.AddStackExchangeRedisCache(o =>
{
o.InstanceName = redisConfiguration.Instance;
o.ConfigurationOptions = ToRedisConfigurationOptions(redisConfiguration);
});
...where ToRedisConfiguration returns a basic ConfigurationOptions object :
new ConfigurationOptions()
{
EndPoints =
{
{ "clustercfg.ourapp-memorydb-cluster.xxxxx.memorydb.eu-west-1.amazonaws.com", 6379 } // Cluster endpoint
},
User = "username",
Password = "password",
Ssl = true,
AbortOnConnectFail = false,
ConnectTimeout = 60000
};
We tried multiple shards with multiple nodes and it also sometimes fail to connect to the cluster. We even tried to update the dependency StackExchange.Redis to 2.5.43 but no luck.
We could "solve" it by directly connecting to the primary node, but if a failover occurs and 0001-002 becomes the primary node we would have to manually change our connection string, which is not acceptable in a production environment.
Any help or advice is appreciated, thanks!

How to mock an hbase connection

I need to mock an HBase for the unit test. Particularly, my program will require a Connection to HBase. How should I do this? I simply used HbaseTestingUtility.getConnection(). But obviously, it doesn't work.
Thank you!
This is how I got the connection established with the HBaseTestingUtil class (version 2.0.2):
import org.apache.hadoop.hbase.HBaseTestingUtility
val utility = new HBaseTestingUtiliy
utility.startMiniCluster() // defaults to 1 master and 1 region server
val connection = utility.getConnection()
In case you need to add some specific configuration (e.g. security settings) you can add hbase-site.xml to your resources.

Hazelcast cluster over AWS using Docker

Hi am trying to configure hazelcast cluster over AWS.
I am running hazelcast in docker container and using --net=host to use host network config.
when i look at hazelcast logs, I see
[172.17.0.1]:5701 [herald] [3.8] Established socket connection between /[node2]:5701 and /[node1]:47357
04:24:22.595 [hz._hzInstance_1_herald.IO.thread-out-0] DEBUG c.h.n.t.SocketWriterInitializerImpl - [172.17.0.1]:5701 [herald] [3.8] Initializing SocketWriter WriteHandler with Cluster Protocol
04:24:22.595 [hz._hzInstance_1_herald.IO.thread-in-0] WARN c.h.nio.tcp.TcpIpConnectionManager - [172.17.0.1]:5701 [herald] [3.8] Wrong bind request from [172.17.0.1]:5701! This node is not requested endpoint: [node2]:5701
04:24:22.595 [hz._hzInstance_1_herald.IO.thread-in-0] INFO c.hazelcast.nio.tcp.TcpIpConnection - [172.17.0.1]:5701 [herald] [3.8] Connection[id=40, /[node2]:5701->/[node1]:47357, endpoint=null, alive=false, type=MEMBER] closed. Reason: Wrong bind request from [172.17.0.1]:5701! This node is not requested endpoint: [node2]:5701
I can see error saying bind request is coming from 172.17.0.1 to node1, and node1 is not accepting this request.
final Config config = new Config();
config.setGroupConfig(clientConfig().getGroupConfig());
final NetworkConfig networkConfig = new NetworkConfig();
final JoinConfig joinConfig = new JoinConfig();
final TcpIpConfig tcpIpConfig = new TcpIpConfig();
final MulticastConfig multicastConfig = new MulticastConfig();
multicastConfig.setEnabled(false);
final AwsConfig awsConfig = new AwsConfig();
awsConfig.setEnabled(true);
// awsConfig.setSecurityGroupName("xxxx");
awsConfig.setRegion("xxxx");
awsConfig.setIamRole("xxxx");
awsConfig.setTagKey("type");
awsConfig.setTagValue("xxxx");
awsConfig.setConnectionTimeoutSeconds(120);
joinConfig.setAwsConfig(awsConfig);
joinConfig.setMulticastConfig(multicastConfig);
joinConfig.setTcpIpConfig(tcpIpConfig);
networkConfig.setJoin(joinConfig);
final InterfacesConfig interfaceConfig = networkConfig.getInterfaces();
interfaceConfig.setEnabled(true).addInterface("172.29.238.71");
config.setNetworkConfig(networkConfig);
above is the code to configure AWSConfig
Please help me resolve this issue.
Thanks
You are experiencing an issue (#11795) in default Hazelcast bind address selection mechanism.
There are several workarounds available:
Workaround 1: System property
You can set the bind address by providing correct IP address as a hazelcast.local.localAddress system property:
java -Dhazelcast.local.localAddress=[yourCorrectIpGoesHere]
or
System.setProperty("hazelcast.local.localAddress", "[yourCorrectIpGoesHere]")
Read details in System properties chapter of Hazelcast Reference Manual.
Workaround 2: Hazelcast Network configuration
Hazelcast Network configuration allows you to specify which IP addresses can be used to bind the server.
Declarative in hazelcast.xml:
<hazelcast>
...
<network>
...
<interfaces enabled="true">
<interface>10.3.16.*</interface>
<interface>10.3.10.4-18</interface>
<interface>192.168.1.3</interface>
</interfaces>
</network>
...
</hazelcast>
Programmatic:
Config config = new Config();
NetworkConfig network = config.getNetworkConfig();
InterfacesConfig interfaceConfig = network.getInterfaces();
interfaceConfig.setEnabled(true).addInterface("192.168.1.3");
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(config);
Read details in Interfaces section of Hazelcast Reference Manual.
Update:
With the earlier steps you are able to set a proper bind address - the local one returned by ip addr show for instance. Nevertheless, it could be insufficient if you run Hazelcast in an environment where local IP and public IP differs (clouds, docker).
Next Step: Configure public address
This step is necessary in environments, where cluster nodes doesn't see each other under the reported local address of the other node. You have to set the public address - it's the one which nodes are able to reach (optionally with port specified).
networkConfig.setPublicAddress("172.29.238.71");
// or if a non-default Hazelcast port is used - e.g.9991
networkConfig.setPublicAddress("172.29.238.71:9991");

Unit Test with spring-boot-starter-test and cassandra

My spring boot web application uses Cassandra DB via the Datastax client and the connection occurs as follow:
public CassandraManager(#Autowired CassandraConfig cassandraConfig) {
config = cassandraConfig;
cluster = Cluster.builder()
.addContactPoint(config.getHost())
.build();
session = cluster.connect(config.getKeyspace());
}
When I run my Unit Tests, the spring boot application tries to load the CassandraManager Bean and connect to the Cassandra DB which is not up for the Unit Test as I do not need it. I get the following error: [localhost/127.0.0.1:9042] Cannot connect)
Is there a way to avoid loading this Cassandra Manager Bean to run my UT as they do not need to connect to the DB ? Is it a good practice to do so ?
You can try something like below which worked for me assuming, you are using spring-data-cassandra
First we create another configuration class which will be used for the tests that does not need cassandra connection. It is required as we need to exlude the CassandraDataAutoConfiguration class. Ex:
#SpringBootApplication(exclude = {CassandraDataAutoConfiguration.class})
public class NoCassandraConfig {
}
Then we will use this configuration on our test(s). Ex:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = NoCassandraConfig.class)
public class UtilitiesTest {
/* Lots of tests that does not need DB connection */
}
And there you go.

Calling a web service using WS via an HTTP proxy

I am trying to call a web service from a playframework 2 application running in an environment where I need to go through a proxy server to access external web services. In my application.conf file I have added the following properties:
http.proxyPort=8000
http.proxyHost=myproxyhost.innitech.com
In my play application code I can access the system properties and verify they have been picked up. However, at runtime the proxy configuration is not being used. If I run the application in an environment where I do not need to use the proxy to access the service, the service call works fine.
Is it possible to call web services via a proxy using the play framework, and if so, how?
Here's an example of the call:
def watched(username: String, password: String): Promise[Seq[Repo]] = {
val promiseResponse = WS.url(baseUrl + "/user/watched")
.withAuth(username, password, com.ning.http.client.Realm.AuthScheme.BASIC)
.get
promiseResponse.map(_.json.as[Seq[Repo]])
}
The following stack trace represents what I see at run time:
play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[Connec
tException: https://api.github.com/user]]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:82) [p
lay_2.9.1.jar:2.0]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:63) [p
lay_2.9.1.jar:2.0]
at akka.actor.Actor$class.apply(Actor.scala:290) [akka-actor.jar:2.0]
at play.core.ActionInvoker.apply(Invoker.scala:61) [play_2.9.1.jar:2.0]
at akka.actor.ActorCell.invoke(ActorCell.scala:617) [akka-actor.jar:2.0]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:179) [akka-actor.jar:2.0]
Caused by: java.net.ConnectException: https://api.github.com/user
at com.ning.http.client.providers.netty.NettyConnectListener.operationCo
mplete(NettyConnectListener.java:100) ~[async-http-client.jar:na]
at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultCh
annelFuture.java:397) ~[netty.jar:na]
at org.jboss.netty.channel.DefaultChannelFuture.addListener(DefaultChann
elFuture.java:143) ~[netty.jar:na]
at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.doConnect
(NettyAsyncHttpProvider.java:1004) ~[async-http-client.jar:na]
at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.execute(N
ettyAsyncHttpProvider.java:829) ~[async-http-client.jar:na]
at com.ning.http.client.AsyncHttpClient.executeRequest(AsyncHttpClient.j
ava:499) ~[async-http-client.jar:na]
Caused by: java.nio.channels.UnresolvedAddressException: null
at sun.nio.ch.Net.checkAddress(Net.java:30) ~[na:1.6.0_25]
at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:480) ~[na
:1.6.0_25]
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.connec
t(NioClientSocketPipelineSink.java:142) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventS
unk(NioClientSocketPipelineSink.java:105) ~[netty.jar:na]
at org.jboss.netty.handler.ssl.SslHandler.handleDownstream(SslHandler.ja
va:459) ~[netty.jar:na]
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream
(OneToOneEncoder.java:55) ~[netty.jar:na]
The current snapshot in github should fix this problem, as it builds a AsyncHttpClientConfig using the Play context, then initializes the AsynchHttpClient using the config:
lazy val client = {
import play.api.Play.current
val config = new AsyncHttpClientConfig.Builder()
.setConnectionTimeoutInMs(current.configuration.getMilliseconds("ws.timeout").getOrElse(120000L).toInt)
.setFollowRedirects(current.configuration.getBoolean("ws.followRedirects").getOrElse(true))
.setUseProxyProperties(current.configuration.getBoolean("ws.useProxyProperties").getOrElse(true))
current.configuration.getString("ws.useragent").map { useragent =>
config.setUserAgent(useragent)
}
new AsyncHttpClient(config.build())
}