The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Data::Conveyor::Service::Methods - service method definitions

SYNOPSIS

   package My::Service::Methods;

   use warnings;
   use strict;

   use base 'Data::Conveyor::Service::Methods';

   sub SERVICE_METHODS {
     domain_tickets => {
         object => 'ticket',
         $_[0]->PARAMS(
             "+domain|d=s  Domain name.",
             "?limit|l=s   Limit number of rows returned.",
         ),
         description => "...",
         examples => [
             { domain => 'foo.at' },
             { domain => 'xn--brse-5qa.at' },
             { domain => ':b\x{F6}rse.at' },
             { domain => ':börse.at' },
         ],
     };
   }
     
   1;

DESCRIPTION

The service methods and interfaces make it possible to service the machinery while it is running.

WRITING A NEW SERVICE METHOD

As seen in the synopsis, you're probably going to have a separate class derived from Data::Conveyor::Service::Methods which you use to define your custom service methods in.

In the SERVICE_METHODS hash, which will be collected using Data::Inherited's every_hash(), you have to write the definition of your service methods.

You have to specify the method name and the object type - see the environment classes' GENERAL_CLASS_NAME_HASH for details - on which the method is called. You also have to specify the number and types of parameters which the method takes. You can optionally give a description and examples of usage.

There are some shorthands which make that job easier. If you adhere to certain naming conventions, it gets easier still.

The example in the synopsis defines a service method called domain_tickets, which is called on the ticket class, meaning the class implementing the ticket object type as defined in the environment. Because the method name is not defined, the method is expected to be called sif_domain_tickets. If it was called something different, you could specify the name using the method key within the specification hash.

As you can see from the description, it shows tickets regarding a certain domain - the service method is intended to be used within a domain registry. The method takes two parameters.

The first one specifies the domain name. It is mandatory, indicated by the plus sign at the beginning of the parameter specification. For service interfaces that support parameter name abbreviations (e.g., the shell service interface), the parameter can be abbreviated to d. The =s tells us that it takes a string argument.

The second argument is used to limit the number of resulting rows that is returned by the service method. It too has an abbreviation, l, but it is optional, as indicated by the question mark at the beginning of the parameter specification. It too takes a string argument. Actually, only a numeric argument will make sense, but that's for the service method implementation to check.

Each service interface - shell and SOAP, for example - will, upon startup, ask the service methods object for the specifications of all the service methods it knows. This is, as has been noted, done by combining the output of all the SERVICE_METHODS() down the class hierarchy. The service interface will then interpret these specifications according to its own design.

Therefore each service interface is just a wrapper around the service methods.

For example, for the shell service interface, there is a help command giving details about the service methods. These details are taken directly from the specification. Parameters given to the service interface call are also checked against the service method's parameter specifications.

A service interface doesn't have to use all of the information contained in the specification. For example, the SOAP service interface does not support parameter name abbreviations, so it doesn't use them.

Let's look at the actual implementation of the service method. To continue the example given in the synopsis, here is a sample implementation of the domain_tickets service method:

    sub sif_domain_tickets {
        my ($self, %opt) = @_;
        assert_getopt $opt{domain}, 'Called without domain name.';
        assert_getopt $opt{limit},  'Called without limit.';
        $self->delegate->make_obj('service_result_tabular')->set_from_rows(
            limit  => $limit,
            fields => [ qw/ticket_no stage status ticket_type origin
                           real effective mdate/ ],
            rows   => scalar $self->storage->get_object_tickets(
                normalize_to_ace($opt{domain}), $opt{limit},
            ),
        );
    }

The relevant things here are that the service method gets its arguments in a hash, first uses assert_getopt() to check the existence of arguments, then it constructs a tabular service result object which it populates with the results from a storage call. Each service method gets its arguments in a hash. Each service method needs to construct a service result object (tabular or otherwise) in which it has to return the results. It needs to return this result object - here, the set_from_rows() call returns the result object.

