Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • retrieving form metadata
  • saving form data
  • retrieving saved record ID of form data
  • retrieving form data
  • updating form data and 
  • deleting the form data

The program is written using Java and Spring REST framework. Developers OpenSpecimen integration developers are free to choose language and tools of their choice.

Code Block

public class TestFormApis {
   //
   // this can be a configuration setting. For illustration purpose, API base URL is hardcoded
   //
   private static final String API_BASE_URL = "http://myopenspecimenserver.com/openspecimen/rest/ng";

   private static RestTemplate template = new RestTemplate();

   //
   // Input specimen ID and this program will add destruction date, method and remove it.
   //
   public static void main(String[] args)
   throws Exception {
      if (args.length == 0) {
         return;
      }


      //
      // Step 0: Input specimen ID could come from any source.
      // In this example, specimen ID is picked from command line arguments
      //
      Long specimenId = Long.parseLong(args[0]);

      //
      // Step 1: Login and get an authentication token for use in subsequent API calls
      //
      String token = login();

      //
      // Step 2: Retrieve form metadata
      //
      Map<String, Object> formMetadata = getFormMetadata(token, "Specimen", specimenId, "Specimen Destruction Details");
      if (formMetadata == null) {
         // No form with name "Specimen Destruction Details" attached at Specimen level
         return;
      }

      //
      // Step 3: Save form data
      //
      Long recordId = saveFormData(token, specimenId, formMetadata);
       //
      // Step 4: Retrieve form dataSystem.out.println("Successfully saved form record: " + recordId);
      //
      // recordId can be used to maintain Map<String,a Object>mapping formDatabetween = getFormData(token, recordId, formMetadata);
      your data and OpenSpecimen form record
      // this mapping can be subsequently used for //updating useform therecord formwithout dataresorting fieldsto forstep processing4.
      //
destructionDate and destructionMethod are field names
      //
      System.out.println(formData.get("destructionDate"));  
      System.out.println(formData.get("destructionMethod"));// Step 4: Retrieve form record ID
       //
      //recordId Step 5: Delete form data
      //
      deleteFormData(token, recordId= getRecordId(token, "Specimen", specimenId, formMetadata);

      //
      // Step 65: Retrieve form logoutdata
      //
      logout(token);
   }
Map<String, Object> formData = getFormData(token, recordId, formMetadata);
   private static String login() {
     System.out.println(formData.get("destructionDate"));  // use the form data fields for //processing
username and password could be fetched from client configuration database System.out.println(formData.get("destructionMethod"));

      //
      Map<String,// Object>Step payload6: =Update new HashMap<>();form data
      payload.put("loginName", "admin@admin.com");//
       payload.put("password", "Login420");updateFormData(token, recordId, formData);

      //
  Map<String, Object> resp = template.postForObject(getUrl("/sessions"), payload, Map.class);
  // Step 7: Delete form data
    return (String) resp.get("token"); //
   }   deleteFormData(token, recordId, privateformMetadata);
static
void logout(String token) {   //
   invokeApi(HttpMethod.DELETE, "/sessions", token, null, Map.class);
   }// Step 8: logout
      //
 private  static Map<String, Object> getFormMetadata(String token, String entityType, Long objectId, String formName)
   throws Exception {
 logout(token);
   }

   private static String login() {
      //
    String uri =// null;username and password could be fetched from if (entityType.equals("Specimen")) {
   your client configuration database
     uri = "/specimens/" +
objectId + "/forms";     Map<String, Object> }payload else= ifnew HashMap<>(entityType.equals("Visit")) {);
          uri = "/visits/" + objectId + "/forms"payload.put("loginName", "admin@admin.com");
      } else if (entityType.equals("CollectionProtocolRegistration")) {payload.put("password", "Login420");
      Map<String, Object>  resp uri = "/collection-protocol-registrations/" + objectId + "/forms"template.postForObject(getUrl("/sessions"), payload, Map.class);
      }return else {(String) resp.get("token");
   }

