private void injectAccountAndContainerForPostAndVerify(Container container, boolean shouldAllowServiceIdBasedPut)
      throws Exception {
    configProps.setProperty("frontend.allow.service.id.based.post.request",
        String.valueOf(shouldAllowServiceIdBasedPut));
    verifiableProperties = new VerifiableProperties(configProps);
    frontendConfig = new FrontendConfig(verifiableProperties);
    accountAndContainerInjector = new AccountAndContainerInjector(accountService, frontendMetrics, frontendConfig);
    frontendRestRequestService = getFrontendRestRequestService();
    frontendRestRequestService.start();
    populateAccountService();

    // should succeed when serviceId-based PUT requests are allowed.
    postBlobAndVerifyWithAccountAndContainer(null, null, "serviceId", !container.isCacheable(),
        shouldAllowServiceIdBasedPut ? InMemAccountService.UNKNOWN_ACCOUNT : null,
        shouldAllowServiceIdBasedPut ? (container.isCacheable() ? Container.DEFAULT_PUBLIC_CONTAINER
            : Container.DEFAULT_PRIVATE_CONTAINER) : null,
        shouldAllowServiceIdBasedPut ? null : RestServiceErrorCode.BadRequest);

    // should fail, because accountName needs to be specified.
    postBlobAndVerifyWithAccountAndContainer(null, "dummyContainerName", "serviceId", !container.isCacheable(), null,
        null, RestServiceErrorCode.MissingArgs);

    // should fail, because account name from serviceId could not be located in account service.
    postBlobAndVerifyWithAccountAndContainer(null, Container.UNKNOWN_CONTAINER_NAME, "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidContainer);

    // should fail, because accountName needs to be specified.
    postBlobAndVerifyWithAccountAndContainer(null, refContainer.getName(), "serviceId", !container.isCacheable(), null,
        null, RestServiceErrorCode.MissingArgs);

    // should fail, because accountName is not allowed.
    postBlobAndVerifyWithAccountAndContainer(Account.UNKNOWN_ACCOUNT_NAME, null, "serviceId", !container.isCacheable(),
        null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because accountName is not allowed.
    postBlobAndVerifyWithAccountAndContainer(Account.UNKNOWN_ACCOUNT_NAME, "dummyContainerName", "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because accountName is not allowed.
    postBlobAndVerifyWithAccountAndContainer(Account.UNKNOWN_ACCOUNT_NAME, Container.UNKNOWN_CONTAINER_NAME,
        "serviceId", !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because accountName is not allowed.
    postBlobAndVerifyWithAccountAndContainer(Account.UNKNOWN_ACCOUNT_NAME, refContainer.getName(), "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because container name needs to be specified
    postBlobAndVerifyWithAccountAndContainer(refAccount.getName(), null, "serviceId", !container.isCacheable(), null,
        null, RestServiceErrorCode.MissingArgs);

    // should fail, because containerName does not exist.
    postBlobAndVerifyWithAccountAndContainer(refAccount.getName(), "dummyContainerName", "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidContainer);

    // should fail, because containerName is not allowed.
    postBlobAndVerifyWithAccountAndContainer(refAccount.getName(), Container.UNKNOWN_CONTAINER_NAME, "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidContainer);

    // should succeed.
    String blobIdStr =
        postBlobAndVerifyWithAccountAndContainer(refAccount.getName(), refContainer.getName(), "serviceId",
            !container.isCacheable(), refAccount, refContainer, null);
    // should succeed.
    verifyAccountAndContainerFromBlobId(blobIdStr, refAccount, refContainer, null);

    // should fail, because containerName needs to be specified.
    postBlobAndVerifyWithAccountAndContainer("dummyAccountName", null, "serviceId", !container.isCacheable(), null,
        null, RestServiceErrorCode.MissingArgs);

    // should fail, because accountName does not exist.
    postBlobAndVerifyWithAccountAndContainer("dummyAccountName", "dummyContainerName", "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because container name is now allowed.
    postBlobAndVerifyWithAccountAndContainer("dummyAccountName", Container.UNKNOWN_CONTAINER_NAME, "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidContainer);

    // should fail, because accountName does not exist.
    postBlobAndVerifyWithAccountAndContainer("dummyAccountName", refContainer.getName(), "serviceId",
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because accountName implicitly set by serviceId is not allowed.
    postBlobAndVerifyWithAccountAndContainer(null, null, Account.UNKNOWN_ACCOUNT_NAME, !container.isCacheable(), null,
        null, RestServiceErrorCode.InvalidAccount);

    // should fail, because accountName implicitly set by serviceId is not allowed.
    postBlobAndVerifyWithAccountAndContainer(null, "dummyContainerName", Account.UNKNOWN_ACCOUNT_NAME,
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because accountName implicitly set by serviceId is not allowed.
    postBlobAndVerifyWithAccountAndContainer(null, Container.UNKNOWN_CONTAINER_NAME, Account.UNKNOWN_ACCOUNT_NAME,
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should fail, because accountName implicitly set by serviceId is not allowed.
    postBlobAndVerifyWithAccountAndContainer(null, refContainer.getName(), Account.UNKNOWN_ACCOUNT_NAME,
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidAccount);

    // should succeed if the serviceId-based PUT requests are allowed, but this is a special case that account is
    // created without the legacy containers for public and private put.
    postBlobAndVerifyWithAccountAndContainer(null, null, refAccount.getName(), !container.isCacheable(),
        shouldAllowServiceIdBasedPut ? refAccount : null,
        shouldAllowServiceIdBasedPut ? (container.isCacheable() ? refDefaultPublicContainer
            : refDefaultPrivateContainer) : null,
        shouldAllowServiceIdBasedPut ? null : RestServiceErrorCode.BadRequest);

    // should fail, because accountName needs to be specified.
    postBlobAndVerifyWithAccountAndContainer(null, "dummyContainerName", refAccount.getName(), !container.isCacheable(),
        null, null, RestServiceErrorCode.MissingArgs);

    // should fail, because accountName implicitly set by serviceId does not have the default container.
    postBlobAndVerifyWithAccountAndContainer(null, Container.UNKNOWN_CONTAINER_NAME, refAccount.getName(),
        !container.isCacheable(), null, null, RestServiceErrorCode.InvalidContainer);

    // should fail, because accountName needs to be specified.
    postBlobAndVerifyWithAccountAndContainer(null, refContainer.getName(), refAccount.getName(),
        !container.isCacheable(), null, null, RestServiceErrorCode.MissingArgs);

    Container legacyContainerForPublicBlob =
        new ContainerBuilder(Container.DEFAULT_PUBLIC_CONTAINER_ID, "containerForLegacyPublicPut",
            Container.ContainerStatus.ACTIVE, "This is a container for putting legacy public blob",
            refAccount.getId()).build();
    Container legacyContainerForPrivateBlob =
        new ContainerBuilder(Container.DEFAULT_PRIVATE_CONTAINER_ID, "containerForLegacyPrivatePut",
            Container.ContainerStatus.ACTIVE, "This is a container for putting legacy private blob",
            refAccount.getId()).setCacheable(false).build();
    Account accountWithTwoDefaultContainers =
        new AccountBuilder(refAccount).addOrUpdateContainer(legacyContainerForPrivateBlob)
            .addOrUpdateContainer(legacyContainerForPublicBlob)
            .build();
    accountService.updateAccounts(Collections.singletonList(accountWithTwoDefaultContainers));
    if (!container.isCacheable()) {
      // should succeed if serviceId-based PUT requests are allowed.
      postBlobAndVerifyWithAccountAndContainer(null, null, accountWithTwoDefaultContainers.getName(),
          !container.isCacheable(), shouldAllowServiceIdBasedPut ? accountWithTwoDefaultContainers : null,
          shouldAllowServiceIdBasedPut ? accountWithTwoDefaultContainers.getContainerById(
              Container.DEFAULT_PRIVATE_CONTAINER_ID) : null,
          shouldAllowServiceIdBasedPut ? null : RestServiceErrorCode.BadRequest);
      // should fail, because accountName needs to be specified.
      postBlobAndVerifyWithAccountAndContainer(null, "dummyContainerName", accountWithTwoDefaultContainers.getName(),
          !container.isCacheable(), null, null, RestServiceErrorCode.MissingArgs);
    } else {
      // should succeed if serviceId-based PUT requests are allowed.
      postBlobAndVerifyWithAccountAndContainer(null, null, accountWithTwoDefaultContainers.getName(),
          !container.isCacheable(), shouldAllowServiceIdBasedPut ? accountWithTwoDefaultContainers : null,
          shouldAllowServiceIdBasedPut ? accountWithTwoDefaultContainers.getContainerById(
              Container.DEFAULT_PUBLIC_CONTAINER_ID) : null,
          shouldAllowServiceIdBasedPut ? null : RestServiceErrorCode.BadRequest);
      // should fail, because accountName needs to be specified.
      postBlobAndVerifyWithAccountAndContainer(null, "dummyContainerName", accountWithTwoDefaultContainers.getName(),
          !container.isCacheable(), null, null, RestServiceErrorCode.MissingArgs);
    }
  }
Puts blobs and verify injected target {@link Account} and {@link Container}.
@param container the {@link Container} to use.
@param shouldAllowServiceIdBasedPut {@code true} if PUT requests with serviceId parsed as {@link Account} name is
                                                allowed; {@code false} otherwise.
@throws Exception
ambry-frontend/src/test/java/com/github/ambry/frontend/FrontendRestRequestServiceTest.java