anchor.diff:  ----
   
   
  -
  -
  -
  +== The Build File
  +
  
positive.code: -rw-rw-r-- 1 dpp dpp 4254796 Jan  2 17:42 target/thang-0.1.0-jar-with-dependencies.jar
  ----
  
  To upload:
  
  [source, shell]
  
negative.code: You can create `ServiceVendorBuilder` instances for any `type` and, boom, have access to those services
  based on Execution Properties.
  
  === Serializers
  
  By default, Funcatron uses https://github.com/FasterXML/jackson[Jackson] to serialize and
   deserialized JSON data. This is fine for Java PoJos that have getters/setters. But if you
   are using http://stackoverflow.com/questions/3511120/why-shouldnt-i-use-immutable-pojos-instead-of-javabeans[immutable pojos],
   Scala case classes, etc., you may have more complex serialization needs.
   
  The `Func` interface allows you to write custom serializers.
  
  To deserialize incoming data using special rules, override the `jsonDecoder` method in `Func`
  and to serialize returned data using special rules, override the `jsonEncoder` method:
  
  [source,java]
  ----
      public Function<InputStream, Data> jsonDecoder() {
          return m -> {
              try {
                  return jackson.readValue(m, Data.class);
              } catch (Exception e) {
                  throw new RuntimeException("Failed to deserialize", e);
              }
          };
      }
  ----
  
  The method returns a `Function` that takes an `InputStream` and returns an instance
  of the type matching the first parameter of `apply` method.
  
  The `jsonEncoder` method does the opposite. Here's a Scala example:
  
  [source,scala]
  ----
  trait DecoderOMatic[T] {
  
    protected def ct: Class[T]
  
    def jsonDecoder(): Function[InputStream, T] = {
      new Function[InputStream, T] {
        def apply(t: InputStream): T = DecoderOMatic.jackson.readValue(t, ct)
      }
    }
  
    def jsonEncoder(): Function[Object, Array[Byte]] =
      new Function[Object, Array[Byte]] {
        def apply(o: Object) = DecoderOMatic.jackson.writer().writeValueAsBytes(o)
      }
  }
  
  object DecoderOMatic {
    val jackson: ObjectMapper = {
      val mapper = new ObjectMapper()
      mapper.registerModule(DefaultScalaModule)
      mapper
    }
  }
  ----
  
  The above code creates an instance of the Jackson `ObjectMapper` and adds the Scala module.
  
  For complex data types, build your own serializers.
  
  == Funcatron Swagger File
  
  So... how does Funcatron associate code with HTTP endpoints? How does Funcatron
   ensure that the functions are called with properly shaped data?
   
  Funcatron endpoints are defined in a http://swagger.io/[Swagger] file named
   either `funcatron.yaml` or `funcatron.json`. Define the endpoints, associate them with
   the class that implements the `Func` interface via the `operationId` field and
   Funcatron does the rest.
   
  What's "the rest"?
  
  * Funcatron ensures the incoming data is shaped correctly and will not
    attempt to deserialize the JSON data if it's not properly shaped.
  * Funcatron ensures all the rules defined in the Swagger file (e.g.,
    OAuth rules, etc.) are properly enforced.
  * In production, wires up the front end web servers to respond to requests.
  * In development mode, presents a UI to test out the API endpoints at
    http://localhost:3000/ui/
    
  So, let's see some of the Swagger magic in action. Point your browser to
  http://localhost:3000/ui/ then click through "default" and "POST". Cool.
  You can try out a `POST` from your browser.
  
  Next, let's update the `funcatron.yaml` file. Replace the `post:` line
  and all subsequent lines in the file with:
  
  [source,yaml]
  ----
      post:
        description: Creates new sample data
        operationId: my.stellar.MyFunction
        parameters:
          - name: body
            in: body
            required: true
            schema:
              $ref: '#/definitions/Data'
        responses:
          "200":
            description: sample response
          default:
            description: unexpected error
  
  definitions:
    Data:
      required:
        - name
        - age
      properties:
        name:
          type: string
        age:
          type: number
  ----
  
  Now, reload the browser and you can see the UI presents you with the option
  of entering JSON data. Enter some and click the `Try it out!` button.
  
  Well... you get the idea. Basically, model your REST endpoints in Swagger,
  test stuff out in the browser. Associate your classes with the `operationId`
  field, and the code will Just Work(TM).
  
  == Execution Properties
  
  The static relationship between REST endpoints and your code as well as access control
  rules, etc. are defined in your code and the `funcatron.yaml` Swagger file.
  
  However, there will be runtime properties that are different among different environments.
  For example, you'll have database access credentials for development time, for testing time,
  staging, and production.
  
  Those items bundled together in "`Execution Properties`".
  
  For the development-time project, we have the `exec_props.json` file which
  contains Execution Properties that are used during development-time.
  
  We've seen if the Execution Properties have a `type` field and a named Service Vendor
  is associated with the type, the service is available in the `Context`.
  
  The entire contents of the Execution Properties information is available in the
  `Context.properties()` method. This returns a `Map` of key/value pairs.
  Put any old information associated with the execution of the code in the
  Execution Properties and it's available to the `Func`.
  
  Execution properties are defined via JSON when a Func Bundle is deployed. See <<Deploying>>.
  
  == Packaging your Func Bundle
  
  