I had promised more thoughts on top of your interface thoughts. Here they are.

[snip]
Simon Laws wrote
Same thoughts translated into interface speak....

public abstract class SCADomainFactory
    public static SCADomainFactory newInstance()
-$1 public abstract SCADomain createSCADomain(String domainURI);
    public abstract SCADomain getSCADomain(String domainURI);

+$1 public class SCADomainImplFactoryImpl implements SCADomainFactory
+$1 public class SCADomainProxyFactoryImpl implements SCADomainFactory

public interface SCADomain
    public void start();
    public void stop();
    public String getURI();
 $4 void addContribution(URL url);
    void removeContribution(URL url);
    void addComposite(QName qname);
    void removeComposite(QName qname);
    void startComposite(QName qname);
    void stopComposite(QName qname);
+$2 void startComponent(Qname qname);
+$2 void stopComponent(Qname qname);
    public <B, R extends CallableReference<B>> R cast(B target) throws
IllegalArgumentException;
    public <B> B getService(Class<B> businessInterface, String serviceName);
    public <B> ServiceReference<B> getServiceReference(Class<B>
businessInterface, String referenceName);


public abstract class SCANodeFactory
    public static SCANodeFactory newInstance()
$5  public abstract SCANode createSCANode(String nodeURI, String domainURI)

public interface SCANode
    public void start();
 $6   public void stop();
 $3 public void configure(QName composite, URL... contributions);
    public String getURI();
 $7  public SCADomain getSCADomain();
    void startComposite();
    void stopComposite();
+$2 void startComponent(Qname qname);
+$2 void stopComponent(Qname qname);


Specific but rather random comments.

  $1 Not sure about createDomain. It adds potential confusion. People will
have
     to decide when to create and when to get a domain. In out model of
having a central representation of the domain
     it works quite well in that in one place you "create" and everywhere
else you "get" but doesn't work so well
     in other models, e.g if there is no central manager and that each
domain object holds references to all other domain
     objects and nodes. Do you "create" or do you "get". How about we take
this out and assume there is a different SCADomainFactory
     impl instantiated (via newInstance) in the case where we want to do the
creation step?

Having the same method do different things under the covers could be confusing. I was seeing two pretty different use cases:

a) The Tuscany runtime implements an SCA domain service. It gets an SCADomainFactory, creates an SCAdomain, starts the domain admin service, on request from a system adminstrator adds contributions, composites, starts them.

Here's sample code to illustrate that use case:
http://svn.apache.org/repos/asf/incubator/tuscany/sandbox/sebastien/java/sca/domain-and-node/samples/
SampleTuscanyDomainImplementation.java

b) Application code finds a domain, asks the domain for a proxy to an application service, invokes the service.

Sample code to illustrate that:
SampleClient.java

  $2 The fundamental operation is starting/stopping components.
Starting/stopping composites is a useful shortcut

Correct, but here are a few reasons for preferring startComposite IMO:

I was imagining that startComposite would:
1. Take the composite and cut it into smaller composites that can be distributed to different nodes 2. Distribute the composites and the contributions they require to the selected nodes
3. Assemble (build) each composite on the node on which it's going to run
4. Start the composite
5. At that point start each component contained in the composite... pfeewww :)

Exposing a startComponent method will force us to expose other APIs for the 5 steps. That being said, a sample piece of code showing how to script these steps without introducing too many other APIs may convince me.

Also as system administrator using the SCA domain, I'm deploying a composite, so I'm not sure why I'd want to not start the composite as a whole. Turning this around, people always claim that they want to start components individually but never complain that they can't deploy them individually and everybody seems to be happy with deploying composites... I find this rather funny :) My guess is that users will put components that belong together in the same composite, to deploy, undeploy, update, start and stop them together.

Finally, maybe the more convincing point because it's more concrete: Starting our current Calculator sample would require 5 calls to startComponent, that's too much...

  $3 The same effect be achieved with the familiar pattern
       void addContribution(URL url);
       void addComposite(QName qname);
       void startComposite(QName qname);
I see that this is a useful device in our desire to differentiate the
operation of a node from that of a domain.
     I actually don't mind them having very similar interfaces. The
difference in my mind is one of scope. Dealing with a node
     you are just deling with that
     one runtime (a common pattern we use in out samples/tests). Dealing
with a domain you don't care where the contributed
     artifacts run.

With configure(composite, contributions) I was trying to provide that "immutable" feel, and avoid the usual slippery slope:
- ah I can add
- then I should be able to remove
- and update
- can I add contributions after I've added composites?
- how about updating contributions?
- ah I see that I can start multiple composites, can I add more composites after I start?
- what if I update when it's running?
... and when is all of this going to work? OK I stop now :)

More seriously, I'm looking for the right API pattern to express something like:
- a node is small
- a node is loaded with artifacts, frozen, then runs
- a node is reset, then is ready to run again with new artifacts
- a node is NOT a big application server

  $4 We haven't explored and magic domain to node allocation algorithms to
date. How about we start with picking he next
     node that doesn't yet have a contribution. If you run out of nodes its
bad luck, i.e. implies no magic node provisioning so if you want more nodes
     you have to start them manually.

+1

  $5  Can you pass null in here (or some special constant  if you want an
association with a domain
   that will only every have this one node in it? This is a special case as
there are potentially several economies that can be made in terms of
starting or
   trying to connect to domain services.


Didn't get that. Could you show a sample?

  $6 Has the effect of removing all configuration.


Yes, but looking at it now we need something clearer. I added unloadContributions() to SCANode. Let me know what you think.

  $7 Wondering if this should return the domain URL so that you get the
domain object manually.

+1 I made the change.

Possibly a neater solution to $5 in that a different
domain
  factory (and domain implementation) can be introduced in the case that you
know an application is only going to have domain with a single node

Still didn't understand $5 :)
Simon

Staring at interfaces is fun but it's probably easier to look at sample use cases.

I have put several use cases there:
http://svn.apache.org/repos/asf/incubator/tuscany/sandbox/sebastien/java/sca/domain-and-node/samples/

- SampleClient.java
Application code finds a domain, gets a proxy to a service, invokes the service

- SampleMiniUnitTestDomainWithClient.java
For testing purposes, an application test case bootstraps its own mini domain, installs a contribution and composite in it, starts it, gets a proxy to a service and invokes it.

- SampleTuscanyDomainImplementation.java
A mockup of what a Tuscany domain runtime implementation could look like. A real implementation would run as a server and provide a SOAP or JSON Service for example to add/remove contributions, add/remove/start/stop composites, and under the covers we'd create/find/allocate nodes and run the composites on nodes. Here I just scripted that scenario by hand in the main method to show how the APIs would be used.

- SampleUnitTestCalculatorNodeWithClient.java
For testing purposes, an application test case bootstraps its own node, configures it with a contribution and composite, starts the composite, then find the domain, gets a proxy to a service and invokes it.

- SampleTuscanyNodeImplementation.java
A mockup of what a Tuscany node runtime implementation could look like. A real implementation would run as a server and provide a SOAP or JSON Service for example to configure the node and start/stop its composite. Here I just scripted that scenario by hand in the main method to show how the APIs would be used.

--
Jean-Sebastien


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to