Corona Design Container

From Eclipsepedia

Jump to: navigation, search
Eclipse Home Corona Wiki Home Development Design

Contents

Corona Context Container

Description

The Context Container is a server-side Corona component that manages distributed container so that it can be shared with many Eclipse Client RCP's. For example an active Project User List will be maintained as part of the Context Information.


References

Scope

Assumptions

  • Security will be added via an IoC Interceptor.
  • A repository of users will be accessable.

Design

Basic Container

Project Container is a specialization of Generic Container. Generic Container model is described by the following schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:con="http://www.eclipse.org/corona/model/container" targetNamespace="http://www.eclipse.org/corona/model/container">
	<xs:complexType name="context-container">
		<xs:sequence>
			<xs:element name="container-uri" type="xs:anyURI" minOccurs="0"/>
			<xs:element name="container-path" type="con:container-path-element" maxOccurs="1" minOccurs="0"/>
			<xs:element name="container-type" type="xs:anyURI" minOccurs="0"/>
			<xs:element name="container-description" type="xs:string" minOccurs="0"/>
			<xs:element name="repositories" type="con:repositories" minOccurs="0" maxOccurs="1"/>
			<xs:element name="related-containers" type="con:related-containers" minOccurs="0" maxOccurs="1"/>
			<xs:element name="container-properties" type="con:container-properties" minOccurs="0" maxOccurs="1"/>
			<xs:element name="relationship-resource-set" type="con:relationship-resource-set" minOccurs="0" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="name" type="xs:string" use="required"/>
	</xs:complexType>
	
	<xs:complexType name="relationship-resource-set">
		<xs:sequence>
			<xs:element name="relationship-file" type="con:relationship-file" maxOccurs="unbounded" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="relationship-file">
		<xs:attribute name="type" type="xs:string" use="required"/>
		<xs:attribute name="version" type="xs:string" use="required"/>
		<xs:attribute name="uri" type="xs:anyURI" use="required"/>
	</xs:complexType>

	<xs:complexType name="repositories">
		<xs:sequence>
			<xs:element name="repository" type="con:repository" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="repository">
		<xs:sequence>
			<xs:element name="description" type="xs:string"/>
			<xs:element name="repository-configurations" type="con:repository-configurations" minOccurs="0" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="name" type="xs:string" use="required"/>
		<xs:attribute name="uri" type="xs:anyURI" use="required"/>
		<xs:attribute name="content-type" type="xs:anyURI" use="required"/>
	</xs:complexType>
	
	<xs:complexType name="repository-configurations">
		<xs:sequence>
			<xs:element name="repository-configuration" type="con:repository-configuration" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
        <xs:attribute name="default-configuration-name" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="repository-configuration">
		<xs:sequence>
				<xs:element name="repository-connection-parameters" type="con:repository-connection-parameters" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>

     <xs:complexType name="repository-connection-parameters">
		<xs:sequence>
			<xs:element name="repository-connection-parameter" type="con:repository-connection-parameter" maxOccurs="unbounded" minOccurs="0"/>
			<!-- only one resource-subset allowed per one connection parameters set -->
			<xs:element name="resource-subset" type="con:resource-subset" minOccurs="0" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="name" type="xs:string"/>
		<xs:attribute name="access-type" type="xs:anyURI" use="required"/>
    </xs:complexType>

    <xs:complexType name="repository-connection-parameter">
		 <xs:attribute name="name" type="xs:string" use="required"/>
         <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="resource-subset">
		<xs:attribute name="type" type="xs:anyURI" use="required"/>
		<xs:attribute name="selection-criteria" type="xs:string" use="required"/>
     </xs:complexType>

	<xs:complexType name="container-properties">
		<xs:sequence>
			<xs:element name="container-property" type="con:container-property" maxOccurs="unbounded" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="container-property">
		<xs:attribute name="name" type="xs:string" use="required"/>
		<xs:attribute name="value" type="xs:string" use="required"/>
	</xs:complexType>
	
	<xs:complexType name="container-path-element">
		<xs:sequence>
			<xs:element name="container-path-element" type="xs:anyURI" maxOccurs="unbounded" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
	
	<xs:complexType name="related-containers">
		<xs:sequence>
			<xs:element name="related-container-uri" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
	</xs:complexType>
	
</xs:schema>

This schema serves as an input for SDO model code generator.

Basic Repository

