blob: 21f36ea06245703f6ab54e22f0d1c7ad2bc79621 [file] [log] [blame]
/* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
module org.apache.etch.services.ns
/**
* The NameService provides translation from an abstract name for a service to a
* uri that may be used to contact the service. A given service may offer
* several different connection schemes, and a client may only support a subset
* of those. So, when a client wishes to connect to a service, it may query
* the NameService with both abstract name and desired schemes in order to find
* a suitable match.
*
* Some example queries:
*
* All services with servicename='Foo' and instancename='bar' and qualifier='tcp'
*
* sourceUri='Foo/bar/tcp'
*
* Same as the query above, but written out longhand:
*
* servicename='Foo' and instancename='bar' and qualifier='tcp'
*
* Fully qualified sourceUri:
*
* sourceUri='Foo/bar/tcp/1'
*
* Any instance of service Foo located in Austin, TX:
*
* servicename='Foo' and qualities.location='Austin, TX'
*
* Instances of service Foo with capacity >= 400:
*
* servicename='Foo' and qualities.capacity>=400
*
* Relative operations on qualities require that the quality be present and be
* comparable (with mixed types some type promotion is supported). But you might
* be surprised, qualities which are absent will give a negative comparison no
* matter which sense is used: both qualities.x > 50 and qualities.x < 50 are
* false whenever qualities.x is null. Consider this test: not qualities.x < 50.
* This is not the same as qualities.x >= 50. It is the same as qualities.x =
* null or qualities.x >= 50.
*/
@Timeout( 30000 )
service NameService
{
/** An entry describing a service. */
struct Entry
(
/** A service description uri, composed of
* servicename/instancename/qualifier[/priority]. */
string sourceUri,
/** Qualities of this service instance. */
Map qualities,
/** Etch service connection uri, for example
* tcp://localhost:9000?filter=KeepAlive */
string targetUri,
/** Lifetime in seconds from last update. */
int ttl,
/** Who created or last update. */
string who,
/** Date / time of create or last update. */
Datetime lastUpdate,
/** Flag indicating entry has been removed. */
boolean removed
)
/**
* Look up an entry by matching it against the sourceUri.
*
* @param source source uri
*
* @return entry matching the source uri. In the case of an
* absent instance name or qualifier, the implementation
* can decide which Entry to return.
*/
@Authorize( canLookup, source )
Entry lookup( string source )
/**
* Looks up entries by matching them against the query string. Entries are
* returned in a stable and consistent order, increasing alphabetical by
* servicename, instancename, and scheme, and then increasing numerical by
* priority. If a scheme search term appears with a list, schemes are
* returned in the specified order (e.g., scheme='tls,tcp').
*
* @param query a sql-like query expression using the elements of the
* sourceUri, targetUri, and qualities. If query is null or the empty
* string, all entries are matched.
*
* @param offset offset in the list of matched items of the first item to
* return. This parameter and the count parameter are used to step through
* the result set when there are many results.
*
* @param count number of items to return.
*
* @return entries matching query. If you requested 10 items and 10 are
* returned, there could be more. To get the next batch, add results.length
* to offset and call find again:
*
* int i = 0;
* int n = 10;
* Entry[] results;
* while ((results = service.find( null, i, n )).length > 0)
* {
* for (Entry e: results)
* processEntry( e );
* if (results.length < n)
* break;
* i += results.length;
* }
*/
@Authorize( canFind, query )
Entry[] find( string query, int offset, int count )
/**
* Adds or updates the specified entry. The given parameters replace any
* existing values in an Entry whose key is sourceUri, whereas who and
* lastUpdate are set to the current user and current date / time,
* respectively.
*
* @param sourceUri the uri describing the service. The uri should be of
* the form "servicename/instancename/scheme[/priority]", where servicename
* is a valid fully qualified service name (e.g.,
* etch.services.ns.NameService"), instancename is a valid etch identifier
* (e.g, fred, alice01), scheme is a valid uri scheme (e.g., tcp, tls), and
* priority is an integer >= 1. If priority is omitted, it is defaulted to
* 1.
*
* @param qualities a map which may be used to describe additional features
* of the entry, such as purpose, licenses, capacity, location, owner,
* whatever. Query strings may test values of qualities using a variety of
* sql-like operators. Qualities may be null.
*
* @param targetUri the uri describing the contact information for the
* service.
*
* @param ttl the lifetime of the entry specified as seconds. 0 means
* forever, -1 means remove immediately when the connection to the
* NameService is dropped.
*/
@Authorize( canRegister, sourceUri, qualities, targetUri )
void register( string sourceUri, Map qualities, string targetUri, int ttl )
/**
* Registers a number of entries all in one operation. Identical to calling
* register with each entry in turn.
*
* @param entries a sequence of Entry records with sourceUri, targetUri,
* qualities, and ttl as specified in register() above. Who and lastUpdate
* fields are ignored.
*/
@Authorize( canRegisterBulk, entries )
void registerBulk( Entry[] entries )
/**
* Removes the specified entry.
*
* @param sourceUri the uri describing the service.
*/
@Authorize( canUnregister, sourceUri, deleteEntry )
void unregister( string sourceUri, boolean deleteEntry )
/**
* Adds a request for notification of changes to entries matching the query.
* The current value of all matching entries is delivered via entryChanged
* client message, as well as any updates or new entries.
*
* @param query a sql-like query expression using the elements of the
* sourceUri, targetUri, and qualities. If query is null or the empty
* string, all entries are matched.
*/
@Authorize( canFind, query )
void subscribe( string query )
/**
* Removes a request for notification of changes to entries matching the
* query.
*
* @param query a query previously passed to subscribe. The string must
* match exactly.
*/
void unsubscribe( string query )
/**
* Removes all requests for notification of changes to entries. This
* operation is implicitly performed when the connection to the NameService
* is dropped.
*/
void unsubscribeAll()
////////////////////
// RIGHTS TESTING //
////////////////////
/**
* Tests whether the current user is authorized to lookup the source.
* @param source the complete specification api/instance/scheme.
*/
boolean canLookup( string source )
/**
* Tests whether the current user is authorized to run the query.
*
* @param query a sql-like query expression using the elements of the
* sourceUri, targetUri, and qualities. If query is null or the empty
* string, all entries are matched.
*
* @return true if the current user is authorized to run the query.
*/
boolean canFind( string query )
/**
* Tests whether the current user is authorized to register the service.
*
* @param sourceUri the uri describing the service.
*
* @param qualities a map which may be used to describe additional features
* of the entry.
*
* @param targetUri the actual uri of the service
*
* @return true if the current user is authorized to register the service.
*/
boolean canRegister( string sourceUri, Map qualities, string targetUri )
/**
* Tests whether the current user is authorized to unregister the service.
*
* @param sourceUri the uri describing the service.
*
* @param deleteEntry if true, the entire entry matching the sourceUri
* would be deleted. if false, only the target uri matching the sourceUri
* would be deleted, but the entry would be intact.
*
* @return true if the current user is authorized to register the service.
*/
boolean canUnregister( string sourceUri, boolean deleteEntry )
/**
* Tests whether the current user is authorized to register the entries.
* This is the same as:
*
* for (Entry entry: entries)
* if (!canRegister( entry.sourceUri, entry.qualities ))
* return false;
* return true;
*
* @param entries a sequence of Entry records with sourceUri, targetUri,
* qualities, and ttl as specified in register() above. Who and lastUpdate
* fields are ignored.
*
* @return true if the current user is authorized to register the entries.
* This is an all or nothing proposition.
*/
boolean canRegisterBulk( Entry[] entries )
////////////////////
// CLIENT METHODS //
////////////////////
/**
* Notifies the client of a change in an entry. The entry might have been
* created, updated, or removed.
*
* Note: while this might have normally been an event, we made it a call
* to slow down the processing of what might otherwise be a rather large
* change set.
*
* Note: when keeping track of entries, always keep the one with the latest
* lastUpdate.
*
* @param query the query which triggered the notification.
*
* @param entry the entry which has changed.
*/
@Direction( client )
void entryChanged( string query, Entry entry )
}