/*
* Copyright © 2015 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package co.cask.cdap.examples.profiles;
import co.cask.cdap.api.app.AbstractApplication;
import co.cask.cdap.api.data.schema.Schema;
import co.cask.cdap.api.data.stream.Stream;
import co.cask.cdap.api.dataset.DatasetProperties;
import co.cask.cdap.api.dataset.lib.KeyValueTable;
import co.cask.cdap.api.dataset.table.ConflictDetection;
import co.cask.cdap.api.dataset.table.Table;
/**
* Demonstrates the use of column-level conflict detection by the example of managing user profiles,
* where individual attributes such as name and email address can be updated without conflicting
* with updates to other attributes such as the last active time of the user. This is achieved
* by setting the conflict resolution level of the "profiles" table to COLUMN.
*/
public class UserProfiles extends AbstractApplication {
@Override
public void configure() {
setName("UserProfiles");
setDescription("Demonstrates the use of column-level conflict detection");
addStream(new Stream("events"));
addFlow(new ActivityFlow());
addService(new UserProfileService());
createDataset("counters", KeyValueTable.class,
DatasetProperties.builder().setDescription("Counters key-value table").build());
// create the profiles table with a schema so that it can be explored via Hive
Schema profileSchema = Schema.recordOf(
"profile",
// id, name, and email are never null and are set when a user profile is created
Schema.Field.of("id", Schema.of(Schema.Type.STRING)),
Schema.Field.of("name", Schema.of(Schema.Type.STRING)),
Schema.Field.of("email", Schema.of(Schema.Type.STRING)),
// login and active are never set when a profile is created but are set later, so they are nullable.
Schema.Field.of("login", Schema.nullableOf(Schema.of(Schema.Type.LONG))),
Schema.Field.of("active", Schema.nullableOf(Schema.of(Schema.Type.LONG)))
);
createDataset("profiles", Table.class.getName(), DatasetProperties.builder()
// create the profiles table with column-level conflict detection
.add(Table.PROPERTY_CONFLICT_LEVEL, ConflictDetection.COLUMN.name())
.add(Table.PROPERTY_SCHEMA, profileSchema.toString())
// to indicate that the id field should come from the row key and not a row column
.add(Table.PROPERTY_SCHEMA_ROW_FIELD, "id")
.setDescription("Profiles table with column-level conflict detection")
.build());
}
}