@Test
  public void testContainerFetchOnDemand() throws Exception {
    MySqlAccountService producerAccountService = mySqlAccountService;
    // Create second account service with scheduled polling disabled
    mySqlConfigProps.setProperty(UPDATER_POLLING_INTERVAL_SECONDS, "0");
    accountServiceConfig = new MySqlAccountServiceConfig(new VerifiableProperties(mySqlConfigProps));
    MySqlAccountStore consumerAccountStore =
        spy(new MySqlAccountStoreFactory(new VerifiableProperties(mySqlConfigProps),
            new MetricRegistry()).getMySqlAccountStore());
    MySqlAccountStoreFactory mockMySqlAccountStoreFactory = mock(MySqlAccountStoreFactory.class);
    when(mockMySqlAccountStoreFactory.getMySqlAccountStore()).thenReturn(consumerAccountStore);
    AccountServiceMetricsWrapper accountServiceMetricsWrapper = new AccountServiceMetricsWrapper(new MetricRegistry());
    // Note: for these tests, consumer must NOT be notified of changes
    MySqlAccountService consumerAccountService =
        new MySqlAccountService(accountServiceMetricsWrapper, accountServiceConfig, mockMySqlAccountStoreFactory, null);

    // Add new account "a1" on producer account service
    short accountId = 101;
    String accountName = "a1";
    int onDemandContainerFetchCount = 0;
    Container container = new ContainerBuilder((short) 1, "c1", ContainerStatus.ACTIVE, DESCRIPTION, accountId).build();
    Account account = new AccountBuilder(accountId, accountName, Account.AccountStatus.ACTIVE).containers(
        Collections.singletonList(container)).build();
    producerAccountService.updateAccounts(Collections.singletonList(account));

    // Test getContainer on consumer account service should fail since account doesn't exist
    assertNull("Expected null since Account doesn't exist in consumerAccountService cache",
        consumerAccountService.getContainerByName(accountName, "c1"));
    assertNull("Expected null since Account doesn't exist in consumerAccountService cache",
        consumerAccountService.getContainerById(accountId, (short) 1));

    // Fetch and update cache in consumer account service
    consumerAccountService.fetchAndUpdateCache();
    assertEquals("Account mismatch", account, consumerAccountService.getAccountByName(accountName));
    assertEquals("Container mismatch", container, consumerAccountService.getContainerByName(accountName, "c1"));
    assertEquals("Container mismatch", container, consumerAccountService.getContainerById(accountId, (short) 1));

    // Add new container in producer account service
    producerAccountService.updateContainers(accountName, Collections.singletonList(
        new ContainerBuilder((short) -1, "c2", ContainerStatus.ACTIVE, DESCRIPTION, accountId).build()));
    Container newContainer = producerAccountService.getContainerByName(accountName, "c2");

    // Test getContainerByName() on consumer account service is successful (by fetching from mysql on demand)
    assertEquals("getContainerByName() expected to fetch container from MySql db", newContainer,
        consumerAccountService.getContainerByName(accountName, "c2"));
    verify(consumerAccountStore).getContainerByName(eq((int) accountId), eq(newContainer.getName()));
    assertEquals("Number of on-demand container requests should be 1", ++onDemandContainerFetchCount,
        accountServiceMetricsWrapper.getAccountServiceMetrics().onDemandContainerFetchCount.getCount());

    // verify in-memory cache is updated with the fetched container "c2"
    assertEquals("Container c2 should be present in consumer account service", newContainer,
        consumerAccountService.getAccountByName(accountName).getContainerByName(newContainer.getName()));

    // Add new container in producer account service
    producerAccountService.updateContainers(accountName, Collections.singletonList(
        new ContainerBuilder((short) -1, "c3", ContainerStatus.ACTIVE, DESCRIPTION, accountId).build()));
    newContainer = producerAccountService.getContainerById(accountId, (short) 3);

    // Test getContainerById() on consumer account service is successful (by fetching from mysql on demand)
    assertEquals("getContainerById() expected to fetch container from MySql db", newContainer,
        consumerAccountService.getContainerById(accountId, (short) 3));
    verify(consumerAccountStore).getContainerById(eq((int) accountId), eq((int) newContainer.getId()));
    assertEquals("Number of on-demand container requests should be 2", ++onDemandContainerFetchCount,
        accountServiceMetricsWrapper.getAccountServiceMetrics().onDemandContainerFetchCount.getCount());

    // verify in-memory cache is updated with the fetched container "c3"
    assertEquals("Container c3 should be present in consumer account service", newContainer,
        consumerAccountService.getAccountByName(accountName).getContainerById(newContainer.getId()));
  }
Container on-demand fetch for multiple account services.
ambry-account/src/integration-test/java/com/github/ambry/account/MySqlAccountServiceIntegrationTest.java