Search in sources :

Example 1 with IonValue

use of com.amazon.ion.IonValue in project amazon-qldb-dmv-sample-java by aws-samples.

the class GetRevision method queryRegistrationsByVin.

/**
 * Query the registration history for the given VIN.
 *
 * @param txn
 *              The {@link TransactionExecutor} for lambda execute.
 * @param vin
 *              The unique VIN to query.
 * @return a list of {@link IonStruct} representing the registration history.
 * @throws IllegalStateException if failed to convert parameters into {@link IonValue}
 */
public static List<IonStruct> queryRegistrationsByVin(final TransactionExecutor txn, final String vin) {
    log.info(String.format("Let's query the 'VehicleRegistration' table for VIN: %s...", vin));
    log.info("Let's query the 'VehicleRegistration' table for VIN: {}...", vin);
    final String query = String.format("SELECT * FROM _ql_committed_%s WHERE data.VIN = ?", Constants.VEHICLE_REGISTRATION_TABLE_NAME);
    try {
        final List<IonValue> parameters = Collections.singletonList(Constants.MAPPER.writeValueAsIonValue(vin));
        final Result result = txn.execute(query, parameters);
        List<IonStruct> list = ScanTable.toIonStructs(result);
        log.info(String.format("Found %d document(s)!", list.size()));
        return list;
    } catch (IOException ioe) {
        throw new IllegalStateException(ioe);
    }
}
Also used : IonValue(com.amazon.ion.IonValue) IonStruct(com.amazon.ion.IonStruct) IOException(java.io.IOException) GetRevisionResult(com.amazonaws.services.qldb.model.GetRevisionResult) Result(software.amazon.qldb.Result) GetDigestResult(com.amazonaws.services.qldb.model.GetDigestResult)

Example 2 with IonValue

use of com.amazon.ion.IonValue in project amazon-qldb-dmv-sample-java by aws-samples.

the class GetRevision method verifyRegistration.

/**
 * Verify each version of the registration for the given VIN.
 *
 * @param driver
 *              A QLDB driver.
 * @param ledgerName
 *              The ledger to get digest from.
 * @param vin
 *              VIN to query the revision history of a specific registration with.
 * @throws Exception if failed to verify digests.
 * @throws AssertionError if document revision verification failed.
 */