The name repository in the Schema and model is going to be changed to RepositoryDescriptor since there is confusion between an actual repository implementation and the descriptor that holds information on connecting to the repository implementation.

Any repository used within Project Container (e.g. Team Member Repository) is a specialization of Generic Repository. Generic Repository model is described by the following schema:

	<xs:complexType name="repository">
		<xs:sequence>
			<xs:element name="description" type="xs:string"/>
			<xs:element name="repository-configurations" type="con:repository-configurations" minOccurs="0" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="name" type="xs:string" use="required"/>
		<xs:attribute name="uri" type="xs:anyURI" use="required"/>
		<xs:attribute name="content-type" type="xs:anyURI" use="required"/>
	</xs:complexType>
	
	<xs:complexType name="repository-configurations">
		<xs:sequence>
			<xs:element name="repository-configuration" type="con:repository-configuration" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
        <xs:attribute name="default-configuration-name" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="repository-configuration">
		<xs:sequence>
				<xs:element name="repository-connection-parameters" type="con:repository-connection-parameters" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>

     <xs:complexType name="repository-connection-parameters">
		<xs:sequence>
			<xs:element name="repository-connection-parameter" type="con:repository-connection-parameter" maxOccurs="unbounded" minOccurs="0"/>
			<!-- only one resource-subset allowed per one connection parameters set -->
			<xs:element name="resource-subset" type="con:resource-subset" minOccurs="0" maxOccurs="1"/>
		</xs:sequence>
		<xs:attribute name="name" type="xs:string"/>
		<xs:attribute name="access-type" type="xs:anyURI" use="required"/>
    </xs:complexType>

    <xs:complexType name="repository-connection-parameter">
		 <xs:attribute name="name" type="xs:string" use="required"/>
         <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="resource-subset">
		<xs:attribute name="type" type="xs:anyURI" use="required"/>
		<xs:attribute name="selection-criteria" type="xs:string" use="required"/>
     </xs:complexType>

This schema serves as an input for SDO model code generator.

Collaboration Events

Collaboration Events will notify the Project Container of project change activities occurring on Eclipse Client. The ProjectContainer will if needed forward Collaboration Events from one Eclipse Client to another.

Event Focus

The ProjectContainer acts as lense to focus all events related to a project. This focus create a central knowledge collection point for the Corona Knowledge Base.

Resources

The ProjectContainer will not typically contain project resources. The ProjectContainer will usually deal with references to the resources and artifacts. The ProjectContainer will use URI based references whenever possible. The URI identification approach meshes with the Corona SOA orientation as well as the Knowledge Base OWL/RDF object metadata defintion.

IoC

The ProjectContainer utilizes an Inversion of Control (IoC) implementation for extensibility. As new ProjectContainers are instantiated the chain of registered intercepters will be called. Likewise, when an object is added to the ProjectContainers the object is accessable to the registered interceptors.

Containers are related to other Containers

Containers can be related to other Containers. This gives Containers access to information in their related Containers. If two Containers need information about one another then each would have the other in its related container list. Originally, we specified containers as being nest but decided that didn't allow the flexible to relate many container easily. We have replaced nested Containers with related Containers. This change means that Container no longer a simple hierarchy or tree structure but instead a graph structure. Our thinking is that the user will have a Container of primary interest and the will still be represented as a tree structure from the Container of interest. One issue with a graph structure is that a graph may have cycles.

Related Container Cycles

Main objects used with Container - currently implemented as ProjectContainerManager

  • ContainerFactory
  • Container
  • ContainerConfiguration

ContainerFactory

    • this is the ContainerFactory instantiates Containers
    • responsible for locating persisted Containers
    • API
      • getContainer(ContainerName)
      • getContainerList()
      • openContainer
      • closeContainer
      • saveContainer
      • loadContainer
      • listOpenContainers

Container

    • holds context and state
    • the persisted location of a Container is loaded from the ContainerConfiguration
    • the initial context is loaded from an XML Container file
    • holds a list of repositories that contain relavant resources to this context
    • API
      • AddRepository - add a respository to Container.
      • removeRepository - remove a repository from ProjectContainer
      • Question should I just continue with Repository?
      • saveContext - causes the context of the ProjectContainer to be persisted
      • restoreContext - restores the context of the ProjectContainer from the persisted backing store
      • addRelatedContainer - add a Container reference to the current Container
      • removeRelatedContainer - remove the reference to a Container in the current Container
      • listRelatedContainers - list related Containers within current Container related Container List
      • listAllRelatedContainer - recursively list all related Containers within the current Container requires cycle detection

