Code Monkey home page Code Monkey logo

addressverifier's Introduction

AddressVerifier

This project implements the addressScorer API, which can be accessed through a POST HTTP request to http://server:port/addressScorer. The body of the POST message should be a JSON with the following structure:

{
  "line1": ADDR_LINE_1,
  "line2": ADDR_LINE_2,
  "city": CITY,
  "state": STATE,
  "zipCode": ZIP
}

The return reponse will contain a JSON message of the following structure:

{
    "success": TRUE or FALSE,
    "score": The score for this individual assessment,
    "average": The average of the last ten assessments (or this score if
               there are less then ten assessments recorded).
 }

The "success" field will be FALSE if score < 0.78 or if average < 0.70 AND there were at least ten assessments to draw an average from (this parameter will be ignored otherwise). Otherwise, the field will be TRUE.

In case of an error on the server side (through timeout or error in processing the request), the HTTP response will have a status code of 500 and a message will be provided indicating the reason for the server error.

Implementation

The REST API web server is implemented with Akka HTTP, as it was fairly straightforward and simple to get a working REST API server with minimal work.

The web server is itself implemented as an actor using the Akka Actors library, to give it flexibility in its own running space, so it can handle both receiving requests from clients and passing messages off to the score assessor. The start and stop messages to the web server actor will handle the HTTP lsitener's state, as well as handle the HTTP listener's actor system (separate from the main actor system as there should be no relationship between the two outside of the REST API handler function(s)). The web server actor creates a child actor which will handle the final verdict of the assessment and pass the result back to the web server actor to send to the client. When a REST API request is handled, the score assessor will be sent a message to calculate the score result, and that result sent back to the REST API caller.

The score assessor is also an actor, which will communicate with both its storage medium and the provided AddressFraudProbabilityScorer actor. For simplicity in this case, the storage medium is implemented as an in-memory, mutable queue limited to 10 items to make it easier to contain growth over time, as only the last 10 items are required for the score averaging. In other cases, this could be implemented as a database connector or other client to a remote data store.

The communication between actors is handled with Actor messaging, using "ask" requests to receive a Scala Future object, which can then be handled asynchronously. Only the web server itself will wait on the result of the future, as it must have that information before it can satisfy the REST API call. The other actors will pipe futures back to the caller, whether they be successful or indicative of failure conditions.

A hard timeout of 5 seconds is specified for the future Await as well as all Ask messages between actors, as that was a very specific requirement. If this timeout passes, an appropriate response will be sent back to the client via a HTTP Response with a status code of 500.

Building and Running

This project has a build.sbt file, so to build, please run:

sbt compile

This should download akka and other dependencies. The project also defines a Main object, so you can:

sbt run

to run the server.

Notes

The AddressFraudProbabilityScorer seemed to have a slight issue with creating a Future for a simulated failure condition. This code:

private def scoreAddress(address: Address): Future[Double] = {
    if (simulateServiceFailure) {
        Future.failed(throw new Exception(s"Could not score address" +
                                          s"(address=$address)"))
    }
    Future.successful {
        val addressScore = Random.nextDouble()
        simulateServiceLatency()
        addressScore
    }
}

will actually throw the exception while trying to fail the future, ending up with a future that does not get filled. Instead, the ask will time out with an AskTimeoutException after the timeout period.

However, changing the code to:

private def scoreAddress(address: Address): Future[Double] = {
    if (simulateServiceFailure)
        Future.failed(
            new Exception(s"Could not score address (address=$address)"))
    else Future.successful {
        val addressScore = Random.nextDouble()
        simulateServiceLatency()
        addressScore
    }
}

will make sure the future gets completed with a failure carrying the proper exception (the Future.failed() function takes a Throwable parameter), and will also make sure the Future.successful doesn't get run on the failure condition.

With the above code, the web server will return the "Could not score address" message immediaetly, rather than waiting for a timeout.

Testing

Testing was done with curl via the command line as well as with a Python module (included as clientTester.py) written with the curl_utils module from:

http://github.com/kitsuneninetails/python-utils

addressverifier's People

Watchers

James Cloos avatar Michael Micucci avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.