river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Firmstone <j...@zeus.net.au>
Subject Re: MarshalledServiceItem
Date Tue, 01 Feb 2011 02:35:12 GMT
Gregg Wonderly wrote:
> One of the important things for my use of my changes to the ServiceRegistrar interface
was separating deserialization of the Entrys from the service object.  Ultimately, I wanted
to not have to worry about how the "codebase" was structured in order to minimize downloading.
Some Jini deployers have done things to put a small jar at the front of the codebase that
just has the preferred.list in it.  Even that download, for me, would have been too much.
 My customers' deployments have nearly 50 codebases visible when my client starts up.  Those
50 connections over a cellular or other high latency network would make service selection
take way too long.
>
> Being able to defer downloading was also controlled by the changes to ClassLoading to
include the "neverPrefer" settings on a class name.  I can do that now through the recent
RMIClassLoaderSPI override capabilities.  But I still need to be able to control which Entry
is deserialized.  I need to be able to ask what classes, by name, are in the namespace of
each Entry object as my implementation allowed. I had made changes to Reggie marshalling to
use reflection to get the class hierarchy, and then provided access to the list of classnames
as part of the returned, marshalled value in my API.
>
> Gregg Wonderly
>
> On Jan 30, 2011, at 2:23 PM, Peter Firmstone wrote:
>   
>
Thanks Gregg,

What follows, is an interface for a lookup service, that extends the 
existing ServiceRegistrar lookup service interface, enabling existing 
clients to utilise the existing discovery mechanisms and interfaces.

I researched your implementation before writing this, so I was strongly 
influenced by your lookup service, delayed umarshalling and selective 
unmarshalling of Entry's are very important features, missing from River.

I wanted to utilise the features you created, at the same time, I wanted 
a lookup service for the internet, so it also needed to be able to 
retrieve an almost infinite collection of results incrementally, over 
time, that may contain duplicates using a ResultStream (somewhat similar 
to MatchSet in javaspaces).  In the lookup method below, the caller can 
provide the Class files of any Entry's it's interested in, after first 
retrieving and determining them using a ServiceTemplate and 
ResultStream.  A ResultStream can use filter chaining where each filter 
performs a single simple operation (like proxy verification, 
unmarshalling, Entry based comparison, or removal), and can utilise the 
existing ServiceItemFilter interface (when applicable), uninteresting 
services can be removed from the ResultStream, or categorised and placed 
in different queues for parallel processing, or left in the stream for 
serial processing.

Once you've built a filter based result stream, this can be reused over 
and over, to process lookup results from multiple lookup services.

I have plans to create some DNS-SRV discovery support classes, used to 
produce LookupLocator's (actually a subclass of LookupLocator), to be 
used by LookupLocatorDiscovery, using Unicast discovery to find lookup 
services all over the internet.  Each domain should be responsible for 
providing lookup services for all public Jini Services it provides.

Another piece in the puzzle relates to ensuring we're reasonably 
protected against unmarshalling DOS attacks, before proxy trust is 
established.

So what I've got here is a small part of a much larger puzzle, I'm very 
interested to hear your thoughts, have your input and make changes based 
on your recommendations, and admit that the interface below has been 
inspired by your work that long preceded it.

Best regards & many thanks,

Peter.

/*
 * 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.
 */
package org.apache.river.api.lookup;

import java.io.IOException;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;
import net.jini.core.lookup.ServiceItem;
import org.apache.river.api.util.ResultStream;

/**
 * Defines the interface to the lookup service.  The interface is not a
 * remote interface; each implementation of the lookup service exports
 * proxy objects that implement the StreamServiceRegistrar interface 
local to
 * the client, using an implementation-specific protocol to communicate
 * with the actual remote server.  All of the proxy methods obey normal
 * RMI remote interface semantics except where explicitly noted.  Two
 * proxy objects are equal if they are proxies for the same lookup service.
 * Every method invocation (on both StreamServiceRegistrar and 
ServiceRegistration)
 * is atomic with respect to other invocations.
 *
 * The StreamServiceRegistrar is intended to perform the same function
 * as the ServiceRegistrar, but with the ability to return results as a
 * stream, so memory consumption can be minimised at the client.
 *
 * All clients utilising ServiceRegistrar, should switch to the
 * StreamServiceRegistrar.
 *
 * @see ServiceRegistrar
 * @see PortableServiceRegistrar
 * @see ServiceRegistration
 * @author Peter Firmstone
 * @since 2.2.0
 */
public interface StreamServiceRegistrar extends ServiceRegistrar{