   private throwstatic newvoid IllegalArgumentExceptionlogout("Invalid entity type: " + entityType);
      }

 String token) {
    Map[] forms = invokeApi(HttpMethod.GETDELETE, uri"/sessions", token, null, Map[].class);
      for (Map form : forms) {
 template.exchange(getUrl("/sessions"), HttpMethod.DELETE, getHttpEntity(token), Map.class);
   }

   private static Map<String, ifObject> (Objects.equals(form.get("formCaption"), formName)) {
    getFormMetadata(String token, String entityType, Long objectId, String formName)
   throws Exception {
      String returnuri = formnull;
      if (entityType.equals("Specimen")) {
  }       }uri = "/specimens/" + objectId + "/forms";
 return null;    } else if (entityType.equals("Visit")) {
private static Long saveFormData(String token, Long specimenId, Map<String, Object> formMetadata) {
        uri = "/visits/" + objectId + "/forms";
    Map<String, Object> appData} =else new HashMap<>();if (entityType.equals("CollectionProtocolRegistration")) {
       appData.put("useUdn",     true); // to let API know we use human readable field names instead of cryptic ones  uri = "/collection-protocol-registrations/" + objectId + "/forms";
      } else {
         throw new appData.putIllegalArgumentException("formCtxtId", formMetadata.get("formCtxtId")Invalid entity type: " + entityType);
      appData.put("objectId",   specimenId);}

       Calendar calMap[] forms = Calendar.getInstance();
      cal.set(2020, 12, 31);invokeApi(HttpMethod.GET, uri, token, null, Map[].class);
      for long(Map destructionDateform = cal.getTimeInMillis();
: forms) {
      Map<String, Object> formData = new HashMap<>();
 if (Objects.equals(form.get("formCaption"), formName)) {
            formData.put("appData", appData);return form;
        // }
     // form}
field
values      return //null;
   }

 formData.put("destructionDate", destructionDate); private static Long saveFormData(String token,  formData.put("destructionMethod", "Cremation"Long specimenId, Map<String, Object> formMetadata) {
      Map<String, Object> appData = new HashMap<>();
      appData.put("useUdn",     true); // to let API know we use human readable field names instead of cryptic ones
      appData.put("formCtxtId", formMetadata.get("formCtxtId"));
      appData.put("objectId",   specimenId);

      Calendar cal = Calendar.getInstance();
      cal.set(2020, 12, 31);
      long destructionDate = cal.getTimeInMillis();

      Map<String, Object> formData = new HashMap<>();
      formData.put("appData", appData);

      //
      // form field values
      //
      formData.put("destructionDate", destructionDate);
      formData.put("destructionMethod", "Cremation");

      Number formId = (Number)formMetadata.get("formId");
      String uri = "/forms/" + formId + "/data";
      Map savedData = invokeApi(HttpMethod.POST, uri, token, formData, Map.class);

      //
      // return record ID on saving form data
      //
      return ((Number)savedData.get("id")).longValue();
   }

   private static Long updateFormData(String token, Long recordId, Map<String, Object> formData) {
      formData.put("recordId", recordId);
      formData.put("destructionMethod", "Not Specified");

      Number formId = (Long)formData.get("containerId");
      String uri = "/forms/" + formId + "/data/" + recordId;
      Map savedData = invokeApi(HttpMethod.PUT, uri, token, formData, Map.class);
      return ((Number)savedData.get("id")).longValue();
   }

   private static Long getRecordId(String token, String entityType, Long objectId, Map<String, Object> formMetadata) {
      String uri = "";
      if (entityType.equals("Specimen")) {
         uri = "/specimens/";
      } else if (entityType.equals("Visit")) {
         uri = "/visits/";
      } else if (entityType.equals("CollectionProtocolRegistration")) {
         uri = "/collection-protocol-registrations/";
      } else {
         throw new IllegalArgumentException("Invalid entity type: " + entityType);
      }

      Long formCtxtId = (Long) formMetadata.get("formCtxtId");
      uri = String.format(uri + "%d/forms/%d/records", objectId, formCtxtId);
      Map<String, Object> entityRecs = invokeApi(HttpMethod.GET, uri, token, null, Map.class);
      Map<String, NumberObject>[] formIdrecords = (Number)formMetadataMap<String, Object>[])entityRecs.get("formIdrecords");

      if (records == null || records.length String== uri0) ={
"/forms/" + formId + "/data";     return null;
Map savedData = invokeApi(HttpMethod.POST, uri, token, formData, Map.class);}

      return ((Number)savedDataLong)records[0].get("idrecordId")).longValue();
   }

   private static Map<String, Object> getFormData(String token, Long recordId, Map<String, Object> formMetadata) {
      Number formId = (Number)formMetadata.get("formId");
      String uri = "/forms/" + formId + "/data/" + recordId;
      return (Map<String, Object>)invokeApi(HttpMethod.GET, uri, token, null, Map.class);
   }

   private static void deleteFormData(String token, Long recordId, Map<String, Object> formMetadata) {
      Number formId = (Number)formMetadata.get("formId");
      String uri = "/forms/" + formId + "/data/" + recordId;
      invokeApi(HttpMethod.DELETE, uri, token, null, Long.class);
   }

   private static <T> T invokeApi(HttpMethod httpMethod, String uri, String token, Object body, Class<T> returnType) {
      ResponseEntity<T> resp = template.exchange(getUrl(uri), httpMethod, getHttpEntity(token, body), returnType);
      if (resp.getStatusCode() == HttpStatus.OK) {
         return resp.getBody();
      }

      //
      // Handle API failures
      //
      throw new RuntimeException("Error invoking API: " + uri);
   }

   private static HttpEntity<?> getHttpEntity(String token) {
      return getHttpEntity(token, null);
   }

   private static HttpEntity<?> getHttpEntity(String token, Object body) {
      HttpHeaders headers = new HttpHeaders();
      headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
      headers.set("X-OS-API-TOKEN", token); // API auth token header
      return new HttpEntity<>(body, headers);
   }

   private static String getUrl(String uri) {
      return API_BASE_URL + uri;
   }
}