git clone https://github.com/financeCoding/dart_datastore_example.git
cd dart_datastore_example
pub install
If you are not connected to a Compute Engine instance, make sure to run
the following commands (in a bash-like shell):
12345678910
# convert the .p12 private key file to a .pem file# if asked to enter import password, use "notasecret"openssl pkcs12 -in <privatekey>.p12 -nocerts -passin pass:notasecret -nodes -out <rsa_private_key>.pem
# configure your credentialsexport DATASTORE_SERVICE_ACCOUNT=<service-account>
export DATASTORE_PRIVATE_KEY_FILE=<path-to-pem-file>
export CLOUD_PROJECT_ID=<project-id>
export CLOUD_PROJECT_NUMBER=<project-number>
Alternatively the sample allows for passing parameters via commandline:
12345
cd dart_datastore_example
pub install
cd bin
# dart dart_datastore_example.dart <project-id> <project-number> <path-to-pem-file> <service-account>dart dart_datastore_example.dart dartcloud 657648630269 privatekey.pem 657648630269-ge2he8e46y4u42bd89nmgtj52j3ilzvv@developer.gserviceaccount.com
Example output on first run:
123456
dartcloud
657648630269
privatekey.pem
657648630269-ge2he8e46y4u42bd89nmgtj52j3ilzvv@developer.gserviceaccount.com
did not found entity
> entity={question: {"stringValue":"Meaning of life?"}, answer: {"integerValue":42}}
Example output on second run:
123456
dartcloud
657648630269
privatekey.pem
657648630269-ge2he8e46y4u42bd89nmgtj52j3ilzvv@developer.gserviceaccount.com
found entity={"key":{"partitionId":{"datasetId":"s~dartcloud"},"path":[{"kind":"Trivia","name":"hgtg"}]},"properties":{"question":{"stringValue":"Meaning of life?"},"answer":{"integerValue":42}}}> entity={question: {"stringValue":"Meaning of life?"}, answer: {"integerValue":42}}
The comments in the sample’s source explain its behavior in detail:
import"dart:io";import"package:google_oauth2_client/google_oauth2_console.dart";import"package:google_datastore_v1beta2_api/datastore_v1beta2_api_client.dart"asclient;import"package:google_datastore_v1beta2_api/datastore_v1beta2_api_console.dart"asconsole;voidmain(List<String>args){Map<String,String>envVars=Platform.environment;StringprojectId=envVars['CLOUD_PROJECT_ID']==null?args[0]:envVars['CLOUD_PROJECT_ID'];StringprojectNumber=envVars['CLOUD_PROJECT_NUMBER']==null?args[1]:envVars['CLOUD_PROJECT_NUMBER'];StringpemFilename=envVars['DATASTORE_PRIVATE_KEY_FILE']==null?args[2]:envVars['DATASTORE_PRIVATE_KEY_FILE'];StringserviceAccountEmail=envVars['DATASTORE_SERVICE_ACCOUNT']==null?args[3]:envVars['DATASTORE_SERVICE_ACCOUNT'];print(projectId);print(projectNumber);print(pemFilename);print(serviceAccountEmail);Stringiss=serviceAccountEmail;Stringscopes='https://www.googleapis.com/auth/userinfo.email ''https://www.googleapis.com/auth/datastore';Stringrsa_private_key_file=newFile(pemFilename).readAsStringSync();ComputeOAuth2ConsolecomputeEngineClient=newComputeOAuth2Console(projectNumber,privateKey:rsa_private_key_file,iss:iss,scopes:scopes);console.Datastoredatastore=newconsole.Datastore(computeEngineClient)..makeAuthRequests=true;// Create a RPC request to begin a new transactionvarbeginTransactionRequest=newclient.BeginTransactionRequest.fromJson({});Stringtransaction;client.Keykey;client.Entityentity;// Execute the RPC asynchronouslydatastore.datasets.beginTransaction(beginTransactionRequest,projectId).then((client.BeginTransactionResponsebeginTransactionResponse){// Get the transaction handle from the response.transaction=beginTransactionResponse.transaction;// Create a RPC request to get entities by key.varlookupRequest=newclient.LookupRequest.fromJson({});// Create a new entities by keykey=newclient.Key.fromJson({});// Set the entity key with only one `path_element`: no parent.varpath=newclient.KeyPathElement.fromJson({'kind':'Trivia','name':'hgtg'});key.path=newList<client.KeyPathElement>();key.path.add(path);lookupRequest.keys=newList<client.Key>();// Add one key to the lookup request.lookupRequest.keys.add(key);// Set the transaction, so we get a consistent snapshot of the// entity at the time the transaction started.lookupRequest.readOptions=newclient.ReadOptions.fromJson({'transaction':transaction});// Execute the RPC and get the response.returndatastore.datasets.lookup(lookupRequest,projectId);}).then((client.LookupResponselookupResponse){// Create a RPC request to commit the transaction.varreq=newclient.CommitRequest.fromJson({});// Set the transaction to commit.req.transaction=transaction;if(lookupResponse.found.isNotEmpty){// Get the entity from the response if foundentity=lookupResponse.found.first.entity;print("found entity = ${entity.toString()}");}else{print("did not found entity");// If no entity was found, insert a new one in the commit request mutation.entity=newclient.Entity.fromJson({});req.mutation=newclient.Mutation.fromJson({});req.mutation.insert=newList<client.Entity>();req.mutation.insert.add(entity);// Copy the entity key.entity.key=newclient.Key.fromJson(key.toJson());// Add two entity properties:// - a utf-8 string: `question`client.Propertyproperty=newclient.Property.fromJson({});property.stringValue="Meaning of life?";entity.properties=newMap<String,client.Property>();entity.properties['question']=property;// - a 64bit integer: `answer`property=newclient.Property.fromJson({});property.integerValue=42;entity.properties['answer']=property;// Execute the Commit RPC synchronously and ignore the response:// Apply the insert mutation if the entity was not found and close// the transaction.returndatastore.datasets.commit(req,projectId);}}).then((client.CommitResponsecommitResponse)=>print("> entity = ${entity.properties}"));}
Example deployment and startup scripts for GCE with Dart
setup-instance.sh script creates the node with the right correct scopes and image.
12345678910111213141516171819202122232425
#!/usr/bin/env bashset+oxtraceUSER=$USERPROJECT=dart-compute-projectINSTANCE_NAME=dart-computeTAGS=dartMACHINE_TYPE=f1-microNETWORK=defaultIP=ephemeralIMAGE=https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/backports-debian-7-wheezy-v20140318SCOPES=https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/devstorage.full_control,https://www.googleapis.com/auth/datastorePERSISTENT_BOOT_DISK=trueAUTO_DELETE_BOOT_DISK=trueZONE=us-central1-bSTARTUP_SCRIPT=startup-script.shGCUTIL="gcutil --service_version=v1 --project=$PROJECT"$GCUTILaddinstance$INSTANCE_NAME--tags=$TAGS--zone=$ZONE--machine_type=$MACHINE_TYPE--network=$NETWORK--external_ip_address=$IP--service_account_scopes=$SCOPES--image=$IMAGE--persistent_boot_disk=$PERSISTENT_BOOT_DISK--auto_delete_boot_disk=$AUTO_DELETE_BOOT_DISK--metadata_from_file=startup-script:$STARTUP_SCRIPTrc=$?if[[$rc!=0]];thenecho"Not able to add instance"exit$rcfi
startup-script.sh script that provisions the node with dart.
12345678910111213141516171819202122
#!/usr/bin/env bash#Addanaddtionalsourceforthelatestglibcsudosed-i'1i deb http://ftp.us.debian.org/debian/ jessie main'/etc/apt/sources.list#Updatesourcessudoapt-getupdate#DownloadlatestglibcsudoDEBIAN_FRONTEND=noninteractiveapt-get-tjessieinstall-ylibc6libc6-devlibc6-dbggitscreenunzipvim#Downloadthelatestdartsdkwgethttp://storage.googleapis.com/dart-archive/channels/dev/release/latest/sdk/dartsdk-linux-x64-release.zip -O dartsdk-linux-x64-release.zip #Unpackthedartsdkunzip-d/dartsdk-linux-x64-release.zip#Makethesdkreadablechmod-Rgo+rx/dart-sdk#Adddartbintoglobalpathecho"export PATH=\$PATH:/dart-sdk/bin">>/etc/profile