/** ******************************************************************************** */
  private void assertContentItem(String data, String mimeTypeRawData, String expectedFileSuffix)
      throws Exception {
    // Simulates what ContentFrameworkImpl would do
    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
    ContentItem contentItem =
        new IncomingContentItem(uuid, IOUtils.toInputStream(data), mimeTypeRawData);
    CreateRequest createRequest = new CreateRequestImpl(contentItem, null);
    CreateResponse createResponse = provider.create(createRequest);
    ContentItem createdContentItem = createResponse.getCreatedContentItem();

    assertNotNull(createdContentItem);
    String id = createdContentItem.getId();
    assertNotNull(id);
    assertThat(id, equalTo(uuid));

    String contentUri = createdContentItem.getUri();
    LOGGER.debug("contentUri = {}", contentUri);
    assertNotNull(contentUri);
    String expectedContentUri = FileSystemProvider.CONTENT_URI_PREFIX + uuid;
    assertThat(contentUri, equalTo(expectedContentUri));

    File file = createdContentItem.getFile();
    assertNotNull(file);
    assertTrue(file.exists());
    assertTrue(createdContentItem.getSize() > 0);
    assertEquals(mimeTypeRawData, createdContentItem.getMimeTypeRawData());
    assertEquals(data, IOUtils.toString(createdContentItem.getInputStream()));
  }
  @Test
  public void testDelete() throws Exception {
    CreateResponse createResponse =
        storeContentItem(TEST_INPUT_CONTENTS, NITF_MIME_TYPE, TEST_INPUT_FILENAME);
    String id = createResponse.getCreatedContentItem().getId();
    DeleteRequest deleteRequest = new DeleteRequestImpl(createResponse.getCreatedContentItem());

    DeleteResponse deleteResponse = provider.delete(deleteRequest);
    ContentItem item = deleteResponse.getContentItem();

    LOGGER.debug("Item retrieved: {}", item);
    assertEquals(id, item.getId());
    assertEquals(NITF_MIME_TYPE, item.getMimeTypeRawData());
    assertNull(item.getFile());
  }
  @Test
  public void testRead() throws Exception {
    CreateResponse createResponse =
        storeContentItem(TEST_INPUT_CONTENTS, NITF_MIME_TYPE, TEST_INPUT_FILENAME);
    String id = createResponse.getCreatedContentItem().getId();
    ReadRequest readRequest = new ReadRequestImpl(id, null);

    ReadResponse readResponse = provider.read(readRequest);
    ContentItem item = readResponse.getContentItem();

    LOGGER.debug("Item retrieved: {}", item);
    assertEquals(id, item.getId());
    assertEquals(NITF_MIME_TYPE, item.getMimeTypeRawData());

    String expectedFilePath = BASE_DIR + File.separator + id + File.separator + item.getFilename();
    assertThat(item.getFile().getAbsolutePath(), endsWith(expectedFilePath));
    assertTrue(item.getSize() > 0);
    assertTrue(item.getFile().exists());
  }
  protected ContentItem getMockGoodContentItem(
      String content, String fileName, String contentId, Long size, String mimeType)
      throws IOException, MimeTypeParseException {
    ContentItem item = mock(ContentItem.class);
    when(item.getInputStream()).thenReturn(new ByteArrayInputStream(content.getBytes()));
    when(item.getFilename()).thenReturn(fileName);
    when(item.getId()).thenReturn(contentId);
    if (size != null) {
      when(item.getSize()).thenReturn(size);
    } else {
      when(item.getSize()).thenThrow(new IOException("IOException"));
    }
    when(item.getMimeTypeRawData()).thenReturn(mimeType);
    if (mimeType != null) {
      when(item.getMimeType()).thenReturn(new MimeType(mimeType));
    }

    return item;
  }
  @Test
  public void testUpdate() throws Exception {
    CreateResponse createResponse =
        storeContentItem(TEST_INPUT_CONTENTS, NITF_MIME_TYPE, TEST_INPUT_FILENAME);
    String id = createResponse.getCreatedContentItem().getId();
    ContentItem updateItem =
        new IncomingContentItem(id, IOUtils.toInputStream("Updated NITF"), NITF_MIME_TYPE);
    UpdateRequest updateRequest = new UpdateRequestImpl(updateItem);

    UpdateResponse updateResponse = provider.update(updateRequest);
    ContentItem item = updateResponse.getUpdatedContentItem();

    LOGGER.debug("Item retrieved: {}", item);
    assertEquals(id, item.getId());
    assertEquals(NITF_MIME_TYPE, item.getMimeTypeRawData());

    String expectedFilePath = BASE_DIR + File.separator + id + File.separator + item.getFilename();
    assertThat(item.getFile().getAbsolutePath(), endsWith(expectedFilePath));
    assertTrue(item.getSize() > 0);
    assertTrue(item.getFile().exists());

    String updatedFileContents = getFileContentsAsString(item.getFile().getAbsolutePath());
    assertEquals("Updated NITF", updatedFileContents);
  }
  @Override
  public UpdateResponse update(final UpdateRequest updateRequest, Request.Directive directive)
      throws ContentFrameworkException {
    logger.trace("ENTERING: update");

    UpdateResponse updateResponse = null;

    // If directive includes processing and there are no ContentPlugins currently installed to
    // support processing, then throw an exception. (Do not want to do the STORE and get the
    // content repository out of sync with the Metadata Catalog.)
    if ((directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS)
        && (this.contentPlugins.size() == 0)) {
      throw new ContentFrameworkException(
          "Unable to perform " + directive + " because no ContentPlugins are installed.");
    }

    ContentItem itemToUpdate = updateRequest.getContentItem();

    if (directive == Directive.STORE || directive == Directive.STORE_AND_PROCESS) {
      // Verify content item exists in content repository before trying to update it
      try {
        ReadRequest readRequest = new ReadRequestImpl(updateRequest.getContentItem().getId(), null);
        this.provider.read(readRequest);
      } catch (StorageException e) {
        logger.info("File does not exist, cannot update, doing a create: ", e);
        throw new ContentFrameworkException(
            "File does not exist, cannot update, doing a create: ", e);
      } catch (Exception e) {
        logger.warn("Content Provider error during update", e);
        throw new ContentFrameworkException(
            "Unable to perform update because no content storage provider is installed or there is a problem with the content storage provider.",
            e);
      }

      logger.info("Updating content repository for content item: " + itemToUpdate.getId());
      try {
        updateResponse = this.provider.update(updateRequest);
        try {
          logger.debug(
              "updated item file length = " + updateResponse.getUpdatedContentItem().getSize());
        } catch (IOException ioe) {
        }
      } catch (StorageException e) {
        throw new ContentFrameworkException(e);
      } catch (Exception e) {
        logger.warn("Content Provider error during update", e);
        throw new ContentFrameworkException(
            "Unable to perform update because no content storage provider is installed or there is a problem with the content storage provider.",
            e);
      }
    }

    if (directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS) {
      if (directive == Directive.PROCESS) {
        // No content update occurred to return an UpdateResponse. So need to
        // instantiate an UpdateResponse with the original UpdateRequest's ContentItem
        // in it.
        if (updateResponse == null) {
          updateResponse = new UpdateResponseImpl(updateRequest, updateRequest.getContentItem());
        }
      }

      // Execute each ContentPlugin on the content item. If any plugin fails, then
      // assume the entire transaction fails, rolling back the storage of the content
      // item in the content repository (if applicable)
      try {
        for (final ContentPlugin plugin : contentPlugins) {
          updateResponse = plugin.process(updateResponse);
        }
      } catch (PluginExecutionException e) {

        logger.info("Content Plugin processing failed.", e);

        // Re-throw the exception (this will fail the Camel route that may have
        // started this request)
        throw new ContentFrameworkException(
            "Content Plugin processing failed. " + e.getMessage(), e);
      }
    }

    logger.trace("EXITING: update");

    return updateResponse;
  }