Ejemplo n.º 1
0
  /**
   * Update the married status of a new user record.
   *
   * <p>This method demonstrates updating both a UserProfileModel and a UserActionsModel with a
   * single HBase request using the composite dao. It performs a get/update/put operation, which is
   * protected by the check_conflict field on UserProfileModel from colliding with another
   * get/update/put operation.
   *
   * @param firstName The first name of the user we are updating
   * @param lastName The last name of the user we are updating
   * @param married True if this person is married. Otherwise false.
   */
  public void updateUserProfile(String firstName, String lastName, boolean married) {
    // Get the timestamp we'll use to set the value of the profile_updated
    // action.
    long ts = System.currentTimeMillis();

    // Construct the key we'll use to fetch the user.
    PartitionKey key =
        userProfileActionsDao.getPartitionStrategy().partitionKey(lastName, firstName);

    // Get the profile and actions entity from the composite dao.
    UserProfileActionsModel profileActionsModel = userProfileActionsDao.get(key);

    // Updating the married status is hairy since our avro compiler isn't setup
    // to compile setters for fields. We have to construct a clone through the
    // builder.
    UserProfileActionsModel updatedProfileActionsModel =
        UserProfileActionsModel.newBuilder(profileActionsModel)
            .setUserProfileModel(
                UserProfileModel.newBuilder(profileActionsModel.getUserProfileModel())
                    .setMarried(married)
                    .build())
            .build();
    // Since maps are mutable, we can update the actions map without having to
    // go through the builder like above.
    updatedProfileActionsModel
        .getUserActionsModel()
        .getActions()
        .put("profile_updated", Long.toString(ts));

    if (!userProfileActionsDao.put(updatedProfileActionsModel)) {
      // If put returns false, a write conflict occurred where someone else
      // updated the row between the times we did the get and put.
      System.out.println("Updating the user profile failed due to a write conflict");
    }
  }
Ejemplo n.º 2
0
  /**
   * Print the user profiles and actions for all users with the provided last name
   *
   * <p>This method demonstrates how to open a scanner with a start key. It's using the composite
   * dao, so the records it returns will be a composite of both the profile model and actions model.
   *
   * @param lastName The last name of users to scan.
   */
  public void printUserProfileActionsForLastName(String lastName) {
    // Create a partial key that will allow us to start the scanner from the
    // first user record that has last name equal to the one provided.
    PartitionKey startKey = userProfileActionsDao.getPartitionStrategy().partitionKey("lastName");

    // Get the scanner with the start key. Null for stopKey in the getScanner
    // method indicates that the scanner will scan to the end of the table. Our
    // loop will break out when it encounters a record without the last name.

    EntityScanner<UserProfileActionsModel> scanner =
        userProfileActionsDao.getScanner(startKey, null);
    scanner.open();
    try {
      // scan until we find a last name not equal to the one provided
      for (UserProfileActionsModel entity : scanner) {
        if (!entity.getUserProfileModel().getLastName().equals(lastName)) {
          // last name of row different, break out of the scan.
          break;
        }
        System.out.println(entity.toString());
      }
    } finally {
      // scanners need to be closed.
      scanner.close();
    }
  }