    /**
     * Returns a ResultStream that provides access to MarshalledServiceItem
     * instances.  The ResultStream terminates with a null value.  The 
result
     * stream may be infinite.
     *
     * MarshalledServiceItem extends ServiceItem and can be used anywhere a
     * ServiceItem can.  A MarshalledServiceItem implementation instance
     * contains the marshalled form of a Service and it's Entry's,
     * the corresponding superclass ServiceItem however contains null values
     * for the service and excludes any Entry's that are not 
specifically requested
     * unmarshalled by this method. The ServiceID will be unmarshalled 
always.
     *
     * This method is designed to allow the caller to control exactly what
     * is unmarshalled and when, it allows unmarshalling of specific entries
     * that the caller may wish to utilise for filtering. It is
     * designed to allow both the caller and the implementer to deal 
with very
     * large result sets in an incremental fashion.
     *
     * It is absolutely essential that the caller closes and deletes any 
references to
     * the returned result stream as soon as it is no longer requried.
     *
     * @param tmpl template to match
     * specified template
     * @param unmarshalledEntries only Entry's with these classes will be in
     * unmarshalled form.
     * @param maxBatchSize Allows the caller to limit the number of results
     * held locally, larger batch sizes reduce network traffic, but may 
delay
     * processing locally depending on implementation.
     * @return ResultStream containing ServiceItem's
     * @throws java.rmi.RemoteException
     * @see MarshalledServiceItem
     * @see ServiceItem
     * @see ResultStream
     * @see ServiceResultStreamFilter
     * @see ResultStreamUnmarshaller
     * @since 2.2.0
     */
    ResultStream lookup(ServiceTemplate tmpl,
        Class[] unmarshalledEntries, int maxBatchSize) throws IOException;
   
    /**
     * Looks at all service items that match the specified template, finds
     * every entry (among those service items) that either doesn't match any
     * entry templates or is a subclass of at least one matching entry
     * template, and returns the set of the (most specific) classes of those
     * entries.  Duplicate classes are eliminated, and the order of classes
     * within the returned array is arbitrary.  Null (not an empty array) is
     * returned if there are no such entries or no matching items.  If a
     * returned class cannot be deserialized, that element of the returned
     * array is set to null and no exception is thrown.
     *
     * @param tmpl template to match
     * @param maxBatchSize
     * @return a ResultStream containing Class of entry (attribute sets) 
for every service
     * that matches the specified template
     * @throws java.rmi.RemoteException
     */
    ResultStream getEntryClasses(ServiceTemplate tmpl, int maxBatchSize)
            throws IOException;

    /**
     * Looks at all service items that match the specified template, finds
     * every entry (among those service items) that matches
     * tmpl.attributeSetTemplates[setIndex], and returns the set of values
     * of the specified field of those entries.  Duplicate values are
     * eliminated, and the order of values isarbitrary. 
     * If a returned value cannot be deserialized, that
     * element is excluded and no exception is thrown.
     *
     * @param tmpl template to match
     * @param setIndex index into tmpl.attributeSetTemplates
     * @param field name of field of tmpl.attributeSetTemplates[setIndex]
     *
     * @param maxBatchSize
     * @return a ResultStream of objects that represents field values of 
entries
     * associated with services that meet the specified matching
     * criteria
     *
     * @throws NoSuchFieldException field does not name a field of the
     * entry template
     * @throws java.rmi.RemoteException
     */
    ResultStream getFieldValues(ServiceTemplate tmpl, int setIndex, 
String field,
            int maxBatchSize) throws NoSuchFieldException, IOException;
   
    /**
     * Looks at all service items that match the specified template, and for
     * every service item finds the most specific type (class or interface)
     * or types the service item is an instance of that are neither 
equal to,
     * nor a superclass of, any of the service types in the template and 
that
     * have names that start with the specified prefix, and returns the set
     * of all such types.  Duplicate types are eliminated, and the order of
     * types within the returned array is arbitrary. 
     * Null is returned if there are no such types.  If a returned type
     * cannot be deserialized, that element is excluded and no exception 
is thrown.
     *
     * @param tmpl template to match
     * @param prefix class name prefix
     *
     * @param maxBatchSize
     * @return a ResultStream containing a Class for all services that 
either match the
     * specified template or match the specified prefix
     * @throws java.rmi.RemoteException
     */
    ResultStream getServiceTypes(ServiceTemplate tmpl, String prefix,
            int maxBatchSize) throws IOException;

}





Mime
View raw message