Search in sources :

Example 1 with ZNRecord

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

the class HelixAccountServiceTest method testReadBadZNRecordCase7.

/**
 * Tests reading {@link ZNRecord} from {@link HelixPropertyStore} and ambry, where the ambry has valid accounts
 * record but {@link ZNRecord} has invalid list. 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 testReadBadZNRecordCase7() 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()));
    RouterStore.writeAccountMapToRouter(accountMap, mockRouter);
    List<String> list = Collections.singletonList("bad_list_string");
    zNRecord.setListField(RouterStore.ACCOUNT_METADATA_BLOB_IDS_LIST_KEY, list);
    updateAndWriteZNRecord(zNRecord, false);
}
Also used : HashMap(java.util.HashMap) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord) Test(org.junit.Test)

Example 2 with ZNRecord

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

the class HelixAccountServiceTest method testReadBadZNRecordCase4.

/**
 * Tests reading {@link ZNRecord} from {@link HelixPropertyStore}, where the {@link ZNRecord} has a map field
 * ({@link LegacyMetadataStore#ACCOUNT_METADATA_MAP_KEY}: accountMap), and accountMap contains
 * ("accountId": accountJsonStr) that does not match. This is a NOT good {@link ZNRecord} format that should
 * fail fetch or update.
 * @throws Exception Any unexpected exception.
 */
@Test
public void testReadBadZNRecordCase4() throws Exception {
    Map<String, String> mapValue = new HashMap<>();
    mapValue.put("-1", objectMapper.writeValueAsString(new AccountBuilder(refAccount).snapshotVersion(refAccount.getSnapshotVersion() + 1).build()));
    ZNRecord zNRecord = null;
    if (useNewZNodePath) {
        String blobID = RouterStore.writeAccountMapToRouter(mapValue, mockRouter);
        List<String> list = Collections.singletonList(new RouterStore.BlobIDAndVersion(blobID, 1).toJson());
        zNRecord = makeZNRecordWithListField(null, RouterStore.ACCOUNT_METADATA_BLOB_IDS_LIST_KEY, list);
    } else {
        zNRecord = makeZNRecordWithMapField(null, LegacyMetadataStore.ACCOUNT_METADATA_MAP_KEY, mapValue);
    }
    updateAndWriteZNRecord(zNRecord, false);
}
Also used : HashMap(java.util.HashMap) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord) Test(org.junit.Test)

Example 3 with ZNRecord

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

the class HelixAccountServiceTest method writeAccountsToHelixPropertyStore.

/**
 * Pre-populates a collection of {@link Account}s to the underlying {@link org.apache.helix.store.HelixPropertyStore}
 * using {@link com.github.ambry.clustermap.HelixStoreOperator} (not through the {@link HelixAccountService}). This method
 * does not check any conflict among the {@link Account}s to write.
 * @throws Exception Any unexpected exception.
 */
private void writeAccountsToHelixPropertyStore(Collection<Account> accounts, boolean shouldNotify) throws Exception {
    HelixStoreOperator storeOperator = new HelixStoreOperator(mockHelixAccountServiceFactory.getHelixStore(ZK_CONNECT_STRING, storeConfig));
    ZNRecord zNRecord = new ZNRecord(String.valueOf(System.currentTimeMillis()));
    Map<String, String> accountMap = new HashMap<>();
    for (Account account : accounts) {
        accountMap.put(String.valueOf(account.getId()), objectMapper.writeValueAsString(new AccountBuilder(account).snapshotVersion(refAccount.getSnapshotVersion() + 1).build()));
    }
    if (useNewZNodePath) {
        String blobID = RouterStore.writeAccountMapToRouter(accountMap, mockRouter);
        List<String> list = Collections.singletonList(new RouterStore.BlobIDAndVersion(blobID, 1).toJson());
        zNRecord.setListField(RouterStore.ACCOUNT_METADATA_BLOB_IDS_LIST_KEY, list);
        storeOperator.write(RouterStore.ACCOUNT_METADATA_BLOB_IDS_PATH, zNRecord);
    } else {
        zNRecord.setMapField(LegacyMetadataStore.ACCOUNT_METADATA_MAP_KEY, accountMap);
        // Write account metadata into HelixPropertyStore.
        storeOperator.write(LegacyMetadataStore.FULL_ACCOUNT_METADATA_PATH, zNRecord);
    }
    if (shouldNotify) {
        notifier.publish(ACCOUNT_METADATA_CHANGE_TOPIC, FULL_ACCOUNT_METADATA_CHANGE_MESSAGE);
    }
}
Also used : HelixStoreOperator(com.github.ambry.clustermap.HelixStoreOperator) Account(com.github.ambry.account.Account) HashMap(java.util.HashMap) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord)