public static void verifyRegistration(final QldbDriver driver, final String ledgerName, final String vin) throws Exception {
    log.info(String.format("Let's verify the registration with VIN=%s, in ledger=%s.", vin, ledgerName));
    try {
        log.info("First, let's get a digest.");
        GetDigestResult digestResult = GetDigest.getDigest(ledgerName);
        ValueHolder digestTipAddress = digestResult.getDigestTipAddress();
        byte[] digestBytes = Verifier.convertByteBufferToByteArray(digestResult.getDigest());
        log.info("Got a ledger digest. Digest end address={}, digest={}.", QldbStringUtils.toUnredactedString(digestTipAddress), Verifier.toBase64(digestBytes));
        log.info(String.format("Next, let's query the registration with VIN=%s. " + "Then we can verify each version of the registration.", vin));
        List<IonStruct> documentsWithMetadataList = new ArrayList<>();
        driver.execute(txn -> {
            documentsWithMetadataList.addAll(queryRegistrationsByVin(txn, vin));
        });
        log.info("Registrations queried successfully!");
        log.info(String.format("Found %s revisions of the registration with VIN=%s.", documentsWithMetadataList.size(), vin));
        for (IonStruct ionStruct : documentsWithMetadataList) {
            QldbRevision document = QldbRevision.fromIon(ionStruct);
            log.info(String.format("Let's verify the document: %s", document));
            log.info("Let's get a proof for the document.");
            GetRevisionResult proofResult = getRevision(ledgerName, document.getMetadata().getId(), digestTipAddress, document.getBlockAddress());
            final IonValue proof = Constants.MAPPER.writeValueAsIonValue(proofResult.getProof());
            final IonReader reader = IonReaderBuilder.standard().build(proof);
            reader.next();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IonWriter writer = SYSTEM.newBinaryWriter(baos);
            writer.writeValue(reader);
            writer.close();
            baos.flush();
            baos.close();
            byte[] byteProof = baos.toByteArray();
            log.info(String.format("Got back a proof: %s", Verifier.toBase64(byteProof)));
            boolean verified = Verifier.verify(document.getHash(), digestBytes, proofResult.getProof().getIonText());
            if (!verified) {
                throw new AssertionError("Document revision is not verified!");
            } else {
                log.info("Success! The document is verified");
            }
            byte[] alteredDigest = Verifier.flipRandomBit(digestBytes);
            log.info(String.format("Flipping one bit in the digest and assert that the document is NOT verified. " + "The altered digest is: %s", Verifier.toBase64(alteredDigest)));
            verified = Verifier.verify(document.getHash(), alteredDigest, proofResult.getProof().getIonText());
            if (verified) {
                throw new AssertionError("Expected document to not be verified against altered digest.");
            } else {
                log.info("Success! As expected flipping a bit in the digest causes verification to fail.");
            }
            byte[] alteredDocumentHash = Verifier.flipRandomBit(document.getHash());
            log.info(String.format("Flipping one bit in the document's hash and assert that it is NOT verified. " + "The altered document hash is: %s.", Verifier.toBase64(alteredDocumentHash)));
            verified = Verifier.verify(alteredDocumentHash, digestBytes, proofResult.getProof().getIonText());
            if (verified) {
                throw new AssertionError("Expected altered document hash to not be verified against digest.");
            } else {
                log.info("Success! As expected flipping a bit in the document hash causes verification to fail.");
            }
        }
    } catch (Exception e) {
        log.error("Failed to verify digests.", e);
        throw e;
    }
    log.info(String.format("Finished verifying the registration with VIN=%s in ledger=%s.", vin, ledgerName));
}
Also used : IonValue(com.amazon.ion.IonValue) GetDigestResult(com.amazonaws.services.qldb.model.GetDigestResult) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ValueHolder(com.amazonaws.services.qldb.model.ValueHolder) IOException(java.io.IOException) IonStruct(com.amazon.ion.IonStruct) QldbRevision(software.amazon.qldb.tutorial.qldb.QldbRevision) IonReader(com.amazon.ion.IonReader) IonWriter(com.amazon.ion.IonWriter) GetRevisionResult(com.amazonaws.services.qldb.model.GetRevisionResult)

Example 3 with IonValue

use of com.amazon.ion.IonValue in project amazon-qldb-dmv-sample-java by aws-samples.

the class InsertIonTypes method updateRecordAndVerifyType.

/**
 * Update a document's Name value in the database. Then, query the value of the Name key and verify the expected Ion type was
 * saved.
 *
 * @param txn
 *              The {@link TransactionExecutor} for statement execution.
 * @param ionValue
 *              The {@link IonValue} to set the document's Name value to.
 *
 * @throws AssertionError when no value is returned for the Name key or if the value does not match the expected type.
 */
public static void updateRecordAndVerifyType(final TransactionExecutor txn, final IonValue ionValue) {
    final String updateStatement = String.format("UPDATE %s SET Name = ?", TABLE_NAME);
    final List<IonValue> parameters = Collections.singletonList(ionValue);
    txn.execute(updateStatement, parameters);
    log.info("Updated document.");
    final String searchQuery = String.format("SELECT VALUE Name FROM %s", TABLE_NAME);
    final Result result = txn.execute(searchQuery);
    if (result.isEmpty()) {
        throw new AssertionError("Did not find any values for the Name key.");
    }
    for (IonValue value : result) {
        if (!ionValue.getClass().isInstance(value)) {
            throw new AssertionError(String.format("The queried value, %s, is not an instance of %s.", value.getClass().toString(), ionValue.getClass().toString()));
        }
        if (!value.getType().equals(ionValue.getType())) {
            throw new AssertionError(String.format("The queried value type, %s, does not match %s.", value.getType().toString(), ionValue.getType().toString()));
        }
    }
    log.info("Successfully verified value is instance of {} with type {}.", ionValue.getClass().toString(), ionValue.getType().toString());
}
Also used : IonValue(com.amazon.ion.IonValue) IonString(com.amazon.ion.IonString) Result(software.amazon.qldb.Result)

Example 4 with IonValue

use of com.amazon.ion.IonValue in project amazon-qldb-dmv-sample-java by aws-samples.

the class RegisterDriversLicense method registerNewDriversLicense.

