Beispiel #1
0
 def test__get_default_configuration_file_name_from_type_positive(self):
     """Test for _get_default_configuration_file_name_from_type method positive result."""
     _get_default_configuration_file_name_from_type("agent")
     _get_default_configuration_file_name_from_type("connection")
     _get_default_configuration_file_name_from_type("protocol")
     _get_default_configuration_file_name_from_type("skill")
     _get_default_configuration_file_name_from_type("contract")
Beispiel #2
0
def fingerprint_package(package_dir: Path,
                        package_type: Union[str, PackageType]) -> None:
    """
    Fingerprint components of an item.

    :param ctx: the context.
    :param item_type: the item type.
    :param item_public_id: the item public id.
    :return: None
    """
    package_type = PackageType(package_type)
    item_type = str(package_type)
    default_config_file_name = _get_default_configuration_file_name_from_type(
        item_type)
    config_loader = ConfigLoader.from_configuration_type(item_type)
    config_file_path = Path(package_dir, default_config_file_name)
    config = config_loader.load(open_file(config_file_path))

    if not package_dir.exists():
        # we only permit non-vendorized packages to be fingerprinted
        raise ValueError("Package not found at path {}".format(package_dir))

    fingerprints_dict = _compute_fingerprint(
        package_dir, ignore_patterns=config.fingerprint_ignore_patterns
    )  # type: Dict[str, str]

    # Load item specification yaml file and add fingerprints
    config.fingerprint = fingerprints_dict
    config_loader.dump(config, open_file(config_file_path, "w"))
Beispiel #3
0
def _get_item_details(ctx, item_type) -> List[Dict]:
    """Return a list of item details, given the item type."""
    result = []
    item_type_plural = item_type + "s"
    public_ids = getattr(ctx.agent_config,
                         item_type_plural)  # type: Set[PublicId]
    default_file_name = _get_default_configuration_file_name_from_type(
        item_type)
    for public_id in public_ids:
        # first, try to retrieve the item from the vendor directory.
        configuration_filepath = Path(
            ctx.cwd,
            "vendor",
            public_id.author,
            item_type_plural,
            public_id.name,
            default_file_name,
        )
        # otherwise, if it does not exist, retrieve the item from the agent custom packages
        if not configuration_filepath.exists():
            configuration_filepath = Path(ctx.cwd, item_type_plural,
                                          public_id.name, default_file_name)
        configuration_loader = ConfigLoader.from_configuration_type(
            PackageType(item_type))
        details = retrieve_details(public_id.name, configuration_loader,
                                   str(configuration_filepath))
        result.append(details)
    return result
Beispiel #4
0
def _validate_config_consistency(ctx: Context):
    """
    Validate fingerprints for every agent component.

    :param ctx: the context
    :raise ValueError: if there is a missing configuration file.
                       or if the configuration file is not valid.
                       or if the fingerprints do not match
    """
    packages_public_ids_to_types = dict([
        *map(lambda x: (x, PackageType.PROTOCOL), ctx.agent_config.protocols),
        *map(
            lambda x: (x, PackageType.CONNECTION),
            ctx.agent_config.connections,
        ),
        *map(lambda x: (x, PackageType.SKILL), ctx.agent_config.skills),
        *map(lambda x: (x, PackageType.CONTRACT), ctx.agent_config.contracts),
    ])  # type: Dict[PublicId, PackageType]

    for public_id, item_type in packages_public_ids_to_types.items():

        # find the configuration file.
        try:
            # either in vendor/ or in personal packages.
            # we give precedence to custom agent components (i.e. not vendorized).
            package_directory = Path(item_type.to_plural(), public_id.name)
            is_vendor = False
            if not package_directory.exists():
                package_directory = Path("vendor", public_id.author,
                                         item_type.to_plural(), public_id.name)
                is_vendor = True
            # we fail if none of the two alternative works.
            enforce(package_directory.exists(),
                    "Package directory does not exist!")

            loader = ConfigLoaders.from_package_type(item_type)
            config_file_name = _get_default_configuration_file_name_from_type(
                item_type)
            configuration_file_path = package_directory / config_file_name
            enforce(
                configuration_file_path.exists(),
                "Configuration file path does not exist!",
            )
        except Exception:
            raise ValueError("Cannot find {}: '{}'".format(
                item_type.value, public_id))

        # load the configuration file.
        try:
            package_configuration = loader.load(
                configuration_file_path.open("r"))
        except ValidationError as e:
            raise ValueError("{} configuration file not valid: {}".format(
                item_type.value.capitalize(), str(e)))

        _check_aea_version(package_configuration)
        _compare_fingerprints(package_configuration, package_directory,
                              is_vendor, item_type)