Example 4 with ZNRecord

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

the class RouterStoreTest method getBlobIDAndVersionInHelix.

/**
 * Fetch the list of {@link RouterStore.BlobIDAndVersion} from the helixStore.
 * @param count The expected number of elements in the list.
 * @return The list of {@link RouterStore.BlobIDAndVersion}.
 */
private List<RouterStore.BlobIDAndVersion> getBlobIDAndVersionInHelix(int count) {
    // Verify that ZNRecord contains the right data.
    ZNRecord record = helixStore.get(RouterStore.ACCOUNT_METADATA_BLOB_IDS_PATH, null, AccessOption.PERSISTENT);
    assertNotNull("ZNRecord missing after update", record);
    List<String> accountBlobs = record.getListField(RouterStore.ACCOUNT_METADATA_BLOB_IDS_LIST_KEY);
    assertNotNull("Blob ids are missing from ZNRecord", accountBlobs);
    // version also equals to the number of blobs
    assertEquals("Number of blobs mismatch", count, accountBlobs.size());
    List<RouterStore.BlobIDAndVersion> blobIDAndVersions = new ArrayList<>(count);
    for (String json : accountBlobs) {
        blobIDAndVersions.add(RouterStore.BlobIDAndVersion.fromJson(json));
    }
    return blobIDAndVersions;
}
Also used : ArrayList(java.util.ArrayList) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord)

Example 5 with ZNRecord

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

the class HelixClusterManager method initializeHelixManagerAndPropertyStoreInLocalDC.

/**
 * Initialize HelixManager in local datacenter and complete subscription of HelixPropertyStore to listen for
 * PartitionOverride zNode. This needs to happen before other datacenters are initialized so that any partition
 * overrides can be properly honored.
 * @param dataCenterToZkAddress the map mapping each datacenter to its corresponding ZkAddress.
 * @param instanceName the String representation of the instance associated with this manager.
 * @param helixFactory the factory class to construct and get a reference to a {@link HelixManager}.
 * @return the HelixManager of local datacenter, or {@code null} if the local datacenter is
 *         {@link ReplicaType#CLOUD_BACKED}, as we currently do not support getting cluster state from Helix for cloud
 *         datacenters.
 * @throws Exception
 */
private HelixManager initializeHelixManagerAndPropertyStoreInLocalDC(Map<String, DcZkInfo> dataCenterToZkAddress, String instanceName, HelixFactory helixFactory) throws Exception {
    DcZkInfo dcZkInfo = dataCenterToZkAddress.get(clusterMapConfig.clusterMapDatacenterName);
    if (dcZkInfo.getReplicaType() == ReplicaType.CLOUD_BACKED) {
        return null;
    }
    // For now, the first ZK endpoint (if there are more than one endpoints) will be adopted by default. Note that, Ambry
    // doesn't support multiple HelixClusterManagers(spectators) on same node.
    String zkConnectStr = dcZkInfo.getZkConnectStrs().get(0);
    HelixManager manager = helixFactory.getZkHelixManagerAndConnect(clusterName, instanceName, InstanceType.SPECTATOR, zkConnectStr);
    helixPropertyStoreInLocalDc = manager.getHelixPropertyStore();
    logger.info("HelixPropertyStore from local datacenter {} is: {}", dcZkInfo.getDcName(), helixPropertyStoreInLocalDc);
    IZkDataListener dataListener = new IZkDataListener() {

        @Override
        public void handleDataChange(String dataPath, Object data) {
            logger.info("Received data change notification for: {}", dataPath);
        }

        @Override
        public void handleDataDeleted(String dataPath) {
            logger.info("Received data delete notification for: {}", dataPath);
        }
    };
    logger.info("Subscribing data listener to HelixPropertyStore.");
    helixPropertyStoreInLocalDc.subscribeDataChanges(PARTITION_OVERRIDE_ZNODE_PATH, dataListener);
    logger.info("Getting PartitionOverride ZNRecord from HelixPropertyStore");
    ZNRecord zNRecord = helixPropertyStoreInLocalDc.get(PARTITION_OVERRIDE_ZNODE_PATH, null, AccessOption.PERSISTENT);
    if (clusterMapConfig.clusterMapEnablePartitionOverride) {
        if (zNRecord != null) {
            partitionOverrideInfoMap.putAll(zNRecord.getMapFields());
            logger.info("partitionOverrideInfoMap is initialized!");
        } else {
            logger.warn("ZNRecord from HelixPropertyStore is NULL, the partitionOverrideInfoMap is empty.");
        }
    }
    return manager;
}
Also used : HelixManager(org.apache.helix.HelixManager) IZkDataListener(org.apache.helix.zookeeper.zkclient.IZkDataListener) JSONObject(org.json.JSONObject) 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