Repository

Main objects used with a Repository

  • RepositoryDescriptor - the object that describes how to find the repository and how to connect
  • RepositoryDescriptorViewer - the object that knows how to display RepositoryDescriptor information
  • RepositoryAdaptor - the object that connects to and interacts with the actual repository
  • RepositoryAdapterViewer - the object that knows how to display repository adaptor information
  • RepositoryViewer - the object that knows how to display some or all of the repository contents
  • MatchMaker - a utility for matching and tracking combinations of the other objects...see below

How a RepositorySystem gets installed

  1. A bundle representing a new Repository type should contain the following -
    1. A RepositoryAdaptor and RepositoryAdaptorFactory implementation
    2. A RepositoryDescriptor and RepositoryDescriptorFactory implementation
    3. Specific viewers/editors may be installed (viewers may be optional if we handle generic mime types like text/xml and html, but a descriptor editor is required).
    4. A manifest.mf export for the RepositoryAdapter and RepositoryAdaptorFactory
    5. A plugin.xml definition for the extension points for editors and viewers
    6. A plugin.xml definition for the editor and viewer extensions
  2. RepositoryAdaptorFactory registers with MatchMaker
  3. RepositoryDescriptorFactory registers with MatchMaker
  4. The bundle activator should register the factories with the MatchMaker.
  5. The new RepositoryDescriptorFactory type will be surfaced later in the GUI (pick-list, etc.). Some provision may need to be made for an icon...

NOTE: The viewers and editors are typically extension points. Adaptors and Descriptors should be implemented as services.


RepositoryDescriptor -currently this is org.eclipse.corona.model.container.Repository

  • holds basic information used to locate a respository of information for example URI, authentication properties, connection properties
  • holds properties regarding access to the repository
  • API
  • updateRepositoryConfiguration(RepositoryName, RepositoryConfigurationName, RepositoryConfiguration) - add/remove/change properties defined in the RepositoryDescriptor (repository-configuration)
  • How a Repository Descriptor gets created
    • Pick the target RepositoryDescriptor type from a list.
    • MatchMaker provides appropriate RepositoryDescriptorEditorViewer.
    • The MatchMaker will retrieve the RepositoryDescriptorEditorViewer's job to create descriptor from factory and populate.

RepositoryDescriptorEditorViewer - no implementation available

  • Need user interface for defining a new RepositoryDescriptor - after Demo

RepositoryDescriptorFactory - current implementation is the ProjectContainerManager

  • makes RepositoryDescriptors and deals with singleton-type relationships
  • How a RepositoryDescriptor gets Saved/Read
    • It's the RepositoryDescriptorFactory's job to deal with saving and reading of RepositoryDescriptors into Containers. Containers should be reference by uri, which must enforce uniqueness.

RepositoryAdaptor - currently the closest thing is the org.eclipse.corona.server.container.common.IRepository

  • object that interacts with the actual repository
  • consumes a RepositoryDescriptor and optionally connects to the target Repository.
  • It is the sole responsibility of the adaptor to mediate between the repository and any consumer of repository information. If the repository is accessed via webservices/jdbc/rmi, it's the adaptor's issue.
  • It is the adaptor's job to expose the repository contents as an object model.
  • API
    • open - uses connection properties and authentication properties from the RepositoryDescriptor to connect to the respository. Should there be a reopen when a reconnection to a repository is needed?
    • close - closes the connection to a repository
    • resourceExists - verify whether a resource exists in the repository
    • addResource - add a resource to the repository
    • removeResource - remove a resource to the repository
    • fetchResource - retrieve a resource from the repository
    • fetchNativeRepositoryClient - return the object that provides native client access to the particular repository. This allows custom views which are capable of using the native repository interface to do so
    • getRepositoryCapabilities - returns indicator of the capabilities that a repository supports. Review WSDM Capability specification.

RepositoryAdaptorFactory - currently none implemented

  • makes RepositoryAdaptors and deals with singleton-type relationships

Repository

  • How a Repository gets connected
    • Given a RepositoryDescriptor, the MatchMaker finds an appropriate RepositoryAdaptorFactory, and requests that factory to provide an RepositoryAdaptor using the target RepositoryDescriptor. The Matchmaker tracks the RepositoryDescriptor/RepositoryAdaptor pair.