Ejemplo n.º 3
0
  @Test
  public void testSpecific() throws Exception {
    // Construct Dao
    Dao<CompositeRecord> dao =
        SpecificAvroDao.buildCompositeDao(
            tablePool,
            tableName,
            Arrays.asList(subRecord1String, subRecord2String),
            CompositeRecord.class);

    // Construct records
    SubRecord1 subRecord1 =
        SubRecord1.newBuilder()
            .setKeyPart1("1")
            .setKeyPart2("1")
            .setField1("field1_1")
            .setField2("field1_2")
            .build();
    SubRecord2 subRecord2 =
        SubRecord2.newBuilder()
            .setKeyPart1("1")
            .setKeyPart2("1")
            .setField1("field2_1")
            .setField2("field2_2")
            .build();

    CompositeRecord compositeRecord =
        CompositeRecord.newBuilder().setSubRecord1(subRecord1).setSubRecord2(subRecord2).build();

    // Test put and get
    dao.put(compositeRecord);

    PartitionKey key = dao.getPartitionStrategy().partitionKey("1", "1");
    CompositeRecord returnedCompositeRecord = dao.get(key);
    assertEquals("field1_1", returnedCompositeRecord.getSubRecord1().getField1());
    assertEquals("field1_2", returnedCompositeRecord.getSubRecord1().getField2());
    assertEquals("field2_1", returnedCompositeRecord.getSubRecord2().getField1());
    assertEquals("field2_2", returnedCompositeRecord.getSubRecord2().getField2());

    // Test OCC
    assertFalse(dao.put(compositeRecord));
    assertTrue(dao.put(returnedCompositeRecord));

    // Test null field
    subRecord1 =
        SubRecord1.newBuilder()
            .setKeyPart1("1")
            .setKeyPart2("2")
            .setField1("field1_1")
            .setField2("field1_2")
            .build();
    compositeRecord = CompositeRecord.newBuilder().setSubRecord1(subRecord1).build();
    dao.put(compositeRecord);
    key = dao.getPartitionStrategy().partitionKey("1", "2");
    compositeRecord = dao.get(key);
    assertEquals(null, compositeRecord.getSubRecord2());
  }
Ejemplo n.º 4
0
  /**
   * Create a fresh new user record.
   *
   * <p>This method demonstrates creating both a UserProfileModel and a UserActionsModel atomically
   * in a single row. When creating a user profile, we add the "created" action to the actions map.
   * This shows how we can use the CompositeDao to accomplish this.
   *
   * @param firstName The first name of the user we are creating
   * @param lastName The last name of the user we are creating
   * @param married True if this person is married. Otherwise false.
   */
  public void create(String firstName, String lastName, boolean married) {
    long ts = System.currentTimeMillis();

    UserProfileModel profileModel =
        UserProfileModel.newBuilder()
            .setFirstName(firstName)
            .setLastName(lastName)
            .setMarried(married)
            .setCreated(ts)
            .build();
    UserActionsModel actionsModel =
        UserActionsModel.newBuilder()
            .setFirstName(firstName)
            .setLastName(lastName)
            .setActions(new HashMap<String, String>())
            .build();
    actionsModel.getActions().put("profile_created", Long.toString(ts));

    UserProfileActionsModel profileActionsModel =
        UserProfileActionsModel.newBuilder()
            .setUserProfileModel(profileModel)
            .setUserActionsModel(actionsModel)
            .build();

    if (!userProfileActionsDao.put(profileActionsModel)) {
      // If put returns false, a user already existed at this row
      System.out.println("Creating a new user profile failed due to a write conflict.");
    }
  }
Ejemplo n.º 5
0
 /**
  * Print all user profiles.
  *
  * <p>This method demonstrates how to open a scanner that will scan the entire table. It has no
  * start or stop keys specified.
  */
 public void printUserProfies() {
   EntityScanner<UserProfileModel> scanner = userProfileDao.getScanner();
   scanner.open();
   try {
     for (UserProfileModel entity : scanner) {
       System.out.println(entity.toString());
     }
   } finally {
     // scanners need to be closed.
     scanner.close();
   }
 }
Ejemplo n.º 6
0
  /**
   * Add an action to the user profile.
   *
   * <p>This method demonstrates how we can use a keyAsColumn map field (the actions field of the
   * UserActionsModel) to add values to the map without having to do a get/update/put operation.
   * When doing the put, it won't remove columns that exist in the row that aren't in the new map we
   * are putting. It will just add the additional columns we are now putting to the row.
   *
   * @param firstName The first name of the user we are updating
   * @param lastName The last name of the user we are updating
   * @param actionType A string representing the action type which is the key of the map
   * @param actionValue A string representing the action value.
   */
  public void addAction(String firstName, String lastName, String actionType, String actionValue) {
    // Create a new UserActionsModel, and add a new actions map to it with a
    // single action value. Even if one exists in this row, since it has a lone
    // keyAsColumn field, it won't remove any actions that already exist in the
    // actions column family.
    UserActionsModel actionsModel =
        UserActionsModel.newBuilder()
            .setLastName(lastName)
            .setFirstName(firstName)
            .setActions(new HashMap<String, String>())
            .build();
    actionsModel.getActions().put(actionType, actionValue);

    // Perform the put.
    userActionsDao.put(actionsModel);
  }