Example #1
0
def populate_categories():
    """ask blockchain for categories and update the database
    """
    if app.config["BYPASS_API_CALLS"] or app.config["BYPASS_LEDGER_CALLS"]:
        return

    print("Retrieving blockchain categories ...")
    categories = get_blockchain_categories()

    # delete old categories if their UUID's no longer exists

    new_uuids = [category_dict["uuid"] for category_dict in categories]
    parts = db_session.query(Part).all()

    for category in db_session.query(Category).all():
        if category.uuid not in new_uuids:
            db_session.delete(category)

            # delete all the parts relations that had this category

            for part in parts:
                for part_category in part.categories:
                    if part_category.uuid == category.uuid:
                        part.categories.remove(part_category)

    db_session.flush()

    # update existing or insert new categories

    for category_dict in categories:
        category_query = db_session.query(Category).filter(
            Category.uuid == category_dict["uuid"])

        if category_query.count() == 1:
            # update
            category = category_query.one()
            category.name = category_dict["name"]
            category.description = category_dict["description"]
        else:
            # insert
            category = Category()
            category.uuid = category_dict["uuid"]
            category.name = category_dict["name"]
            category.description = category_dict["description"]
            db_session.add(category)

    db_session.flush()
    db_session.commit()
Example #2
0
def delete_part():
    """json route for deleting a part. expects part_id.
    """
    response_data = {}
    data = request.json

    # validate supplier password

    response_data["incorrect_password"] = \
        not supplier_password_is_correct(data["supplier_id"], data["password"])
    if response_data["incorrect_password"]:
        return jsonify(response_data)

    # make sure that the part exists

    part_query = db_session.query(Part).filter(Part.id == data["part_id"])
    response_data["part_exists"] = (part_query.count() == 1)

    if not response_data["part_exists"]:
        return jsonify(response_data)

    try:
        part = part_query.one()

        db_session.delete(part)
        db_session.flush()

        if part.envelope:
            delete_envelope(part.envelope)

        db_session.commit()
        response_data["failed"] = False
    except:
        response_data["failed"] = True
        response_data["error_message"] = stacktrace()

    return jsonify(response_data)
Example #3
0
def delete_envelope(envelope):
    """delete envelope and all its associated artifacts, boms, and files
    """
    if envelope.boms:
        boms = envelope.boms[:]
        envelope.boms = []
        db_session.flush()

        for bom in boms:
            bomitems = bom.items[:]
            bom.items = []
            db_session.flush()

            for item in bomitems:
                db_session.delete(item)

            db_session.flush()
            db_session.delete(bom)
            db_session.flush()

    artifacts = envelope.artifacts[:]
    envelope.artifacts = []
    db_session.flush()

    for artifact in artifacts:
        db_session.delete(artifact)
        artifact_path = os.path.join(app.config["ARTIFACT_FOLDER"],
                                     artifact.checksum)
        if os.path.exists(artifact_path):
            os.remove(artifact_path)

    db_session.delete(envelope)
    db_session.flush()
    db_session.commit()

    shutil.rmtree(envelope.extract_dir)
