:EP: 11
:Title: Multipart Request Creation
:Status: Proposed

**********************************
EP011 - Multipart Request Creation
**********************************

Abstract
########

The process of creating a Multipart Request using the lib involves, as it is
now, many steps. It is designed to follow the specification for the creation of
a common Request message and inserting a type and body in it. This blueprint
proposes an option for the NApp developer to create Multipart Requests in an
easier way, given types and bodies are directly related and standardized.


Affected projects
#################

    ::

        python-openflow (v0x04)


Description
###########

Although MultipartReplies are created by the switch and need only to be
unpacked correctly, the process of creating multipart requests now involves:

1. Creation of a *BodyRequest* object.
2. Create a *MultipartRequest* object.
3. Assign the correct type to the Multipart Request.
4. Assign the *BodyRequest* object as the MultipartRequest body.
5. Pack.

As each multipart request has an unique type related to an unique body, the
library should be able to create the *MultipartRequest* object based only in
the specific request needed.

Multipart Requests fall in one of three cases. For each case, the needed steps
to create and pack requests are shown below:

Case 1: Requests with empty body
================================

.. code:: python

  from pyof.v0x04.controller2switch.common import MultipartTypes as MTypes
  from pyof.v0x04.controller2switch.multipart_request import MultipartRequest

  request = MultipartRequest(multipart_type = MTypes.EXAMPLE_EMPTY_BODY)
  data = request.pack()

Case 2: Requests with a single struct body
==========================================

.. code:: python

  from pyof.v0x04.controller2switch.common import MultipartTypes as MTypes
  from pyof.v0x04.controller2switch.multipart_request import (MultipartRequest,
        SpecificRequestBody)

  specific_req = SpecificRequestBody(some_data=1)
  request = MultipartRequest(
        multipart_type = MTypes.EXAMPLE_SPECIFIC_STRUCT_BODY)
  request.body = specific_req
  data = request.pack()

Case 3: Requests with an array of structs as body
=================================================

.. code:: python

  from pyof.v0x04.controller2switch.common import MultipartTypes as MTypes
  from pyof.v0x04.controller2switch.multipart_request import (MultipartRequest,
        SpecificRequestBody)

  multi_request_1 = SpecificRequestBody(some_data=1)
  multi_request_2 = SpecificRequestBody(some_data=2)
  multi_request_3 = SpecificRequestBody(some_data=3)

  request = MultipartRequest(
        multipart_type = MTypes.EXAMPLE_SPECIFIC_ARRAY_BODY)
  request.body = (multi_request_1, multi_request_2, multi_request_3)
  data = request.pack()

Solution
########

The ideal solution would be simplifying the creation for each case, making the
Multipart common message and type transparent to the NApp developer, like in:

Case 1: Requests with empty body
================================

.. code:: python

  from pyof.v0x04.controller2switch.multipart_request import SpecificRequestBody

  request = SpecificRequestBody()
  data = request.pack()

Case 2: Requests with a single struct body
==========================================

.. code:: python

  from pyof.v0x04.controller2switch.multipart_request import SpecificRequestBody

  request = SpecificRequestBody(some_data=1)
  data = request.pack()

Case 3: Requests with an array of structs as body
=================================================

.. code:: python

  from pyof.v0x04.controller2switch.multipart_request import SpecificRequestBody

  request = SpecificRequestBody(list_of_data=(1,2,3))
  data = request.pack()


Cases 1 and 2 are clear and straightforward regarding implementation, but case
3 needs special care.


Related Issues
##############

- https://github.com/kytos/python-openflow/issues/308