Repository Example Implementation

  • TeamRepository - currently org.eclipse.corona.server.repository.team.TeamRepository
    • Assumption: Team members could have different roles in different project contexts. So, I think each project would have a reference to it own TeamRepository.
    • API
      • addMember(MemberName)
      • removeMember(MemberName)
      • setMemberRole(MemberName, RoleName) - the role name should be well defined and each role name be unique, I'm thinking OWL/RDF defintion of Roles.
      • getMemberRole - return the primary role defined in this Repository
      • getMemberRoles(MemberName) - return list of all roles on a project
      • deleteMember(MemberName) - remove the member from this repository
      • setMemberPrimaryRole(MemberName, Role) - not currently needed
      • setMemberProperties(MemberName, Properties) - not currently needed

RepositoryAdaptor Implementation - still needed

  • ArtifactRepository - should implement/extend RepositoryAdaptor
    • holds properties regarding access to artifacts probably just a wrapper around CVS, Subversion etc.
    • see ALF vocabulary definitions for Source Code Management (SCM).
    • I think we only want to be able to retrieve a specifically versioned artifact.
    • Do we need to update a versioned artifact or can we just receive notification of the update?

Nice to have

  • ProcessCollaborationRepository
    • holds properties regard access to process defintion, hopefully the API on the Eclipse Process Framework (EPF Project) will be rich enough that can access Process information.
    • will have to monitor EPF API's to see how this will work

Nice to have

  • TaskCollaborationRepository
    • RepositoryAdaptor or an actual implementation if shared Task repository needed by Mylar
    • API
      • addTask
      • removeTask
      • setTaskProperties

RepositoryViewer

  • currently a ProjectContainerRepositoryPage ????
  • consumes an adaptor/configuration pair and interacts with the repository via the RepositoryAdaptor interface (and whatever extended interfaces the adaptor makes available
  • How a Repository gets Viewed
    • Given a RepositoryAdaptor, the MatchMaker returns a list of RepositoryViewers (sorted most to least preferred).
    • The RepositoryDescriptor information corresponding to the RepositoryAdaptor is retrievable from the tracked descriptor/ adaptor pair (see previous comments)


MatchMaker

  • matches adaptors to descriptors, viewers to descriptors, and viewers to adaptors.
  • the MatchMaker is responsible for knowing how to match a descriptor with adaptor and viewers, tracking combination pairs, and matching viewers with adaptors based on their bound state.
  • It's the MatchMaker's job to identify the appropriate viewer/editor. This is done by computing the best

match based on the descriptor's generic parameters (see sample xml comments).

  • The MatchMaker returns a list of viewers (sorted most to least preferred).



Client Collaboration Nature

The Client Collaboration Nature forwards events similar the events received by "builders". These events include create/read/update/delete. They are sent to the ProjectContainer as Collaboration Events.

Risk

  • ProjectContainer needs to allow knowledge collection. Iformation in the Project Container must be complete enough to collect knowledge within correct context.
  • Performance Risk, Many client may generate so many Collaboration Events the the Project Container cannot process them "fast enough".
  • Hooks to other Repositories have to be written and we may not have enough people to write all required interfaces to an ever expanding set of repositories.

!Project to ProjectContainer Communication The first implementation is target ECF as the communication mechanism between the RCP Application and the Corona ProjectContainer

  • Scenerio One
    • User creates a Client side project and adds a collaboration nature to it
    • The client side project sends an collaboration message to the ProjectManager on the Corona Server. The collaboration message contains the name of a ProjectContainer instance.
    • The ProjectManager looks to see if a ProjectContainer instance with the client specified name exists.
    • If the name doesn't exist then the ProjectManager
      • calls the ProjectContainerFactory to create a new ProjectContainer with the specified name
      • The ProjectManager adds the ProjectContainer name to its active list as wells as its available list (available ProjectContainers have been serialized out so they do not take up memory whereas, active ProjectContainers are in memory.
      • ProjectManager creates an Collaboration Topic matching the name of the ProjectContainer (an ECF Topic in this case).
      • the client is added to the active user list
      • After the topic has been created the ProjectManager publishes a collaboration message on the Collaboration Topic indicating a new ProjectContainer with the client specified has been created.
      • The client receives the collaboration message and subscribes to the ProjectContainer Topic (does an ECF join).
    • when the name does exist the ProjectManager
      • loads Project Container if it is not on its active list.
      • adds the user to the ProjectContainers active user list - after authentication
      • the client subscribes to the Project Container Topic
      • use is then part of workgroup and receives Project collaboration events