use of io.cdap.cdap.proto.element.EntityType in project cdap by caskdata.
the class EntityId method findParentType.
/**
* Finds a valid known CDAP entity which can be considered as the parent for the MetadataEntity by walking up the
* key-value hierarchy of the MetadataEntity
*
* @param metadataEntity whose EntityType needs to be determined
* @return {@link EntityType} of the given metadataEntity
*/
@Nullable
private static EntityType findParentType(MetadataEntity metadataEntity) {
List<String> keys = new ArrayList<>();
metadataEntity.getKeys().forEach(keys::add);
int curIndex = keys.size() - 1;
EntityType entityType = null;
while (curIndex >= 0) {
try {
entityType = EntityType.valueOf(keys.get(curIndex).toUpperCase());
// found a valid entity type;
break;
} catch (IllegalArgumentException e) {
// the current key is not a valid cdap entity type so try up in hierarchy
curIndex--;
}
}
return entityType;
}
use of io.cdap.cdap.proto.element.EntityType in project cdap by caskdata.
the class EntityId method fromString.
protected static <T extends EntityId> T fromString(String string, @Nullable Class<T> idClass) {
String[] typeAndId = string.split(IDSTRING_TYPE_SEPARATOR, 2);
if (typeAndId.length != 2) {
throw new IllegalArgumentException(String.format("Expected type separator '%s' to be in the ID string: %s", IDSTRING_TYPE_SEPARATOR, string));
}
String typeString = typeAndId[0];
EntityType typeFromString = EntityType.valueOf(typeString.toUpperCase());
Class<T> idClassFromString = (Class<T>) typeFromString.getIdClass();
if (idClass != null && !idClassFromString.equals(idClass)) {
/* idClass can differ from idClassFromString only when typeFromString is EntityType.PROGRAM and idClass is
* of WorkflowId.class, because when toString method is called for WorkflowId, its superclass ProgramId calls
* EntityId's toString() method and the string always contains ProgramId as type. */
if (!idClassFromString.isAssignableFrom(idClass) || !typeFromString.equals(EntityType.PROGRAM)) {
throw new IllegalArgumentException(String.format("Expected EntityId of class '%s' but got '%s'", idClass.getName(), typeFromString.getIdClass().getName()));
}
}
String idString = typeAndId[1];
try {
List<String> idParts = Arrays.asList(IDSTRING_PART_SEPARATOR_PATTERN.split(idString));
// special case for DatasetId, DatasetModuleId, DatasetTypeId since we allow . in the name
if (EnumSet.of(EntityType.DATASET, EntityType.DATASET_MODULE, EntityType.DATASET_TYPE).contains(typeFromString)) {
int namespaceSeparatorPos = idString.indexOf(IDSTRING_PART_SEPARATOR);
if (namespaceSeparatorPos > 0) {
idParts = new ArrayList<>();
idParts.add(idString.substring(0, namespaceSeparatorPos));
idParts.add(idString.substring(namespaceSeparatorPos + 1));
}
}
return typeFromString.fromIdParts(idParts);
} catch (IllegalArgumentException e) {
String message = idClass == null ? String.format("Invalid ID: %s", string) : String.format("Invalid ID for type '%s': %s", idClass.getName(), string);
throw new IllegalArgumentException(message, e);
}
}
use of io.cdap.cdap.proto.element.EntityType in project cdap by caskdata.
the class EntityId method getSelfOrParentEntityId.
/**
* Creates a valid known CDAP entity which can be considered as the parent for the MetadataEntity by walking up the
* key-value hierarchy of the MetadataEntity till a known CDAP {@link EntityType} is found. If the last node itself
* is known type then that will be considered as the parent.
*
* @param metadataEntity whose parent entityId needs to be found
* @return {@link EntityId} of the given metadataEntity
* @throws IllegalArgumentException if the metadataEntity does not have any know entity type in it's hierarchy or if
* it does not have all the required key-value pairs to construct the identified EntityId.
*/
public static <T extends EntityId> T getSelfOrParentEntityId(MetadataEntity metadataEntity) {
EntityType entityType = findParentType(metadataEntity);
if (entityType == null) {
throw new IllegalArgumentException(String.format("No known type found in the hierarchy of %s", metadataEntity));
}
List<String> values = new LinkedList<>();
// get the key-value pair till the known entity-type. Note: for application the version comes after application
// key-value pair and needs to be included too
List<MetadataEntity.KeyValue> extractedParts = metadataEntity.head(entityType.toString());
// if a version was specified extract that else use the default version
String version = metadataEntity.containsKey(MetadataEntity.VERSION) ? metadataEntity.getValue(MetadataEntity.VERSION) : ApplicationId.DEFAULT_VERSION;
if (entityType == EntityType.APPLICATION) {
// if the entity is an application our extractParts will not contain the version info since we extracted till
// application so append it
extractedParts.add(new MetadataEntity.KeyValue(MetadataEntity.VERSION, version));
}
if (entityType == EntityType.PROGRAM || entityType == EntityType.SCHEDULE || entityType == EntityType.PROGRAM_RUN) {
// (namespace, application, version) if the version information is not present
if (!metadataEntity.containsKey(MetadataEntity.VERSION)) {
extractedParts.add(2, new MetadataEntity.KeyValue(MetadataEntity.VERSION, version));
}
}
// for artifacts get till version (artifacts always have version
if (entityType == EntityType.ARTIFACT) {
extractedParts = metadataEntity.head(MetadataEntity.VERSION);
}
// for plugins get till plugin name
if (entityType == EntityType.PLUGIN) {
extractedParts = metadataEntity.head(MetadataEntity.PLUGIN);
}
extractedParts.iterator().forEachRemaining(keyValue -> values.add(keyValue.getValue()));
return entityType.fromIdParts(values);
}
use of io.cdap.cdap.proto.element.EntityType in project cdap by caskdata.
the class EntityIdTypeAdapter method deserialize.
@Override
public EntityId deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject map = json.getAsJsonObject();
JsonElement entityTypeJson = map.get("entity");
if (entityTypeJson == null) {
throw new JsonParseException("Expected entity in EntityId JSON");
}
String entityTypeString = entityTypeJson.getAsString();
EntityType type = EntityType.valueOf(entityTypeString);
if (type == null) {
throw new JsonParseException("Invalid entity: " + entityTypeString);
}
return context.deserialize(json, type.getIdClass());
}
use of io.cdap.cdap.proto.element.EntityType in project cdap by caskdata.
the class Authorizable method fromString.
/**
* Constructs an {@link Authorizable} from the given entityString. The entityString must be a representation of an
* entity similar to {@link EntityId#toString()} with the exception that the string can contain wildcards (? and *).
* ChildType can be optionally specified after a second ":" character.
* Note:
* <ol>
* <li>
* The only validation that this class performs on the entityString is that it checks if the string has enough
* valid parts for the given {@link #entityType}. It does not check if the entity exists or not. This is
* required to allow pre grants.
* </li>
* <li>
* CDAP Authorization does not support authorization on versions of {@link io.cdap.cdap.proto.id.ApplicationId}
* and {@link io.cdap.cdap.proto.id.ArtifactId}. If a version is included while construction an Authorizable
* through {@link #fromString(String)} an {@link IllegalArgumentException} will be thrown.
* </li>
* </ol>
*
* @param entityString the {@link EntityId#toString()} of the entity which may or may not contains wildcards(? or *)
*/
public static Authorizable fromString(String entityString) {
if (entityString == null || entityString.isEmpty()) {
throw new IllegalArgumentException("Null or empty entity string.");
}
String[] typeAndId = entityString.split(EntityId.IDSTRING_TYPE_SEPARATOR, 3);
if (typeAndId.length < 2) {
throw new IllegalArgumentException(String.format("Cannot extract the entity type from %s", entityString));
}
String typeString = typeAndId[0];
EntityType type = EntityType.valueOf(typeString.toUpperCase());
String idString = typeAndId[1];
EntityType childType = typeAndId.length == 3 ? EntityType.valueOf(typeAndId[2].toUpperCase()) : null;
List<String> idParts = Collections.emptyList();
switch(type) {
case KERBEROSPRINCIPAL:
// kerberos principal might contain . which is also EntityId.IDSTRING_PART_SEPARATOR_PATTERN so don't split for
// them and also principal doesn't have other parts so just initialize
idParts = Collections.singletonList(idString);
break;
case DATASET:
case DATASET_TYPE:
case DATASET_MODULE:
int namespaceSeparatorPos = idString.indexOf(EntityId.IDSTRING_PART_SEPARATOR);
if (namespaceSeparatorPos > 0) {
idParts = new ArrayList<>();
idParts.add(idString.substring(0, namespaceSeparatorPos));
idParts.add(idString.substring(namespaceSeparatorPos + 1));
}
break;
default:
idParts = Arrays.asList(EntityId.IDSTRING_PART_SEPARATOR_PATTERN.split(idString));
}
Map<EntityType, String> entityParts = new LinkedHashMap<>();
checkParts(type, idParts, idParts.size() - 1, entityParts);
return new Authorizable(type, entityParts, childType);
}
Aggregations