Development documentation

Schema location

The schemas are located in the folder: src/main/resources.

Adding the schemas to the main project web site

During the site phase the schemas are copied to the main site in the pineapple-project. The schemas are copied to the directory /ns.

This is implemented in the pom.xml for the pineapple-api project

Generation of classes from XML schemas

The project uses JAXB through the Maven plugin cxf-xjc-plugin to generate classes from XML schema.

Customized package names

The generated classes are mapped into the package com.alpha.pineapple.model using the JAXB bindings file at: src/main/resources/bindings.xjb.

Customized type names

The JAXB bindings file also defines mappings of Schema type into Java types. The applied rule is to remove the postfixed Type from the Schema type in the corresponding Java types, i.e. from the schema type named NiceType a Java type named Nice is generated by JAXB.

Internal configuration

Logging

The project uses log4j for logging. Each pineapple client must provide a Log4j configuration which is accessible at runtime as a result of the build process.

The project does not provide a Log4j configuration as part of its production build. A log4j configuration file is defined in the project in the directory src/test/resources/log4.properties for testing.

The test configuration configures Log4j to write to the log file to ${user.home}/.pineapple/logs/pineapple.log.

Spring configuration file(s)

The project contains a configuration file which defines a Spring application context which initializes the object in the project and can be imported into other projects who wishes to use the content of this project. The file is located in src/main/resources/com.alpha.pineapple.process.execution-config.xml.

Internationalization (I18N) configuration file

The project uses internationalization. Messages used by classes in the project are located in the file src/main/resources/com.alpha.pineapple.process.execution-messages.properties.

Test

Unit test

The project contain a copy of EasyMock test utility class named com.alpha.easymockutils.MessageProviderAnswerImpl of which the master copy can be found in the pineapple-test-utils project. To avoid circular Maven dependencies in there can be no link to the pineapple-test-utils project from the pineapple-api project.

Implementation

Administration API classes

The package com.alpha.pineapple.admin contains public interfaces for the administration API supporting runtime administration of the core component:

  • Administration defines Pineapple Core administration interface. This is the main interface for execution of administration tasks, e.g. configuration of the core component.
  • AdministrationProvider defines interface for administration provider which provides access to runtime administration and configuration of the core component from plugins. The Interface is part of the plugin framework The interface extends the Administration interface and no methods of it own.

    The API is implemented in the core component project.

Credential handling classes

The package com.alpha.pineapple.credential contains classes used to provide credentials to Pineapple resources. The credentials are used to access and authenticate the application with external resources:

  • EnvironmentInfo defines interface for info about a configured environment defined in the credential configuration read by Pineapple. Environment info's are stored in credential providers.
  • CredentialInfo defines interface for info about a configured credential defined in the credential configuration read by Pineapple. Credential info's are stored in credential providers.
  • CredentialProvider defines interface for credential providers which can supply Pineapple with security credentials when requested to.
  • CredentialNotFoundException is an exception class for signaling failure to look up a credential in a credential provider.
  • EnvironmentNotFoundException is an exception class for signaling failure to look up an environment in a credential provider.
  • CredentialAlreadyExitsException is an exception class for signaling failure to create a credential since the credential already exists in the credential provider.
  • SaveConfigurationFailedException is an exception class for signaling that saving the credential configuration failed.

Directory resolution

The package com.alpha.pineapple.io.file contains helper classes for resolution of directories:

  • RuntimeDirectoryProvider defines interface for directory provider which resolves the runtime directories where Pineapple reads and writes its files to. The interface is implemented by the core component.

Execution classes

The package com.alpha.pineapple.execution contains the classes which constitutes the Pinapple execution framework which is used to storage of information about execution of operation on modules:

  • ExecutionInfo defines interface for capture of information about the execution of an operation on a module.
  • ResultRepository defines interface for repository which contains the results of executing operations and implements the role of subject in the observer pattern where interested parties can register themselves for notification when operations are executed.
  • ResultListener defines listener interface for objects which want to to notified of how the execution of operations proceeds. A listener must be registered in a result repository to receive notifications.
  • ExecutionResultFactory defines a simple interface for creating execution result objects.
  • ExecutionResultFactoryImpl is the default implementation of the ExecutionResultFactoryImpl interface.
  • ExecutionInfoProvider defines interface for resolution of execution info object in plugins. The purpose of this interface is to enable plugins to gain access to the execution info object for the current operation. The interface is implemented by the core component.
  • OperationTask is an interface for execution of operations by the core component.
  • ExecutionInfoNotFoundException is an exception class for signaling undefined execution info in core component.
  • ExecutionResultException is an exception which can used to signal an error during execution of execution result by encapsulating the result..

