Skip to content

Latest commit

 

History

History
81 lines (55 loc) · 5.67 KB

How-Cattle-works:-Process-handling.md

File metadata and controls

81 lines (55 loc) · 5.67 KB

Overview

This article described how process works in cattle.

Process

Most operation of the resources are defined in resource lifecycle. spring-core-process-contexts.xml define the lifecycle for each resource. Most of resources just follow the defaultProcess, for example this process map shows the defaultProcess applied on host resource.

The process different from defaultProcess can be defined in the file as well. defaultProcess is not required for each resource. For example the following code defined lifecycle of snapshot:

<!-- Snapshot -->
<process:process name="snapshot.create" resourceType="snapshot" start="requested" transitioning="creating" done="created" />
<process:process name="snapshot.backup" resourceType="snapshot" start="created" transitioning="backing-up" done="backed-up" />
<process:process name="snapshot.remove" resourceType="snapshot" start="creating,created,backing-up,backed-up" transitioning="removing" done="removed" />

Defined the process for snapshot, which doesn't involve defaultProcess at all.

Process handler

The process name defined in "spring-core-process-contexts.xml" can be used to identify the action would be taken when resource state changed. All the process handling logic is in DefaultProcessInstanceImpl.java. There are three places can be hooked in to process handling, which called: Prelistener, Handler and Postlistener respectively.

Most handlers should expands AbstractObjectProcessHandler. The AbstractDefaultProcessHandler adds two things on top of the AbstractObjectProcessHandler for convenient:

  1. Sets priority to Priority.DEFAULT. if you don't set a priority it is assumed to be Priority.SPECIFIC which runs before DEFAULT

  2. Automatically turns the classname in the the processname to attach to. So the class InstanceStart becomes "instance.start" which set process name which should match the action name. Mostly the Java class name should match the "ResourceAction.java" pattern, then process name can be set automatically.

The core function of handler class is:

public HandlerResult handle(ProcessState state, ProcessInstance process)

The state field contained resource object(getResource()).

  • Return: HandlerResult Parameters:
  • shouldContinue(): If it's necessary to continue executing following handlers.
  • Key value pair: The key value pair would be used to update resource. It would be represented by a nested map without the top level key(resource type itself). All the children resources can be updated as well. For example, assume InstanceHostMap has: Instance, Host, Data fields, and instance has field name, the map format would be: { Instance: { name: "xxx" ...}, Host: { ... }, Data: { ... } }
  • withChainProcessName(): This option would invoke a following action immediately, thus skip the unfavorable intermediate state, prevent it from seen by user. For example, this option is used by instance.stop to skip the Stopped state when restart is required. It would invoke instance.start immediately, without leaving room for Stopped state.

AgentBasedProcessHandler

AgentBasedProcessHandler is the basic class for all communication with agent. The logic of generating correlated handler is at spring-core-logic-context.xml

Here is a example of definition of a bean:

<bean class="io.cattle.platform.process.common.handler.AgentBasedProcessHandler"
    p:reportProgress="true"
    p:name="ImageStoragePoolMapActivate"
    p:commandName="storage.image.activate"
    p:agentResourceRelationship="storagePool"
    p:dataTypeClass="io.cattle.platform.core.model.ImageStoragePoolMap"
    p:processNames="imagestoragepoolmap.activate" >
    <property name="priority">
        <util:constant static-field="io.cattle.platform.util.type.Priority.DEFAULT"/>
    </property>
</bean>
  • name: Name of class. Matched naming convention of object ImageStoragePoolMap.activate.
  • commandName: The event's command name. Define the which kind of event is transferring to agent.
  • dataTypeClass: The resource type would be attached to the event to the agent.
  • agentResourceRelationship: Identify the agent this command would be send to. The class here would be a child of main resource, and would implement the method getAgentId() to identify the agent.
  • processNames: The process name used to identify this class, which would be called during handling this process.

The main function of AgentBasedProcessHandler is still handle(). There are three resources define how it works:

  • eventResource: The resource would be transferred in event as main resource.
  • dataResource: The other data resource would be come along with the event.
  • agentResource: The agent resource this event would be sent to.

The data come along with the event is the serialized form of dataResource. The serializer is defined at defaults.properities, like this:

event.data.imageStoragePoolMap=storagePool|image event.data.instance=volumes[${event.data.volume}]|offering|image|ports|nics[${event.data.nic}]|instanceLinks[targetInstance]
event.data.instanceHostMap=instance[${event.data.instance}]|host event.data.nic=ipAddresses[subnet]|network[networkServiceProviders|networkServices]
event.data.volume=offering|instance|storagePools|image
event.data.volumeStoragePoolMap=volume[${event.data.volume}]|storagePool

The serialized form would contained all the informations agent needs to know to perform the correct action.

The reply would be in the form of Event as well, whose data would be used as a parameter of returned HandlerResult and update the resource immediately.