/**
 * Register a new driver's license.
 *
 * @param txn
 *              The {@link TransactionExecutor} for lambda execute.
 * @param govId
 *              The government ID of the new owner.
 * @param license
 *              The new license to register.
 * @param personId
 *              The unique personId of the new owner.
 * @throws IllegalStateException if failed to convert document ID to an IonValue.
 */
public static void registerNewDriversLicense(final TransactionExecutor txn, final String govId, final DriversLicense license, final String personId) {
    try {
        if (personHadDriversLicense(txn, personId)) {
            log.info("Person with government ID '{}' already has a license! No new license added.", govId);
            return;
        }
        final String query = "INSERT INTO DriversLicense ?";
        log.info(new IonObjectMapper().writeValueAsIonValue(license).toPrettyString());
        final List<IonValue> parameters = Collections.singletonList(Constants.MAPPER.writeValueAsIonValue(license));
        txn.execute(query, parameters);
        Result result = queryDriversLicenseByPersonId(txn, govId);
        if (ScanTable.toIonStructs(result).size() > 0) {
            log.info("Problem occurred while inserting new license, please review the results.");
        } else {
            log.info("Successfully registered new driver.");
        }
    } catch (IOException ioe) {
        throw new IllegalStateException(ioe);
    }
}
Also used : IonValue(com.amazon.ion.IonValue) IOException(java.io.IOException) IonObjectMapper(com.fasterxml.jackson.dataformat.ion.IonObjectMapper) Result(software.amazon.qldb.Result)

Example 5 with IonValue

use of com.amazon.ion.IonValue in project amazon-qldb-dmv-sample-java by aws-samples.

the class TransferVehicleOwnership method findPrimaryOwnerForVehicle.

/**
 * Find the primary owner for the given VIN.
 *
 * @param txn
 *              The {@link TransactionExecutor} for lambda execute.
 * @param vin
 *              Unique VIN for a vehicle.
 * @return a {@link Person} object.
 * @throws IllegalStateException if failed to convert parameter into {@link IonValue}.
 */
public static Person findPrimaryOwnerForVehicle(final TransactionExecutor txn, final String vin) {
    try {
        log.info("Finding primary owner for vehicle with Vin: {}...", vin);
        final String query = "SELECT Owners.PrimaryOwner.PersonId FROM VehicleRegistration AS v WHERE v.VIN = ?";
        final List<IonValue> parameters = Collections.singletonList(Constants.MAPPER.writeValueAsIonValue(vin));
        Result result = txn.execute(query, parameters);
        final List<IonStruct> documents = ScanTable.toIonStructs(result);
        ScanTable.printDocuments(documents);
        if (documents.isEmpty()) {
            throw new IllegalStateException("Unable to find registrations with VIN: " + vin);
        }
        final IonReader reader = IonReaderBuilder.standard().build(documents.get(0));
        final String personId = Constants.MAPPER.readValue(reader, LinkedHashMap.class).get("PersonId").toString();
        return findPersonFromDocumentId(txn, personId);
    } catch (IOException ioe) {
        throw new IllegalStateException(ioe);
    }
}
Also used : IonValue(com.amazon.ion.IonValue) IonStruct(com.amazon.ion.IonStruct) IonReader(com.amazon.ion.IonReader) IOException(java.io.IOException) Result(software.amazon.qldb.Result)

Aggregations

IonValue (com.amazon.ion.IonValue)185 Test (org.junit.Test)115 IonSequence (com.amazon.ion.IonSequence)61 SymbolTable (com.amazon.ion.SymbolTable)21 IonDatagram (com.amazon.ion.IonDatagram)20 IonStruct (com.amazon.ion.IonStruct)18 IonInt (com.amazon.ion.IonInt)16 IOException (java.io.IOException)14 IonReader (com.amazon.ion.IonReader)13 IonSystem (com.amazon.ion.IonSystem)12 Result (software.amazon.qldb.Result)11 SymbolToken (com.amazon.ion.SymbolToken)10 ArrayList (java.util.ArrayList)10 IonString (com.amazon.ion.IonString)9 IonException (com.amazon.ion.IonException)7 IonType (com.amazon.ion.IonType)6 IonObjectMapper (com.fasterxml.jackson.dataformat.ion.IonObjectMapper)6 Event (com.amazon.tools.events.Event)5 com.amazon.ion.impl._Private_IonValue (com.amazon.ion.impl._Private_IonValue)4 EventType (com.amazon.tools.events.EventType)4