Execution continuation classes

The package com.alpha.pineapple.execution.continuation contains the classes which constitutes the Pinapple execution framework which is used to define continuation policy:

  • ContinuationPolicy defines interface for continuation policy which defines which defines how the execution should react to events regarding the interruption of the execution. The continuation policy supports these event:
    • Execution is aborted when an failure or error occurs.
    • Execution is interrupted by external party, e.g. the human user.
  • DefaultContinuationPolicyImpl is the default implementation of the ContinuationPolicy interface.
  • InterruptedExecutionException is a runtime exception thrown by the continuation policy when execution should be aborted or is interrupted.

Execution reporting classes

The package com.alpha.pineapple.execution.report contains classes which support generation of reports (for classes which implements the create-report operation:

  • JaxbReportUtils is a helper which can generate report content from a JAXB generated object structure. The generated report information is mapped into a tree of execution result objects.

Scheduled execution classes

The package com.alpha.pineapple.execution.scheduled contains the classes which defines the scheduled execution of operations:

  • ScheduledOperationInfo defines interface for a scheduled operation within the Pineapple core.
  • ScheduledOperationRespository defines interface for repository which manages and contains information about all scheduled operations.
  • ScheduledOperationNotFoundException is a runtime exception thrown by the repository when queried for an non existing operation.
  • ScheduledOperationAlreadyExistsException is a runtime exception thrown by the repository when an operation already is registered with the same ID.

Module classes

The package com.alpha.pineapple.module contains classes for representation and storage of modules:

  • ModuleInfo defines interface for representation of information about a module in the module repository.
  • ModuleRepository defines interface for repository which contains information about all modules available to Pineapple.
  • ModuleNotFoundException defines exception to signal failure to look up module in the module repository.
  • ModuleDeletionFailureException defines exception to signal failure to delete module in the module repository.
  • ModelAlreadyExistsException defines exception to signal failure to create model since it already exists in repository.

Plugin classes

The package com.alpha.pineapple.plugin contains the public interfaces, annotations and classes which constitutes the Pinapple plugin framework used to implement plugins in Pineapple:

  • Operation defines interface for single operation which is implemented by a plugin.
  • @Plugin defines plugin annotation for annotating a class as a plugin class.
  • PluginException defines exception for signaling errors in plugins.
  • PluginExecutionFailedException defines exception for signaling errors in during execution of a plugin.
  • PluginInitializationFailedException defines exception for signaling errors in during initialization of a plugin.
  • @PluginOperation defines annotation for annotating a class as a plugin operation.
  • @PluginSession defines annotation for annotating a class as a plugin session.

The package com.alpha.pineapple.plugin.repository contains the public interfaces for access to the plugin repository as part of the Administration API:

  • PluginRepository defines interface for plugin repository which provides methods for registration of plugins and querying about plugins.

Session classes

The package com.alpha.pineapple.session contains the public interfaces and classes which implements sessions as part of the Pinapple plugin framework:

  • Session defines interface for plugin sessions.
  • NullSessionImpl defines null implementation of plugin session which is used by Pineapple to provide sessions at runtime for plugin which doesn't support session handling.
  • DefaultSessionImpl defines basic implementation of plugin session which can be used by plugin which like to have simple session support to gain access credential and resource runtime information.
  • SessionException defines exception to signal failure during session access to a resource.
  • SessionConnectException defines exception to signal errors in sessions during connecting to a resource.
  • SessionDisconnectException defines exception to signal errors in sessions during disconnecting from a resource.

Resource classes

The package com.alpha.pineapple.resource contains classes for storage of information about resources defined in the environment configuration:

  • EnvironmentInfo defines interface for info about a configured environment defined in the environment configuration read by Pineapple. Environment info's are stored in the resource repository.
  • ResourceInfo defines interface for info about a configured resource defined in the environment configuration read by Pineapple. Resource info's are stored in the resource repository.
  • ResourcePropertyInfo defines interface for info about a configured resource property defined in the environment configuration read by Pineapple. Resource info's are stored in the resource repository.
  • ResourceRepository defines interface for repository which contains information about all configured resources in the environment configuration.
  • ResourceNotFoundException defines exception to signal failure to look up resource in the resource repository.
  • PropertyNotFoundException defines exception to signal failure to look up resource property on resource.
  • PropertyAlreadyExistsException defines exception to signal failure to create a resource property since it already exists.
  • SaveConfigurationFailedException defines exception to signal failure to save environment configuration.
  • EnvironmentAlreadyExistsException defines exception to signal failure to create an environment since it already exists.
  • ResourceAlreadyExitsException is an exception class for signaling failure to create a resource since the resource already exists in the resource repository.

Model mapping classes

The package com.alpha.pineapple.model contains classes for mapping model objects to/from objects used by the core component:

  • ExecutionResultMapper defines interface for mapping ExecutionResult object graphs to model classes to the Execution result schema.
  • ExecutionResultMapperImpl is the default implementation of the ExecutionResultMapper interface.
ExecutionResultMapperImpl

The class implements two methods for mapping objects between the two object models:

  • Results mapResultToModel(ExecutionResultNotification[] notifications) maps a sequence of execution result notifications to model classes defined by the Execution result schema. This method is used by the REST API to generate a sequence of execution result updates from execution results which describes the outcome of a operation.
  • void mapModelToResults(Results modelResults, Map<Integer, ExecutionResult> results) adds a sequence of model objects to a object graph of execution results. This method is used by the agent plugin to map a received model into the object graph of execution results. This method is idempotent (e.g. multiple invocations with the same data have the same result as one invocation). This method is used by the agent plugin to poll updates from agents and each invocation of the method will return a different sequence of model results, e.g. the result updates taken place at the agent side since the last updates. The map argument is internally by the mapper to map model correlation ID's to the execution results created by the mapper.
The algorithm of mapResultToModel method

Creation of a sequence of model objects:

  1. Create model.
  2. Iterate over the array of execution result notifications:
    1. Create model result MR.
    2. Map description (from result in notification).
    3. Map start time (from result in notification).
    4. Map execution time (from result in notification).
    5. Map execution state (from notification, NOT result in notification).
    6. Map correlation ID from the hash code.
    7. Map messages.
    8. If execution result isn't the root result then get the parent result and set the parent correlation ID from its hash code.
    9. Add model result MR to the model.

    Please Notice: The algorithm doesn't care whether the same execution results appears multiple times in the input. The legal case for this, is when a execution results has changed its state, e.g. first captured as running then later as success/failure/error.

The algorithm of mapModelToResults

The algorithm assumes that result map contains the root result is stored at index -1 (as defined by constant ExecutionResultMapperImpl.LOCAL_ROOT_INDEX).

Mapping a sequence of model objects into a graph of execution results:

  1. If the result sequence is undefined then exit.
  2. Iterate over the sequence of model result:
    1. If model result is a new result (e.g. the model result correlation ID isn't defined in in the result map) then create a new result by:
      1. Resolve the parent result (PR). The PR is resolved from the parent correlation ID. If the parent correlation ID is defined in the model result then the parent result is looked up in the result map. Otherwise is it assumed that model result in question is the remote root result and the parent result is resolved to root result initially stored in the result map.
      2. Create a new child result on the PR including description.
      3. Step 2.1.2 will create the result with execution state EXECUTING. No further mapping will be done. Since the only legal state for a new result is EXECUTING. If the model result contains a different state then it is ignored at the point, the state will only be mapped when a result is updated.
      4. Map messages.
      5. Start time is computed locally (e.g. the times recorded in the model result is ignored).
      6. Register the created result in result map with the correlation ID as key.
      7. Skip to next iteration.
    2. If model result is an existing result (e.g. the model result correlation ID is defined in in the result map) then update the result by:
      1. Resolve the result by looking it up in the result map.
      2. Update the description.
      3. Update the execution state.
      4. Update the messages.
      5. If the execution is change from executing to something else then the execution time is computed locally (e.g. the times recorded in the model result is ignored).

Variable substitution classes

The package com.alpha.pineapple.substitution contains classes for variable substitution in files and models:

  • VariableSubstitutionProvider defines interface for variable substitution provider which provides functionality for variable substitution of artifacts (e.g. text and files) in plugins. The Interface is part of the plugin framework. The provider is implemented in the core component project.
  • VariableSubstitutionException is an exception class used to signal exceptions during variable substitution.
  • SourceFileValidationFailureException is a sub class of VariableSubstitutionException used to signal exceptions during validation of the fitness of a source file for variable substitution.

Helper classes

The package com.alpha.javautils contains helper class for different purposes:

  • NetworkUtils defines a helper class with network related functionality.
  • StringUtils defines a helper class to support manipulation of strings.
  • ZipUtils defines a helper class to support creation of ZIP archives and unpacking.
  • ZipProgressCallback defines a call back interface to monitor the progress of unpacking of a ZIP archive.

The package com.alpha.javautils.reflection contains helper class for usage of reflection:

  • GetterMethodMatcher defines an interface for identification of getter methods and attribute names of a particular style of objects.
  • MethodUtils defines a helper class for querying about types and methods. Furthermore the class support invocation using reflection.