Example #4
0
def reset_handler():
    """respond to conductor call RESET by purging the database and repopulating with sample data
    """
    response_data = {}

    try:

        # clear all the tables

        for part in db_session.query(Part).all():
            part.categories = []
            part.envelope = None
            part.supplier = None
            db_session.delete(part)

        db_session.flush()

        db_session.query(Category).delete()
        db_session.query(Supplier).delete()

        for envelope in db_session.query(Envelope).all():
            envelope.boms = []
            envelope.artifacts = []
            db_session.delete(envelope)

        db_session.flush()

        for bom in db_session.query(BOM).all():
            bom.items = []
            bom.artifact = None
            db_session.delete(bom)

        db_session.flush()

        db_session.query(Artifact).delete()
        db_session.query(BOMItem).delete()

        db_session.flush()
        db_session.commit()

        # delete all envelope and artifact files

        empty_directory(app.config["UPLOAD_FOLDER"])
        empty_directory(app.config["ARTIFACT_FOLDER"])

        # insert suppliers

        for supplier_dict in read_csv_file("suppliers.csv"):

            supplier = Supplier()
            supplier.name = supplier_dict["name"]
            supplier.uuid = supplier_dict["uuid"]
            supplier.password = hashlib.md5(codecs.encode(supplier_dict["password"], "utf-8"))\
                .hexdigest()
            supplier.blockchain = (supplier_dict["blockchain"] == "true")

            if supplier.blockchain:
                supplier.save_to_blockchain()

            db_session.add(supplier)

        db_session.flush()

        # insert categories

        categories_by_uuid = {}

        for category_dict in read_csv_file("categories.csv"):
            category = Category()
            category.name = category_dict["name"]
            category.uuid = category_dict["uuid"]
            category.description = category_dict["description"]
            db_session.add(category)

            category.save_to_blockchain()

            categories_by_uuid[category.uuid] = category

        db_session.flush()

        # read part category association table

        part_category_instances = {}

        for part_category_relation in read_csv_file("part-categories.csv"):
            if part_category_relation[
                    "part_uuid"] not in part_category_instances:
                part_category_instances[
                    part_category_relation["part_uuid"]] = []

            part_category_instances[part_category_relation["part_uuid"]].append( \
                categories_by_uuid[part_category_relation["category_uuid"]])

        # insert parts

        categories = db_session.query(Category).all()

        for part_dict in read_csv_file("parts.csv"):

            part = Part()

            part_supplier_query = db_session.query(Supplier)\
                .filter(Supplier.uuid == part_dict["supplier_uuid"])

            assert part_supplier_query.count() == 1, \
                "Invalid supplier UUID in the following sample part. \n" \
                + json.dumps(part_dict) + " Could not find a supplier with UUID '" \
                + part_dict["supplier_uuid"] + "'"

            part.supplier = part_supplier_query.one()

            part.blockchain = (part_dict["blockchain"] == "true")

            for field in ["uuid", "usku", "supplier_part_id", "name", "version", \
                "licensing", "url", "status", "description", "checksum", "src_uri"]:

                setattr(part, field, part_dict[field])

            if part.uuid in part_category_instances:
                for category in part_category_instances[part.uuid]:
                    part.categories.append(category)

            db_session.add(part)

            if part.blockchain:

                part.save_to_blockchain()

                for category in part.categories:
                    save_part_category_relation(part, category)

                save_part_supplier_relation(part, part.supplier)

        db_session.flush()

        # read envelope part association table

        envelope_parts = {}

        for envelope_parts_dict in read_csv_file("part-envelopes.csv"):
            envelope_parts[envelope_parts_dict[
                "envelope_uuid"]] = envelope_parts_dict["part_uuid"]

        # unpack and parse envelopes

        for envelope_path in glob.glob(\
                os.path.join(app.config["SAMPLE_DATA_FOLDER"], "envelopes/*")):

            envelope = create_envelope(envelope_path)

            part_query = db_session.query(Part).filter(
                Part.uuid == envelope_parts[envelope.uuid])

            assert part_query.count() == 1, \
                "Invalid sample data. No part was found with UUID " + envelope_parts[envelope.uuid]

            part = part_query.one()
            part.envelope = envelope
            envelope.blockchain = part.blockchain

            if envelope.blockchain:
                envelope.save_to_blockchain()
                save_part_envelope_relation(part, envelope)

            db_session.flush()

        db_session.commit()

        response_data["status"] = "success"

    except AssertionError as error:
        response_data["status"] = "failed"
        response_data["error_message"] = str(error)

    except APIError as error:
        response_data["status"] = "failed"
        response_data["error_message"] = "Encountered an error while calling blockchain API. " \
            + str(error)

    except (OSError, IOError):
        response_data["status"] = "failed"
        response_data["error_message"] = stacktrace()

    except:
        response_data["status"] = "failed"
        response_data[
            "error_message"] = "Unhandled Exception \n\n" + stacktrace()

    return jsonify(response_data)