If anything goes wrong during the the service method call, the method should throw an exception. The service interface will then act upon the exception accordingly. For example, the shell service interface will print the exception's text. assert_getopt() also throws a special exception, if necessary.

Here is a more detailed explanation of how to specify parameters. The specification given in the synopsis, repeated here:

    $_[0]->PARAMS(
        "+domain|d=s  Domain name.",
        "?limit|l=s   Limit number of rows returned.",
    ),

is actually equivalent to:

    params => [
        { name        => 'domain',
          short       => 'd',
          type        => $self->delegate->SIP_STRING,
          necessity   => $self->delegate->SIP_MANDATORY,
          description => 'Domain name.',
        },
        { name        => 'limit',
          short       => 'l',
          type        => $self->delegate->SIP_STRING,
          necessity   => $self->delegate->SIP_OPTIONAL,
          description => 'Limit number of rows returned.',
        },
    ],

You can also give set a default value for a parameter using the default hash key. The short notation used in the synopsis can be defined as:

    <necessity><name>|<short>[=<type>][><default>]

The necessity can be either + (mandatory) or ? (optional). 'name' and 'short' are the parameter names. The type can be =s to indicate that the parameter takes a string value, or empty to indicate a boolean parameter. 'type' and 'default' are optional.

METHODS

Data::Conveyor::Service::Methods inherits from Data::Conveyor::Service.

The superclass Class::Scaffold::Storable defines these methods and functions:

    MUNGE_CONSTRUCTOR_ARGS(), clear_storage_info(), clear_storage_type(),
    delete_storage_info(), exists_storage_info(), id(),
    keys_storage_info(), storage(), storage_info(), storage_info_clear(),
    storage_info_delete(), storage_info_exists(), storage_info_keys(),
    storage_info_values(), storage_type(), storage_type_clear(),
    values_storage_info()

The superclass Class::Scaffold::Base defines these methods and functions:

    new(), FIRST_CONSTRUCTOR_ARGS(), add_autoloaded_package(), init(),
    log()

The superclass Data::Inherited defines these methods and functions:

    every_hash(), every_list(), flush_every_cache_by_key()

The superclass Data::Comparable defines these methods and functions:

    comparable(), comparable_scalar(), dump_comparable(),
    prepare_comparable(), yaml_dump_comparable()

The superclass Class::Scaffold::Delegate::Mixin defines these methods and functions:

    delegate()

The superclass Class::Scaffold::Accessor defines these methods and functions:

    mk_framework_object_accessors(), mk_framework_object_array_accessors(),
    mk_readonly_accessors()

The superclass Class::Accessor::Complex defines these methods and functions:

    mk_abstract_accessors(), mk_array_accessors(), mk_boolean_accessors(),
    mk_class_array_accessors(), mk_class_hash_accessors(),
    mk_class_scalar_accessors(), mk_concat_accessors(),
    mk_forward_accessors(), mk_hash_accessors(), mk_integer_accessors(),
    mk_new(), mk_object_accessors(), mk_scalar_accessors(),
    mk_set_accessors(), mk_singleton()

The superclass Class::Accessor defines these methods and functions:

    _carp(), _croak(), _mk_accessors(), accessor_name_for(),
    best_practice_accessor_name_for(), best_practice_mutator_name_for(),
    follow_best_practice(), get(), make_accessor(), make_ro_accessor(),
    make_wo_accessor(), mk_accessors(), mk_ro_accessors(),
    mk_wo_accessors(), mutator_name_for(), set()

The superclass Class::Accessor::Installer defines these methods and functions:

    install_accessor()

The superclass Class::Accessor::Constructor defines these methods and functions:

    _make_constructor(), mk_constructor(), mk_constructor_with_dirty(),
    mk_singleton_constructor()

