Class JsonHttpService

java.lang.Object
jmri.server.json.JsonHttpService
Direct Known Subclasses:
JsonConsistHttpService, JsonMessageHttpService, JsonNonProvidedNamedBeanHttpService, JsonOperationsHttpService, JsonPowerHttpService, JsonRosterHttpService, JsonSchemaHttpService, JsonThrottleHttpService, JsonTimeHttpService, JsonUtilHttpService

public abstract class JsonHttpService
extends Object
Provide HTTP method handlers for JSON RESTful messages

It is recommended that this class be as lightweight as possible, by relying either on a helper stored in the InstanceManager, or a helper with static methods.

Message ID Handling

A message ID from a client is a positive integer greater than zero, to be passed back unchanged to the client so the client can track direct responses to requests (this is not needed in the RESTful API, but is available in the RESTful API). The Message ID (or zero if none) is passed into most public methods of JsonHttpService as the id parameter. When creating an object that is to be embedded in another object as a property, it is permissable to pass the additive inverse of the ID to ensure the ID is not included in the embedded object, but allow any error messages to be thrown with the correct message ID.

Note that to ensure this works, only create a complete object with message(String, JsonNode, String, int) or one of its variants.

  • Field Details

    • mapper

      protected final com.fasterxml.jackson.databind.ObjectMapper mapper
  • Constructor Details

    • JsonHttpService

      protected JsonHttpService​(@Nonnull com.fasterxml.jackson.databind.ObjectMapper mapper)
      Create an HTTP handler for a JSON service.
      Parameters:
      mapper - the ObjectMapper to create new JSON nodes
  • Method Details

    • doGet

      @Nonnull public abstract com.fasterxml.jackson.databind.JsonNode doGet​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull JsonRequest request) throws JsonException
      Respond to an HTTP GET request for the requested name.

      If name is null, return a list of all objects for the given type, if appropriate.

      This method should throw a 500 Internal Server Error if type is not recognized.

      Parameters:
      type - the type of the requested object
      name - the system name of the requested object
      data - JSON data set of attributes of the requested object
      request - the JSON request
      Returns:
      a JSON description of the requested object
      Throws:
      JsonException - if the named object does not exist or other error occurs
    • doGet

      @Deprecated @Nonnull public com.fasterxml.jackson.databind.JsonNode doGet​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull Locale locale, int id) throws JsonException
      Deprecated.
      Respond to an HTTP GET request for the requested name.

      If name is null, return a list of all objects for the given type, if appropriate.

      This method should throw a 500 Internal Server Error if type is not recognized.

      Parameters:
      type - the type of the requested object
      name - the system name of the requested object
      data - JSON data set of attributes of the requested object
      locale - the requesting client's Locale
      id - the message id set by the client
      Returns:
      a JSON description of the requested object
      Throws:
      JsonException - if the named object does not exist or other error occurs
    • doPost

      @Nonnull public abstract com.fasterxml.jackson.databind.JsonNode doPost​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull JsonRequest request) throws JsonException
      Respond to an HTTP POST request for the requested name.

      This method should throw a 400 Invalid Request error if the named object does not exist.

      Parameters:
      type - the type of the requested object
      name - the system name of the requested object
      data - JSON data set of attributes of the requested object to be updated
      request - the JSON request
      Returns:
      a JSON description of the requested object after updates have been applied
      Throws:
      JsonException - if the named object does not exist or other error occurs
    • doPost

      @Deprecated @Nonnull public com.fasterxml.jackson.databind.JsonNode doPost​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull Locale locale, int id) throws JsonException
      Deprecated.
      Respond to an HTTP POST request for the requested name.

      This method should throw a 400 Invalid Request error if the named object does not exist.

      Parameters:
      type - the type of the requested object
      name - the system name of the requested object
      data - JSON data set of attributes of the requested object to be updated
      locale - the requesting client's Locale
      id - the message id set by the client
      Returns:
      a JSON description of the requested object after updates have been applied
      Throws:
      JsonException - if the named object does not exist or other error occurs
    • doPut

      @Nonnull public com.fasterxml.jackson.databind.JsonNode doPut​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull JsonRequest request) throws JsonException
      Respond to an HTTP PUT request for the requested name.

      Throw an HTTP 405 Method Not Allowed exception if new objects of the type are not intended to be addable.

      Parameters:
      type - the type of the requested object
      name - the system name of the requested object
      data - JSON data set of attributes of the requested object to be created or updated
      request - the JSON request
      Returns:
      a JSON description of the requested object
      Throws:
      JsonException - if the method is not allowed or other error occurs
    • doPut

      @Deprecated @Nonnull public com.fasterxml.jackson.databind.JsonNode doPut​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull Locale locale, int id) throws JsonException
      Deprecated.
      Respond to an HTTP PUT request for the requested name.

      Throw an HTTP 405 Method Not Allowed exception if new objects of the type are not intended to be addable.

      Parameters:
      type - the type of the requested object
      name - the system name of the requested object
      data - JSON data set of attributes of the requested object to be created or updated
      locale - the requesting client's Locale
      id - the message id set by the client
      Returns:
      a JSON description of the requested object
      Throws:
      JsonException - if the method is not allowed or other error occurs
    • doDelete

      public void doDelete​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull JsonRequest request) throws JsonException
      Respond to an HTTP DELETE request for the requested name.

      Throw an HTTP 405 Method Not Allowed exception if the object is not intended to be removable.

      Do not throw an error if the requested object does not exist.

      Parameters:
      type - the type of the deleted object
      name - the system name of the deleted object
      data - additional data
      request - the JSON request
      Throws:
      JsonException - if this method is not allowed or other error occurs
    • doDelete

      @Deprecated public void doDelete​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull Locale locale, int id) throws JsonException
      Deprecated.
      Respond to an HTTP DELETE request for the requested name.

      Throw an HTTP 405 Method Not Allowed exception if the object is not intended to be removable.

      Do not throw an error if the requested object does not exist.

      Parameters:
      type - the type of the deleted object
      name - the system name of the deleted object
      data - additional data
      locale - the requesting client's Locale
      id - the message id set by the client
      Throws:
      JsonException - if this method is not allowed or other error occurs
    • doGetList

      @Nonnull public abstract com.fasterxml.jackson.databind.JsonNode doGetList​(@Nonnull String type, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull JsonRequest request) throws JsonException
      Respond to an HTTP GET request for a list of items of type.

      This is called by the JsonServlet to handle get requests for a type, but no name. Services that do not have named objects, such as the JsonTimeHttpService should respond to this with a list containing a single JSON object. Services that can't return a list may throw a 400 Bad Request JsonException in this case.

      Parameters:
      type - the type of the requested list
      data - JSON data set of attributes of the requested objects
      request - the JSON request
      Returns:
      a JSON list or message containing type "list", the list as data, and the passed in id
      Throws:
      JsonException - may be thrown by concrete implementations
    • doGetList

      @Deprecated @Nonnull public com.fasterxml.jackson.databind.JsonNode doGetList​(@Nonnull String type, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @Nonnull Locale locale, int id) throws JsonException
      Deprecated.
      Respond to an HTTP GET request for a list of items of type.

      This is called by the JsonServlet to handle get requests for a type, but no name. Services that do not have named objects, such as the JsonTimeHttpService should respond to this with a list containing a single JSON object. Services that can't return a list may throw a 400 Bad Request JsonException in this case.

      Parameters:
      type - the type of the requested list
      data - JSON data set of attributes of the requested objects
      locale - the requesting client's Locale
      id - the message id set by the client
      Returns:
      a JSON list or message containing type "list", the list as data, and the passed in id
      Throws:
      JsonException - may be thrown by concrete implementations
    • doSchema

      @Nonnull public abstract com.fasterxml.jackson.databind.JsonNode doSchema​(@Nonnull String type, boolean server, @Nonnull JsonRequest request) throws JsonException
      Get the JSON Schema for the data property of the requested type of JSON object. It is a invalid for implementations to not return a valid schema that clients can use to validate a request to or response from the JSON services.

      Note that a schema must be contained in a standard object as:

      {"type":"schema", "data":{"schema":<em>schema</em>, "server":boolean}}

      If using doSchema(String, boolean, String, String, int), an implementation can be as simple as: return doSchema(type, server, "path/to/client/schema.json", "path/to/server/schema.json", id);

      Parameters:
      type - the type for which a schema is requested
      server - true if the schema is for a message from the server; false if the schema is for a message from the client
      request - the JSON request
      Returns:
      a JSON Schema valid for the type
      Throws:
      JsonException - if an error occurs preparing schema; if type is is not a type handled by this service, this must be thrown with an error code of 500 and the localized message ERROR_UNKNOWN_TYPE
    • doSchema

      @Deprecated @Nonnull public com.fasterxml.jackson.databind.JsonNode doSchema​(@Nonnull String type, boolean server, @Nonnull Locale locale, int id) throws JsonException
      Deprecated.
      since 4.19.2; use doSchema(String, boolean, JsonRequest) instead
      Get the JSON Schema for the data property of the requested type of JSON object. It is a invalid for implementations to not return a valid schema that clients can use to validate a request to or response from the JSON services.

      Note that a schema must be contained in a standard object as:

      {"type":"schema", "data":{"schema":<em>schema</em>, "server":boolean}}

      If using doSchema(String, boolean, String, String, int), an implementation can be as simple as: return doSchema(type, server, "path/to/client/schema.json", "path/to/server/schema.json", id);

      Parameters:
      type - the type for which a schema is requested
      server - true if the schema is for a message from the server; false if the schema is for a message from the client
      locale - the requesting client's Locale
      id - the message id set by the client
      Returns:
      a JSON Schema valid for the type
      Throws:
      JsonException - if an error occurs preparing schema; if type is is not a type handled by this service, this must be thrown with an error code of 500 and the localized message ERROR_UNKNOWN_TYPE
    • doSchema

      @Nonnull protected final com.fasterxml.jackson.databind.JsonNode doSchema​(@Nonnull String type, boolean server, @Nonnull String serverSchema, @Nonnull String clientSchema, int id) throws JsonException
      Helper to make implementing doSchema(String, boolean, JsonRequest) easier. Throws a JsonException based on an IOException or NullPointerException if unable to read the schemas as resources.
      Parameters:
      type - the type for which a schema is requested
      server - true if the schema is for a message from the server; false if the schema is for a message from the client
      serverSchema - the path to the schema for a response object of type
      clientSchema - the path to the schema for a request object of type
      id - the message id set by the client
      Returns:
      a JSON Schema valid for the type
      Throws:
      JsonException - if an error occurs preparing schema
    • doSchema

      @Nonnull protected final com.fasterxml.jackson.databind.JsonNode doSchema​(@Nonnull String type, boolean server, @Nonnull com.fasterxml.jackson.databind.JsonNode schema, int id)
      Helper to make implementing doSchema(String, boolean, JsonRequest) easier.
      Parameters:
      type - the type for which a schema is requested
      server - true if the schema is for a message from the server; false if the schema is for a message from the client
      schema - the schema for a response object of type
      id - the message id set by the client
      Returns:
      a JSON Schema valid for the type
    • getObjectMapper

      @Nonnull public final com.fasterxml.jackson.databind.ObjectMapper getObjectMapper()
      Get the in-use ObjectMapper for this service.
      Returns:
      the object mapper
    • acceptForceDeleteToken

      public final boolean acceptForceDeleteToken​(@Nonnull String type, @Nonnull String name, @CheckForNull String token)
      Verify a deletion token. If the token is not valid any pending deletion tokens for the type and name are also deleted.
      Parameters:
      type - the type of object pending deletion
      name - the name of object pending deletion
      token - the token previously provided to client
      Returns:
      true if token was provided to client and no other delete attempt was made by client with a different or missing token since token was issued to client; false otherwise
    • throwDeleteConflictException

      public final void throwDeleteConflictException​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.node.ArrayNode conflicts, @Nonnull JsonRequest request) throws JsonException
      Throw an HTTP CONFLICT (409) exception when an object is requested to be deleted and it is in use. This exception will include a token that can be used to force deletion by the client and may include a JSON list of the objects using the object for which deletion was requested.
      Parameters:
      type - the type of object in conflicting state
      name - the name of the object in conflicting state
      conflicts - the using objects of this object; may be empty
      request - the JSON request
      Throws:
      JsonException - the exception
    • throwDeleteConflictException

      @Deprecated public final void throwDeleteConflictException​(@Nonnull String type, @Nonnull String name, @Nonnull com.fasterxml.jackson.databind.node.ArrayNode conflicts, @Nonnull Locale locale, int id) throws JsonException
      Throw an HTTP CONFLICT (409) exception when an object is requested to be deleted and it is in use. This exception will include a token that can be used to force deletion by the client and may include a JSON list of the objects using the object for which deletion was requested.
      Parameters:
      type - the type of object in conflicting state
      name - the name of the object in conflicting state
      conflicts - the using objects of this object; may be empty
      locale - the client locale
      id - the message id set by the client
      Throws:
      JsonException - the exception
    • message

      public final com.fasterxml.jackson.databind.JsonNode message​(@Nonnull com.fasterxml.jackson.databind.node.ArrayNode data, int id)
      Create a message node from an array.
      Parameters:
      data - the array
      id - the message id provided by the client or its additive inverse
      Returns:
      if id is a positive, non-zero integer, return a message of type "list" with data as the data and id set; otherwise return data without modification
      See Also:
      message(String, JsonNode, String, int), message(String, JsonNode, int), message(ObjectMapper, ArrayNode, String, int), message(ObjectMapper, String, JsonNode, String, int)
    • message

      public final com.fasterxml.jackson.databind.node.ObjectNode message​(@Nonnull String type, @Nonnull com.fasterxml.jackson.databind.JsonNode data, int id)
      Create a message node without an explicit method.
      Parameters:
      type - the message type
      data - the message data
      id - the message id provided by the client or its additive inverse
      Returns:
      a message node without a method property; an id property is only present if id is greater than zero
      See Also:
      message(ArrayNode, int), message(String, JsonNode, String, int), message(ObjectMapper, ArrayNode, String, int), message(ObjectMapper, String, JsonNode, String, int)
    • message

      public final com.fasterxml.jackson.databind.node.ObjectNode message​(@Nonnull String type, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @CheckForNull String method, int id)
      Create a message node.
      Parameters:
      type - the message type
      data - the message data
      method - the message method
      id - the message id provided by the client or its additive inverse
      Returns:
      a message node; an id proper
      See Also:
      message(ArrayNode, int), message(String, JsonNode, int), message(ObjectMapper, ArrayNode, String, int), message(ObjectMapper, String, JsonNode, String, int)
    • message

      public static final com.fasterxml.jackson.databind.JsonNode message​(@Nonnull com.fasterxml.jackson.databind.ObjectMapper mapper, @Nonnull com.fasterxml.jackson.databind.node.ArrayNode data, @CheckForNull String method, int id)
      Create a message node from an array.
      Parameters:
      mapper - the ObjectMapper to use to construct the message
      data - the array
      method - the message method
      id - the message id provided by the client or its additive inverse
      Returns:
      if id is a positive, non-zero integer, return a message of type "list" with data as the data and id set; otherwise just return data without modification
      See Also:
      message(ArrayNode, int), message(String, JsonNode, String, int), message(String, JsonNode, int), message(ObjectMapper, String, JsonNode, String, int)
    • message

      public static final com.fasterxml.jackson.databind.node.ObjectNode message​(@Nonnull com.fasterxml.jackson.databind.ObjectMapper mapper, @Nonnull String type, @Nonnull com.fasterxml.jackson.databind.JsonNode data, @CheckForNull String method, int id)
      Create a message node.
      Parameters:
      mapper - the ObjectMapper to use to construct the message
      type - the message type
      data - the message data
      method - the message method or null
      id - the message id provided by the client or its additive inverse
      Returns:
      a message node; if method is null, no method property is included; if id is not greater than zero, no id property is included
      See Also:
      message(ArrayNode, int), message(String, JsonNode, String, int), message(String, JsonNode, int), message(ObjectMapper, ArrayNode, String, int)