Beispiel #5
0
def _add_item(click_context, item_type, item_public_id) -> None:
    """
    Add an item.

    :param click_context: the click context.
    :param item_type: the item type.
    :param item_public_id: the item public id.
    :return: None
    """
    ctx = cast(Context, click_context.obj)
    agent_name = cast(str, ctx.agent_config.agent_name)
    item_type_plural = item_type + "s"
    supported_items = getattr(ctx.agent_config, item_type_plural)

    is_local = ctx.config.get("is_local")

    click.echo("Adding {} '{}' to the agent '{}'...".format(
        item_type, item_public_id, agent_name))

    # check if we already have an item with the same name
    logger.debug("{} already supported by the agent: {}".format(
        item_type_plural.capitalize(), supported_items))
    if _is_item_present(item_type, item_public_id, ctx):
        logger.error("A {} with id '{}/{}' already exists. Aborting...".format(
            item_type, item_public_id.author, item_public_id.name))
        sys.exit(1)

    # find and add protocol
    if item_public_id in [DEFAULT_CONNECTION, DEFAULT_PROTOCOL, DEFAULT_SKILL]:
        package_path = _find_item_in_distribution(ctx, item_type,
                                                  item_public_id)
        _copy_package_directory(ctx, package_path, item_type,
                                item_public_id.name, item_public_id.author)
    elif is_local:
        package_path = _find_item_locally(ctx, item_type, item_public_id)
        _copy_package_directory(ctx, package_path, item_type,
                                item_public_id.name, item_public_id.author)
    else:
        package_path = fetch_package(item_type,
                                     public_id=item_public_id,
                                     cwd=ctx.cwd)
    if item_type in {"connection", "skill"}:
        configuration_file_name = _get_default_configuration_file_name_from_type(
            item_type)
        configuration_path = package_path / configuration_file_name
        configuration_loader = ConfigLoader.from_configuration_type(
            ConfigurationType(item_type))
        item_configuration = configuration_loader.load(
            configuration_path.open())
        _add_protocols(click_context, item_configuration.protocols)

    # add the item to the configurations.
    logger.debug("Registering the {} into {}".format(item_type,
                                                     DEFAULT_AEA_CONFIG_FILE))
    supported_items.add(item_public_id)
    ctx.agent_loader.dump(
        ctx.agent_config,
        open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
def find_item_locally(
        ctx: Context, item_type: str,
        item_public_id: PublicId) -> Tuple[Path, ComponentConfiguration]:
    """
    Find an item in the local registry.

    :param ctx: the CLI context.
    :param item_type: the type of the item to load. One of: protocols, connections, skills
    :param item_public_id: the public id of the item to find.

    :return: tuple of path to the package directory (either in registry or in aea directory) and component configuration

    :raises SystemExit: if the search fails.
    """
    item_type_plural = item_type + "s"
    item_name = item_public_id.name

    # check in registry
    registry_path = (os.path.join(ctx.cwd, ctx.agent_config.registry_path)
                     if ctx.registry_path is None else ctx.registry_path)
    package_path = Path(registry_path, item_public_id.author, item_type_plural,
                        item_name)
    config_file_name = _get_default_configuration_file_name_from_type(
        item_type)
    item_configuration_filepath = package_path / config_file_name
    if not item_configuration_filepath.exists():
        raise click.ClickException("Cannot find {}: '{}'.".format(
            item_type, item_public_id))

    # try to load the item configuration file
    try:
        item_configuration_loader = ConfigLoader.from_configuration_type(
            PackageType(item_type))
        with item_configuration_filepath.open() as fp:
            item_configuration = item_configuration_loader.load(fp)
    except ValidationError as e:
        raise click.ClickException(
            "{} configuration file not valid: {}".format(
                item_type.capitalize(), str(e)))

    # check that the configuration file of the found package matches the expected author and version.
    version = item_configuration.version
    author = item_configuration.author
    if item_public_id.author != author or (
            not item_public_id.package_version.is_latest
            and item_public_id.version != version):
        raise click.ClickException(
            "Cannot find {} with author and version specified.".format(
                item_type))

    return package_path, item_configuration
Beispiel #7
0
def _find_item_locally(ctx, item_type, item_public_id) -> Path:
    """
    Find an item in the registry or in the AEA directory.

    :param ctx: the CLI context.
    :param item_type: the type of the item to load. One of: protocols, connections, skills
    :param item_public_id: the public id of the item to find.
    :return: path to the package directory (either in registry or in aea directory).
    :raises SystemExit: if the search fails.
    """
    item_type_plural = item_type + "s"
    item_name = item_public_id.name

    # check in registry
    registry_path = os.path.join(ctx.cwd, ctx.agent_config.registry_path)
    package_path = Path(registry_path, item_public_id.author, item_type_plural,
                        item_name)
    config_file_name = _get_default_configuration_file_name_from_type(
        item_type)
    item_configuration_filepath = package_path / config_file_name
    if not item_configuration_filepath.exists():
        # then check in aea dir
        registry_path = AEA_DIR
        package_path = Path(registry_path, item_type_plural, item_name)
        item_configuration_filepath = package_path / config_file_name
        if not item_configuration_filepath.exists():
            logger.error("Cannot find {}: '{}'.".format(
                item_type, item_public_id))
            sys.exit(1)

    # try to load the item configuration file
    try:
        item_configuration_loader = ConfigLoader.from_configuration_type(
            ConfigurationType(item_type))
        item_configuration = item_configuration_loader.load(
            item_configuration_filepath.open())
    except ValidationError as e:
        logger.error("{} configuration file not valid: {}".format(
            item_type.capitalize(), str(e)))
        sys.exit(1)

    # check that the configuration file of the found package matches the expected author and version.
    version = item_configuration.version
    author = item_configuration.author
    if item_public_id.author != author or item_public_id.version != version:
        logger.error(
            "Cannot find {} with author and version specified.".format(
                item_type))
        sys.exit(1)

    return package_path
Beispiel #8
0
 def load_agent_config(cls, agent_name: str) -> AgentConfig:
     """Load agent configuration."""
     if agent_name not in cls.agents:
         raise AEATestingException(
             f"Cannot find agent '{agent_name}' in the current test case."
         )
     loader = ConfigLoaders.from_package_type(PackageType.AGENT)
     config_file_name = _get_default_configuration_file_name_from_type(
         PackageType.AGENT
     )
     configuration_file_path = Path(cls.t, agent_name, config_file_name)
     with open_file(configuration_file_path) as file_input:
         agent_config = loader.load(file_input)
     return agent_config
Beispiel #9
0
def load_item_config(item_type: str, package_path: Path) -> PackageConfiguration:
    """
    Load item configuration.

    :param item_type: type of item.
    :param package_path: path to package from which config should be loaded.

    :return: configuration object.
    """
    configuration_file_name = _get_default_configuration_file_name_from_type(item_type)
    configuration_path = package_path / configuration_file_name
    configuration_loader = ConfigLoader.from_configuration_type(PackageType(item_type))
    with open_file(configuration_path) as file_input:
        item_config = configuration_loader.load(file_input)
    return item_config
def find_item_in_distribution(  # pylint: disable=unused-argument
        ctx: Context, item_type: str, item_public_id: PublicId) -> Path:
    """
    Find an item in the AEA directory.

    :param ctx: the CLI context.
    :param item_type: the type of the item to load. One of: protocols, connections, skills
    :param item_public_id: the public id of the item to find.
    :return: path to the package directory (either in registry or in aea directory).
    :raises SystemExit: if the search fails.
    """
    item_type_plural = item_type + "s"
    item_name = item_public_id.name

    # check in aea dir
    registry_path = AEA_DIR
    package_path = Path(registry_path, item_type_plural, item_name)
    config_file_name = _get_default_configuration_file_name_from_type(
        item_type)
    item_configuration_filepath = package_path / config_file_name
    if not item_configuration_filepath.exists():
        raise click.ClickException("Cannot find {}: '{}'.".format(
            item_type, item_public_id))

    # try to load the item configuration file
    try:
        item_configuration_loader = ConfigLoader.from_configuration_type(
            PackageType(item_type))
        with item_configuration_filepath.open() as fp:
            item_configuration = item_configuration_loader.load(fp)
    except ValidationError as e:
        raise click.ClickException(
            "{} configuration file not valid: {}".format(
                item_type.capitalize(), str(e)))

    # check that the configuration file of the found package matches the expected author and version.
    version = item_configuration.version
    author = item_configuration.author
    if item_public_id.author != author or (
            not item_public_id.package_version.is_latest
            and item_public_id.version != version):
        raise click.ClickException(
            "Cannot find {} with author and version specified.".format(
                item_type))

    return package_path  # pragma: no cover
Beispiel #11
0
def dump_item_config(package_configuration: PackageConfiguration,
                     package_path: Path) -> None:
    """
    Dump item configuration.

    :param package_configuration: the package configuration.
    :param package_path: path to package from which config should be dumped.

    :return: None
    """
    configuration_file_name = _get_default_configuration_file_name_from_type(
        package_configuration.package_type)
    configuration_path = package_path / configuration_file_name
    configuration_loader = ConfigLoader.from_configuration_type(
        package_configuration.package_type)
    with configuration_path.open("w") as file_output:
        configuration_loader.dump(package_configuration,
                                  file_output)  # type: ignore
Beispiel #12
0
 def _get_item_dependencies(item_type, public_id: PublicId) -> Dependencies:
     """Get the dependencies from item type and public id."""
     item_type_plural = item_type + "s"
     default_config_file_name = _get_default_configuration_file_name_from_type(
         item_type)
     path = Path(
         "vendor",
         public_id.author,
         item_type_plural,
         public_id.name,
         default_config_file_name,
     )
     if not path.exists():
         path = Path(item_type_plural, public_id.name,
                     default_config_file_name)
     config_loader = ConfigLoader.from_configuration_type(item_type)
     config = config_loader.load(path.open())
     deps = cast(Dependencies, config.dependencies)
     return deps
Beispiel #13
0
def fingerprint_item(ctx: Context, item_type: str, item_public_id: PublicId) -> None:
    """
    Fingerprint components of an item.

    :param ctx: the context.
    :param item_type: the item type.
    :param item_public_id: the item public id.
    :return: None
    """
    item_type_plural = item_type + "s"

    click.echo(
        "Fingerprinting {} components of '{}' ...".format(item_type, item_public_id)
    )

    # create fingerprints
    package_dir = Path(ctx.cwd, item_type_plural, item_public_id.name)
    try:
        default_config_file_name = _get_default_configuration_file_name_from_type(
            item_type
        )
        config_loader = ConfigLoader.from_configuration_type(item_type)
        config_file_path = Path(package_dir, default_config_file_name)
        config = config_loader.load(config_file_path.open())

        if not package_dir.exists():
            # we only permit non-vendorized packages to be fingerprinted
            raise click.ClickException(
                "Package not found at path {}".format(package_dir)
            )

        fingerprints_dict = _compute_fingerprint(
            package_dir, ignore_patterns=config.fingerprint_ignore_patterns
        )  # type: Dict[str, str]

        # Load item specification yaml file and add fingerprints
        config.fingerprint = fingerprints_dict
        config_loader.dump(config, open(config_file_path, "w"))
    except Exception as e:
        raise click.ClickException(str(e))