Updated the TODO
[project/deploy.git] / API.txt
1
2 CONTENTS OF THIS FILE
3 ---------------------
4
5  * API outline
6  * Summary of the deployment cycle
7  * The plan object
8  * The endpoint object
9  * The aggregator plugin
10  * The processor plugin
11  * The service plugin
12  * The authenticator plugin
13
14 API OUTLINE
15 -----------
16
17 The Deploy module is used to deploy Drupal content to other Drupal sites or
18 arbritary systems. The definition used here for "content" is Drupal entities.
19 Thus, entities are the only Drupal object that can be deployed. Other objects
20 (usually configuration objects), like Views and Panels are preferably deployed
21 in code with the Features module and a version controll system.
22
23 The Deploy module depends on the Entity API module, which gives us the
24 advantage of wrapping more meta data around each entity and makes us able to
25 handle all entities in one generic way.
26
27 A deployment cycle is represented by six types of objects. The two main objects
28 are:
29
30  * Plans
31  * Endpoints
32
33 Those two objects are basically configuration and factory objects around the
34 following plugins, which are all CTools plugins:
35
36  * Aggregators
37  * Processors
38  * Authenticators
39  * Services
40
41 The API and the relation between all the objects is built around the dependency
42 injection pattern as much as possible. Read more about that pattern here:
43 http://en.wikipedia.org/wiki/Dependency_injection
44
45 SUMMARY OF THE DEPLOYMENT CYCLE
46 -------------------------------
47
48 This section is intended to give a brief summary of how the deployment cycle
49 works. For more in-depth information about each specific object type, please
50 refer to the later topics in this document.
51
52  0. Deployment of a plan is due. The plan is loaded with 'deploy_plan_load()',
53     (1) either from the database or from the default hook.
54
55  1. The plan object is configured through 'deploy_plan_create()' or loaded from
56     a default hook. The fully configured plan object is returned to the load
57     function which returns it back to the trigger.
58
59  2. The trigger calls the 'deploy' method on the plan object which starts the
60     whole deployment cycle.
61
62  3. The plan iterates over its endpoint references and hands them over to the
63     processor.
64
65  4. The processor processes each endpoint by requesting all entities from the
66     aggregator (5) and hands them over to the endpoint when appropriate (6).
67     Between 5 and 6 the processor decides to either process all endpoints and
68     entities directly, batch them into smaller pieces or queue the process for
69     later.
70
71  5. The aggregator gets called by the processor and goes aggregating all
72     entities for deployment. It passes all the entity types and entity ids into
73     the 'DeployIterator' that will find out all dependencies. Since
74     'DeployIterator' is recursive, the aggregator passes it into
75     'DeployIteratorIterator' which basically flattens it.
76
77  6. The endpoint is loaded by the processor, with a fully configured
78     authenticator plugin. It is also handed a batch of entities for deployment.
79     The endpoint is wrapping all entities with some additional meta data.
80
81  7. The endpoint calls 'deploy' one the authenticator (8) with the batch of
82     entities itself was handed.
83
84  8. The authenticator gets called and can do its magic. Since the authenticator
85     wrapps the service object, it has access to modify it or add parameters as
86     needed. When it's done it calls 'deploy' on the service (9) with the batch
87     of entities itself was handed.
88
89  9. The service plugin is handed the batch of entities and deploys them over
90     its service.
91
92 THE PLAN OBJECT
93 ---------------
94
95 One plan consists of one aggregator plugin and one processor plugin and
96 references to one or many endpoints. This gives us a good representation of
97 what a plan actually is -- a workflow for aggregating and processing entities
98 for deployment to one or many endpoints.
99
100 When a deployment is triggered for a plan object, that object is responsible
101 for iterating over its endpoints and process them with its processor. The
102 plan's responsibility ends there.
103
104 Plans are CTools exportable objects and are instances of the 'DeployPlan'
105 class. 'DeployPlan' must be fully configured before calling 'deploy()' on it.
106 See how that is done in its factory function 'deploy_plan_create()'.
107
108 Deployment of plans can be triggered in many different ways. Either manually by
109 an end user, by a custom Rules event or through a Drush command. More ways of
110 triggering deployment of a plan can be provided by contrib modules.
111
112 THE ENDPOINT OBJECT
113 -------------------
114
115 One endpoint consists of one authenticator plugin and one service plugin. This
116 gives us a good representation of what an endpoint actually is -- another site
117 or system accessible through one specific type of service with one specific
118 type of authentication method.
119
120 An endpoint objects is handed an iterator of entities and is responsible for
121 calling its authenticator and hand the entities over to its service. The
122 endpoint's responsibility ends there.
123
124 Endpoints are CTools exportable objects and are instances of the
125 'DeployEndpoint' class. 'DeployEndpoint' must be fully configured before
126 'deploy()' is called on it. See how that is done in its factory function
127 'deploy_endpoint_create()'.
128
129 Depending on the processor used in the plan, the endpoint might be handed one
130 or many entities to deploy.
131
132 THE AGGREGATOR PLUGIN
133 ---------------------
134
135 The aggregator plugin is responsible for aggregating entities that shall be
136 deployed, for a processor to process. The method for how an aggregator
137 aggregates its entities can widely vary between plugins. The one aggregator
138 plugin that comes with the Deploy module is aggregating entities with a user
139 defined view.
140
141 Aggregator plugins needs to implement the 'DeployAggregator' interface. That
142 interface extends the Standard PHP Library (SPL) inteface 'IteratorAggregate'
143 which makes the object traversable. This brings us cleaner, more consistent and
144 more readable code.
145
146 One requirement to implement the 'IteratorAggregate' inteface is to define a
147 'getIterator' method which must return an iterator. This is the method where
148 the aggregator will aggregate all its entities and construct a 'DeployIterator'
149 with its entity types and entity ids. The 'DeployIterator' will then iterate
150 over all aggregated entities and find all their recursive dependencies. This
151 makes the aggregator not needing to figure out dependencies.
152
153 Since the nature of 'DeployIterator' is recursive with all dependencies, and we
154 want processors to process all entities in a flat way, the 'getIterator' method
155 needs to return an instance of 'DeployIteratorIterator', which basically will
156 flatten the result.
157
158 Aggregator plugins are defined by implementing 'hook_deploy_aggregators()'.
159 See 'deploy_deploy_aggregators()' for more information on how the
160 implementation should look like.
161
162 THE PROCESSOR PLUGIN
163 --------------------
164
165 The processor plugin is responsible for processing all aggregated entities and
166 hand them over to an endpoint for deployment. The reason why processors exists
167 is because large plans might take a long time to walk through. Processors gives
168 the possibility to queue or batch this operation into smaller pieces.
169
170 Processor plugins needs to implement the 'DeployProcessor' interface and takes
171 a fully configured aggregator object upon construction. When processing are due
172 its handed an endpoint name, which its responsible to load and hand the
173 traversable aggregator to, or pieces of it.
174
175 Processor plugins are defined by implementing 'hook_deploy_processors()'. See
176 'deploy_deploy_processors()' for more information on how the implementation
177 should look like.
178
179 THE SERVICE PLUGIN
180 ------------------
181
182 The service plugin is responsible for doing the actual deployment of one or
183 many entities to a remote site or arbritary system, through a specific type of
184 service.
185
186 When deployment is due, the service object is handed a traversable iterator of
187 entities to deploy. Depending on the processor it might be one or many entities
188 in that iterator.
189
190 Service plugins are defined by implementing 'hook_deploy_services()'. See
191 'deploy_deploy_services()' for more information on how the implementation
192 should look like.
193
194 THE AUTHENTICATOR PLUGIN
195 ------------------------
196
197 The authenticator plugin is responsible for authenticating on the endpoint.
198 Configured in an endpoit, authenticators wraps the service object which gives
199 us a good representation of how it actually works -- the 'deploy' method needs
200 to go through the authenticator.
201
202 Authenticators needs to implement the 'DeployAuthenticator' interface and takes
203 a fully configured service object upon construction. When deployment is due, the
204 'deploy' method is called on the authenticator where it is responsible for doing
205 its magic. After it is successfully done, it needs to call 'deploy' on its
206 service object.
207
208 Authenticator plugins are defined by implementing
209 'hook_deploy_authenticators()'. See 'deploy_deploy_authenticators()' for more
210 information on how the implementation should look like.