Search in sources :

Example 11 with ZNRecord

use of org.apache.helix.zookeeper.datamodel.ZNRecord in project ambry by linkedin.

the class HelixAccountServiceTest method testReadBadZNRecordCase3.

/**
 * Tests reading {@link ZNRecord} from {@link HelixPropertyStore}, where the {@link ZNRecord} has a map field
 * ("key": someValidAccountMap), but ({@link LegacyMetadataStore#ACCOUNT_METADATA_MAP_KEY}: someValidMap)
 * is missing. This is a good {@link ZNRecord} format that should NOT fail fetch or update.
 * @throws Exception Any unexpected exception.
 */
@Test
public void testReadBadZNRecordCase3() throws Exception {
    Map<String, String> mapValue = new HashMap<>();
    mapValue.put(String.valueOf(refAccount.getId()), objectMapper.writeValueAsString(new AccountBuilder(refAccount).snapshotVersion(refAccount.getSnapshotVersion() + 1).build()));
    ZNRecord zNRecord = makeZNRecordWithMapField(null, "key", mapValue);
    updateAndWriteZNRecord(zNRecord, true);
}
Also used : HashMap(java.util.HashMap) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord) Test(org.junit.Test)

Example 12 with ZNRecord

use of org.apache.helix.zookeeper.datamodel.ZNRecord in project ambry by linkedin.

the class HelixAccountServiceTest method testReadBadZNRecordCase8.

/**
 * Tests reading {@link ZNRecord} from {@link HelixPropertyStore} and ambry, where the ambry has valid accounts
 * record but {@link ZNRecord} has an invalid list item and a valid list item. This is a NOT good {@link ZNRecord}
 * format and it should fail fetch or update operations, with none of the record should be read.
 * @throws Exception Any unexpected exception.
 */
@Test
public void testReadBadZNRecordCase8() throws Exception {
    if (!useNewZNodePath) {
        return;
    }
    ZNRecord zNRecord = new ZNRecord(String.valueOf(System.currentTimeMillis()));
    Map<String, String> accountMap = new HashMap<>();
    accountMap.put(String.valueOf(refAccount.getId()), objectMapper.writeValueAsString(new AccountBuilder(refAccount).snapshotVersion(refAccount.getSnapshotVersion() + 1).build()));
    String blobID = RouterStore.writeAccountMapToRouter(accountMap, mockRouter);
    List<String> list = new ArrayList<>();
    list.add("badliststring");
    list.add(new RouterStore.BlobIDAndVersion(blobID, 1).toJson());
    zNRecord.setListField(RouterStore.ACCOUNT_METADATA_BLOB_IDS_LIST_KEY, list);
    updateAndWriteZNRecord(zNRecord, false);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord) Test(org.junit.Test)

Example 13 with ZNRecord

use of org.apache.helix.zookeeper.datamodel.ZNRecord in project ambry by linkedin.

the class AccountMetadataStore method fetchAccountMetadata.

/**
 * fetchAccountMetadata would fetch the latest full set of {@link Account} metadata from the store. It returns null
 * when there is no {@link Account} created.
 * @return A collection of {@link Account} metadata.
 */
Collection<Account> fetchAccountMetadata() {
    long startTimeMs = System.currentTimeMillis();
    logger.trace("Start reading ZNRecord from path={}", znRecordPath);
    Stat stat = new Stat();
    ZNRecord znRecord = helixStore.get(znRecordPath, stat, AccessOption.PERSISTENT);
    long helixFetchTime = System.currentTimeMillis() - startTimeMs;
    accountServiceMetrics.fetchRemoteAccountTimeInMs.update(helixFetchTime);
    logger.trace("Fetched ZNRecord from path={}, took time={} ms", znRecordPath, helixFetchTime);
    if (znRecord == null) {
        logger.info("The ZNRecord to read does not exist on path={}", znRecordPath);
        return null;
    }
    Map<String, String> newAccountMap = fetchAccountMetadataFromZNRecord(znRecord);
    Map<Short, Account> idToAccountMap = new HashMap<>();
    Map<String, Account> nameToAccountMap = new HashMap<>();
    for (Map.Entry<String, String> entry : newAccountMap.entrySet()) {
        String idKey = entry.getKey();
        if (idKey == null) {
            accountServiceMetrics.remoteDataCorruptionErrorCount.inc();
            throw new IllegalStateException("Invalid account record when reading accountMap because idKey=null");
        }
        String valueString = entry.getValue();
        Account account;
        try {
            account = objectMapper.readValue(valueString, Account.class);
        } catch (JsonProcessingException e) {
            logger.error("Failed to deserialize {} to an Account object", valueString, e);
            throw new RuntimeException(e);
        }
        if (account.getId() != Short.parseShort(idKey)) {
            accountServiceMetrics.remoteDataCorruptionErrorCount.inc();
            throw new IllegalStateException("Invalid account record when reading accountMap because idKey and accountId do not match. idKey=" + idKey + " accountId=" + account.getId());
        }
        if (idToAccountMap.containsKey(account.getId()) || nameToAccountMap.containsKey(account.getName())) {
            throw new IllegalStateException("Duplicate account id or name exists. id=" + account.getId() + " name=" + account.getName());
        }
        idToAccountMap.put(account.getId(), account);
        nameToAccountMap.put(account.getName(), account);
    }
    if (newAccountMap != null) {
        backupFileManager.persistAccountMap(idToAccountMap.values(), stat.getVersion(), stat.getMtime() / 1000);
    }
    return idToAccountMap.values();
}
Also used : HashMap(java.util.HashMap) Stat(org.apache.zookeeper.data.Stat) Map(java.util.Map) HashMap(java.util.HashMap) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord)

