Created
November 23, 2017 18:38
-
-
Save DazWilkin/d03b47a50bb02c3d0ffb7614b50064b4 to your computer and use it in GitHub Desktop.
Deploy ‘fabcar’ on Corda
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template; | |
import com.google.common.collect.ImmutableList; | |
import com.google.common.collect.ImmutableMap; | |
import net.corda.core.messaging.CordaRPCOps; | |
import net.corda.core.messaging.FlowProgressHandle; | |
import net.corda.core.node.NodeInfo; | |
import net.corda.core.identity.CordaX500Name; | |
import net.corda.core.identity.Party; | |
import net.corda.core.contracts.StateAndRef; | |
import net.corda.core.transactions.SignedTransaction; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import javax.ws.rs.GET; | |
import javax.ws.rs.PUT; | |
import javax.ws.rs.Path; | |
import javax.ws.rs.QueryParam; | |
import javax.ws.rs.Produces; | |
import javax.ws.rs.core.MediaType; | |
import javax.ws.rs.core.Response; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.concurrent.ExecutionException; | |
import static java.util.stream.Collectors.toList; | |
import static javax.ws.rs.core.Response.Status.BAD_REQUEST; | |
import static javax.ws.rs.core.Response.Status.CREATED; | |
@Path("fabcar") | |
public class CarApi { | |
private final CordaRPCOps rpcOps; | |
private final CordaX500Name myLegalName; | |
private final List<String> serviceNames = ImmutableList.of("Controller", "Network Map Service"); | |
static private final Logger logger = LoggerFactory.getLogger(CarApi.class); | |
public CarApi(CordaRPCOps services) { | |
this.rpcOps = services; | |
this.myLegalName = rpcOps | |
.nodeInfo() | |
.getLegalIdentities() | |
.get(0) | |
.getName(); | |
} | |
@GET | |
@Path("peers") | |
@Produces(MediaType.APPLICATION_JSON) | |
public Map<String, List<CordaX500Name>> getPeers() { | |
List<NodeInfo> nodeInfoSnapshot = rpcOps.networkMapSnapshot(); | |
return ImmutableMap.of("peers", nodeInfoSnapshot | |
.stream() | |
.map(node -> node.getLegalIdentities().get(0).getName()) | |
.filter(name -> !name.equals(myLegalName) && !serviceNames.contains(name.getOrganisation())) | |
.collect(toList())); | |
} | |
@GET | |
@Path("cars") | |
@Produces(MediaType.APPLICATION_JSON) | |
public List<StateAndRef<CarState>> getCars() { | |
return rpcOps.vaultQuery(CarState.class).getStates(); | |
} | |
@PUT | |
@Path("changeCarOwner") | |
public Response changeCarOwner( | |
@QueryParam("color") String color, | |
@QueryParam("make") String make, | |
@QueryParam("model") String model, | |
@QueryParam("newOwner") CordaX500Name newOwnerX500 | |
) throws InterruptedException, ExecutionException { | |
if (newOwnerX500 == null) { | |
return Response | |
.status(BAD_REQUEST) | |
.entity("Query parameter 'newOwner' missing or has wrong format.\n") | |
.build(); | |
} | |
final Party newOwner = rpcOps.wellKnownPartyFromX500Name(newOwnerX500); | |
try { | |
FlowProgressHandle<SignedTransaction> flowHandle = rpcOps | |
.startTrackedFlowDynamic(CarFlow.class, color, make, model, newOwner); | |
flowHandle | |
.getProgress() | |
.subscribe(evt -> System.out.printf(">> %s\n", evt)); | |
final SignedTransaction result = flowHandle | |
.getReturnValue() | |
.get(); | |
final String msg = String.format("Transaction id %s committed to ledger.\n", result.getId()); | |
return Response | |
.status(CREATED) | |
.entity(msg) | |
.build(); | |
} catch (Throwable ex) { | |
final String msg = ex.getMessage(); | |
logger.error(ex.getMessage(), ex); | |
return Response | |
.status(BAD_REQUEST) | |
.entity(msg) | |
.build(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template; | |
import co.paralleluniverse.fibers.Suspendable; | |
import net.corda.core.contracts.Command; | |
import net.corda.core.contracts.CommandData; | |
import net.corda.core.flows.*; | |
import net.corda.core.identity.Party; | |
import net.corda.core.transactions.SignedTransaction; | |
import net.corda.core.transactions.TransactionBuilder; | |
import net.corda.core.utilities.ProgressTracker; | |
import static com.template.TemplateContract.TEMPLATE_CONTRACT_ID; | |
@InitiatingFlow | |
@StartableByRPC | |
public class CarFlow extends FlowLogic<SignedTransaction> { | |
private final String color; | |
private final String make; | |
private final String model; | |
private final Party newOwner; | |
private final ProgressTracker progressTracker = new ProgressTracker(); | |
public CarFlow(String color, String make, String model, Party newOwner) { | |
this.color = color; | |
this.make = make; | |
this.model = model; | |
this.newOwner = newOwner; | |
} | |
@Suspendable | |
@Override | |
public SignedTransaction call() throws FlowException { | |
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); | |
CarState outputState = new CarState(color, make, model, newOwner); | |
CommandData cmdType = new TemplateContract.Commands.Action(); | |
Command cmd = new Command<>(cmdType, getOurIdentity().getOwningKey()); | |
final TransactionBuilder txBuilder = new TransactionBuilder(notary) | |
.addOutputState(outputState, TEMPLATE_CONTRACT_ID) | |
.addCommand(cmd); | |
final SignedTransaction signedTx = getServiceHub().signInitialTransaction(txBuilder); | |
subFlow(new FinalityFlow(signedTx)); | |
return null; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template; | |
import com.google.common.collect.ImmutableList; | |
import net.corda.core.contracts.ContractState; | |
import net.corda.core.identity.AbstractParty; | |
import net.corda.core.identity.Party; | |
import java.util.Collections; | |
import java.util.List; | |
public class CarState implements ContractState { | |
private final String color; | |
private final String make; | |
private final String model; | |
private final Party owner; | |
public CarState(String color, String make, String model, Party owner) { | |
this.color = color; | |
this.make = make; | |
this.model = model; | |
this.owner = owner; | |
} | |
public String getColor() { | |
return this.color; | |
} | |
public String getMake() { | |
return this.make; | |
} | |
public String getModel() { | |
return this.model; | |
} | |
public Party getOwner() { | |
return this.owner; | |
} | |
@Override | |
public List<AbstractParty> getParticipants() { | |
return ImmutableList.of(owner); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.google.common.collect.ImmutableList; | |
import com.google.common.collect.ImmutableMap; | |
import net.corda.core.messaging.CordaRPCOps; | |
import net.corda.webserver.services.WebServerPluginRegistry; | |
import org.jetbrains.annotations.NotNull; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.function.Function; | |
public class TemplateWebPlugin implements WebServerPluginRegistry { | |
@NotNull | |
@Override | |
public List<Function<CordaRPCOps, ?>> getWebApis() { | |
return ImmutableList.of(CarApi::new); | |
} | |
@NotNull | |
@Override | |
public Map<String, String> getStaticServeDirs() { | |
return ImmutableMap.of( | |
// This will serve the templateWeb directory in resources to /web/template | |
"template", getClass().getClassLoader().getResource("templateWeb").toExternalForm()); | |
} | |
@Override | |
public void customizeJSONSerialization(ObjectMapper objectMapper) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment