I use fabrc-sdk-java to operate the e2e_cli network.The e2e uses CA and the TLS is disabled.
I successfully create the channel and install the chaincode.
create channel:
Channel newChannel = client.newChannel(myChannel.getChannelName(), orderer, channelConfiguration, channelConfigurationSignatures.toArray(new byte[myPeerOrgs.size()][]));
channelConfigurationSignatures contains signatures from two organizations.
install chaincode:
Every organization has to send an installation proposal once, using its own peerAdmin organization.
reference:https://github.com/IBM/blockchain-application-using-fabric-java-sdk
But,when I prepare to instantiate chaincode,I get the error:
0endorser failed with Sending proposal to peer0.org1.example.com failed because of: gRPC failure=Status{code=UNKNOWN, description=Failed to deserialize creator identity, err MSP Org1 is unknown, cause=null}. Was verified:false
These are related codes:
client.setUserContext(myPeerOrgs.get(0).getPeerAdmin());
InstantiateProposalRequest instantiateProposalRequest = client.newInstantiationProposalRequest();
instantiateProposalRequest.setProposalWaitTime(fabricConfig.getProposalWaitTime());
instantiateProposalRequest.setChaincodeID(chaincodeID);
instantiateProposalRequest.setFcn(ininFun);
instantiateProposalRequest.setArgs(args);
Map<String, byte[]> tm = new HashMap<>();
tm.put("HyperLedgerFabric", "InstantiateProposalRequest:JavaSDK".getBytes(UTF_8));
tm.put("method", "InstantiateProposalRequest".getBytes(UTF_8));
instantiateProposalRequest.setTransientMap(tm);
ChaincodeEndorsementPolicy chaincodeEndorsementPolicy = new ChaincodeEndorsementPolicy();
chaincodeEndorsementPolicy.fromYamlFile(new File(myChaincode.getChaincodeEndorsementPolicyPath()));
instantiateProposalRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
logger.trace("Sending instantiateProposalRequest to all peers with arguments: " + Arrays.toString(args));
Collection<ProposalResponse> successful = new LinkedList<>();
Collection<ProposalResponse> failed = new LinkedList<>();
Collection<ProposalResponse> responses = channel.sendInstantiationProposal(instantiateProposalRequest);
for (ProposalResponse response : responses) {
if (response.isVerified() && response.getStatus() == ProposalResponse.Status.SUCCESS) {
successful.add(response);
logger.trace(String.format("Succesful instantiate proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName()));
} else {
failed.add(response);
}
}
logger.trace(String.format("Received %d instantiate proposal responses. Successful+verified: %d . Failed: %d", responses.size(), successful.size(), failed.size()));
if (failed.size() > 0) {
ProposalResponse first = failed.iterator().next();
logger.error("Not enough endorsers for instantiate :" + successful.size() + "endorser failed with " + first.getMessage() + ". Was verified:" + first.isVerified());
System.exit(1);
}
I thought it was a serialization problem,but the MyUser class and the MyEnrollement class both inherit the Serializable interface, and both define the serialVersionUID.
I have compared blockchain-application-using-fabric-java-sdk and have not identified the problem.
I finally solved this problem.The problem is in the following code:
Channel newChannel = client.newChannel(myChannel.getChannelName(), orderer, channelConfiguration, channelConfigurationSignatures.toArray(new byte[myPeerOrgs.size()][]));
The above code is written by me with reference to End2endIT:
//Create channel that has only one signer that is this orgs peer admin. If channel creation policy needed more signature they would need to be added too.
Channel newChannel = client.newChannel(name, anOrderer, channelConfiguration, client.getChannelConfigurationSignature(channelConfiguration, sampleOrg.getPeerAdmin()));
I don't know if it is wrong with my usage.But my code, the error is in this sentence, when joining the node later, the error is reported.
I referenced https://github.com/IBM/blockchain-application-using-fabric-java-sdk/blob/master/java/src/main/java/org/app/network/CreateChannel.java and found the correct way of writing.
public Channel createChannel() {
logger.info("Begin create channel: " + myChannel.getChannelName());
ChannelConfiguration channelConfiguration = new ChannelConfiguration(new File(fabricConfig.getChannelArtifactsPath() + "/" + myChannel.getChannelName() + ".tx"));
logger.trace("Read channel " + myChannel.getChannelName() + " configuration file:" + fabricConfig.getChannelArtifactsPath() + "/" + myChannel.getChannelName() + ".tx");
byte[] channelConfigurationSignatures = client.getChannelConfigurationSignature(channelConfiguration, myPeerOrgs.get(0).getPeerAdmin());
Channel newChannel = client.newChannel(myChannel.getChannelName(), orderer, channelConfiguration, channelConfigurationSignatures);;
for (Peer peer : myPeerOrgs.get(0).getPeers()) {
// create a channel for the first time, only `joinPeer` here, not `addPeer`
newChannel.joinPeer(peer);
}
for (EventHub eventHub : myPeerOrgs.get(0).getEventHubs()) {
newChannel.addEventHub(eventHub);
}
if (!newChannel.isInitialized()) {
newChannel.initialize();
}
// I have only tested two organizations
// I don’t know if there are any errors in the three organizations.
for (int i = 1; i < myPeerOrgs.size(); i++) {
client.setUserContext(myPeerOrgs.get(i).getPeerAdmin());
newChannel = client.getChannel(myChannel.getChannelName());
for (Peer peer : myPeerOrgs.get(i).getPeers()) {
newChannel.joinPeer(peer);
}
for (EventHub eventHub : myPeerOrgs.get(i).getEventHubs()) {
newChannel.addEventHub(eventHub);
}
}
logger.trace("Node that has joined the channel:");
Collection<Peer> peers = newChannel.getPeers();
for (Peer peer : peers) {
logger.trace(peer.getName() + " at " + peer.getUrl());
}
logger.info("Success, end create channel: " + myChannel.getChannelName() + "\n");
return newChannel;
}
Related code later, such as installing and initializing chaincode, also refer to https://github.com/IBM/blockchain-application-using-fabric-java-sdk. This is an excellent example.
If anyone knows how to use the fourth variable parameter of newChannel, please let me know. Thanks.
Finally, I don't know how to dynamically join nodes, organizations and channels, I am looking for and testing, there are only examples of nodejs on the network, there is no java, if anyone knows, please tell me, I really need. Thanks.
Related
I downloaded a lot of blockchain data using https://bitcoin.org, I took some file and I try to analyse it with bitcoinj library.
I would like to get information from every transaction:
-who send bitcoins,
-how much,
-who receive bitcoins.
I use:
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>
<version>0.15.10</version>
</dependency>
I have a code:
NetworkParameters np = new MainNetParams();
Context.getOrCreate(MainNetParams.get());
BlockFileLoader loader = new BlockFileLoader(np,List.of(new File("test/resources/blk00450.dat")));
for (Block block : loader) {
for (Transaction tx : block.getTransactions()) {
System.out.println("Transaction ID" + tx.getTxId().toString());
for (TransactionInput ti : tx.getInputs()) {
// how to get wallet addresses of inputs?
}
// this code works for 99% of transactions but for some throws exceptions
for (TransactionOutput to : tx.getOutputs()) {
// sometimes this line throws: org.bitcoinj.script.ScriptException: Cannot cast this script to an address
System.out.println("out address:" + to.getScriptPubKey().getToAddress(np));
System.out.println("out value:" + to.getValue().toString());
}
}
}
Can you share some snippet that will work for all transactions in the blockchain?
There are at least two type of transaction, P2PKH and P2SH.
Your code would work well with P2PKH, but wouldn not work with P2SH.
You can change the line from:
System.out.println("out address:" + to.getScriptPubKey().getToAddress(np));
to:
System.out.println("out address:" + to.getAddressFromP2PKHScript(np)!=null?to.getAddressFromP2PKHScript(np):to.getAddressFromP2SH(np));
The API of Bitcoin says the methods getAddressFromP2PKHScript() and getAddressFromP2SH() are deprecated, and I have not find suitable method.
However, P2SH means "Pay to Script Hash", which means it could contain two or more public keys to support multi-signature. Moreover, getAddressFromP2SH() returns only one address, perhaps this is the reason why it is deprecated.
I also wrote a convinient method to check the inputs and outputs of a block:
private void printCoinValueInOut(Block block) {
Coin blockInputSum = Coin.ZERO;
Coin blockOutputSum = Coin.ZERO;
System.out.println("--------------------Block["+block.getHashAsString()+"]------"+block.getPrevBlockHash()+"------------------------");
for(Transaction tx : block.getTransactions()) {
Coin txInputSum = tx.getOutputSum();
Coin txOutputSum = tx.getOutputSum();
blockInputSum = blockInputSum.add(txInputSum);
blockOutputSum = blockOutputSum.add(txOutputSum);
System.out.println("Tx["+tx.getTxId()+"]:\t" + txInputSum + "(satoshi) IN, " + txOutputSum + "(satoshi) OUT.");
}
System.out.println("Block total:\t" + blockInputSum + "(satoshi) IN, " + blockOutputSum + "(satoshi) OUT. \n");
}
I am working in a project using Jenkins and JPPF.
How do I get which node is connected to JPPF server? If possible, please give me the guideline detail.
Thanks,
Disclaimer: JPPF developer here.
You can monitor the nodes connected to a JPPF server using the JMX-based server management APIs. There are many things you can monitor, and a lot of different information you can obtain from the server and the nodes. Hopefully, the following example will give you a good starting point:
// connect using a JMX remote connection wrapper
try (JMXDriverConnectionWrapper serverJmx = new JMXDriverConnectionWrapper("jppf_server_host", 11111)) {
serverJmx.connectAndWait(5_000L);
if (serverJmx.isConnected()) {
// get summary information on all the connected nodes
Collection<JPPFManagementInfo> nodeInfos = serverJmx.nodesInformation();
System.out.println("there are " + nodeInfos.size() + " connected nodes:");
for (JPPFManagementInfo info: nodeInfos) {
System.out.println("node uuid: " + info.getUuid() + ", host is " + info.getHost());
}
// get detailed information on the nodes
// the node forwarder will send the same request to all selected nodes
// and group the results in a map where each key is a node uuid
JPPFNodeForwardingMBean forwarder = serverJmx.getNodeForwarder();
Map<String, Object> responses = forwarder.systemInformation(NodeSelector.ALL_NODES);
for (Map.Entry<String, Object> response: responses.entrySet()) {
String nodeUuid = response.getKey();
if (response.getValue() instanceof Exception) {
System.out.println("node with uuid = " + nodeUuid + " raised an exception:");
((Exception) response.getValue()).printStackTrace(System.out);
} else {
JPPFSystemInformation systemInfo = (JPPFSystemInformation) response.getValue();
System.out.println("system properties for node uuid " + nodeUuid + " :");
System.out.println(systemInfo.getSystem());
}
}
} else {
System.out.println("could not connect to jppf_server_host:11111");
}
} catch (Exception e) {
e.printStackTrace();
}
Note that the web and standalone administration consoles, which are built on top of the same management APIs, will also provide this information.
Does anyone have an example of retrieving data using Actian's JCL to a loosely coupled pervasive database in Java? The database I am connecting to only has DAT files. My goal is to create a link between pervasive and MS SQL.
I am not looking for a freebie, but someone to point me in the right direction so I can learn and grow.
Thank you in advanced!
Found this in my archives. Don't know when it was written, whether it works, or if this interface is still supported. You don't say what version of PSQL you're using so I don't even know if this will work with your version.
import pervasive.database.*;
public class VersionTest implements Consts
{
public VersionTest()
{
try
{
Session session = Driver.establishSession();
Database db = session.connectToDatabase("PMKE:");
XCursor xcursor = db.createXCursor(57000);
//Using local TABL.DAT (length 255 assures no leftovers!)
xcursor.setKZString(0,255,"plsetup\\tabl.dat");
//Open the file to load local MKDE
int status = xcursor.BTRV(BTR_OPEN);
System.out.println("Local Open status: " + status);
//Using remote TABL.DAT (length 255 assures no leftovers!)
xcursor.setKZString(0,255,"h:\\basic2c\\develop\\tabl.dat");
//set the buffer size
xcursor.setDataSize(15);
//get version
status = xcursor.BTRV(BTR_VERSION);
System.out.println("Version status: " + status);
// should be 15, always prints 5
System.out.println("Version length: " + xcursor.getRecLength());
System.out.println("Version: " + xcursor.getDString(0,15));
// try with an open file on a server
XCursor xcursor2 = db.createXCursor(57000);
//Using remote TABL.DAT (length 255 assures no leftovers!)
xcursor2.setKZString(0,255,"h:\\basic2c\\develop\\tabl.dat");
//Open the file
status = xcursor2.BTRV(BTR_OPEN);
System.out.println("Remote Open status: " + status);
//set the buffer size
xcursor2.setDataSize(15);
//get version
status = xcursor2.BTRV(BTR_VERSION);
System.out.println("Version status: " + status);
// should be 15, always prints 5
System.out.println("Version length: " + xcursor2.getRecLength());
System.out.println("Version: " + xcursor2.getDString(0,15));
// clean up resources
Driver.killAllSessions();
}catch(Exception exp)
{
exp.printStackTrace();
}
}
public static void main(String[] args)
{
new VersionTest();
}
}
JCL APIs are still supported with Actian PSQL v12 and v13.
You can find more documentation on retrieving data using Actian JCL at
http://docs.pervasive.com/products/database/psqlv12/wwhelp/wwhimpl/js/html/wwhelp.htm#href=jcl/java_api.2.2.html
To link to MS Sql Server you would need to create the data dictionary files(DDFs) for the PSQl data files to use with relational interfaces.
I am really new to SOAP web services and to Netsuite ERP and I am trying to generate a report in my company where I need to obtain all the Clients and their Invoices using the data available in Netsuite ERP. I followed the Java and Axis tutorial they offer with their sample app for the ERP and I successfully created a Java project in Eclipse that consumes the WSDL for netsuite 2015-2 and compiles the needed classes to run the sample app. So, I followed an example found in their CRM exapmle app to obtain a Client's information but the only problem is that their example method needs you to introduce the Client's ID. Here is the sample code:
public int getCustomerList() throws RemoteException,
ExceededUsageLimitFault, UnexpectedErrorFault, InvalidSessionFault,
ExceededRecordCountFault, UnsupportedEncodingException {
// This operation requires a valid session
this.login(true);
// Prompt for list of internalIds and put in an array
_console
.write("\ninternalIds for records to retrieved (separated by commas): ");
String reqKeys = _console.readLn();
String[] internalIds = reqKeys.split(",");
return getCustomerList(internalIds, false);
}
private int getCustomerList(String[] internalIds, boolean isExternal)
throws RemoteException, ExceededUsageLimitFault,
UnexpectedErrorFault, InvalidSessionFault, ExceededRecordCountFault {
// Build an array of RecordRef objects and invoke the getList()
// operation to retrieve these records
RecordRef[] recordRefs = new RecordRef[internalIds.length];
for (int i = 0; i < internalIds.length; i++) {
RecordRef recordRef = new RecordRef();
recordRef.setInternalId(internalIds[i]);
recordRefs[i] = recordRef;
recordRefs[i].setType(RecordType.customer);
}
// Invoke getList() operation
ReadResponseList getResponseList = _port.getList(recordRefs);
// Process response from get() operation
if (!isExternal)
_console.info("\nRecords returned from getList() operation: \n");
int numRecords = 0;
ReadResponse[] getResponses = getResponseList.getReadResponse();
for (int i = 0; i < getResponses.length; i++) {
_console.info("\n Record[" + i + "]: ");
if (!getResponses[i].getStatus().isIsSuccess()) {
_console.errorForRecord(getStatusDetails(getResponses[i]
.getStatus()));
} else {
numRecords++;
Customer customer = (Customer) getResponses[i].getRecord();
_console.info(" internalId="
+ customer.getInternalId()
+ "\n entityId="
+ customer.getEntityId()
+ (customer.getCompanyName() == null ? ""
: ("\n companyName=" + customer
.getCompanyName()))
+ (customer.getEntityStatus() == null ? ""
: ("\n status=" + customer.getEntityStatus().getName()))
+ (customer.getEmail() == null ? ""
: ("\n email=" + customer.getEmail()))
+ (customer.getPhone() == null ? ""
: ("\n phone=" + customer.getPhone()))
+ "\n isInactive="
+ customer.getIsInactive()
+ (customer.getDateCreated() != null ? ""
: ("\n dateCreated=" + customer
.getDateCreated().toString())));
}
}
return numRecords;
}
So as you can see, this method needs the internal ID of each Customer which I find not useful as I have a many Customers and I don't want to pass each Customer's ID. I read their API docs (which I find hard to navigate and kind of useless) and I found a web service called getAll() that gives all the records given a getAllRecord object which requires a getAllRecordType object. However, the getAllRecordType object does not support Customer entities, so I can't obtain all the customers on the ERP this way.
Is there an easy way to obtain all the Customers in my Netsuite ERP (maybe using other thing rather than the SOAP Web Services they offer? I am desperate about this situation as understanding how Netsuite's Web Services API has been really troublesome.
Thanks!
You would normally use a search to select a list of customers. On a large account you would not normally get all customers on any regular basis. If you are trying to get the invoices you might just find it more practical to get those with a search.
You wrote "in your company". Are you trying to write an application of some sort? If this is an internal project (and even if it's not) you'll probably find using SuiteScripts much more efficient in terms of your time and frustration level.
I made it using the following code on my getCustomerList method:
CustomerSearch customerSrch = new CustomerSearch();
SearchResult searchResult = _port.search(customerSrch);
System.out.println(searchResult.getTotalRecords());
RecordList rl = searchResult.getRecordList();
for (int i = 0; i <searchResult.getTotalRecords()-1; i++) {
Record r = rl.getRecord(i);
System.out.println("Customer # " + i);
Customer testcust = (Customer)r;
System.out.println("First Name: " + testcust.getFirstName());
}
First of all, I'll admit I am new to this and I've probably just forgotten to set an option somewhere to the correct variable, but my Googling has failed me and I have no idea what to do, so I was hoping to get some help.
I have based this on the SecureChat example, it can be located here: http://netty.io/docs/unstable/xref/org/jboss/netty/example/securechat/package-summary.html
And the difference I have made, have been only in the SecureChatServerHandler. More precisely in the messageRecieved block:
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
// Convert the message to a string
String request = (String) e.getMessage();
System.out.println("Message recieved: " + request);
if (request.equalsIgnoreCase("clients")) {
channels.write("We currently have: " + channels.size() + " clients");
} else if (request.toLowerCase().equals("koko"))
for (Channel c : channels) {
if (c == e.getChannel())
c.write("HELLO WORLD");
}
else {
// Then send it to all channels, but the current one.
for (Channel c : channels)
if (c != e.getChannel())
c.write("[" + e.getChannel().getRemoteAddress() + "] " + request + "\n");
else
c.write("[you] " + request + "\n");
}
if (request.equalsIgnoreCase("bye"))
e.getChannel().close();
}
If I send a normal message that is getting broadcasted, everything works. But if I send a command, like clients or koko, I get no response, until I press enter again and send a empty message. First then I get the response back.
C:\Device Manager\Application Server\Examp
les\SecureChat\SecureChatClient\bin>java -jar client.jar 127.0.0.1 8080
UNKNOWN SERVER CERTIFICATE: CN=securechat.example.netty.gleamynode.net, OU=Contr
ibutors, O=The Netty Project, L=Seongnam-si, ST=Kyunggi-do, C=KR
Welcome to Electus secure chat service!
Your session is protected by TLS_DHE_RSA_WITH_AES_128_CBC_SHA cipher suite
You are the 1th user
koko<ENTER>
<PRESS ENTER AGAIN>
HELLO WORLD[you]
clients<ENTER>
<AND ENTER ONCE AGAIN>
We currently have: 1 clients[you]
What I don't understand, and don't want, is the -pressing of enter button twice- thing. It seems highly inlogical and it is irritating. I didn't have these problem with the Telnet Example.
Thank you for your time.
Regards,
Aldrian.
This is one of those humiliating times where you just forgot one small detail, and that messes everything up.
if (request.equalsIgnoreCase("clients")) {
channels.write("We currently have: " + channels.size() + " clients /n"); // Forgot /n here
} else if (request.toLowerCase().equals("koko"))
for (Channel c : channels) {
if (c == e.getChannel())
c.write("HELLO WORLD /n"); // <- Forgot /n here as well
}