Moved repository master into its own directory
66
repository/docs/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Community Technical Documentation Index
|
||||
|
||||
## Repository
|
||||
|
||||
### Meta-data Services
|
||||
* [Node Storage and Retrieval](./meta-data-services/node-storage-and-retrieval)
|
||||
* Dictionary
|
||||
* Files and Folders
|
||||
* Smart Folders
|
||||
* [Versions](./meta-data-services/versions)
|
||||
* Permissions
|
||||
* Tagging
|
||||
* Multilingual Content
|
||||
|
||||
### Content Store
|
||||
* Content Storage and Retrieval
|
||||
|
||||
### Rules Engine
|
||||
* Rules
|
||||
* Actions
|
||||
|
||||
### Workflow
|
||||
* Embedded Activiti
|
||||
|
||||
### Transformation
|
||||
* Renditions
|
||||
|
||||
### Content Analysis
|
||||
* Meta-data Extraction
|
||||
|
||||
### File Protocols
|
||||
* FTP Protocol
|
||||
* WebDAV Protocol
|
||||
|
||||
### Application Protocols
|
||||
* IMAP Protocol
|
||||
* Office Protocols
|
||||
|
||||
### Scripting
|
||||
* JavaScript API
|
||||
* Freemarker API
|
||||
|
||||
### Sync and Transfer
|
||||
* Content Replication
|
||||
* Content Transfer
|
||||
|
||||
### Event Log
|
||||
* Audit
|
||||
* Log Messages
|
||||
|
||||
### Identity Provider
|
||||
* [Authentication](./identity-provider/authentication)
|
||||
* LDAP Sync
|
||||
|
||||
### Deployment
|
||||
* Installer
|
||||
* MMT
|
||||
* Patch
|
||||
|
||||
### Messaging
|
||||
* Messages and Topics
|
||||
|
||||
### Infrastructure
|
||||
* Module Framework
|
||||
* Policies and Behaviours
|
||||
* Multi-tenancy
|
BIN
repository/docs/event-log/audit/resource/data/audit-data.png
Normal file
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,41 @@
|
||||
@startuml
|
||||
|
||||
title Audit and Attributes - High Level Entities
|
||||
|
||||
skinparam linetype ortho
|
||||
|
||||
rectangle AuditDAO #lightgrey {
|
||||
rectangle AuditApplication #orange
|
||||
rectangle AuditModel #white
|
||||
rectangle ModelContent #white
|
||||
rectangle AuditEntry #white
|
||||
}
|
||||
|
||||
rectangle PropertyValueDAO #lightgrey {
|
||||
rectangle Attribute #orange
|
||||
rectangle ComplexProperty #white
|
||||
rectangle SimpleProperty #white
|
||||
rectangle Value #white
|
||||
rectangle Caches #white {
|
||||
rectangle PropertyUniqueContextSharedCache #white
|
||||
rectangle PropertyClassSharedCache #white
|
||||
rectangle PropertyValueSharedCache #white
|
||||
}
|
||||
}
|
||||
|
||||
AuditApplication --* AuditModel
|
||||
AuditApplication --* AuditEntry
|
||||
AuditModel -- ModelContent
|
||||
PropertyClassSharedCache ->SimpleProperty
|
||||
PropertyValueSharedCache ->SimpleProperty
|
||||
PropertyUniqueContextSharedCache ->Attribute
|
||||
SimpleProperty .. Value :value
|
||||
SimpleProperty -- Attribute: keys (1 to 3)
|
||||
ComplexProperty -- SimpleProperty
|
||||
ComplexProperty -- AuditEntry :audit values
|
||||
ComplexProperty -- AuditApplication :disabled paths
|
||||
Attribute -- ComplexProperty
|
||||
|
||||
center footer Copyright 2016 Alfresco Software Inc
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 206 KiB |
After Width: | Height: | Size: 193 KiB |
@@ -0,0 +1,86 @@
|
||||
@startuml
|
||||
|
||||
' Generated using https://github.com/juanmf/Java2PlantUML
|
||||
|
||||
left to right direction
|
||||
' Participants
|
||||
|
||||
interface org.alfresco.jlan.ftp.FTPAuthenticator {
|
||||
--
|
||||
+ authenticateUser(c ClientInfo, c FTPSrvSession) : boolean
|
||||
+ closeAuthenticator() : void
|
||||
+ initialize(c ServerConfiguration, i ConfigElement) : void
|
||||
|
||||
}
|
||||
interface org.springframework.beans.factory.DisposableBean {
|
||||
--
|
||||
+ destroy() : void
|
||||
|
||||
}
|
||||
interface org.alfresco.filesys.auth.ftp.package-info {
|
||||
--
|
||||
|
||||
}
|
||||
interface org.alfresco.repo.management.subsystems.ActivateableBean {
|
||||
--
|
||||
+ isActive() : boolean
|
||||
|
||||
}
|
||||
class org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase {
|
||||
# logger : i Log
|
||||
# serverConfiguration : i ServerConfigurationAccessor
|
||||
- active : boolean
|
||||
- authenticationComponent : i AuthenticationComponent
|
||||
- authenticationService : i AuthenticationService
|
||||
- authorityService : i AuthorityService
|
||||
- transactionService : i TransactionService
|
||||
--
|
||||
+ FTPAuthenticatorBase()
|
||||
# checkForAdminUserName(c ClientInfo) : void
|
||||
# createTransaction() : UserTransaction
|
||||
# getAuthenticationComponent() : AuthenticationComponent
|
||||
# getAuthenticationService() : AuthenticationService
|
||||
# getAuthorityService() : AuthorityService
|
||||
# getTransactionService() : TransactionService
|
||||
+ authenticateUser(c ClientInfo, c FTPSrvSession) : boolean
|
||||
+ closeAuthenticator() : void
|
||||
+ destroy() : void
|
||||
+ initialize() : void
|
||||
+ initialize(c ServerConfiguration, i ConfigElement) : void
|
||||
+ isActive() : boolean
|
||||
+ setActive(boolean) : void
|
||||
+ setAuthenticationComponent(i AuthenticationComponent) : void
|
||||
+ setAuthenticationService(i AuthenticationService) : void
|
||||
+ setAuthorityService(i AuthorityService) : void
|
||||
+ setConfig(i ServerConfigurationAccessor) : void
|
||||
+ setTransactionService(i TransactionService) : void
|
||||
|
||||
}
|
||||
class org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator {
|
||||
# m_encryptor : c PasswordEncryptor
|
||||
# m_md4Encoder : i MD4PasswordEncoder
|
||||
--
|
||||
+ AlfrescoFtpAuthenticator()
|
||||
# doGuestLogon(c AlfrescoClientInfo, c SrvSession) : void
|
||||
+ authenticateUser(c ClientInfo, c FTPSrvSession) : boolean
|
||||
|
||||
}
|
||||
|
||||
' Relations
|
||||
|
||||
org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator "1" o-left- "1" org.alfresco.repo.security.authentication.MD4PasswordEncoder : m_md4Encoder: i MD4PasswordEncoder
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase "1" o-left- "1" org.alfresco.service.transaction.TransactionService : transactionService: i TransactionService
|
||||
org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator "1" o-left- "1" org.alfresco.jlan.server.auth.PasswordEncryptor : m_encryptor: c PasswordEncryptor
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase "1" o-left- "1" org.apache.commons.logging.Log : logger: i Log
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase "1" o-left- "1" org.alfresco.jlan.server.config.ServerConfigurationAccessor : serverConfiguration: i ServerConfigurationAccessor
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase "1" o-left- "1" org.alfresco.repo.security.authentication.AuthenticationComponent : authenticationComponent: i AuthenticationComponent
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase "1" o-left- "1" org.alfresco.service.cmr.security.AuthorityService : authorityService: i AuthorityService
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase "1" o-left- "1" org.alfresco.service.cmr.security.AuthenticationService : authenticationService: i AuthenticationService
|
||||
org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator -up|> org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase ..up|> org.alfresco.jlan.ftp.FTPAuthenticator
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase ..up|> org.alfresco.repo.management.subsystems.ActivateableBean
|
||||
org.alfresco.filesys.auth.ftp.FTPAuthenticatorBase ..up|> org.springframework.beans.factory.DisposableBean
|
||||
|
||||
' Notes
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 808 KiB |
165
repository/docs/identity-provider/authentication/README.md
Normal file
@@ -0,0 +1,165 @@
|
||||
## Authentication
|
||||
|
||||