Example 14 with ZNRecord

use of org.apache.helix.zookeeper.datamodel.ZNRecord in project ambry by linkedin.

the class HelixAccountServiceFactory method getAccountService.

@Override
public AccountService getAccountService() {
    try {
        long startTimeMs = System.currentTimeMillis();
        logger.info("Starting a HelixAccountService");
        HelixPropertyStore<ZNRecord> helixStore = CommonUtils.createHelixPropertyStore(accountServiceConfig.zkClientConnectString, storeConfig, null);
        logger.info("HelixPropertyStore started with zkClientConnectString={}, zkClientSessionTimeoutMs={}, " + "zkClientConnectionTimeoutMs={}, rootPath={}", accountServiceConfig.zkClientConnectString, storeConfig.zkClientSessionTimeoutMs, storeConfig.zkClientConnectionTimeoutMs, storeConfig.rootPath);
        ScheduledExecutorService scheduler = accountServiceConfig.updaterPollingIntervalMs > 0 ? Utils.newScheduler(1, HELIX_ACCOUNT_UPDATER_PREFIX, false) : null;
        HelixAccountService helixAccountService = new HelixAccountService(helixStore, accountServiceMetrics, notifier, scheduler, accountServiceConfig);
        long spentTimeMs = System.currentTimeMillis() - startTimeMs;
        logger.info("HelixAccountService started, took {} ms", spentTimeMs);
        accountServiceMetrics.startupTimeInMs.update(spentTimeMs);
        return helixAccountService;
    } catch (Exception e) {
        throw new IllegalStateException("Could not instantiate HelixAccountService", e);
    }
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord)

Example 15 with ZNRecord

use of org.apache.helix.zookeeper.datamodel.ZNRecord in project ambry by linkedin.

the class RouterStore method fetchAllBlobIDAndVersions.

/**
 * Get the list of {@link BlobIDAndVersion} from {@link ZNRecord}. This function returns null when there
 * is any error.
 * @return list of {@link BlobIDAndVersion}.
 */
private List<BlobIDAndVersion> fetchAllBlobIDAndVersions() {
    if (router.get() == null) {
        logger.error("Router is not yet initialized");
        return null;
    }
    long startTimeMs = System.currentTimeMillis();
    logger.trace("Start reading ZNRecord from path={}", znRecordPath);
    Stat stat = new Stat();
    ZNRecord znRecord = helixStore.get(znRecordPath, stat, AccessOption.PERSISTENT);
    logger.trace("Fetched ZNRecord from path={}, took time={} ms", znRecordPath, System.currentTimeMillis() - startTimeMs);
    if (znRecord == null) {
        logger.info("The ZNRecord to read does not exist on path={}", znRecordPath);
        return null;
    }
    List<String> blobIDAndVersionsJson = znRecord.getListField(ACCOUNT_METADATA_BLOB_IDS_LIST_KEY);
    if (blobIDAndVersionsJson == null || blobIDAndVersionsJson.size() == 0) {
        logger.info("ZNRecord={} to read on path={} does not have a simple list with key={}", znRecord, ACCOUNT_METADATA_BLOB_IDS_PATH, ACCOUNT_METADATA_BLOB_IDS_LIST_KEY);
        return null;
    } else {
        return blobIDAndVersionsJson.stream().map(BlobIDAndVersion::fromJson).collect(Collectors.toList());
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord)

Aggregations

ZNRecord (org.apache.helix.zookeeper.datamodel.ZNRecord)37 HashMap (java.util.HashMap)19 Test (org.junit.Test)18 Map (java.util.Map)10 ArrayList (java.util.ArrayList)8 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)8 VerifiableProperties (com.github.ambry.config.VerifiableProperties)6 HashSet (java.util.HashSet)6 InstanceConfig (org.apache.helix.model.InstanceConfig)6 MetricRegistry (com.codahale.metrics.MetricRegistry)5 Properties (java.util.Properties)5 Stat (org.apache.zookeeper.data.Stat)5 ClusterMapConfig (com.github.ambry.config.ClusterMapConfig)4 HelixPropertyStoreConfig (com.github.ambry.config.HelixPropertyStoreConfig)4 IOException (java.io.IOException)4 JSONObject (org.json.JSONObject)4 List (java.util.List)3 Random (java.util.Random)3 PropertyKey (org.apache.helix.PropertyKey)3 IdealState (org.apache.helix.model.IdealState)3