The superclass Class::Accessor::FactoryTyped defines these methods and functions:

    clear_factory_typed_accessors(), clear_factory_typed_array_accessors(),
    count_factory_typed_accessors(), count_factory_typed_array_accessors(),
    factory_typed_accessors(), factory_typed_accessors_clear(),
    factory_typed_accessors_count(), factory_typed_accessors_index(),
    factory_typed_accessors_pop(), factory_typed_accessors_push(),
    factory_typed_accessors_set(), factory_typed_accessors_shift(),
    factory_typed_accessors_splice(), factory_typed_accessors_unshift(),
    factory_typed_array_accessors(), factory_typed_array_accessors_clear(),
    factory_typed_array_accessors_count(),
    factory_typed_array_accessors_index(),
    factory_typed_array_accessors_pop(),
    factory_typed_array_accessors_push(),
    factory_typed_array_accessors_set(),
    factory_typed_array_accessors_shift(),
    factory_typed_array_accessors_splice(),
    factory_typed_array_accessors_unshift(),
    index_factory_typed_accessors(), index_factory_typed_array_accessors(),
    mk_factory_typed_accessors(), mk_factory_typed_array_accessors(),
    pop_factory_typed_accessors(), pop_factory_typed_array_accessors(),
    push_factory_typed_accessors(), push_factory_typed_array_accessors(),
    set_factory_typed_accessors(), set_factory_typed_array_accessors(),
    shift_factory_typed_accessors(), shift_factory_typed_array_accessors(),
    splice_factory_typed_accessors(),
    splice_factory_typed_array_accessors(),
    unshift_factory_typed_accessors(),
    unshift_factory_typed_array_accessors()

The superclass Class::Scaffold::Factory::Type defines these methods and functions:

    factory_log()

The superclass Class::Factory::Enhanced defines these methods and functions:

    add_factory_type(), make_object_for_type(), register_factory_type()

The superclass Class::Factory defines these methods and functions:

    factory_error(), get_factory_class(), get_factory_type_for(),
    get_loaded_classes(), get_loaded_types(), get_my_factory(),
    get_my_factory_type(), get_registered_class(),
    get_registered_classes(), get_registered_types(),
    remove_factory_type(), unregister_factory_type()

The superclass Class::Accessor::Constructor::Base defines these methods and functions:

    STORE(), clear_dirty(), clear_hygienic(), clear_unhygienic(),
    contains_hygienic(), contains_unhygienic(), delete_hygienic(),
    delete_unhygienic(), dirty(), dirty_clear(), dirty_set(),
    elements_hygienic(), elements_unhygienic(), hygienic(),
    hygienic_clear(), hygienic_contains(), hygienic_delete(),
    hygienic_elements(), hygienic_insert(), hygienic_is_empty(),
    hygienic_size(), insert_hygienic(), insert_unhygienic(),
    is_empty_hygienic(), is_empty_unhygienic(), set_dirty(),
    size_hygienic(), size_unhygienic(), unhygienic(), unhygienic_clear(),
    unhygienic_contains(), unhygienic_delete(), unhygienic_elements(),
    unhygienic_insert(), unhygienic_is_empty(), unhygienic_size()

The superclass Tie::StdHash defines these methods and functions:

    CLEAR(), DELETE(), EXISTS(), FETCH(), FIRSTKEY(), NEXTKEY(), SCALAR(),
    TIEHASH()

BUGS AND LIMITATIONS

No bugs have been reported.

Please report any bugs or feature requests through the web interface at http://rt.cpan.org.

INSTALLATION

See perlmodinstall for information and options on installing Perl modules.

AVAILABILITY

The latest version of this module is available from the Comprehensive Perl Archive Network (CPAN). Visit <http://www.perl.com/CPAN/> to find a CPAN site near you. Or see <http://www.perl.com/CPAN/authors/id/M/MA/MARCEL/>.

AUTHORS

Florian Helmberger <fh@univie.ac.at>

Achim Adam <ac@univie.ac.at>

Mark Hofstetter <mh@univie.ac.at>

Heinz Ekker <ek@univie.ac.at>

Marcel Grünauer, <marcel@cpan.org>

COPYRIGHT AND LICENSE

Copyright 2004-2008 by the authors.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.