|
||||
|
||||
### Purpose
|
||||
|
||||
The purpose of this sub-component is to authenticate users.
|
||||
***
|
||||
|
||||
### Overview
|
||||
|
||||
In order to use any service in Alfresco, a user must be authenticated.
|
||||
|
||||
Alfresco provides a default Authentication implementation that uses userid's and passwored
|
||||
managed by Alfresco. But, importantly, Alfresco also allows the customer
|
||||
to integrate with a number of external Authentication providers including
|
||||
* Active Directory
|
||||
* Kerberos
|
||||
* LDAP
|
||||
|
||||
***
|
||||
|
||||
### Artifacts and Guidance
|
||||
|
||||
* Source Code Links:
|
||||
* https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root/enterpriseprojects/repository/source/java/
|
||||
* https://github.com/Alfresco/alfresco-data-model/tree/master/src/main/java/org/alfresco/repo/security/authentication
|
||||
* License: LGPL
|
||||
* Issue Tracker Link: https://issues.alfresco.com/jira/issues/?jql=project%3DREPO
|
||||
* Documentation Link: http://docs.alfresco.com/5.2/concepts/auth-intro.html
|
||||
* Contribution Model: Alfresco Open Source
|
||||
***
|
||||
|
||||
|
||||
### Prerequisite Knowledge
|
||||
|
||||
* [Acegi](http://springinpractice.com/2008/02/26/acegi-overview)
|
||||
* [CAS](https://en.wikipedia.org/wiki/Central_Authentication_Service)
|
||||
* [JAAS](http://docs.oracle.com/javase/8/docs/technotes/guides/security/jaas/JAASRefGuide.html)
|
||||
* [Kerberos](https://msdn.microsoft.com/en-us/library/bb742516.aspx)
|
||||
* [LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol)
|
||||
***
|
||||
|
||||
### Design
|
||||
|
||||
#### Default Authentication
|
||||
|
||||
In order to use any service in Alfresco, a user or client must be authenticated.
|
||||
|
||||
There is a default implementation provided that authenticates users based on a userid and password, where the userid's and passwords
|
||||
are stored in the Alfresco repository.
|
||||
|
||||
#### Chaining
|
||||
|
||||
Most production systems that use Alfresco will rely upon more secure approaches, so Alfresco also allows the
|
||||
customer to integrate a choice of existing authentication providers, including *Active Directory*, *Kerberos* and *LDAP*.
|
||||
|
||||
The implementation of each such Authorization provider is delivered as a separate Alfresco Subsystem.
|
||||
The Subsystems are chained together as an ordered list of providers each of which, in turn, will be given
|
||||
a chance to authenticate the user, until the user is authenticated or there are no providers, in
|
||||
which case the authentication of the user fails.
|
||||
|
||||
|
||||
#### Component Model
|
||||
|
||||
#### Data Model
|
||||

|
||||
|
||||
#### Data Dictionary
|
||||
|
||||
#### Flows
|
||||
|
||||
##### Login Flow
|
||||
|
||||
##### Default Authentication Login Flow
|
||||
This flow starts when the Login Post request
|
||||
depicted in [Client Login](../../../share/share-app/resource/sequence/client-login-sequence.png) reaches the repository tier.
|
||||

|
||||
|
||||
##### Default Authentication Logoff Flow
|
||||

|
||||
|
||||
##### Kerberos Authentication Login Flow
|
||||

|
||||
|
||||
#### Class Diagram
|
||||

|
||||
|
||||
|
||||
### APIs and Interfaces
|
||||
|
||||
#### Java
|
||||
|
||||
The sub-component provides a definition and implementation of the following
|
||||
Java interfaces.
|
||||
|
||||
* **Authentication Service**
|
||||
**Note**: This service is part of the Public API
|
||||
* authenticate using a user name and password
|
||||
* authenticate using a ticket
|
||||
* create, update and delete authentication information
|
||||
* clear the current authentication
|
||||
* invalidate a ticket
|
||||
* get the username for who is currently authenticated
|
||||
* get a ticket for subsequent re-authentication
|
||||
* determine if the current user is 'the system user
|
||||
* **MutableAuthenticationService*
|
||||
|
||||
In addition, there are a number of related interfaces that provide
|
||||
a way to manage users and groups and permissions
|
||||

|
||||
*This information should probably move to the Identity sub-component after the content already there (future design thoughts)
|
||||
is relocated*
|
||||
|
||||
* **Authority Service**
|
||||
**Note**: This service is part of the Public API
|
||||
* create authority identifiers
|
||||
* query for authority identifiers
|
||||
* delete authority identifiers
|
||||
* organize authority identifiers into hierarchies
|
||||
* query against authority identifiers hierarchies
|
||||
* find all the authorties that apply to the current authenticated user
|
||||
* determine if the current authenticated user has admin rights
|
||||
* **Ownable Service**
|
||||
**Note**: This service is **not** part of the Public API
|
||||
* determine the owner of a node;
|
||||
* set the owner of a node;
|
||||
* determine if a node has an owner
|
||||
* allow the current user to take ownership of a node
|
||||
* **Person Service**
|
||||
**Note**: This service is part of the Public API
|
||||
* obtain a reference to the Person node for a given user name
|
||||
* determine if a person entry exists for a user
|
||||
* create missing people entries, with default settings, on demand
|
||||
* supply a list of mutable properties for each person
|
||||
* create, delete and update personal information
|
||||
***
|
||||
#### REST
|
||||
|
||||
The sub-component provides the following REST API
|
||||
* https://api-explorer.alfresco.com/api-explorer/#/authentication
|
||||
|
||||
### Configuration
|
||||
***
|
||||
|
||||
### Performance Considerations
|
||||

|
||||
Describe Caching of tickets
|
||||
As mentioned in the *Security Considerations* section, Bcrypt can be used to encrypt passwords. Note that is
|
||||
is much slower than MD4 or SHA-256.
|
||||
***
|
||||
|
||||
### Security Considerations
|
||||
***
|
||||
In the case of the default Authentication provider, Alfresco is responsible for storing
|
||||
userid's and passwords. The passwords are stored as hashed values. The default hashing
|
||||
algorithm used is MD4, but the customer can also elect to use more secure hashing algorithms
|
||||
include SHA-256 and Bcrypt. The system property *system.preferred.password.encoding* is used
|
||||
to select which algorithm is used.
|
||||
|
||||
### Cloud Considerations
|
||||
|
||||

|
||||
Describe OAuth2 for protection of Cloud REST API's.
|
||||
***
|
After Width: | Height: | Size: 180 KiB |
@@ -0,0 +1,117 @@
|
||||
@startuml
|
||||
|
||||
Title: Default Authentication Login Flow
|
||||
|
||||
participant "Repository\nContainer" as W
|
||||
participant "LoginPost\nbean" as LB
|
||||
participant "SubsystemChaining\nAuthenticationService" as SCAS
|
||||
participant "MutableAuthentication\nServiceImpl" as AS
|
||||
participant "Authentication\nComponentImpl" as AC
|
||||
participant "PersonServiceImpl" as PS
|
||||
participant "NodeService" as NS
|
||||
participant "Authentication\nContextImpl" as ACX
|
||||
participant "Authentication\nUtil" as AU
|
||||
participant "InMemoryTicketComponentImpl" as ITC
|
||||
participant "AuthorityServiceImpl" as AUS
|
||||
participant "RepositoryAuthenticatedUser" as RAU
|
||||
participant "RepositoryAuthenticationDao" as RAD
|
||||
participant "MD4PasswordEncoderImpl" as MPE
|
||||
participant "RepositoryAuthenticationProvider" as RAP
|
||||
participant "CompositePasswordEncoder" as CPE
|
||||
|
||||
activate W
|
||||
W->LB: login request <username> <password>
|
||||
LB->LB: login <username> <password>
|
||||
LB->SCAS:authenticate <username> <password>
|
||||
note right of SCAS
|
||||
allowedUsers and maxUsers check
|
||||
end note
|
||||
SCAS->SCAS: preAuthenticationCheck
|
||||
note right of SCAS
|
||||
get list of usableAuthenticationServices
|
||||
and iterates over this list. In
|
||||
this default case there is a single
|
||||
service 'alfrescoNtlm'
|
||||
end note
|
||||
SCAS->AS: authenticate\n<username> <password>
|
||||
AS->AC:clearCurrentSecurityContext
|
||||
AC->ACX:clearCurrentSecurityContext
|
||||
ACX->AU:clearCurrentSecurityContext
|
||||
AU->ACX: done
|
||||
ACX->AC: done
|
||||
AC->AS: done
|
||||
AS->ITC:clearCurrentTicket
|
||||
ITC->AS: done
|
||||
note right of AS
|
||||
allowedUsers and maxUsers check
|
||||
end note
|
||||
AS->AS: preAuthenticationCheck
|
||||
note right of AS
|
||||
Checks cache to detect
|
||||
Brute Force attack
|
||||
end note
|
||||
AS->AS: isUserProtected <username>
|
||||
AS->AC: authenticate\n<username> <password>
|
||||
AC->PS:getUserIdentifier <username>
|
||||
PS->PS:getPersonOrNullImpl
|
||||
PS->PS:looks for Person\nin Cache
|
||||
PS->NS:get properties of Person\nand checks if\nneeds to add to cache
|
||||
PS->AC: username
|
||||
note right of AC
|
||||
Checks for guest
|
||||
end note
|
||||
AC->AC:isGuestUserName
|
||||
AC->AC: authenticateImpl <username> <password>
|
||||
AC->AU: getUserTenant
|
||||
AU->AC: tenant
|
||||
group Retrying Transaction
|
||||
AC->RAD: loadUserByUsername <username>
|
||||
RAD->RAU: constructor <username> <hashedpassword>
|
||||
RAD->AC: user details
|
||||
AC->RAP: isPasswordCorrect\n(UsernamePasswordAuthenticationToken, user details)
|
||||
RAP->CPE: matches
|
||||
CPE->MPE:isPasswordValid
|
||||
MPE->MPE:encodeInternal
|
||||
MPE->MPE: true
|
||||
MPE->RAP: true
|
||||
RAP->AC: true
|
||||
AC->AUS: isAdminAuthority
|
||||
AUS->AC: false
|
||||
AC->PS:getPersonOrNullImpl
|
||||
PS->PS:looks for Person\nin Cache
|
||||
PS->NS:get properties of Person\nand checks if\nneeds to add to cache
|
||||
NS->PS: properties
|
||||
PS->AC: username
|
||||
end
|
||||
group setCurrentUser <username>
|
||||
AC->ACX: isSystemUserName <username>
|
||||
ACX->AC: false
|
||||
AC->AC: setUserDetails (role=<b>ROLE_AUTHENTICATED</b>)
|
||||
end
|
||||
note right of AC
|
||||
Increment numberSuccessfulAuthentications
|
||||
end note
|
||||
AC->AC: onAuthenticate
|
||||
AC->AS: succeeded
|
||||
AS->ITC: clearCurrentTicket
|
||||
ITC->AS: done
|
||||
AS->ITC: getCurrentTicket (auto create off)
|
||||
ITC->AS
|
||||
AS->AS: getNewTicket
|
||||
AS->AS: preAuthenticationCheck
|
||||
AS->ITC: getNewTicket
|
||||
AS->SCAS
|
||||
SCAS->LB
|
||||
note right of LB
|
||||
Put ticket into the model
|
||||
end note
|
||||
LB->AS: getCurrentTicket
|
||||
AS->LB: ticket
|
||||
LB->W: Login Request Response
|
||||
note right of W
|
||||
Authentication TICKET
|
||||
returned in model
|
||||
end note
|
||||
deactivate W
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 383 KiB |
@@ -0,0 +1,310 @@
|
||||
@startuml
|
||||
|
||||
' Generated using https://github.com/juanmf/Java2PlantUML
|
||||
|
||||
left to right direction
|
||||
' Participants
|
||||
|
||||
interface org.alfresco.repo.security.authentication.AlfrescoSecureContext {
|
||||
--
|
||||
+ getEffectiveAuthentication() : Authentication
|
||||
+ getRealAuthentication() : Authentication
|
||||
+ setEffectiveAuthentication(i Authentication) : void
|
||||
+ setRealAuthentication(i Authentication) : void
|
||||
|
||||
}
|
||||
interface net.sf.acegisecurity.context.security.SecureContext {
|
||||
--
|
||||
+ getAuthentication() : Authentication
|
||||
+ setAuthentication(i Authentication) : void
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.AuthenticationUtil$ThreadLocalStack {
|
||||
--
|
||||
~ AuthenticationUtil$ThreadLocalStack()
|
||||
# initialValue() : Stack
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.TicketExpiredException {
|
||||
- serialVersionUID : long
|
||||
--
|
||||
+ TicketExpiredException(c String)
|
||||
+ TicketExpiredException(c String, c Throwable)
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$Ticket {
|
||||
- expires : c InMemoryTicketComponentImpl$ExpiryMode
|
||||
- expiryDate : c Date
|
||||
- serialVersionUID : long
|
||||
- testDuration : c Duration
|
||||
- ticketId : c String
|
||||
- userName : c String
|
||||
- validDuration : c Duration
|
||||
--
|
||||
- InMemoryTicketComponentImpl$Ticket(c InMemoryTicketComponentImpl$ExpiryMode, c Date, c String, c Duration, c String)
|
||||
~ InMemoryTicketComponentImpl$Ticket(c InMemoryTicketComponentImpl$ExpiryMode, c Date, c String, c Duration)
|
||||
# getExpires() : InMemoryTicketComponentImpl$ExpiryMode
|
||||
# getExpiryDate() : Date
|
||||
# getTicketId() : String
|
||||
# getUserName() : String
|
||||
+ equals(c Object) : boolean
|
||||
+ hashCode() : int
|
||||
~ getNewEntry() : InMemoryTicketComponentImpl$Ticket
|
||||
~ hasExpired(c Date) : boolean
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl {
|
||||
+ GRANTED_AUTHORITY_TICKET_PREFIX : c String
|
||||
- currentTicket : ThreadLocal< String>
|
||||
- expiryMode : c InMemoryTicketComponentImpl$ExpiryMode
|
||||
- guid : c String
|
||||
- oneOff : boolean
|
||||
- ticketsCache : SimpleCache< String, InMemoryTicketComponentImpl$Ticket>
|
||||
- ticketsExpire : boolean
|
||||
- useSingleTicketPerUser : boolean
|
||||
- validDuration : c Duration
|
||||
--
|
||||
+ InMemoryTicketComponentImpl()
|
||||
+ clearCurrentSecurityContext() : void
|
||||
+ clearCurrentTicket() : void
|
||||
+ countTickets(boolean) : int
|
||||
+ equals(c Object) : boolean
|
||||
+ getAuthorityForTicket(c String) : String
|
||||
+ getCurrentTicket(c String, boolean) : String
|
||||
+ getNewTicket(c String) : String
|
||||
+ getUseSingleTicketPerUser() : boolean
|
||||
+ getUsersWithTickets(boolean) : Set
|
||||
+ hashCode() : int
|
||||
+ invalidateTicketById(c String) : void
|
||||
+ invalidateTicketByUser(c String) : void
|
||||
+ invalidateTickets(boolean) : int
|
||||
+ setExpiryMode(c String) : void
|
||||
+ setOneOff(boolean) : void
|
||||
+ setTicketsCache( SimpleCache< String, InMemoryTicketComponentImpl$Ticket>) : void
|
||||
+ setTicketsExpire(boolean) : void
|
||||
+ setUseSingleTicketPerUser(boolean) : void
|
||||
+ setValidDuration(c String) : void
|
||||
+ validateTicket(c String) : String
|
||||
- findNonExpiredUserTicket(c String) : InMemoryTicketComponentImpl$Ticket
|
||||
- getTicketByTicketString(c String) : InMemoryTicketComponentImpl$Ticket
|
||||
- getTicketKey(c String) : String
|
||||
|
||||
}
|
||||
interface org.springframework.beans.factory.InitializingBean {
|
||||
--
|
||||
+ afterPropertiesSet() : void
|
||||
|
||||
}
|
||||
interface org.alfresco.repo.security.authentication.AuthenticationStep {
|
||||
--
|
||||
+ getArgs() : Object;
|
||||
+ getKey() : String
|
||||
+ getMessage() : String
|
||||
+ isSuccess() : boolean
|
||||
|
||||
}
|
||||
interface org.alfresco.repo.security.authentication.AuthenticationUtil$RunAsWork <Result extends c Object> {
|
||||
--
|
||||
+ doWork() : Object
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.AuthenticationUtil {
|
||||
+ SYSTEM_USER_NAME : c String
|
||||
- defaultAdminUserName : c String
|
||||
- defaultGuestUserName : c String
|
||||
- initialized : boolean
|
||||
- mtEnabled : boolean
|
||||
- threadLocalFullAuthenticationStack : ThreadLocal< Stack< Authentication>>
|
||||
- threadLocalRunAsAuthenticationStack : ThreadLocal< Stack< Authentication>>
|
||||
- threadLocalTenantDomainStack : ThreadLocal< Stack< String>>
|
||||
~ s_logger : i Log
|
||||
--
|
||||
+ AuthenticationUtil()
|
||||
+ afterPropertiesSet() : void
|
||||
+ clearCurrentSecurityContext() : void
|
||||
+ getAdminRoleName() : String
|
||||
+ getAdminUserName() : String
|
||||
+ getFullAuthentication() : Authentication
|
||||
+ getFullyAuthenticatedUser() : String
|
||||
+ getGuestRoleName() : String
|
||||
+ getGuestUserName() : String
|
||||
+ getRunAsAuthentication() : Authentication
|
||||
+ getRunAsUser() : String
|
||||
+ getSystemUserName() : String
|
||||
+ getUserTenant(c String) : Pair
|
||||
+ isMtEnabled() : boolean
|
||||
+ isRunAsUserTheSystemUser() : boolean
|
||||
+ logAuthenticatedUsers() : void
|
||||
+ logNDC(c String) : void
|
||||
+ popAuthentication() : void
|
||||
+ pushAuthentication() : void
|
||||
+ runAs( AuthenticationUtil$RunAsWork<R>, c String) : Object
|
||||
+ runAsSystem( AuthenticationUtil$RunAsWork<R>) : Object
|
||||
+ setAdminUserAsFullyAuthenticatedUser() : Authentication
|
||||
+ setDefaultAdminUserName(c String) : void
|
||||
+ setDefaultGuestUserName(c String) : void
|
||||
+ setFullAuthentication(i Authentication) : Authentication
|
||||
+ setFullyAuthenticatedUser(c String) : Authentication
|
||||
+ setMtEnabled(boolean) : void
|
||||
+ setRunAsUser(c String) : Authentication
|
||||
+ setRunAsUserSystem() : Authentication
|
||||
- getAuthenticationToken(c String, i UserDetails) : UsernamePasswordAuthenticationToken
|
||||
- getDefaultUserDetails(c String) : UserDetails
|
||||
- getUserName(i Authentication) : String
|
||||
- setFullyAuthenticatedUser(c String, i UserDetails) : Authentication
|
||||
~ setRunAsAuthentication(i Authentication) : Authentication
|
||||
~ setRunAsUser(c String, i UserDetails) : Authentication
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.AuthenticationException {
|
||||
- serialVersionUID : long
|
||||
~ diagnostic : c AuthenticationDiagnostic
|
||||
--
|
||||
+ AuthenticationException(c String)
|
||||
+ AuthenticationException(c String, c AuthenticationDiagnostic)
|
||||
+ AuthenticationException(c String, c AuthenticationDiagnostic, c Object;, c Throwable)
|
||||
+ AuthenticationException(c String, c AuthenticationDiagnostic, c Throwable)
|
||||
+ AuthenticationException(c String, c Object;)
|
||||
+ AuthenticationException(c String, c Object;, c AuthenticationDiagnostic)
|
||||
+ AuthenticationException(c String, c Object;, c Throwable)
|
||||
+ AuthenticationException(c String, c Throwable)
|
||||
+ getDiagnostic() : AuthenticationDiagnostic
|
||||
|
||||
}
|
||||
class org.alfresco.error.AlfrescoRuntimeException {
|
||||
- MESSAGE_DELIMITER : c String
|
||||
- errorCounter : c AtomicInteger
|
||||
- msgId : c String
|
||||
- msgParams : c Object;
|
||||
- serialVersionUID : long
|
||||
--
|
||||
+ AlfrescoRuntimeException(c String)
|
||||
+ AlfrescoRuntimeException(c String, c Object;)
|
||||
+ AlfrescoRuntimeException(c String, c Object;, c Throwable)
|
||||
+ AlfrescoRuntimeException(c String, c Throwable)
|
||||
+ create(c String, c Object;) : AlfrescoRuntimeException
|
||||
+ create(c Throwable, c String, c Object;) : AlfrescoRuntimeException
|
||||
+ getMsgId() : String
|
||||
+ getMsgParams() : Object;
|
||||
+ getNumericalId() : String
|
||||
+ getRootCause() : Throwable
|
||||
+ makeRuntimeException(c Throwable, c String, c Object;) : RuntimeException
|
||||
- buildErrorLogNumber(c String) : String
|
||||
- padInt(c StringBuilder, int, int) : void
|
||||
- resolveMessage(c String, c Object;) : String
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.AuthenticationDiagnostic {
|
||||
+ STEP_KEY_LDAP_AUTHENTICATION : c String
|
||||
+ STEP_KEY_LDAP_CONNECTED : c String
|
||||
+ STEP_KEY_LDAP_CONNECTING : c String
|
||||
+ STEP_KEY_LDAP_FORMAT_USER : c String
|
||||
+ STEP_KEY_LDAP_LOOKEDUP_USER : c String
|
||||
+ STEP_KEY_LDAP_LOOKUP_USER : c String
|
||||
+ STEP_KEY_LDAP_SEARCH : c String
|
||||
+ STEP_KEY_VALIDATION : c String
|
||||
+ STEP_KEY_VALIDATION_AUTHENTICATOR_NOT_ACTIVE : c String
|
||||
+ STEP_KEY_VALIDATION_AUTHENTICATOR_NOT_FOUND : c String
|
||||
- serialVersionUID : long
|
||||
- steps : List< AuthenticationStep>
|
||||
--
|
||||
+ AuthenticationDiagnostic()
|
||||
+ addStep(c String, boolean) : void
|
||||
+ addStep(c String, boolean, c Object;) : void
|
||||
+ addStep(i AuthenticationStep) : void
|
||||
+ getSteps() : List
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.AuthenticationStepImpl {
|
||||
- serialVersionUID : long
|
||||
~ args : c Object;
|
||||
~ key : c String
|
||||
~ success : boolean
|
||||
--
|
||||
+ AuthenticationStepImpl(c String)
|
||||
+ getArgs() : Object;
|
||||
+ getKey() : String
|
||||
+ getMessage() : String
|
||||
+ isSuccess() : boolean
|
||||
+ toString() : String
|
||||
|
||||
}
|
||||
interface net.sf.acegisecurity.context.Context {
|
||||
--
|
||||
+ validate() : void
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.authentication.AlfrescoSecureContextImpl {
|
||||
- effectiveAuthentication : i Authentication
|
||||
- realAuthentication : i Authentication
|
||||
- serialVersionUID : long
|
||||
--
|
||||
+ AlfrescoSecureContextImpl()
|
||||
+ equals(c Object) : boolean
|
||||
+ getAuthentication() : Authentication
|
||||
+ getEffectiveAuthentication() : Authentication
|
||||
+ getRealAuthentication() : Authentication
|
||||
+ hashCode() : int
|
||||
+ setAuthentication(i Authentication) : void
|
||||
+ setEffectiveAuthentication(i Authentication) : void
|
||||
+ setRealAuthentication(i Authentication) : void
|
||||
+ toString() : String
|
||||
+ validate() : void
|
||||
|
||||
}
|
||||
enum org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$ExpiryMode {
|
||||
+ AFTER_FIXED_TIME : c InMemoryTicketComponentImpl$ExpiryMode
|
||||
+ AFTER_INACTIVITY : c InMemoryTicketComponentImpl$ExpiryMode
|
||||
+ DO_NOT_EXPIRE : c InMemoryTicketComponentImpl$ExpiryMode
|
||||
--
|
||||
- InMemoryTicketComponentImpl$ExpiryMode()
|
||||
+ valueOf(c String) : InMemoryTicketComponentImpl$ExpiryMode
|
||||
+ values() : InMemoryTicketComponentImpl$ExpiryMode;
|
||||
|
||||
}
|
||||
interface org.alfresco.repo.security.authentication.TicketComponent {
|
||||
--
|
||||
+ clearCurrentTicket() : void
|
||||
+ countTickets(boolean) : int
|
||||
+ getAuthorityForTicket(c String) : String
|
||||
+ getCurrentTicket(c String, boolean) : String
|
||||
+ getNewTicket(c String) : String
|
||||
+ getUseSingleTicketPerUser() : boolean
|
||||
+ getUsersWithTickets(boolean) : Set
|
||||
+ invalidateTicketById(c String) : void
|
||||
+ invalidateTicketByUser(c String) : void
|
||||
+ invalidateTickets(boolean) : int
|
||||
+ validateTicket(c String) : String
|
||||
|
||||
}
|
||||
|
||||
' Relations
|
||||
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl "1" o-left- "1" org.alfresco.repo.cache.SimpleCache : ticketsCache: SimpleCache< String, InMemoryTicketComponentImpl$Ticket>
|
||||
org.alfresco.repo.security.authentication.AlfrescoSecureContextImpl "1" o-left- "1" net.sf.acegisecurity.Authentication : realAuthentication: i Authentication
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$Ticket "1" o-left- "1" org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$ExpiryMode : expires: c InMemoryTicketComponentImpl$ExpiryMode
|
||||
org.alfresco.error.AlfrescoRuntimeException "1" o-left- "1" java.util.concurrent.atomic.AtomicInteger : errorCounter: c AtomicInteger
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$Ticket "1" o-left- "1" org.alfresco.service.cmr.repository.datatype.Duration : testDuration: c Duration
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$Ticket "1" o-left- "1" org.alfresco.service.cmr.repository.datatype.Duration : validDuration: c Duration
|
||||
org.alfresco.repo.security.authentication.AuthenticationUtil "1" o-left- "1" org.apache.commons.logging.Log : s_logger: i Log
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl "1" o-left- "1" org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$ExpiryMode : expiryMode: c InMemoryTicketComponentImpl$ExpiryMode
|
||||
org.alfresco.repo.security.authentication.AuthenticationException "1" o-left- "1" org.alfresco.repo.security.authentication.AuthenticationDiagnostic : diagnostic: c AuthenticationDiagnostic
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$Ticket "1" o-left- "1" java.util.Date : expiryDate: c Date
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl "1" o-left- "1" org.alfresco.service.cmr.repository.datatype.Duration : validDuration: c Duration
|
||||
org.alfresco.repo.security.authentication.AlfrescoSecureContextImpl "1" o-left- "1" net.sf.acegisecurity.Authentication : effectiveAuthentication: i Authentication
|
||||
org.alfresco.repo.security.authentication.AuthenticationException -up|> org.alfresco.error.AlfrescoRuntimeException
|
||||
org.alfresco.repo.security.authentication.TicketExpiredException -up|> org.alfresco.repo.security.authentication.AuthenticationException
|
||||
"net.sf.acegisecurity.context.Context" -() Serializable
|
||||
"org.alfresco.repo.security.authentication.AuthenticationStepImpl" -() Serializable
|
||||
org.alfresco.repo.security.authentication.AlfrescoSecureContext ..up|> net.sf.acegisecurity.context.security.SecureContext
|
||||
org.alfresco.repo.security.authentication.AuthenticationStepImpl ..up|> org.alfresco.repo.security.authentication.AuthenticationStep
|
||||
org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl ..up|> org.alfresco.repo.security.authentication.TicketComponent
|
||||
net.sf.acegisecurity.context.security.SecureContext ..up|> net.sf.acegisecurity.context.Context
|
||||
"org.alfresco.repo.security.authentication.AuthenticationDiagnostic" -() Serializable
|
||||
"org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl$Ticket" -() Serializable
|
||||
org.alfresco.repo.security.authentication.AlfrescoSecureContextImpl ..up|> org.alfresco.repo.security.authentication.AlfrescoSecureContext
|
||||
org.alfresco.repo.security.authentication.AuthenticationUtil ..up|> org.springframework.beans.factory.InitializingBean
|
||||
|
||||
' Notes
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 369 KiB |
@@ -0,0 +1,344 @@
|
||||
@startuml
|
||||
|
||||
left to right direction
|
||||
|
||||
' Generated using https://github.com/juanmf/Java2PlantUML
|
||||
|
||||
' Participants
|
||||
|
||||
class org.alfresco.error.AlfrescoRuntimeException {
|
||||
- MESSAGE_DELIMITER : c String
|
||||
- errorCounter : c AtomicInteger
|
||||
- msgId : c String
|
||||
- msgParams : c Object;
|
||||
- serialVersionUID : long
|
||||
--
|
||||
+ AlfrescoRuntimeException(c String)
|
||||
+ AlfrescoRuntimeException(c String, c Object;)
|
||||
+ AlfrescoRuntimeException(c String, c Object;, c Throwable)
|
||||
+ AlfrescoRuntimeException(c String, c Throwable)
|
||||
+ create(c String, c Object;) : AlfrescoRuntimeException
|
||||
+ create(c Throwable, c String, c Object;) : AlfrescoRuntimeException
|
||||
+ getMsgId() : String
|
||||
+ getMsgParams() : Object;
|
||||
+ getNumericalId() : String
|
||||
+ getRootCause() : Throwable
|
||||
+ makeRuntimeException(c Throwable, c String, c Object;) : RuntimeException
|
||||
- buildErrorLogNumber(c String) : String
|
||||
- padInt(c StringBuilder, int, int) : void
|
||||
- resolveMessage(c String, c Object;) : String
|
||||
|
||||
}
|
||||
class org.alfresco.service.cmr.security.NoSuchPersonException {
|
||||
- serialVersionUID : long
|
||||
- userName : c String
|
||||
--
|
||||
+ NoSuchPersonException(c String)
|
||||
+ getUserName() : String
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.OwnableService {
|
||||
+ NO_OWNER : c String
|
||||
--
|
||||
+ getOwner(c NodeRef) : String
|
||||
+ hasOwner(c NodeRef) : boolean
|
||||
+ setOwner(c NodeRef, c String) : void
|
||||
+ takeOwnership(c NodeRef) : void
|
||||
|
||||
}
|
||||
class org.alfresco.service.cmr.security.PersonService$PersonInfo {
|
||||
- firstName : c String
|
||||
- lastName : c String
|
||||
- nodeRef : c NodeRef
|
||||
- userName : c String
|
||||
--
|
||||
+ PersonService$PersonInfo(c NodeRef, c String, c String, c String)
|
||||
+ getFirstName() : String
|
||||
+ getLastName() : String
|
||||
+ getNodeRef() : NodeRef
|
||||
+ getUserName() : String
|
||||
|
||||
}
|
||||
enum org.alfresco.service.cmr.security.AccessStatus {
|
||||
+ ALLOWED : c AccessStatus
|
||||
+ DENIED : c AccessStatus
|
||||
+ UNDETERMINED : c AccessStatus
|
||||
--
|
||||
- AccessStatus()
|
||||
+ valueOf(c String) : AccessStatus
|
||||
+ values() : AccessStatus;
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.AuthenticationService {
|
||||
--
|
||||
+ authenticate(c String, class [C) : void
|
||||
+ authenticateAsGuest() : void
|
||||
+ authenticationExists(c String) : boolean
|
||||
+ clearCurrentSecurityContext() : void
|
||||
+ getAuthenticationEnabled(c String) : boolean
|
||||
+ getCurrentTicket() : String
|
||||
+ getCurrentUserName() : String
|
||||
+ getDefaultAdministratorUserNames() : Set
|
||||
+ getDefaultGuestUserNames() : Set
|
||||
+ getDomains() : Set
|
||||
+ getDomainsThatAllowUserCreation() : Set
|
||||
+ getDomainsThatAllowUserDeletion() : Set
|
||||
+ getDomiansThatAllowUserPasswordChanges() : Set
|
||||
+ getNewTicket() : String
|
||||
+ guestUserAuthenticationAllowed() : boolean
|
||||
+ invalidateTicket(c String) : void
|
||||
+ invalidateUserSession(c String) : void
|
||||
+ isCurrentUserTheSystemUser() : boolean
|
||||
+ validate(c String) : void
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.AuthorityService {
|
||||
+ ZONE_APP_DEFAULT : c String
|
||||
+ ZONE_APP_SHARE : c String
|
||||
+ ZONE_AUTH_ALFRESCO : c String
|
||||
+ ZONE_AUTH_EXT_PREFIX : c String
|
||||
--
|
||||
+ addAuthority( Collection< String>, c String) : void
|
||||
+ addAuthority(c String, c String) : void
|
||||
+ addAuthorityToZones(c String, Set< String>) : void
|
||||
+ authorityExists(c String) : boolean
|
||||
+ countGroups() : long
|
||||
+ countUsers() : long
|
||||
+ createAuthority(c AuthorityType, c String) : String
|
||||
+ createAuthority(c AuthorityType, c String, c String, Set< String>) : String
|
||||
+ deleteAuthority(c String) : void
|
||||
+ deleteAuthority(c String, boolean) : void
|
||||
+ findAuthorities(c AuthorityType, c String, boolean, c String, c String) : Set
|
||||
+ getAllAuthorities(c AuthorityType) : Set
|
||||
+ getAllAuthoritiesInZone(c String, c AuthorityType) : Set
|
||||
+ getAllRootAuthorities(c AuthorityType) : Set
|
||||
+ getAllRootAuthoritiesInZone(c String, c AuthorityType) : Set
|
||||
+ getAuthorities() : Set
|
||||
+ getAuthorities(c AuthorityType, c String, c String, boolean, boolean, c PagingRequest) : PagingResults
|
||||
+ getAuthoritiesForUser(c String) : Set
|
||||
+ getAuthoritiesInfo(c AuthorityType, c String, c String, c String, boolean, c PagingRequest) : PagingResults
|
||||
+ getAuthorityDisplayName(c String) : String
|
||||
+ getAuthorityNodeRef(c String) : NodeRef
|
||||
+ getAuthorityZones(c String) : Set
|
||||
+ getContainedAuthorities(c AuthorityType, c String, boolean) : Set
|
||||
+ getContainingAuthorities(c AuthorityType, c String, boolean) : Set
|
||||
+ getContainingAuthoritiesInZone(c AuthorityType, c String, c String, i AuthorityService$AuthorityFilter, int) : Set
|
||||
+ getDefaultZones() : Set
|
||||
+ getName(c AuthorityType, c String) : String
|
||||
+ getOrCreateZone(c String) : NodeRef
|
||||
+ getShortName(c String) : String
|
||||
+ getZone(c String) : NodeRef
|
||||
+ hasAdminAuthority() : boolean
|
||||
+ hasGuestAuthority() : boolean
|
||||
+ isAdminAuthority(c String) : boolean
|
||||
+ isGuestAuthority(c String) : boolean
|
||||
+ removeAuthority(c String, c String) : void
|
||||
+ removeAuthorityFromZones(c String, Set< String>) : void
|
||||
+ setAuthorityDisplayName(c String, c String) : void
|
||||
|
||||
}
|
||||
enum org.alfresco.service.cmr.security.AuthorityType {
|
||||
+ ADMIN : c AuthorityType
|
||||
+ EVERYONE : c AuthorityType
|
||||
+ GROUP : c AuthorityType
|
||||
+ GUEST : c AuthorityType
|
||||
+ OWNER : c AuthorityType
|
||||
+ ROLE : c AuthorityType
|
||||
+ USER : c AuthorityType
|
||||
+ WILDCARD : c AuthorityType
|
||||
--
|
||||
- AuthorityType()
|
||||
+ equals(c String) : boolean
|
||||
+ getAuthorityType(c String) : AuthorityType
|
||||
+ getFixedString() : String
|
||||
+ getOrderPosition() : int
|
||||
+ getPrefixString() : String
|
||||
+ isFixedString() : boolean
|
||||
+ isPrefixed() : boolean
|
||||
+ valueOf(c String) : AuthorityType
|
||||
+ values() : AuthorityType;
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.PersonService {
|
||||
--
|
||||
+ countPeople() : int
|
||||
+ createMissingPeople() : boolean
|
||||
+ createPerson( Map< QName, Serializable>) : NodeRef
|
||||
+ createPerson( Map< QName, Serializable>, Set< String>) : NodeRef
|
||||
+ deletePerson(c NodeRef) : void
|
||||
+ deletePerson(c NodeRef, boolean) : void
|
||||
+ deletePerson(c String) : void
|
||||
+ getAllPeople() : Set
|
||||
+ getMutableProperties() : Set
|
||||
+ getPeople( List< Pair< QName, String>>, boolean, List< Pair< QName, Boolean>>, c PagingRequest) : PagingResults
|
||||
+ getPeople(c String, List< QName>, List< Pair< QName, Boolean>>, c PagingRequest) : PagingResults
|
||||
+ getPeople(c String, List< QName>, Set< QName>, Set< QName>, boolean, List< Pair< QName, Boolean>>, c PagingRequest) : PagingResults
|
||||
+ getPeopleContainer() : NodeRef
|
||||
+ getPeopleFilteredByProperty(c QName, i Serializable, int) : Set
|
||||
+ getPerson(c NodeRef) : PersonService$PersonInfo
|
||||
+ getPerson(c String) : NodeRef
|
||||
+ getPerson(c String, boolean) : NodeRef
|
||||
+ getPersonOrNull(c String) : NodeRef
|
||||
+ getUserIdentifier(c String) : String
|
||||
+ getUserNamesAreCaseSensitive() : boolean
|
||||
+ isEnabled(c String) : boolean
|
||||
+ isMutable() : boolean
|
||||
+ notifyPerson(c String, c String) : void
|
||||
+ personExists(c String) : boolean
|
||||
+ setCreateMissingPeople(boolean) : void
|
||||
+ setPersonProperties(c String, Map< QName, Serializable>) : void
|
||||
+ setPersonProperties(c String, Map< QName, Serializable>, boolean) : void
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.PublicServiceAccessService {
|
||||
--
|
||||
+ hasAccess(c String, c String, c Object;) : AccessStatus
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.MutableAuthenticationService {
|
||||
--
|
||||
+ createAuthentication(c String, class [C) : void
|
||||
+ deleteAuthentication(c String) : void
|
||||
+ isAuthenticationCreationAllowed() : boolean
|
||||
+ isAuthenticationMutable(c String) : boolean
|
||||
+ setAuthentication(c String, class [C) : void
|
||||
+ setAuthenticationEnabled(c String, boolean) : void
|
||||
+ updateAuthentication(c String, class [C, class [C) : void
|
||||
|
||||
}
|
||||
class org.alfresco.service.cmr.security.PermissionContext {
|
||||
- additionalContext : Map< String, Object>
|
||||
- aspects : HashSet< QName>
|
||||
- dynamicAuthorityAssignment : Map< String, Set< String>>
|
||||
- properties : Map< QName, Serializable>
|
||||
- storeAcl : c Long
|
||||
- type : c QName
|
||||
--
|
||||
+ PermissionContext(c QName)
|
||||
+ addDynamicAuthorityAssignment(c String, c String) : void
|
||||
+ getAdditionalContext() : Map
|
||||
+ getAspects() : HashSet
|
||||
+ getDynamicAuthorityAssignment() : Map
|
||||
+ getProperties() : Map
|
||||
+ getStoreAcl() : Long
|
||||
+ getType() : QName
|
||||
+ setStoreAcl(c Long) : void
|
||||
|
||||
}
|
||||
interface org.alfresco.repo.security.permissions.PermissionCheckValue {
|
||||
--
|
||||
+ getNodeRef() : NodeRef
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.PermissionService {
|
||||
+ ADD_CHILDREN : c String
|
||||
+ ADMINISTRATOR_AUTHORITY : c String
|
||||
+ ALL_AUTHORITIES : c String
|
||||
+ ALL_PERMISSIONS : c String
|
||||
+ ASPECTS : c String
|
||||
+ CANCEL_CHECK_OUT : c String
|
||||
+ CHANGE_PERMISSIONS : c String
|
||||
+ CHECK_IN : c String
|
||||
+ CHECK_OUT : c String
|
||||
+ CONSUMER : c String
|
||||
+ CONTRIBUTOR : c String
|
||||
+ COORDINATOR : c String
|
||||
+ CREATE_ASSOCIATIONS : c String
|
||||
+ CREATE_CHILDREN : c String
|
||||
+ DELETE : c String
|
||||
+ DELETE_ASSOCIATIONS : c String
|
||||
+ DELETE_CHILDREN : c String
|
||||
+ DELETE_NODE : c String
|
||||
+ EDITOR : c String
|
||||
+ EXECUTE : c String
|
||||
+ EXECUTE_CONTENT : c String
|
||||
+ FULL_CONTROL : c String
|
||||
+ GROUP_PREFIX : c String
|
||||
+ GUEST_AUTHORITY : c String
|
||||
+ LINK_CHILDREN : c String
|
||||
+ LOCK : c String
|
||||
+ LOCK_OWNER_AUTHORITY : c String
|
||||
+ OWNER_AUTHORITY : c String
|
||||
+ PROPERTIES : c String
|
||||
+ READ : c String
|
||||
+ READ_ASSOCIATIONS : c String
|
||||
+ READ_CHILDREN : c String
|
||||
+ READ_CONTENT : c String
|
||||
+ READ_PERMISSIONS : c String
|
||||
+ READ_PROPERTIES : c String
|
||||
+ ROLE_PREFIX : c String
|
||||
+ SET_OWNER : c String
|
||||
+ TAKE_OWNERSHIP : c String
|
||||
+ UNLOCK : c String
|
||||
+ WRITE : c String
|
||||
+ WRITE_CONTENT : c String
|
||||
+ WRITE_PROPERTIES : c String
|
||||
--
|
||||
+ clearPermission(c NodeRef, c String) : void
|
||||
+ clearPermission(c StoreRef, c String) : void
|
||||
+ deletePermission(c NodeRef, c String, c String) : void
|
||||
+ deletePermission(c StoreRef, c String, c String) : void
|
||||
+ deletePermissions(c NodeRef) : void
|
||||
+ deletePermissions(c StoreRef) : void
|
||||
+ getAllAuthorities() : String
|
||||
+ getAllPermission() : String
|
||||
+ getAllSetPermissions(c NodeRef) : Set
|
||||
+ getAllSetPermissions(c StoreRef) : Set
|
||||
+ getAuthorisations() : Set
|
||||
+ getInheritParentPermissions(c NodeRef) : boolean
|
||||
+ getOwnerAuthority() : String
|
||||
+ getPermissions(c NodeRef) : Set
|
||||
+ getReaders(c Long) : Set
|
||||
+ getReadersDenied(c Long) : Set
|
||||
+ getSettablePermissions(c NodeRef) : Set
|
||||
+ getSettablePermissions(c QName) : Set
|
||||
+ hasPermission(c Long, c PermissionContext, c String) : AccessStatus
|
||||
+ hasPermission(c NodeRef, c String) : AccessStatus
|
||||
+ hasReadPermission(c NodeRef) : AccessStatus
|
||||
+ setInheritParentPermissions(c NodeRef, boolean) : void
|
||||
+ setInheritParentPermissions(c NodeRef, boolean, boolean) : void
|
||||
+ setPermission(c NodeRef, c String, c String, boolean) : void
|
||||
+ setPermission(c StoreRef, c String, c String, boolean) : void
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.AuthorityService$AuthorityFilter {
|
||||
--
|
||||
+ includeAuthority(c String) : boolean
|
||||
|
||||
}
|
||||
interface org.alfresco.service.cmr.security.AccessPermission {
|
||||
--
|
||||
+ getAccessStatus() : AccessStatus
|
||||
+ getAuthority() : String
|
||||
+ getAuthorityType() : AuthorityType
|
||||
+ getPermission() : String
|
||||
+ getPosition() : int
|
||||
+ isInherited() : boolean
|
||||
+ isSetDirectly() : boolean
|
||||
|
||||
}
|
||||
class org.alfresco.repo.security.person.PersonException {
|
||||
- serialVersionUID : long
|
||||
--
|
||||
+ PersonException(c String)
|
||||
+ PersonException(c String, c Object;)
|
||||
+ PersonException(c String, c Object;, c Throwable)
|
||||
+ PersonException(c String, c Throwable)
|
||||
|
||||
}
|
||||
|
||||
' Relations
|
||||
|
||||
org.alfresco.service.cmr.security.PersonService$PersonInfo "1" o-left- "1" org.alfresco.service.cmr.repository.NodeRef : nodeRef: c NodeRef
|
||||
org.alfresco.error.AlfrescoRuntimeException "1" o-left- "1" java.util.concurrent.atomic.AtomicInteger : errorCounter: c AtomicInteger
|
||||
org.alfresco.service.cmr.security.PermissionContext "1" o-left- "*" org.alfresco.service.namespace.QName : aspects: HashSet< QName>
|
||||
org.alfresco.service.cmr.security.PermissionContext "1" o-left- "1" org.alfresco.service.namespace.QName : type: c QName
|
||||
org.alfresco.service.cmr.security.PermissionContext "1" o-left- "*" org.alfresco.service.namespace.QName : properties: Map< QName, Serializable>
|
||||
org.alfresco.repo.security.person.PersonException -up|> org.alfresco.error.AlfrescoRuntimeException
|
||||
org.alfresco.service.cmr.security.NoSuchPersonException -up|> org.alfresco.repo.security.person.PersonException
|
||||
org.alfresco.service.cmr.security.MutableAuthenticationService ..up|> org.alfresco.service.cmr.security.AuthenticationService
|
||||
org.alfresco.service.cmr.security.PersonService$PersonInfo ..up|> org.alfresco.repo.security.permissions.PermissionCheckValue
|
||||
|
||||
' Notes
|
||||
|
||||
@enduml
|
8
repository/docs/infrastructure/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Repository -> Infrastructure
|
||||
|
||||
## Sub-components
|
||||
|
||||
* [ ] [Module Framework](./module-framework)
|
||||
* [ ] [Cluster](./cluster)
|
||||
* [ ] [Policies and Behaviours](./policies-and-behaviours)
|
||||
* [ ] [Multi-tenancy](./multi-tenancy)
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,30 @@
|
||||
@startuml
|
||||
|
||||
title Tenant Service (aws)
|
||||
|
||||
|
||||
|
||||
interface TenantService
|
||||
interface TenantServiceSPI
|
||||
|
||||
class Tenant
|
||||
class TenantServiceDDBImpl
|
||||
class TenantServiceImpl
|
||||
class TenantServiceLambda
|
||||
|
||||
|
||||
Tenant <.. TenantService : uses
|
||||
Tenant <.. TenantServiceDDBImpl : uses
|
||||
Tenant <.. TenantServiceImpl : uses
|
||||
Tenant <.. TenantServiceSPI : uses
|
||||
TenantServiceDDBImpl <.. TenantServiceLambda : uses
|
||||
TenantServiceImpl <.. TenantServiceLambda : uses
|
||||
TenantServiceSPI <.. TenantServiceImpl : uses
|
||||
TenantServiceSPI <.. TenantServiceLambda : uses
|
||||
|
||||
TenantService <|.. TenantServiceImpl : implements
|
||||
TenantServiceSPI <|.. TenantServiceDDBImpl : implements
|
||||
|
||||
center footer © 2016 Alfresco Software Inc. all rights reserved \n Generated from PlantUML
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 68 KiB |
@@ -0,0 +1,89 @@
|
||||
@startuml
|
||||
left to right direction
|
||||
|
||||
|
||||
interface com.alfresco.services.lambda.TenantServiceSPI {
|
||||
--
|
||||
+ createTenant(c String, c String) : Tenant
|
||||
+ deleteTenant(c String) : boolean
|
||||
+ getTenant(c String) : Tenant
|
||||
+ getTenantSchema(c String) : String
|
||||
+ updateTenant(c Tenant) : boolean
|
||||
|
||||
}
|
||||
interface com.alfresco.services.lambda.TenantService {
|
||||
--
|
||||
+ createTenant(c String, c String) : Tenant
|
||||
+ deleteTenant(c String) : boolean
|
||||
+ getTenant(c String) : Tenant
|
||||
+ getTenantSchema(c String) : String
|
||||
+ updateTenant(c Tenant) : boolean
|
||||
|
||||
}
|
||||
class com.alfresco.services.lambda.TenantServiceDDBImpl {
|
||||
- regions : c Regions
|
||||
- tableName : c String
|
||||
--
|
||||
+ TenantServiceDDBImpl()
|
||||
+ createTenant(c String, c String) : Tenant
|
||||
+ deleteTenant(c String) : boolean
|
||||
+ getTenant(c String) : Tenant
|
||||
+ getTenantSchema(c String) : String
|
||||
+ updateTenant(c Tenant) : boolean
|
||||
- log(c String) : void
|
||||
|
||||
}
|
||||
class com.alfresco.services.lambda.TenantServiceLambda {
|
||||
--
|
||||
+ TenantServiceLambda()
|
||||
+ handleRequest(c Tenant, i Context) : Tenant
|
||||
|
||||
}
|
||||
class com.alfresco.services.lambda.TenantServiceImpl {
|
||||
- tenantServiceSPI : i TenantServiceSPI
|
||||
--
|
||||
+ TenantServiceImpl(i TenantServiceSPI)
|
||||
+ createTenant(c String, c String) : Tenant
|
||||
+ deleteTenant(c String) : boolean
|
||||
+ getTenant(c String) : Tenant
|
||||
+ getTenantSchema(c String) : String
|
||||
+ updateTenant(c Tenant) : boolean
|
||||
|
||||
}
|
||||
class com.alfresco.services.lambda.Tenant {
|
||||
- method : c String
|
||||
- schema : c String
|
||||
- spiProvider : c String
|
||||
- tenantId : c String
|
||||
- user : c String
|
||||
--
|
||||
+ Tenant()
|
||||
+ getMethod() : String
|
||||
+ getSchema() : String
|
||||
+ getSpiProvider() : String
|
||||
+ getTenantId() : String
|
||||
+ getUser() : String
|
||||
+ setMethod(c String) : void
|
||||
+ setSchema(c String) : void
|
||||
+ setSpiProvider(c String) : void
|
||||
+ setTenantId(c String) : void
|
||||
+ setUser(c String) : void
|
||||
|
||||
}
|
||||
interface com.amazonaws.services.lambda.runtime.RequestHandler <I extends c Object, O extends c Object> {
|
||||
--
|
||||
+ handleRequest(I, i Context) : Object
|
||||
|
||||
}
|
||||
|
||||
' Relations
|
||||
|
||||
com.alfresco.services.lambda.TenantServiceImpl "1" o-left- "1" com.alfresco.services.lambda.TenantServiceSPI : tenantServiceSPI: i TenantServiceSPI
|
||||
com.alfresco.services.lambda.TenantServiceDDBImpl "1" o-left- "1" com.amazonaws.regions.Regions : regions: c Regions
|
||||
com.alfresco.services.lambda.TenantServiceImpl ..up|> com.alfresco.services.lambda.TenantService
|
||||
com.alfresco.services.lambda.TenantServiceDDBImpl ..up|> com.alfresco.services.lambda.TenantServiceSPI
|
||||
com.alfresco.services.lambda.TenantServiceLambda ..up|> com.amazonaws.services.lambda.runtime.RequestHandler
|
||||
|
||||
' Notes
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,51 @@
|
||||
@startuml
|
||||
|
||||
title Tenant Component (nosql)
|
||||
|
||||
skinparam linetype ortho
|
||||
|
||||
interface ApiConstants
|
||||
interface TenantService
|
||||
interface TenantServiceSPI
|
||||
|
||||
class AbstractRestResource {
|
||||
#switchTenant()
|
||||
}
|
||||
class AbstractServiceClient
|
||||
class An2ApiException
|
||||
class CreateTenantPojo
|
||||
class Cx1TenantService
|
||||
class GetTenantPojo
|
||||
class InitializingBean
|
||||
class NoSuchTenantException
|
||||
class TenantExistsException
|
||||
class TenantService
|
||||
class TenantServiceClient
|
||||
class TenantServiceImpl
|
||||
class TenantServiceIT
|
||||
class TenantServiceRestV1
|
||||
class VersionCheckException
|
||||
|
||||
|
||||
AbstractRestResource <|-- TenantServiceRestV1 : extends
|
||||
AbstractServiceClient <|-- TenantServiceClient : extends
|
||||
An2ApiException <|-- NoSuchTenantException : extends
|
||||
An2ApiException <|-- TenantExistsException : extends
|
||||
An2ApiException <|-- VersionCheckException : extends
|
||||
ApiConstants <|.. TenantServiceImpl : uses
|
||||
CreateTenantPojo <.. TenantServiceClient : uses
|
||||
CreateTenantPojo <.. TenantServiceRestV1 : uses
|
||||
GetTenantPojo <.. TenantServiceClient : uses
|
||||
GetTenantPojo <.. TenantServiceRestV1 : uses
|
||||
InitializingBean <|.. TenantServiceImpl : implements
|
||||
NoSuchTenantException <.. AbstractRestResource : uses
|
||||
TenantService <.. AbstractRestResource : uses
|
||||
TenantService <|.. TenantServiceClient : implements
|
||||
TenantService <|.. TenantServiceImpl : implements
|
||||
TenantService <|.. TenantServiceRestV1 : uses
|
||||
TenantServiceClient <.. TenantServiceIT : uses
|
||||
TenantServiceSPI <.. Cx1TenantService : implements
|
||||
TenantServiceSPI <.. TenantServiceImpl : uses
|
||||
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,39 @@
|
||||
@startuml
|
||||
|
||||
title Tenant Service (nosql)
|
||||
|
||||
skinparam linetype ortho
|
||||
|
||||
node "Service\nClient" as SC #E0F2F1
|
||||
|
||||
node "API Gateway" as APIG #EEEEEE {
|
||||
|
||||
node "/tenants Resource" as TR #EFEBE9 {
|
||||
node "method POST" as POST #FBE9E7 {
|
||||
node "POST \nbody mapping template" #DCEDC8
|
||||
}
|
||||
node "method PUT" as PUT #FBE9E7{
|
||||
node "PUT \nbody mapping template" #DCEDC8
|
||||
}
|
||||
node "method GET" as GET #FBE9E7
|
||||
node "method DELETE" As DELETE #FBE9E7
|
||||
}
|
||||
}
|
||||
node "Tenant Service \nLambda Function" as L #FFD54F
|
||||
|
||||
database "DynamoDB Database\nalf-data-tenants" as DB #80D8FF
|
||||
|
||||
node "DynamoDB\nClient" As DDBC #B3E5FC
|
||||
|
||||
node "DynamoDB" As DDB #B2EBF2
|
||||
|
||||
SC->TR:https
|
||||
POST->L:JSON
|
||||
PUT->L:JSON
|
||||
GET->L:URL {tenant-id}
|
||||
DELETE->L:URL {tenant-id}
|
||||
L->DDBC
|
||||
DDBC->DDB:reads/writes
|
||||
DDB->DB:reads/writes
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 65 KiB |
@@ -0,0 +1,86 @@
|
||||
@startuml
|
||||
|
||||
Title Tenant Deployment\nDesign Options
|
||||
|
||||
skinparam nodeBorderColor black
|
||||
|
||||
left to right direction
|
||||
|
||||
node "AWS" as 2G #EEEEEE {
|
||||
node "Tenant\nService" as 2T #white
|
||||
node "Alfresco\nControl Architecture" as 2CA #white
|
||||
node "Customer A" as 2C1 #FFCDD2 {
|
||||
node "Alfresco 5.1" as 2A1 #E6EE9C {
|
||||
node "Tenant" as 2T1
|
||||
}
|
||||
}
|
||||
node "Customer B" as 2C2 #FFCDD2{
|
||||
node "Alfresco 5.1" as 2A2 #E6EE9C {
|
||||
node "Tenant" as 2T2
|
||||
}
|
||||
}
|
||||
node "Customer C" as 2C3 #FFCDD2{
|
||||
node "Alfresco 5.1" as 2A3 #E6EE9C {
|
||||
node "Tenant" as 2T3
|
||||
}
|
||||
}
|
||||
node "Customers D and E" as CDE #FFCDD2{
|
||||
node "Repository Next" as 2B #B3E5FC
|
||||
node "Tenant\n(Customer D)" as 2CD
|
||||
node "Tenant\n(Customer E)" as 2CE
|
||||
}
|
||||
}
|
||||
|
||||
2CA=>2C1
|
||||
2CA=>2C2
|
||||
2CA=>2C3
|
||||
2CA=>CDE
|
||||
2CA=>2T
|
||||
2T=>2CD
|
||||
2T=>2CE
|
||||
2B=>2T
|
||||
|
||||
node "AWS" as G #EEEEEE {
|
||||
node "Alfresco\nControl Architecture" as CA #white
|
||||
node "Customer A" as C1 #FFCDD2 {
|
||||
node "Alfresco 5.1" as A1 #E6EE9C {
|
||||
node "Tenant" as T1
|
||||
}
|
||||
}
|
||||
node "Customer B" as C2 #FFCDD2{
|
||||
node "Alfresco 5.1" as A2 #E6EE9C {
|
||||
node "Tenant" as T2
|
||||
}
|
||||
}
|
||||
node "Customer C" as C3 #FFCDD2{
|
||||
node "Alfresco 5.1" as A3 #E6EE9C {
|
||||
node "Tenant" as T3
|
||||
}
|
||||
}
|
||||
node "Customer D" as C4 #FFCDD2 {
|
||||
node "Tenant\nService" as TC1 #white
|
||||
node "Tenant" as T5
|
||||
node "Repository Next" as B1 #B3E5FC
|
||||
}
|
||||
node "Customer E" as C5 #FFCDD2 {
|
||||
node "Tenant\nService" as TC2 #white
|
||||
node "Tenant" as T6
|
||||
node "Tenant" as T7
|
||||
node "Tenant" as T8
|
||||
node "Repository Next" as B2 #B3E5FC
|
||||
}
|
||||
}
|
||||
|
||||
TC1=>T5
|
||||
TC2=>T6
|
||||
TC2=>T7
|
||||
TC2=>T8
|
||||
CA=>C1
|
||||
CA=>C2
|
||||
CA=>C3
|
||||
CA=>C4
|
||||
CA=>C5
|
||||
B2=>TC2
|
||||
B1=>TC1
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,69 @@
|
||||
@startuml
|
||||
|
||||
Title: Create a Tenant (NoSQL - AWS)
|
||||
actor "User" as U
|
||||
participant "Tenant Console" as TC
|
||||
participant "API Gateway" as APIG
|
||||
participant "TenantServiceLambda" as TSL
|
||||
participant "TenantServiceImpl" as TSI
|
||||
participant "DDbTenantService" as DDTS
|
||||
participant "Dynamo DB Client" as DDBC
|
||||
database "DynamoDB" as DDB
|
||||
|
||||
U->TC:create Tenant
|
||||
note right
|
||||
What the Tenant Console
|
||||
is is TBD. It
|
||||
may be part of the
|
||||
AWS Control Architecture
|
||||
or a Beowulf Admin
|
||||
Console
|
||||
end note
|
||||
activate TC
|
||||
TC->APIG: HTTP POST {<API Gateway host:port>/public/an2/v1/tenants\nTenant Object(JSON)
|
||||
activate APIG
|
||||
APIG->TSL: handler(serialized Tenant Object(JSON))
|
||||
note right
|
||||
The HTTP Verb and UserInfo is
|
||||
passed to the Tenant Service
|
||||
Lambda in the JSON object.
|
||||
Tenant Service Lambda selects
|
||||
the TenantServiceImpl method
|
||||
to call based on the HTTP Verb
|
||||
end note
|
||||
activate TSL
|
||||
TSL->TSI: createTenant()
|
||||
note right
|
||||
Unsolved Design Challenge #1:
|
||||
How to supply a configuration
|
||||
to allow alternative
|
||||
implementations at
|
||||
runtime. In current
|
||||
form, the TenantServiceSPI
|
||||
passed to TenantServiceImpl
|
||||
is set in an API Gateway
|
||||
template. That would allow
|
||||
us to specify a different
|
||||
provider of the SPI using,
|
||||
for example, an HTTP parm
|
||||
end note
|
||||
activate TSI
|
||||
TSI->DDTS
|
||||
activate DDTS
|
||||
DDTS->DDBC: table.putItem(new Item().withPrimaryKey("tenant-id")
|
||||
activate DDBC
|
||||
DDBC->DDB: store the tenant record
|
||||
DDB->DDBC: success
|
||||
deactivate DDB
|
||||
DDBC->DDTS:success
|
||||
deactivate DDBC
|
||||
DDTS->TSI:success
|
||||
deactivate DDTS
|
||||
TSI->TSL: success
|
||||
deactivate TSI
|
||||
TSL->TC: HTTP 200 OK
|
||||
deactivate TSL
|
||||
TC->>U:success message
|
||||
deactivate TC
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 60 KiB |
@@ -0,0 +1,60 @@
|
||||
@startuml
|
||||
|
||||
Title: Create a Tenant (NoSQL)
|
||||
actor "User" as U
|
||||
participant "Tenant Console" as TC
|
||||
participant "TenantServiceClient" as TCL
|
||||
participant "TenantServiceRestV1" as TRS
|
||||
participant "TenantServiceImpl" as TSI
|
||||
participant "Cx1TenantService" as CTS
|
||||
participant "cassandra-driver-core-2.2.0-rc1" as DDC
|
||||
database "Cassandra" as C
|
||||
|
||||
U->TC:create Tenant
|
||||
note right
|
||||
The Tenant Console
|
||||
may be part of the
|
||||
Admin Console
|
||||
end note
|
||||
activate TC
|
||||
TC->TCL:createTenant()
|
||||
activate TCL
|
||||
TCL->TCL: find server from super\nAbstractServiceClient
|
||||
TCL->TRS: HTTP POST {tenantCtx}/public/an2/v1/tenants\nCreateTenantPojo(JSON)
|
||||
activate TRS
|
||||
note right
|
||||
This is wired
|
||||
to the endpoint
|
||||
using Jersey
|
||||
end note
|
||||
TRS->TSI: create(TenantServiceSPI=Cx1TenantService)
|
||||
activate TSI
|
||||
TSI->CTS: createTenant()
|
||||
note right
|
||||
The Cassandra
|
||||
implementation can
|
||||
be replaced by
|
||||
other implementations
|
||||
(e.g. Dynamo DB)
|
||||
through Spring config
|
||||
end note
|
||||
activate CTS
|
||||
CTS->DDC: insert into Table alf_data_tenants
|
||||
activate DDC
|
||||
DDC->C: store the tenant record
|
||||
C->DDC:success
|
||||
deactivate C
|
||||
DDC->CTS: success
|
||||
deactivate DDC
|
||||
CTS->TSI:success
|
||||
deactivate CTS
|
||||
TSI->TRS: success
|
||||
deactivate TSI
|
||||
TRS->TCL: HTTP 200 OK
|
||||
deactivate TRS
|
||||
TCL->TC: success
|
||||
deactivate TCL
|
||||
TC->>U:success message
|
||||
deactivate TC
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 79 KiB |
@@ -0,0 +1,175 @@
|
||||
@startuml
|
||||
|
||||
title Policies: Policy Component (V4.2 onwards)
|
||||
|
||||
' Split into 2 pages
|
||||
page 2x1
|
||||
|
||||
interface PolicyEndpointService #DDDDDD
|
||||
class PolicyEndpointServiceImpl #DDDDDD implements PolicyEndpointService{
|
||||
- policyComponent : PolicyComponent
|
||||
- policyEndpointRegistry : registry
|
||||
+ registerPolicyEndpoint(QName policy, String endpoint) : void
|
||||
+ registerPolicyEndpoint(QName policy, QName typeOrAspect, String endpoint) : void
|
||||
+ unregisterPolicyEndpoint(QName policy, String endpoint) : void
|
||||
+ unregisterPolicyEndpoint(QName policy, QName typeOrAspect, String endpoint) : void
|
||||
}
|
||||
PolicyEndpointServiceImpl -> PolicyComponent
|
||||
class PolicyEndpointRegistry #DDDDDD {
|
||||
- QueuedBehaviour dynamicBehaviour
|
||||
- Set<PolicyEndPointPolicyEndpoint> registrations
|
||||
+ {static} PolicyEndpointRegistry getInstance()
|
||||
+ reload(long fromTime)
|
||||
+ slip(String body, @Properties Map<String, Object> properties)
|
||||
}
|
||||
PolicyEndpointRegistry *- "1" QueuedBehaviour
|
||||
PolicyEndpointServiceImpl -> PolicyEndpointRegistry
|
||||
class PolicyEndpoint <<immutable>> #DDDDDD {
|
||||
- QName policy
|
||||
- QName typeOrAspect
|
||||
- String endpoint
|
||||
- long modified
|
||||
- boolean active
|
||||
+ getKey()
|
||||
}
|
||||
PolicyEndpointRegistry *- PolicyEndpoint
|
||||
|
||||
|
||||
interface Policy
|
||||
interface ClassPolicy extends Policy
|
||||
interface OnCreateNodePolicy extends ClassPolicy {
|
||||
+QNAME: http://www.alfresco.org:onCreateNode
|
||||
+onCreateNode(ChildAssociationRef childAssocRef)
|
||||
}
|
||||
interface AssociationPolicy extends Policy
|
||||
interface OnCreateChildAssociationPolicy extends AssociationPolicy {
|
||||
+QNAME: http://www.alfresco.org:onCreateChildAssociation
|
||||
+onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode)
|
||||
}
|
||||
|
||||
enum NotificationFrequency {
|
||||
EVERY_EVENT,
|
||||
FIRST_EVENT,
|
||||
TRANSACTION_COMMIT
|
||||
}
|
||||
|
||||
interface Behaviour {
|
||||
+ <T> getInterface(Class<T> policy) : T
|
||||
+ disable()
|
||||
+ enable()
|
||||
+ isEnabled() : boolean
|
||||
+ getNotificationFrequency() : NotificationFrequency
|
||||
}
|
||||
class BaseBehaviour implements Behaviour {
|
||||
# proxies : Map<Class, Object>
|
||||
# frequency : NotificationFrequency
|
||||
- disabled : StackThreadLocal
|
||||
+ disable()
|
||||
+ enable()
|
||||
+ isEnabled() : boolean
|
||||
+ getNotificationFrequency() : NotificationFrequency
|
||||
}
|
||||
class JavaBehaviour extends BaseBehaviour {
|
||||
+ <T> getInterface(Class<T> policy) : T
|
||||
# <T> getInvocationHandler(Object instance, String method, Class<T> policyIF) : InvocationHandler
|
||||
}
|
||||
class QueuedBehaviour <<V5.2>> #DDDDDD extends BaseBehaviour {
|
||||
- ProducerTemplate queueTemplate
|
||||
+ <T> getInterface(Class<T> policy) : T
|
||||
# <T> getInvocationHandler(Object instance, String method, Class<T> policyIF) : InvocationHandler
|
||||
}
|
||||
class ScriptBehaviour extends BaseBehaviour
|
||||
BaseBehaviour o- NotificationFrequency
|
||||
|
||||
interface BehaviourBinding {
|
||||
+ generaliseBinding() : BehaviourBinding
|
||||
}
|
||||
class ClassBehaviourBinding implements BehaviourBinding {
|
||||
+ generaliseBinding() : BehaviourBinding
|
||||
}
|
||||
class ClassFeatureBehaviourBinding extends ClassBehaviourBinding {
|
||||
}
|
||||
class ServiceBehaviourBinding implements BehaviourBinding {
|
||||
+ generaliseBinding() : BehaviourBinding
|
||||
}
|
||||
|
||||
class ClassPolicyDelegate<P extends ClassPolicy> {
|
||||
- dictionary : DictionaryService
|
||||
- factory : CachedPolicyFactory<ClassFeatureBehaviourBinding, P>
|
||||
# ClassPolicyDelegate(DictionaryService dictionary, Class<P> policyClass, BehaviourIndex<ClassBehaviourBinding> index, long tryLockTimeout)
|
||||
}
|
||||
class AssociationPolicyDelegate<P extends AssociationPolicy> {
|
||||
- dictionary : DictionaryService
|
||||
- factory : CachedPolicyFactory<ClassFeatureBehaviourBinding, P>
|
||||
# AssociationPolicyDelegate(DictionaryService dictionary, Class<P> policyClass, BehaviourIndex<ClassFeatureBehaviourBinding> index, long tryLockTimeout)
|
||||
}
|
||||
class PropertyPolicyDelegate<P extends PropertyPolicy> {
|
||||
- dictionary : DictionaryService
|
||||
- factory : CachedPolicyFactory<ClassFeatureBehaviourBinding, P>
|
||||
# PropertyPolicyDelegate(DictionaryService dictionary, Class<P> policyClass, BehaviourIndex<ClassFeatureBehaviourBinding> index, long tryLockTimeout)
|
||||
}
|
||||
class PolicyFactory<B extends BehaviourBinding, P extends Policy> {
|
||||
- index : BehaviourIndex~<B>
|
||||
- policyClass : Class~<P>
|
||||
- transactionHandlerFactory : TransactionInvocationHandlerFactory
|
||||
- tenantService : TenantService
|
||||
--
|
||||
PolicyFactory(Class<P> policyClass, BehaviourIndex~<B> index)
|
||||
--
|
||||
}
|
||||
class CachedPolicyFactory<B extends BehaviourBinding, P extends Policy> extends PolicyFactory
|
||||
|
||||
abstract class AbstractNodeServiceImpl implements NodeService {
|
||||
- policyComponent : PolicyComponent
|
||||
# dictionaryService : DictionaryService
|
||||
# transactionService : TransactionService
|
||||
# tenantService : TenantService
|
||||
- onCreateNodeDelegate : ClassPolicyDelegate<OnCreateNodePolicy>
|
||||
}
|
||||
interface PolicyComponent {
|
||||
+ <P extends ClassPolicy> registerClassPolicy(Class<P> policy) : ClassPolicyDelegate<P>
|
||||
+ <P extends PropertyPolicy> registerPropertyPolicy(Class<P> policy) : PropertyPolicyDelegate<P>
|
||||
+ <P extends AssociationPolicy> registerAssociationPolicy(Class<P> policy) : AssociationPolicyDelegate<P>
|
||||
+ bindClassBehaviour(QName policy, QName className, Behaviour behaviour) : BehaviourDefinition<ClassBehaviourBinding>
|
||||
+ bindClassBehaviour(QName policy, Object service, Behaviour behaviour) : BehaviourDefinition<ServiceBehaviourBinding>
|
||||
+ bindPropertyBehaviour(QName policy, QName className, QName propertyName, Behaviour behaviour) : BehaviourDefinition<ClassFeatureBehaviourBinding>
|
||||
+ bindPropertyBehaviour(QName policy, QName className, Behaviour behaviour) : BehaviourDefinition<ClassFeatureBehaviourBinding>
|
||||
+ bindPropertyBehaviour(QName policy, Object service, Behaviour behaviour) : BehaviourDefinition<ServiceBehaviourBinding>
|
||||
+ bindAssociationBehaviour(QName policy, QName className, QName assocName, Behaviour behaviour) : BehaviourDefinition<ClassFeatureBehaviourBinding>
|
||||
+ bindAssociationBehaviour(QName policy, QName className, Behaviour behaviour) : BehaviourDefinition<ClassFeatureBehaviourBinding>
|
||||
+ bindAssociationBehaviour(QName policy, Object service, Behaviour behaviour) : BehaviourDefinition<ServiceBehaviourBinding>
|
||||
+ removeClassDefinition(BehaviourDefinition<ClassBehaviourBinding> definition) : void
|
||||
}
|
||||
class PolicyComponentImpl implements PolicyComponent {
|
||||
- Map<QName, ClassBehaviourIndex<ClassBehaviourBinding>> classBehaviours
|
||||
- Map<QName, ClassBehaviourIndex<ClassFeatureBehaviourBinding>> propertyBehaviours
|
||||
- Map<QName, ClassBehaviourIndex<ClassFeatureBehaviourBinding>> associationBehaviours
|
||||
+ PolicyComponentImpl(DictionaryService dictionary)
|
||||
+ ... (all)
|
||||
}
|
||||
interface BehaviourFilter {
|
||||
+ disableBehaviour() : void
|
||||
+ disableBehaviour(QName className) : void
|
||||
+ disableBehaviour(QName className, boolean includeSubClasses) : void
|
||||
+ disableBehaviour(NodeRef nodeRef, QName className) : void
|
||||
+ disableBehaviour(NodeRef nodeRef) : void
|
||||
+ enableBehaviour() : void
|
||||
+ enableBehaviour(QName className) : void
|
||||
+ enableBehaviour(NodeRef nodeRef, QName className) : void
|
||||
+ enableBehaviour(NodeRef nodeRef) : void
|
||||
}
|
||||
class BehaviourFilterImpl implements BehaviourFilter {
|
||||
+ ... (all)
|
||||
}
|
||||
|
||||
AbstractNodeServiceImpl -> PolicyComponentImpl
|
||||
PolicyComponentImpl -> BehaviourFilterImpl
|
||||
PolicyComponentImpl -> "creates" ClassPolicyDelegate
|
||||
PolicyComponentImpl -> "creates" AssocationPolicyDelegate
|
||||
PolicyComponentImpl -> "creates" PropertyPolicyDelegate
|
||||
ClassPolicyDelegate --> "uses" PolicyFactory
|
||||
AssociationPolicyDelegate --> "uses" PolicyFactory
|
||||
PropertyPolicyDelegate --> "uses" PolicyFactory
|
||||
PolicyFactory --> "creates" BehaviourBinding
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 44 KiB |
@@ -0,0 +1,56 @@
|
||||
@startuml
|
||||
|
||||
title Policies: Queued Policies (V5.2 Proposal)
|
||||
|
||||
actor user
|
||||
|
||||
database ActiveMQ as AMQ
|
||||
database DB {
|
||||
folder alf_policies
|
||||
}
|
||||
|
||||
component "Client Application" {
|
||||
component [Client Code]
|
||||
component [ClientQueueReceiver]
|
||||
component [Camel(Client App)]
|
||||
}
|
||||
user <--> [Client Code]
|
||||
ClientQueueReceiver <-- [Camel(Client App)]
|
||||
ClientQueueReceiver -> [Client Code]
|
||||
[Camel(Client App)] <- AMQ
|
||||
|
||||
component "Alfresco One Platform" {
|
||||
component Quartz as Q
|
||||
component [Camel] as Camel
|
||||
|
||||
component [Policy ReST API] as PR
|
||||
component PolicyService as PS {
|
||||
[PolicyCheckJob] as PCJ
|
||||
[PolicyMap] as PM <<Map>>
|
||||
component Routes as R {
|
||||
component ToQueue
|
||||
component FromQueue
|
||||
}
|
||||
}
|
||||
component PolicyComponent as PC {
|
||||
component QueuedBehaviour as QB
|
||||
}
|
||||
component [Alfresco Services] as Services
|
||||
component PolicyDAO as PD
|
||||
}
|
||||
|
||||
[Client Code] <-> PR
|
||||
|
||||
Q --> PCJ
|
||||
PCJ -> PM
|
||||
PR --> PS
|
||||
Services -> PC
|
||||
PCJ --> PD
|
||||
PD -> DB
|
||||
QB -> ToQueue
|
||||
ToQueue -> Camel
|
||||
FromQueue <- Camel
|
||||
FromQueue --> Services
|
||||
Camel <-> AMQ
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,37 @@
|
||||
@startuml
|
||||
|
||||
Title: Policies: Register Policy Endpoint (V5.2 Proposal)
|
||||
|
||||
skinparam componentStyle uml2
|
||||
|
||||
actor "Client App" as Client
|
||||
participant "Policy Endpoint Rest API" as API
|
||||
participant "PolicyEndpointService" as PS
|
||||
participant "PolicyEndpointRegistry" as PER
|
||||
participant "PolicyEndpointDAO" as DAO
|
||||
database DB
|
||||
participant "PolicyComponent" as PC
|
||||
database AMQ
|
||||
|
||||
note over DAO,DB
|
||||
UNIQUE : policy,typeOrAspect,endpoint
|
||||
OTHER : active, modified
|
||||
SORT : modified
|
||||
end note
|
||||
|
||||
Client -> API
|
||||
API -> PS : registerPolicyEndpoint(policy, typeOrAspect, endpoint)
|
||||
PS -> DAO : createPolicyEndpoint(policy, typeOrAspect, endpoint)
|
||||
DAO -> DB : INSERT
|
||||
PS <-- DAO : success
|
||||
PS -> PER : reload(fromTime)
|
||||
PER -> DAO : getPolicyEndpoints(fromTime)
|
||||
loop each policy endpoint registration change
|
||||
PER -> PER
|
||||
end
|
||||
PS <-- PER : success
|
||||
API <-- PS : success
|
||||
Client <-- API : OK
|
||||
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 47 KiB |
@@ -0,0 +1,48 @@
|
||||
@startuml
|
||||
|
||||
Title: Policies: Reload Policy Endpoints (V5.2 Proposal)
|
||||
|
||||
skinparam componentStyle uml2
|
||||
|
||||
participant "Quartz"
|
||||
participant "PolicyCheckJob" as PCJ
|
||||
participant "PolicyEndpointRegistry" as PER
|
||||
participant "QueuedBehaviour" as QB
|
||||
participant "PolicyEndpointDAO" as DAO
|
||||
database DB
|
||||
participant "PolicyComponent" as PC
|
||||
database AMQ
|
||||
|
||||
== Static Route Initialization ==
|
||||
|
||||
activate PER
|
||||
PER -> QB: new
|
||||
activate PER
|
||||
PER -> PER: from("direct:policy")
|
||||
PER -> PER: dynamicRouter(method(PolicyEndpointRegistry.class, "slip"))
|
||||
deactivate PER
|
||||
deactivate PER
|
||||
|
||||
== Quartz ==
|
||||
|
||||
note over DAO,DB
|
||||
UNIQUE : policy,typeOrAspect,endpoint
|
||||
OTHER : active, modified
|
||||
SORT : modified
|
||||
end note
|
||||
|
||||
Quartz -> PCJ
|
||||
PCJ -> PER : reload(fromTime)
|
||||
PER -> DAO : getPolicyEndpoints(fromTime)
|
||||
DAO -> DB: SELECT(fromTime)
|
||||
DAO <-- DB
|
||||
PER <-- DAO
|
||||
loop each policy endpoint registration change
|
||||
PER -> PER: updateRegistrations(PolicyEndpoint)
|
||||
PER -> PC: bindClassBehaviour(policy,typeOrAspect, behaviour)
|
||||
end
|
||||
PCJ <-- PER : success
|
||||
Quartz <-- PCJ : success
|
||||
|
||||
|
||||
@enduml
|
@@ -0,0 +1,11 @@
|
||||
# Node Storage and Retrieval
|
||||
|
||||
## Properties
|
||||
|
||||
### Encrypted properties (```d:encrypted```)
|
||||
Encrypted properties are stored as BLOBs in the database, but there is no additional handling for
|
||||
them. In particular, the ```NodeService``` does not encrypt or decrypt them. It only guarantees
|
||||
that properties of this type contain objects of type ```javax.crypto.SealedObject```. It is up to
|
||||
the implementor of a custom extension to handle encryption.
|
||||
The ACS provides the helper class ```MetadataEncryptor``` which provides key handling and a one-stop-shop
|
||||
for encryption. But custom implementations do not need to use it.
|
118
repository/docs/meta-data-services/versions/README.md
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
## Versions
|
||||
|
||||

|
||||
|
||||
### Purpose
|
||||
|
||||
***
|
||||
|
||||
### Overview
|
||||
|
||||
***
|
||||
|
||||
### Artifacts and Guidance
|
||||
|
||||
* Source Code Link:m https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/
|
||||
* License: LGPL
|
||||
* Issue Tracker Link: https://issues.alfresco.com/jira/secure/RapidBoard.jspa?projectKey=REPO&useStoredSettings=true&rapidView=379
|
||||
* Documentation Link: http://docs.alfresco.com/5.1/concepts/versioning.html
|
||||
* Contribution Model: Alfresco publishes the source code and will review proposed patch requests
|
||||
***
|
||||
|
||||
|
||||
### Prerequisite Knowledge
|
||||
|
||||
***
|
||||
|
||||
### Design
|
||||
|
||||
#### Component Model
|
||||
|
||||
#### Data Model
|
||||
|
||||
#### Data Dictionary
|
||||
|
||||
#### Flows
|
||||
|
||||
This is a series of flows illustrating when versions are created, based on changes to content and metadata.
|
||||
|
||||
##### No Autoversion on Property Updates
|
||||
Suppose the defaults in the _cm:versionable_ aspect are set as follows:
|
||||
```
|
||||
version.store.enableAutoVersioning=true
|
||||
version.store.enableAutoVersionOnUpdateProps=false
|
||||
```
|
||||
Note this is the default case when Alfresco is installed.
|
||||
|
||||

|
||||
|
||||
|
||||
##### Autoversion on Property Updates
|
||||
Suppose the defaults in the _cm:versionable_ aspect are set as follows:
|
||||
```
|
||||
version.store.enableAutoVersioning=true
|
||||
version.store.enableAutoVersionOnUpdateProps=true
|
||||
```
|
||||

|
||||
|
||||
|
||||
#### Class Diagram
|
||||
|
||||
***
|
||||
|
||||
### APIs and Interfaces
|
||||
|
||||
***
|
||||
|
||||
### Configuration
|
||||
|
||||
#### What is Versioned
|
||||
Whether an object is versionable at all is governed by the presence of the _cm:versionable_ aspect.
|
||||
If the aspect is present, the object is versioned. Otherwise it is not versioned.
|
||||
|
||||
#### Autoversioning
|
||||
|
||||
Sometimes it is desirable to create a version automatically. Whether this happens is controlled by two variables in the _cm:versionable_ aspect:
|
||||
|
||||
* cm:autoVersion
|
||||
* cm:autoVersionOnUpdateProps
|
||||
|
||||
|
||||
When _cm:autoVersion_ is true, a new version is created when the _cm:content_ of a content node changes.
|
||||
When _cm:autoVersionOnUpdateProps_ is true, a new version is created when any of the properties of a content node change.
|
||||
|
||||
The defaults for these properties are set in the contentModel.xml file in the usual way. But to simplify the admin experience, the values of these properties can also set using global properties:
|
||||
|
||||
* version.store.enableAutoVersioning
|
||||
* version.store.enableAutoVersionOnUpdateProps
|
||||
|
||||
If the values are found in the properties file they have the effect of overriding what may have been set in the contenModel.xml file.
|
||||
|
||||
The effect of these properties can be overridden by Share using a set of two properties:
|
||||
|
||||
* autoVersion
|
||||
* autoVersionProps
|
||||
|
||||
The values of these overrides are contained in the file _upload.post.config.xml_ such as in this example
|
||||
```
|
||||
<autoVersion>true</autoVersion>
|
||||
<autoVersionProps>false</autoVersionProps>
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
### Performance Considerations
|
||||
***
|
||||
|
||||
### Security Considerations
|
||||
***
|
||||
|
||||
### Cloud Considerations
|
||||
None
|
||||
|
||||
***
|
||||
|
||||
### Design Decisions
|
||||
|
||||
***
|
After Width: | Height: | Size: 94 KiB |
@@ -0,0 +1,107 @@
|
||||
@startuml
|
||||
|
||||
Title: Autoversion on Property Update - Versioning Flow
|
||||
|
||||
participant "CMIS Client" as C
|
||||
participant "Repository" as R
|
||||
participant "Version Service" as V
|
||||
participant "workspace://SpacesStore" as SS
|
||||
participant "workspace://version2Store" as VS
|
||||
participant "File System" as FS
|
||||
database "Database" as DB
|
||||
|
||||
C->R:HTTP POST
|
||||
activate R
|
||||
group "transaction"
|
||||
R->V
|
||||
activate V
|
||||
|
||||
V->SS: create node
|
||||
activate SS
|
||||
SS->DB: create node
|
||||
activate DB
|
||||
DB->SS: OK
|
||||
deactivate DB
|
||||
SS->V: OK
|
||||
deactivate SS
|
||||
note right of SS
|
||||
workspace://SpacesStore/6060b6b6-2928-4092-ab66-659a7e68c0f6
|
||||
cm:autoVersionOnUpdateProps=true
|
||||
cm:name=foo.txt
|
||||
cm:versionLabel=1.0
|
||||
end note
|
||||
V->VS: create version history node with one child node
|
||||
activate VS
|
||||
VS->DB: create nodes
|
||||
activate DB
|
||||
DB->VS: OK
|
||||
deactivate DB
|
||||
VS->V: OK
|
||||
deactivate VS
|
||||
note right of VS
|
||||
One Version History Node with one child ...
|
||||
|
||||
workspace://version2Store/62de48fa-6adc-4228-8667-df62584f98de
|
||||
cm:autoVersionOnUpdateProps=true
|
||||
cm:name=foo.txt
|
||||
cm:versionLabel=null
|
||||
ver2:versionLabel=1.0
|
||||
ver2:versionDescription=Initial Version
|
||||
|
||||
end note
|
||||
end
|
||||
V->R: OK
|
||||
deactivate V
|
||||
R->C: 200 OK
|
||||
deactivate R
|
||||
|
||||
C->R:HTTP PUT (cm:name=bar.txt)
|
||||
activate R
|
||||
group "transaction"
|
||||
R->V
|
||||
V->SS: update node
|
||||
activate V
|
||||
activate SS
|
||||
SS->DB: update node
|
||||
activate DB
|
||||
DB->SS: OK
|
||||
deactivate DB
|
||||
SS->V: OK
|
||||
deactivate SS
|
||||
note right of SS
|
||||
workspace://SpacesStore/6060b6b6-2928-4092-ab66-659a7e68c0f6
|
||||
cm:autoVersionOnUpdateProps=true
|
||||
cm:name=bar.txt
|
||||
cm:versionLabel=1.1
|
||||
end note
|
||||
|
||||
V->VS: create a new child of the version history node
|
||||
activate VS
|
||||
VS->DB: create node
|
||||
activate DB
|
||||
DB->VS: OK
|
||||
deactivate DB
|
||||
VS->V: OK
|
||||
deactivate VS
|
||||
note right of VS
|
||||
One Version History Node with two children...
|
||||
|
||||
workspace://version2Store/62de48fa-6adc-4228-8667-df62584f98de
|
||||
cm:autoVersionOnUpdateProps=true
|
||||
cm:name=foo.txt
|
||||
cm:versionLabel=null
|
||||
ver2:versionLabel=1.0
|
||||
ver2:versionDescription=Initial Version
|
||||
|
||||
NEW CHILD:
|
||||
workspace://version2Store/64d5fd85-40d3-4a44-b644-d871cb3a1030
|
||||
cm:autoVersionOnUpdateProps=true
|
||||
cm:name=bar.txt
|
||||
cm:versionLabel=1.0
|
||||
ver2:versionLabel=1.1
|
||||
ver2:versionDescription=Update Name
|
||||
|
||||
end note
|
||||
|
||||
end
|
||||
@enduml
|
After Width: | Height: | Size: 124 KiB |
@@ -0,0 +1,144 @@
|
||||
@startuml
|
||||
|
||||
Title: Autoversion on Content Update - Versioning Flow
|
||||
|
||||
participant "CMIS Client" as C
|
||||
participant "Repository" as R
|
||||
participant "Version Service" as V
|
||||
participant "workspace://SpacesStore" as SS
|
||||
participant "workspace://version2Store" as VS
|
||||
participant "File System" as FS
|
||||
database "Database" as DB
|
||||
|
||||
C->R:HTTP POST
|
||||
activate R
|
||||
group "transaction"
|
||||
R->V
|
||||
activate V
|
||||
|
||||
V->SS: create node
|
||||
activate SS
|
||||
SS->DB: create node
|
||||
activate DB
|
||||
DB->SS: OK
|
||||
deactivate DB
|
||||
SS->V: OK
|
||||
deactivate SS
|
||||
note right of SS
|
||||
workspace://SpacesStore/e8cc2b68-7482-4304-a93e-02c758a80954
|
||||
cm:autoVersionOnUpdateProps=false
|
||||
cm:name=foo.txt
|
||||
cm:versionLabel=1.0
|
||||
end note
|
||||
V->VS: create version history node with one child node
|
||||
activate VS
|
||||
VS->DB: create nodes
|
||||
activate DB
|
||||
DB->VS: OK
|
||||
deactivate DB
|
||||
VS->V: OK
|
||||
deactivate VS
|
||||
note right of VS
|
||||
One Version History Node with one child ...
|
||||
|
||||
workspace://version2Store/ce68aba3-73f6-44f9-ad9b-a9e8d77212de
|
||||
cm:autoVersionOnUpdateProps=false
|
||||
cm:name=foo.txt
|
||||
cm:versionLabel=null
|
||||
ver2:versionLabel=1.0
|
||||
ver2:versionDescription=Initial Version
|
||||
|
||||
end note
|
||||
end
|
||||
V->R: OK
|
||||
deactivate V
|
||||
R->C: 200 OK
|
||||
deactivate R
|
||||
|
||||
C->R:HTTP PUT (cm:name=bar.txt)
|
||||
activate R
|
||||
group "transaction"
|
||||
R->V
|
||||
V->SS: update node
|
||||
activate V
|
||||
activate SS
|
||||
SS->DB: update node
|
||||
activate DB
|
||||
DB->SS: OK
|
||||
deactivate DB
|
||||
SS->V: OK
|
||||
deactivate SS
|
||||
note right of SS
|
||||
workspace://SpacesStore/e8cc2b68-7482-4304-a93e-02c758a80954
|
||||
cm:autoVersionOnUpdateProps=false
|
||||
cm:name=bar.txt
|
||||
cm:versionLabel=1.0
|
||||
end note
|
||||
|
||||
note right of VS
|
||||
One Version History Node with one child...
|
||||
|
||||
workspace://version2Store/ce68aba3-73f6-44f9-ad9b-a9e8d77212de
|
||||
cm:autoVersionOnUpdateProps=false
|
||||
cm:name=foo.txt
|
||||
cm:versionLabel=null
|
||||
ver2:versionLabel=1.0
|
||||
ver2:versionDescription=Initial Version
|
||||
|
||||
end note
|
||||
|
||||
end
|
||||
|
||||
C->R:HTTP PUT (new file content)
|
||||
activate R
|
||||
group "transaction"
|
||||
R->V
|
||||
activate V
|
||||
V->SS: update node
|
||||
activate SS
|
||||
SS->FS: write file content
|
||||
activate FS
|
||||
FS->SS: OK
|
||||
deactivate FS
|
||||
SS->DB: update node to point to new file content
|
||||
activate DB
|
||||
DB->SS: OK
|
||||
deactivate DB
|
||||
SS->V: OK
|
||||
deactivate SS
|
||||
note right of SS
|
||||
workspace://SpacesStore/e8cc2b68-7482-4304-a93e-02c758a80954
|
||||
cm:autoVersionOnUpdateProps=false
|
||||
cm:name=bar.txt
|
||||
cm:versionLabel=1.0
|
||||
end note
|
||||
V->VS: create a new child of the version history node
|
||||
activate VS
|
||||
VS->DB: create node
|
||||
activate DB
|
||||
DB->VS: OK
|
||||
deactivate DB
|
||||
VS->V: OK
|
||||
deactivate VS
|
||||
note right of VS
|
||||
One Version History Node with two children...
|
||||
|
||||
workspace://version2Store/ce68aba3-73f6-44f9-ad9b-a9e8d77212de
|
||||
cm:autoVersionOnUpdateProps=false
|
||||
cm:name=foo.txt
|
||||
cm:versionLabel=null
|
||||
ver2:versionLabel=1.0
|
||||
ver2:versionDescription=Initial Version
|
||||
|
||||
NEW CHILD:
|
||||
workspace://version2Store/9fb3fb08-7cfb-4c0a-ac72-233aaf60fa1e
|
||||
cm:autoVersionOnUpdateProps=false
|
||||
cm:name=bar.txt
|
||||
cm:versionLabel=1.0
|
||||
ver2:versionLabel=1.1
|
||||
ver2:versionDescription=Update New File Content
|
||||
|
||||
end note
|
||||
end
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,37 @@
|
||||
@startuml
|
||||
|
||||
title Actions: Asynchronous Actions Classes (V5.1 Current)
|
||||
|
||||
interface ActionService {
|
||||
+ void executeAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions, boolean executeAsychronously)
|
||||
}
|
||||
class ActionServiceImpl implements ActionService {
|
||||
- ActionTransactionListener transactionListener
|
||||
- Map<String, AsynchronousActionExecutionQueue> asynchronousActionExecutionQueues
|
||||
+ void registerAsynchronousActionExecutionQueue(String key, AsynchronousActionExecutionQueue asyncExecQueue)
|
||||
+ void executeAction(...)
|
||||
- void addPostTransactionPendingAction(action, actionedUponNodeRef, checkConditions, actionChain)
|
||||
- List<PendingAction> getPostTransactionPendingActions()
|
||||
+ postCommit()
|
||||
- queueAction(PendingAction action)
|
||||
+ etc(...)
|
||||
}
|
||||
|
||||
interface AsynchronousActionExecutionQueue {
|
||||
+ void executeAction(RuntimeActionService actionService, Action action, NodeRef actionedUponNodeRef, boolean checkConditions, Set<String> actionChain);
|
||||
}
|
||||
class AsynchronousActionExecutionQueueImpl implements AsynchronousActionExecutionQueue {
|
||||
- ThreadPoolExecutor threadPoolExecutor
|
||||
- TransactionService transactionService
|
||||
- PolicyComponent policyComponent
|
||||
- Map<String, AbstractAsynchronousActionFilter> actionFilters
|
||||
- String id
|
||||
+ void init()
|
||||
+ void executeAction(...)
|
||||
+ etc(...)
|
||||
}
|
||||
|
||||
AsynchronousActionExecutionQueueImpl o- "1" ActionServiceImpl
|
||||
AsynchronousActionExecutionQueueImpl "0..*" -o ActionServiceImpl
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 57 KiB |
@@ -0,0 +1,61 @@
|
||||
@startuml
|
||||
|
||||
title Actions: Queued Actions Classes (V5.2 Proposal)
|
||||
|
||||
interface ActionService {
|
||||
+ void executeAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions, boolean executeAsychronously)
|
||||
}
|
||||
class ActionServiceImpl implements ActionService {
|
||||
- ActionTransactionListener transactionListener
|
||||
- Map<String, AsynchronousActionExecutionQueue> asynchronousActionExecutionQueues
|
||||
+ void registerAsynchronousActionExecutionQueue(String key, AsynchronousActionExecutionQueue asyncExecQueue)
|
||||
+ void executeAction(...)
|
||||
- <b>void bindPendingActionToTransaction(action, actionedUponNodeRef, checkConditions, actionChain)</b>
|
||||
- <s>void addPostTransactionPendingAction(action, actionedUponNodeRef, checkConditions, actionChain)</s>
|
||||
- List<PendingAction> getPostTransactionPendingActions()
|
||||
+ <b>beforeCommit()</b>
|
||||
+ <s>postCommit()</s>
|
||||
- queueAction(PendingAction action)
|
||||
+ etc(...)
|
||||
}
|
||||
|
||||
interface AsynchronousActionExecutionQueue {
|
||||
+ void executeAction(RuntimeActionService actionService, Action action, NodeRef actionedUponNodeRef, boolean checkConditions, Set<String> actionChain);
|
||||
}
|
||||
class AsynchronousActionExecutionQueueImpl implements AsynchronousActionExecutionQueue {
|
||||
- <b>ProducerTemplate producerTemplate</b>
|
||||
- <s>ThreadPoolExecutor threadPoolExecutor</s>
|
||||
- TransactionService transactionService
|
||||
- PolicyComponent policyComponent
|
||||
- Map<String, AbstractAsynchronousActionFilter> actionFilters
|
||||
- String id
|
||||
+ void init()
|
||||
+ void executeAction(...)
|
||||
+ etc(...)
|
||||
}
|
||||
|
||||
package org::apache::camel {
|
||||
class ProducerTemplate {
|
||||
+ void sendBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers)
|
||||
}
|
||||
class RouteBuilder {
|
||||
+ void configure()
|
||||
+ etc(...)
|
||||
}
|
||||
class JacksonDataFormat
|
||||
}
|
||||
|
||||
class QueuedActionProducer extends RouteBuilder {
|
||||
+ void configure()
|
||||
}
|
||||
class QueuedActionReceiver extends RouteBuilder {
|
||||
+ void configure()
|
||||
}
|
||||
|
||||
AsynchronousActionExecutionQueueImpl o- "1" ActionServiceImpl
|
||||
AsynchronousActionExecutionQueueImpl "0..*" -o ActionServiceImpl
|
||||
AsynchronousActionExecutionQueueImpl o- "1" ProducerTemplate
|
||||
QueuedActionProducer --> "uses" JacksonDataFormat
|
||||
QueuedActionReceiver --> "uses" JacksonDataFormat
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 38 KiB |
@@ -0,0 +1,63 @@
|
||||
@startuml
|
||||
class RuleType {
|
||||
String name
|
||||
String displayLabel
|
||||
}
|
||||
|
||||
class Rule {
|
||||
NodeRef nodeRef
|
||||
String title
|
||||
String description
|
||||
boolean ruleDisabled
|
||||
boolean executeAsynchronously
|
||||
boolean isAppliedToChildren
|
||||
}
|
||||
|
||||
class Action
|
||||
|
||||
class RuleTrigger
|
||||
|
||||
|
||||
Rule --> "1..*" RuleType
|
||||
Rule --> "1" Action
|
||||
|
||||
RuleType --> "*" RuleTrigger
|
||||
|
||||
note left of RuleType
|
||||
There are three rule types defined by default:
|
||||
- inbound
|
||||
- outbound
|
||||
- update
|
||||
end note
|
||||
|
||||
together {
|
||||
class BeforeDeleteChildAssociationRuleTrigger
|
||||
class CreateNodeRuleTrigger
|
||||
class OnCreateChildAssociationRuleTrigger
|
||||
class OnMoveNodeRuleTrigger
|
||||
class OnPropertyUpdateRuleTrigger
|
||||
class RestoreNodeRuleTrigger
|
||||
class SingleAssocRefPolicyRuleTrigger
|
||||
class SingleNodeRefPolicyRuleTrigger
|
||||
}
|
||||
|
||||
CreateNodeRuleTrigger -[hidden]--> BeforeDeleteChildAssociationRuleTrigger
|
||||
OnMoveNodeRuleTrigger -[hidden]--> OnCreateChildAssociationRuleTrigger
|
||||
OnPropertyUpdateRuleTrigger -[hidden]--> RestoreNodeRuleTrigger
|
||||
SingleAssocRefPolicyRuleTrigger -[hidden]--> SingleNodeRefPolicyRuleTrigger
|
||||
|
||||
RuleTrigger <|-- BeforeDeleteChildAssociationRuleTrigger
|
||||
RuleTrigger <|-- CreateNodeRuleTrigger
|
||||
RuleTrigger <|-- OnCreateChildAssociationRuleTrigger
|
||||
RuleTrigger <|-- OnMoveNodeRuleTrigger
|
||||
RuleTrigger <|-- OnPropertyUpdateRuleTrigger
|
||||
RuleTrigger <|-- RestoreNodeRuleTrigger
|
||||
RuleTrigger <|-- SingleAssocRefPolicyRuleTrigger
|
||||
RuleTrigger <|-- SingleNodeRefPolicyRuleTrigger
|
||||
|
||||
|
||||
note right of Action
|
||||
See separate diagram for info about Actions
|
||||
end note
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,26 @@
|
||||
@startuml
|
||||
left to right direction
|
||||
skinparam linetype ortho
|
||||
|
||||
component Client
|
||||
component TransformationEngine {
|
||||
component Service
|
||||
component Router
|
||||
component Configuration
|
||||
}
|
||||
component AdminConsole
|
||||
component Log
|
||||
component TransformationFarm {
|
||||
component Worker1
|
||||
component Worker2
|
||||
component Worker3
|
||||
}
|
||||
Client->Service:calls
|
||||
Service->Router:calls
|
||||
Router->Configuration:reads
|
||||
AdminConsole->Configuration:sets
|
||||
Service->Log:writes
|
||||
AdminConsole->Log:writes
|
||||
Router->Worker1:calls
|
||||
|
||||
@enduml
|