From cda9c650bf8acbd560688c20c28a32c533f1a8eb Mon Sep 17 00:00:00 2001 From: Eran Rom <eran@itsonlyme.name> Date: Thu, 29 Sep 2016 19:33:49 +0300 Subject: [PATCH] Adjusting the storlet writing and deploying guide to include python The guide is broken into three parts as follows: A language independent guide and two language specific complimentary guides. While at it the programming model UML was simplified to include only what the storlet writer should care about. Bonus 1: Adjusted all docs to use the same heading format Bonus 2: Moved to archive two outdated .rst to archive Change-Id: I945f410aa96af1895c66856537ff392d5c18be25 --- doc/source/api/overview_api.rst | 2 - .../building_and_deploying_docker_images.rst | 8 +- doc/source/{ => archive}/storlet_api.rst | 0 .../{ => archive}/storlets_management.rst | 0 doc/source/contributing.rst | 1 - doc/source/engine_dev_installation.rst | 8 +- doc/source/engine_dev_tests.rst | 4 - doc/source/getting_started.rst | 4 - doc/source/images/java_prog_model.jpg | Bin 57673 -> 49755 bytes doc/source/images/python_prog_model.jpg | Bin 0 -> 30083 bytes doc/source/images/storlet_engine_drawing.pptx | Bin 59772 -> 61372 bytes doc/source/index.rst | 3 +- doc/source/installation.rst | 9 +- doc/source/s2aio.rst | 1 - doc/source/storlet_engine_overview.rst | 25 +- doc/source/storlets_terminology.rst | 7 +- doc/source/usecases/usecase_chip_bakers.rst | 1 - .../usecases/usecase_secondary_storage.rst | 1 - doc/source/usecases/usecase_security.rst | 1 - .../writing_and_deploying_java_storlets.rst | 104 +++++++ .../writing_and_deploying_python_storlets.rst | 83 ++++++ doc/source/writing_and_deploying_storlets.rst | 272 ++++++++---------- 22 files changed, 320 insertions(+), 214 deletions(-) rename doc/source/{ => archive}/building_and_deploying_docker_images.rst (98%) rename doc/source/{ => archive}/storlet_api.rst (100%) rename doc/source/{ => archive}/storlets_management.rst (100%) create mode 100644 doc/source/images/python_prog_model.jpg create mode 100644 doc/source/writing_and_deploying_java_storlets.rst create mode 100644 doc/source/writing_and_deploying_python_storlets.rst diff --git a/doc/source/api/overview_api.rst b/doc/source/api/overview_api.rst index 3c292852..572b7c7e 100644 --- a/doc/source/api/overview_api.rst +++ b/doc/source/api/overview_api.rst @@ -1,4 +1,3 @@ -=============== Storlets API v1 =============== The storlets API is an extension of the Swift API. In some cases we use @@ -234,7 +233,6 @@ Use the 'X-Storlet-Run-On-Proxy' header to enforce the engine to invoke the stor 'X-Storlet-Run-On-Proxy': '' -============= Storlets ACLs ============= diff --git a/doc/source/building_and_deploying_docker_images.rst b/doc/source/archive/building_and_deploying_docker_images.rst similarity index 98% rename from doc/source/building_and_deploying_docker_images.rst rename to doc/source/archive/building_and_deploying_docker_images.rst index 2864a848..e99e891e 100644 --- a/doc/source/building_and_deploying_docker_images.rst +++ b/doc/source/archive/building_and_deploying_docker_images.rst @@ -1,4 +1,3 @@ -============ Introduction ============ The Swift account manager can supply a Docker image in which the account's storlets @@ -15,7 +14,6 @@ following: The idea is that a user supplied docker image would contain dependencies required by storlets in the form of libraries. -============ Logical Flow ============ The flow of deploying an account manager tailored Docker image to Swift involves @@ -39,7 +37,7 @@ Below are the steps of this flow: The sections below describe in detail the steps taken by the account manager. Downloading the Docker Image -============================ +---------------------------- Downloading the Docker image involves a simple retrieval of a Swift object. To get the exact name of the object just list the docker_images container in the account. The name will carry the base OS system and engine language binding run @@ -93,7 +91,7 @@ In the below we show: X-Trans-Id: tx794e21cd40b544e6a377b-00544bfed3 Tuning the Docker Image -======================= +----------------------- To tune the Docker image, Docker must be used. To install please refer to http://docs.docker.com/installation/ @@ -199,7 +197,7 @@ engine but rather the /bin/bash from which we can run ffmpeg Uploading the Docker Image -========================== +-------------------------- 1. Use docker save to save the image as a tar file: .. code-block:: bash diff --git a/doc/source/storlet_api.rst b/doc/source/archive/storlet_api.rst similarity index 100% rename from doc/source/storlet_api.rst rename to doc/source/archive/storlet_api.rst diff --git a/doc/source/storlets_management.rst b/doc/source/archive/storlets_management.rst similarity index 100% rename from doc/source/storlets_management.rst rename to doc/source/archive/storlets_management.rst diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst index 1728a61c..579036cd 100644 --- a/doc/source/contributing.rst +++ b/doc/source/contributing.rst @@ -1,4 +1,3 @@ -============ Contributing ============ .. include:: ../../CONTRIBUTING.rst diff --git a/doc/source/engine_dev_installation.rst b/doc/source/engine_dev_installation.rst index ad8663a1..16039421 100644 --- a/doc/source/engine_dev_installation.rst +++ b/doc/source/engine_dev_installation.rst @@ -1,4 +1,3 @@ -==================================== Installing a Development Environment ==================================== This guide gives a step by step installation instructions that are simpler @@ -28,9 +27,8 @@ This process has been tested on Ubuntu 14.04 using Swift 2.7.0. pip install --upgrade pbr pip install --upgrade setuptools ------------------------ Make Swift use Keystone ------------------------ +======================= SAIO uses tmpauth as an auth middleware. While storlets do not have a direct dependency on the auth middleware used, Keystone seems to be @@ -139,9 +137,8 @@ Now do: source .bashrc swift stat ----------------- Install Storlets ----------------- +================ Install Dependencies -------------------- @@ -513,7 +510,6 @@ We use the swift cli as follows: --os-tenant-name=test \ storletlog ------------------------- Run the functional tests ------------------------ The functional tests upload various storlets and execute them. diff --git a/doc/source/engine_dev_tests.rst b/doc/source/engine_dev_tests.rst index 72c9eb3a..17e14548 100644 --- a/doc/source/engine_dev_tests.rst +++ b/doc/source/engine_dev_tests.rst @@ -1,4 +1,3 @@ -============================= Development and Testing Guide ============================= @@ -10,7 +9,6 @@ the development environment installation instructions_ or in the getting started .. _instructions: engine_dev_installation.html .. _guide: getting_started.html --------- Building -------- The storlets repository consists of code written in Python, Java and C. We have chose ant to serve as a 'make' tool for all of the code. @@ -32,7 +30,6 @@ The main build task in build.xml is dependent on two other build tasks: #. The Java SCommon code, which has the storlet interface declaration, as well as the accompanying classes appearing in the interface. This code is compiled to a .jar that is required both in the Docker image as well as for building storlets. ---------- Deploying --------- Two additional tasks of interest in our build.xml are the deploy_host_engine and deploy_container_engine. @@ -45,7 +42,6 @@ These tasks are based on the Ansible installation scripts and do the following: in the cluster_config.json and distribute it to all nodes as defined in the configuration. ------------------ Running the Tests ----------------- diff --git a/doc/source/getting_started.rst b/doc/source/getting_started.rst index e67c34aa..4da425ea 100644 --- a/doc/source/getting_started.rst +++ b/doc/source/getting_started.rst @@ -1,4 +1,3 @@ -=============== Getting Started =============== @@ -6,7 +5,6 @@ This is a TL-DR guide to get you started with Storlet experimentation as fast as possible. -------------------- System Requirements ------------------- @@ -14,7 +12,6 @@ Ubuntu Server 14.04 with total disk of 10Gb. A disposal VM is always a good idea. -------------------- Installation Guide ------------------- @@ -22,7 +19,6 @@ Installation Guide For more information please refer to `"s2aio" <http://storlets.readthedocs.io/en/latest/s2aio.html>`__. ---------------------------------------- Writing Deploying and Running a Storlet --------------------------------------- diff --git a/doc/source/images/java_prog_model.jpg b/doc/source/images/java_prog_model.jpg index a511dfc30e65b3177cfaece620ba57ef1d12edcf..2c0ba3cc65dbdc41c76551560d9adf755c0e5699 100644 GIT binary patch delta 19326 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 delta 27485 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 UGx_F<Kf#1A28dOkX_4RYZ-gAX3jhEB diff --git a/doc/source/images/python_prog_model.jpg b/doc/source/images/python_prog_model.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eacac3e79f52775c5a786b457304d5002db681c7 GIT binary patch literal 30083 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 F{{yfIVbK5p literal 0 HcmV?d00001 diff --git a/doc/source/images/storlet_engine_drawing.pptx b/doc/source/images/storlet_engine_drawing.pptx index 6006ea971bb337becceb547c54013b555848ff6c..777017db0ad2905866d3ec062a804801a60e8041 100644 GIT binary patch delta 14455 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 delta 13152 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 diff --git a/doc/source/index.rst b/doc/source/index.rst index 23aab371..f11c543b 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -14,7 +14,6 @@ License for the specific language governing permissions and limitations under the License. -=================================== Welcome to storlets' documentation! =================================== @@ -67,6 +66,8 @@ Storlets Developers :maxdepth: 1 writing_and_deploying_storlets + writing_and_deploying_java_storlets + writing_and_deploying_python_storlets Storlets Deployers ================== diff --git a/doc/source/installation.rst b/doc/source/installation.rst index b8df5dff..b9f55909 100644 --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -1,9 +1,8 @@ -===================== Storlets Installation ===================== Background -========== +---------- Storlets installation (and build) assume an existing Swift cluster that works with Keystone. The installation consists of the following components: @@ -36,7 +35,7 @@ At a high level the installation consists of the following steps: #. Install a set of storlets management scripts. Done on a designated node having a storlet management role. hosts file example -================== +------------------ :: @@ -66,7 +65,7 @@ Few notes: #. It is recommended that the memcache servers on the proxy servers would be accessible from the storage nodes. common.yml -========== +---------- Below are the entries of interest of common.yml Special attention should be given to the swift user and group IDs. Make sure they are identical on all hosts and match what is defined in the common.yml file. @@ -109,7 +108,7 @@ storlets with EC and encryption. Valid values are true / false storlet_execute_on_proxy_only: false Install -======= +------- to perform the installation follow these steps: #. Create a hosts file as described above diff --git a/doc/source/s2aio.rst b/doc/source/s2aio.rst index 84f8e897..593fc3a6 100644 --- a/doc/source/s2aio.rst +++ b/doc/source/s2aio.rst @@ -1,4 +1,3 @@ -===== s2aio ===== diff --git a/doc/source/storlet_engine_overview.rst b/doc/source/storlet_engine_overview.rst index 9ca2fb5a..9e45773a 100644 --- a/doc/source/storlet_engine_overview.rst +++ b/doc/source/storlet_engine_overview.rst @@ -1,15 +1,10 @@ -======================= Storlet Engine Overview ======================= - ----------- -Components ----------- At the high level the storlet engine is made of the components described below. See illustration. The storlet middleware -====================== +---------------------- The storlet middleware is a Swift WSGI middleware that intercepts storlet invocation requests and routes the input data and the computation output into and out of the Docker container where the storlet is executed. This middleware needs to be in both the @@ -24,7 +19,7 @@ Moreover, part of the storlet middleware configuration is what class implementation of the API we refer to as "storlet docker gateway". Swift accounts -============== +-------------- The storlet engine is tightly coupled with accounts in Swift in the following manners: #. In order to invoke a storlet on a data object residing in some Swift account, that account @@ -40,7 +35,7 @@ The storlet engine is tightly coupled with accounts in Swift in the following ma accounts. The Docker image name must be the account id to which it belongs. The Docker image -================ +---------------- As mentioned above there is a Docker image per account that is enabled for storlets. At a high level this image containes: @@ -58,14 +53,13 @@ At a high level this image containes: it has the definition of the invoke API the storlet must implement. The storlet bus -=============== +--------------- The storlet bus is a communication channel between the storlet middleware in the Swift side and the factory daemon and storlet daemon in the Docker container. For each Docker container (or Swift account) there is a communication channel with the storlet factory of that container. For each storlet daemon in the container there is a communication channel on which is listens for invocations. These channels are based on unix domain sockets. ------------------------------------------- The storlet engine components illustration ------------------------------------------ @@ -75,14 +69,13 @@ The storlet engine components illustration :scale: 50 :alt: alternate text ----- Flow ----- +==== To tie everything together we illustrate an end-to-end scenario. Writing and Deploying a storlet -=============================== +------------------------------- The flow begins with writing a storlet followed by deploying it. writing and deploying a storlet is covered in the writing and deploying storlets guide_. @@ -90,7 +83,7 @@ deploying storlets guide_. .. _guide: writing_and_deploying_storlets.html Invoking a Storlet -================== +------------------ A Storlet can be invoked on object download, upload or copy operations (GET, PUT, and COPY respectively). For the flow description lets assume that we wish to invoke the storlet on an object download. This involves doing a Swift GET request with the @@ -98,7 +91,7 @@ additional header "X-Run-Storlet" which specifies the storlet to invoke, e.g. "X-Run-Storlet: compress-1.0.jar". Handling the request at the proxy server -======================================== +---------------------------------------- Seeing the "X-Run-Storlet" header the storlert_middleware at the proxy intercepts the request and performs a HEAD on the storlet specified by the user. This HEAD operation facilitates: @@ -115,7 +108,7 @@ with the request being routed to an object server that holds a replica of the ob specified in the GET uri. Handling the request at the object server -========================================= +----------------------------------------- Seeing the "X-Run-Storlet" header the storlert_middleware at the object server intecepts the request and perform the following two phased flow: diff --git a/doc/source/storlets_terminology.rst b/doc/source/storlets_terminology.rst index ec13b88b..36588b08 100644 --- a/doc/source/storlets_terminology.rst +++ b/doc/source/storlets_terminology.rst @@ -1,11 +1,9 @@ -==================== Storlets Terminology ==================== The overall storlets mechanism involves a lot of moving parts as well as poeple or roles involved throughout the usage of the system. We give below a definition of the various terms used throughout the documentation. -------- Storlet ------- A storlet is the binary code deployed as a Swift object. Invoking a storlet @@ -26,7 +24,6 @@ In a nutshell this interface consists of an input stream, an output stream and a The storlet is assumed to read from the input stream, do its thing, and write the result to the output stream. ------------------- Storlet Invocation ------------------ A storlet invocation is a user request wishing to perform a storlet computation @@ -43,7 +40,6 @@ different ways: data object, where the storlet's output is kept in a newly crerated object. In a regular Swift copy the newly created object is a identical to the source object. ------------------- The Storlet Engine ------------------ The storlet engine is the underlying mechanism that can take a storlet as a Swift object @@ -52,9 +48,8 @@ In a nutshell the engine intercepts invocation requests, route the input data st the storlet and receives back the storlet output stream. The engine is implemented as a Swift middleware. ------ Roles ------ +===== Storlet Developer ----------------- diff --git a/doc/source/usecases/usecase_chip_bakers.rst b/doc/source/usecases/usecase_chip_bakers.rst index a02a9173..9a0c288b 100644 --- a/doc/source/usecases/usecase_chip_bakers.rst +++ b/doc/source/usecases/usecase_chip_bakers.rst @@ -1,4 +1,3 @@ -======================== The Chip Bakers Use Case ======================== diff --git a/doc/source/usecases/usecase_secondary_storage.rst b/doc/source/usecases/usecase_secondary_storage.rst index 2278d615..e8983869 100644 --- a/doc/source/usecases/usecase_secondary_storage.rst +++ b/doc/source/usecases/usecase_secondary_storage.rst @@ -1,4 +1,3 @@ -================================== Queriable "Secondary Storage" Data ================================== It is said that the primary use case for object stores is to serve as secondary diff --git a/doc/source/usecases/usecase_security.rst b/doc/source/usecases/usecase_security.rst index e2f19057..6b9a7f0c 100644 --- a/doc/source/usecases/usecase_security.rst +++ b/doc/source/usecases/usecase_security.rst @@ -1,4 +1,3 @@ -============ Data Privacy ============ diff --git a/doc/source/writing_and_deploying_java_storlets.rst b/doc/source/writing_and_deploying_java_storlets.rst new file mode 100644 index 00000000..af292d11 --- /dev/null +++ b/doc/source/writing_and_deploying_java_storlets.rst @@ -0,0 +1,104 @@ +Java Storlet Writing and Deploying Guide +======================================== + +This is the Java specific storlet writing and deploying guide. This guide complements +the more general_ guide for writing and deploying storlets which should be read first. +To write a Java storlet you will need the SCommon.jar which is being built as part of +the storlets build process as described in the development and testing guide_. + +.. _guide: engine_dev_tests.html +.. _general: writing_and_deploying_storlets.html + +Import the .jar to a Java project in Eclipse and implement the +org.openstack.storlet.common.IStorlet interface. +The interface has a single method that looks like this: + +:: + + public void invoke(ArrayList<StorletInputStream> inStreams, + ArrayList<StorletOutputStream> outStreams, + Map<String,String> parameters, StorletLogger logger) throws StorletException; + +Below is a class diagram illustrating the classes involved in the above API. + +.. image:: images/java_prog_model.jpg + :height: 960px + :width: 1216 px + :scale: 50 % + :alt: Java Programming Model Class Diagram + :align: center + +#. The StorleInputStream is used to stream object's data into the storlet. + An instance of the class is provided whenever the Storlet gets an object as + an input. Practically, it is used in all storlet invocation scenarios to + stream in the object's data and metadata. To consume the data call getStream() + to get a java.io.InputStream on which you can just read(). To consume the + metadata call the getMetadata() method. + +#. StorletObjectOutputStream. In all invocation scenarios the storlet is + called with an instance of this class. + + - Use the setMetadata method to set the Object's metadata. + + - Use getStream to get a java.io.OutputStream on which you can just write() + the content of the object. + + - Notice that setMetadata must be called. Also, it must be called before + writing the data. Additional guidelines on using StorletObjectOutputStream + are given below. + +#. StorletLogger. The StorletLogger class supports a single method called emitLog, + and accepts a String. The storlet logs are written to the host machine. + +When invoked via the Swift REST API the invoke method +will be called as follows: + +#. The inStreams array would include one or more element(s) of type StorleInputStream + representing the object appearing in the request's URI (and possibly extra resources). + +#. The outStreams would include a single element of type StorleObjectOutputStream + representing the response returned to the user. + +#. The parameters map includes execution parameters sent. These parameters can be + specified in the storlet execution request. + +#. A StorletLogger instance. + +Tips +---- + +#. The storlets are executed in an open-jdk 8 environment. Thus, any dependencies + that the storlet code requires which are outside of open-jdk 8 should be + stated as storlet dependencies and uploaded with the storlet. Exact details + are found in the deployment section below. + +#. In some cases the storlet may need to know the path where the storlet .jar + as well as the dependencies are kept inside the Linux container. One reason + may be the need to invoke a binary dependency. To get that path use the + following code: + + :: + + // Get the path of this class image + String strJarPath = StorletUtils.getClassFolder(this.getClass()); + +Deploying a Java Storlet +------------------------ + +Below are specific guidelines for deploying a Java storlet: + +#. The compiled class that implements the storlet needs to be wrapped in a .jar. + This jar must not include the SCommon.jar. + +#. Any jars that the class implementation is dependent on should be uploaded as separate jars. + +#. The name of the Java storlet being uploaded must be of the form <name>-<version>, e.g. + identitystorlet-1.0.jar + +#. The 'X-Object-Meta-Storlet-Main' metadata key shold be the name of the class implementing + the IStorlet interface. E.g. "org.openstack.storlet.identity.IdentityStorlet" + +Deploying a Java Dependency +--------------------------- + +#. A java dependency must be either a .jar or an executable diff --git a/doc/source/writing_and_deploying_python_storlets.rst b/doc/source/writing_and_deploying_python_storlets.rst new file mode 100644 index 00000000..13faa25b --- /dev/null +++ b/doc/source/writing_and_deploying_python_storlets.rst @@ -0,0 +1,83 @@ +Python Storlet Writing and Deployment Guideline +=============================================== + +This is the Python specific storlet writing and deploying guide. This guide complements +the more general_ guide for writing and deploying storlets which should be read first. + +.. _general: writing_and_deploying_storlets.html + +A python module implementing a storlet looks like this: + +:: + + class <Class name>(object): + def __init__(self, logger): + self.logger = logger + + def __call__(self, in_files, out_files, params): + """ + The function called for storlet invocation + :param in_files: a list of StorletInputFile + :param out_files: a list of StorletOutputFile + :param params: a dict of request parameters + """ + +Below is a class diagram illustrating the classes behind the in_files, out_files, and logger. +The diagram lists only the methods that the storlet writer is expected to work with. + +.. image:: images/python_prog_model.jpg + :height: 960px + :width: 1216 px + :scale: 50 % + :alt: Python Programming Model Class Diagram + :align: center + +#. The StorletInputFile is used to stream object's data into the storlet. + StorletInputFile has the same read methods as python FileObject. + Trying to write to a StorletInputFile yields NotImplemented error. + Whenever a storlet is invoked, an instance of this class is provided. + To consume the metadata call the StorletInputFile.get_metadata method. + +#. The StorleOutputFile is used for writing the storlet output. + StorletOutputFile has the same write methods as python FileObject. + Trying to read from a StorletOutputFile yields NotImplemented error. + Whenever a storlet is invoked, an instance of this class is provided. + Use the StorletInputFile.set_metadata method to set the Object's metadata. + Note that the storlet must call the StorletInputFile set_metadata method. + Moreowver, StorletInputFile.set_metadata must be called before writing + the data. + +#. StorletLogger. The StorletLogger class implements the same log methods as the + Python logger. + +When invoked via the Swift REST API the __call__ method +will be called as follows: + +#. The in_files list would include one or more element(s) of type StorleInputFile + representing the object appearing in the request's URI (and possibly extra resources). + +#. The out_files would include a single element of type StorleOutputFile + representing the response returned to the user. + +#. The parameters is a dictionary with the execution parameters sent. These parameters can be + specified in the storlet execution request. + +#. A StorletLogger instance. + +Deploying a Python Storlet +-------------------------- +Below are specific guidelines for deploying a Python storlet: + +#. The object name of the python module containing the storlet class implemetation + must end with .py + +#. Any python modules that the class implementation is dependent on should be uploaded as separate .py(s). + +#. The 'X-Object-Meta-Storlet-Main' metadata key shold be of the form: <module_name>.<class_name>. For example, + if the storlet name is SimpleStorlet and it resides in simple_storlet.py, then the + 'X-Object-Meta-Storlet-Main' metadata key shold be "simple_storlet.SimpleStorlet" + +Deploying a Python Dependency +----------------------------- + +#. Currently, there is no limitation as to what is being uploaded as a dependency. diff --git a/doc/source/writing_and_deploying_storlets.rst b/doc/source/writing_and_deploying_storlets.rst index 8f91c111..9c7927db 100644 --- a/doc/source/writing_and_deploying_storlets.rst +++ b/doc/source/writing_and_deploying_storlets.rst @@ -1,106 +1,50 @@ -=================================== Storlet writing and deploying guide =================================== -Currently, storlets must be written in Java. Writing a storlet involves -implementing a single method interface and following some simple rules and best -practices described below. + +Storlets can be written either in Java or in Python. This guide +is a language independent starting point for writing +and deploying storlets. The Java_ and Python_ specific guides +complement this guide and should be read next after this one. + +.. _Java: writing_and_deploying_java_storlets.html +.. _Python: writing_and_deploying_python_storlets.html + + +Writing a storlet involves implementing a single function referred to +as invoke (the exact name varies between languages). + +Typically, the invoke operation gets an input stream and an +output stream. The input stream will contain the data either being uploaded +(in case the storlet is invoked during upload) or being downloaded (when +the invocation is done during download). The input stream is accompanied with +metadata that reflects the Swift user defined metadata. The output stream +exposes a way to write back not only the storlet output data, but also the +metadata. The input and output streams are exposed to the storlet code +in a way that is native to the language being used. Once the storlet is written and tested it can be uploaded as an object to a -designated container (called 'storlet' by default). In addition in case the -storlet is dependent on some Java library, that library can be uploaded as a -dependency of the storlet. It is assumed that storlet dependencies are small -(on the order of few MBs), heavier dependencies should be part of the Docker -image. +designated container (called 'storlet' by default). Storlet code external +dependencies such as Java libraries or Python modules can be uploaded as well. +It is assumed, however, that storlet dependencies are relatively small +(on the order of few MBs). Heavier dependencies should be part of the Docker +image. Deploying storlets and dependencies are covered below. -To write a storlet you will need the SCommon.jar which is being built as part of -the storlets build process as described in the development and testing guide_ +There are various implementations of storlets in the StorletSamples/java +and StorletSamples/python directories. These storlets are used by the engine's +functional tests. -.. _guide: engine_dev_tests.html +The next two sections describe storlet writing and deploying guidelines that are +indpendent of the language used. -Import the .jar to a Java project in Eclipse and implement the -org.openstack.storlet.common.IStorlet interface. -The interface has a single method that looks like this: - -:: - - public void invoke(ArrayList<StorletInputStream> inStreams, - ArrayList<StorletOutputStream> outStreams, - Map<String,String> parameters, StorletLogger logger) throws StorletException; - -Below is a class diagram illustrating the classes involved in the above API. - -.. image:: images/java_prog_model.jpg - :height: 960px - :width: 1216 px - :scale: 50 % - :alt: Programming Model Class Diagram - :align: center - -#. The StorleInputStream is used to stream object's data into the storlet. - An instance of the class is provided whenever the Storlet gets an object as - an input. Practically, it is used in all storlet invocation scenarios to - stream in the object's data and metadata. To consume the data call getStream() - to get a java.io.InputStream on which you can just read(). To consume the - metadata call the getMetadata() method. -#. The StorleOutputStream is a base class for the StorletObjectOutputStream. - The actual instance received by the storlet will always be StorletObjectOutputStream. -#. StorletObjectOutputStream. In all invocation scenarios the storlet is - called with an instance of this class. - - - Use the setMetadata method to set the Object's metadata. - - Use getStream to get a java.io.OutputStream on which you can just write() - the content of the object. - - Notice that setMetadata must be called. Also, it must be called before - writing the data. Additional guidelines on using StorletObjectOutputStream - are given below. -#. StorletLogger. The StorletLogger class supports a single method called emitLog, - and accepts a String. The storlet logs are written to the host machine. - -When invoked via the Swift REST API the invoke method -will be called as follows: - -#. The inStreams array would include a single element of type StorleInputStream - representing the object appearing in the request's URI. -#. The outStreams would include a single element of type StorleObjectOutputStream - representing the response returned to the user. -#. The parameters map includes execution parameters sent. These parameters can be - specified in the storlet execution request. -#. A StorletLogger instance. - -========================== Storlet Writing Guidelines ========================== -Below are some guidelines for writing a storlet. Some of them are musts, some are -recommendations, and some are tips. +Independent of the language used for writing a storlet, there are several guidelines +to follow. Some of them are musts and some are recommendations. ------ -Musts ------ -#. The storlet code must be thread safe and re-enterant. The invoke method will - be called many times and potentially in parallel. -#. Once the storlet has finished writing the response, it is important to close - the output stream. Failing to do so will result in a timeout. Specifically, - close the java.io.OutputStream obtained from the call to getStreasm() -#. With the current implementation, a storlet must start to respond within 40 - seconds of invocation. Otherwise, Swift would timeout. Moreover, the storlet - must output something every 40 seconds so as not to timeout. This is a - mechanism to ensure that the storlet code does not get stuck. Note that - outputting an empty string does not do the job in terms of resetting the 40 - seconds timeout. -#. For StorletObjectOutputStream, the call to setMetadata must happen before the - storlet starts streaming out the output data. Note the applicability of the 40 - seconds timeout here as well. -#. The total size of metadata given to setMetadata (when serialized as a string) - should not exceed 4096 Bytes -#. While Swift uses the prefix X-Object-Meta to specify that a certain header - reflects a metadata key, the key itself should not begin with that prefix. - More specifically, metadata keys passed to setMetadata should not have that - prefix (unless this is really part of the key) - ---------------- Recommendations --------------- -#. Storlets are tailored for stream processing, that is, process the input as it + +#. Storlets are tailored for stream processing, that is, they process the input as it is read and produce output while still reading. In other words a 'merge sort' of the content of an object is not a good example for a storlet as it requires to read all the content into memory (random reads are not an option as the @@ -109,103 +53,103 @@ Recommendations into memory or doing very intensive computations would have impact on the overall system performance. -#. While this might be obvious it is advisable to test the storlet prior to its - deployment. +#. While this might be obvious make sure to unit test your storlet prior to deploying it. ----- -Tips ----- -#. The storlets are executed in an open-jdk 8 environment. Thus, any dependencies - that the storlet code requires which are outside of open-jdk 8 should be - stated as storlet dependencies and uploaded with the storlet. Exact details - are found in the deployment section below. +Musts +----- -#. In some cases the storlet may need to know the path where the storlet .jar - as well as the dependencies are kept inside the Linux container. One reason - may be the need to invoke a binary dependency. To get that path use the - following code: +#. The storlet code must be thread safe and re-enterant. The invoke method will + be called many times and potentially in parallel. - :: +#. Once the storlet has finished writing the response, it is important to close + the output stream. Failing to do so will result in a timeout. - // Get the path of this class image - String strJarPath = StorletUtils.getClassFolder(this.getClass()); +#. A storlet must start to respond within 40 seconds of invocation. Otherwise, + Swift would timeout. Moreover, the storlet must output something every 40 seconds + so as not to timeout. This is a mechanism to ensure that the storlet code does not + get stuck. Note that outputting an empty string does not do the job in terms of + resetting the 40 seconds timeout. ----------------- -Storlet Examples ----------------- -There are various implementations of storlets in the StorletSamples -directory. These are used in the engine's functional tests -In the below example, we will be using the identity storlet -found under StorletSamples/IdentityStorlet +#. The storlet must write metadata to the output stream, and must do so before it + starts streaming out the data. A typical implementation would read the + input metadata and use it as a basis for the metadata being written. + Note the applicability of the 40 seconds timeout here as well. -======================= -How to Deploy a storlet -======================= -In this paragraph we cover: +#. The total size of metadata that can be set (when serialized as a string) + must not exceed 4096 Bytes -#. The principles behind storlet deployment, plus examples. -#. A Swift client example for uploading a storlet. -#. A python example for uploading a storlet. +#. While Swift uses the prefix X-Object-Meta to specify that a certain header + reflects a metadata key, the key itself should not begin with that prefix. + More specifically, metadata keys being set by the storlet should not have that + prefix (unless this is really part of the key) ------------------------------ -Storlet Deployment Principles ------------------------------ - -The compiled class that implements the storlet needs to be wrapped in a .jar. -This jar must not include the SCommon.jar. Any jars that the class implementation -is dependent on should be uploaded as separate jars as shown in the deployment -section below. +Storlet Deployment Guidelines +============================= Storlet deployment is essentially uploading the storlet and its dependencies to -designated containers in the account we are working with. While a storlet and a +designated containers in the account you are working with. While a storlet and a dependency are regular Swift objects, they must carry some metadata used by the storlet engine. When a storlet is first executed, the engine fetches the necessary -objects from Swift and puts them is a directory accessible by the Docker container. +objects from Swift and puts them in a directory accessible to the Docker container. Note that the dependencies are meant to be small. Having a large list of dependencies or a very large dependency may result in a timeout on the first attempt to execute a storlet. If this happens, just re-send the request again. -We consider two types of dependencies: libraries and executables. libraries would -typically be .jar files the storlet code is dependent on. Alternatively, one can -have a binary dependency, that the storlet code can execute. +We support two types of dependencies: -Following the Identity storlet example, we have 2 objects to upload: +#. External libraries or modules that + are native to the storlet langauge -#. The storlet packaged in a .jar. In our case the jar was named: - identitystorlet-1.0.jar The jar needs to be uploaded to a container named - storlet. The name of the uploaded storlet must be of the form <name>-<version>. - The metadata that must accompany a storlet is as follows: +#. Executables dependency that the storlet code + can execute. + +Storlet Object Metadata +----------------------- +Uploading a storlet must be done to a designated container, called by default "storlet". The uploaded object +must carry the following metadata. See the specific langauge guides for more information. :: - X-Object-Meta-Storlet-Language - currently must be 'java' + X-Object-Meta-Storlet-Language - must be 'python' or 'java' X-Object-Meta-Storlet-Interface-Version - currenltly we have a single version '1.0' - X-Object-Meta-Storlet-Dependency - A comma separated list of dependencies. In our case: 'get42' X-Object-Meta-Storlet-Object-Metadata - Currently, not in use, but must appear. Use the value 'no' - X-Object-Meta-Storlet-Main - The name of the class that implements the IStorlet API. In our case: 'org.openstack.storlet.identity.IdentityStorlet' + X-Object-Meta-Storlet-Main - The name of the class that implements the invoke operation -#. The binary file that the storlet code is dependent on. In our case it is a - binary called get42. The binary should be uploaded to a container named - dependency. The dependency metadata fields appear below. Note the permissions - header. This header is required so that the engine will chmod it accordingly - when placed in the container so that the storlet would be able to execute it. +Optional metadata item is: - :: + :: - X-Object-Meta-Storlet-Dependency-Version - While the engine currently does not parse this header, it must appear. - X-Object-Meta-Storlet-Dependency-Permissions - An optional metadata field, where the user can state the permissions - given to the dependency when it is copied to the Linux container. This is helpful for binary dependencies invoked by the - storlet. For a binary dependency once can specify: '0755' + X-Object-Meta-Storlet-Dependency - A comma separated list of dependencies. If one wishes to update the storlet just upload again, the engine would recognize the update and bring the updated code. -Important: Currently, dependency updates are not recognized, only the Storlet -code itself can be updated. +Dependency Object Metadata +-------------------------- +Uploading a dependency must be done to a designated container, called by default "dependency". The uploaded object +must carry the following metadata. --------------------------------------- -Deploying a Storlet using Swift Client --------------------------------------- + :: + + X-Object-Meta-Storlet-Dependency-Version - While the engine currently does not parse this header, it must appear. + +Optional metadata item is: + + :: + + X-Object-Meta-Storlet-Dependency-Permissions - The permissions given to the dependency when it is copied to the + Docker container. This is helpful for binary dependencies invoked by the storlet. + For a binary dependency once can specify: '0755' + + +.. note:: Currently, dependency updates are not recognized. + + +Deploying a Storlet using Swift Client cli +------------------------------------------ +We show below how to deploy a storlet using the Swift client cli. +The example uses a Java storlet. The differences from deploying a +Python storlet are minor and we highlight them where required. When using the Swift client one needs to provide the credentials, as well as the authentication URI. The credentials can be supplied either via environment @@ -243,10 +187,15 @@ Here is the Swift client command for uploading the storlet. some notes: -H "X-Object-Meta-Storlet-Main:org.openstack.storlet.identity.IdentityStorlet" \ -H "X-Object-Meta-Storlet-Dependency:get42" +.. note:: When deploying a Python storlet the name of the object (identitystorlet-1.0.jar in the above) has a different format + Otherwise, "X-Object-Meta-Storlet-Language" is "Python", and "X-Object-Meta-Storlet-Main" has a different format. + Please refer to Python_ for the exact details. + Here is the Swift client command for uploading the get42 dependency. Again, some notes: #. The container name used here is the first parameter for the upload command and is 'dependency'. + #. We use the optional permissions header as this is a binary . :: @@ -255,9 +204,8 @@ some notes: -H "X-Object-Meta-Storlet-Dependency-Version:1.0" \ -H "X-Object-Meta-Storlet-Dependency-Permissions:0755" -------------------------------- -Deploying a Storlet with Python -------------------------------- +Deploying a Storlet using the Python Swift Client +------------------------------------------------- Here is a code snippet that uploads both the storlet as well as the dependencies. The code assumes v2 authentication, and was tested against a Swift cluster with: @@ -267,6 +215,10 @@ The code assumes v2 authentication, and was tested against a Swift cluster with: #. Under the service account there are already 'storlet' and 'dependency' containers. +The example uses a Java storlet. The differences from deploying a +Python storlet are minor and are the same as the differences highlighted +in the deployment using Swift client section above. + :: from swiftclient import client