/* * 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.proto.codec; import co.cask.cdap.api.artifact.ArtifactVersion; import co.cask.cdap.proto.Id; import co.cask.cdap.proto.ProgramType; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import java.lang.reflect.Type; /** * Codec for {@link co.cask.cdap.proto.Id.NamespacedId}. Currently only supports * {@link co.cask.cdap.proto.Id.Application}, {@link co.cask.cdap.proto.Id.Artifact}, * {@link co.cask.cdap.proto.Id.Program}, {@link co.cask.cdap.proto.Id.DatasetInstance}, * {@link co.cask.cdap.proto.Id.Stream} and {@link co.cask.cdap.proto.Id.Stream.View}. * Support for other {@link co.cask.cdap.proto.Id.NamespacedId} objects will be added later. */ public class NamespacedIdCodec extends AbstractSpecificationCodec<Id.NamespacedId> { @Override public JsonElement serialize(Id.NamespacedId src, Type typeOfSrc, JsonSerializationContext context) { JsonObject jsonObj = new JsonObject(); jsonObj.add("type", new JsonPrimitive(src.getIdType())); jsonObj.add("id", context.serialize(src)); return jsonObj; } @Override public Id.NamespacedId deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObj = json.getAsJsonObject(); JsonObject id = jsonObj.getAsJsonObject("id"); String type = jsonObj.get("type").getAsString(); switch (type) { case "application": return deserializeApplicationId(id); case "program": return deserializeProgramId(id); case "flow": return deserializeFlowId(id); case "flowlet": return deserializeFlowletId(id); case "service": return deserializeServiceId(id); case "schedule": return deserializeSchedule(id); case "worker": return deserializeWorkerId(id); case "workflow": return deserializeWorkflowId(id); case "datasetinstance": return deserializeDatasetInstanceId(id); case "stream": return deserializeStreamId(id); case "view": return deserializeViewId(id); case "artifact": return deserializeArtifactId(id); default: throw new UnsupportedOperationException( String.format("Unsupported object of type %s found. Deserialization of only %s, %s, %s, %s, %s, %s, %s, " + "%s, %s, %s, %s, %s is supported.", type, Id.Application.class.getSimpleName(), Id.Program.class.getSimpleName(), Id.Flow.class.getSimpleName(), Id.Flow.Flowlet.class.getSimpleName(), Id.Service.class.getSimpleName(), Id.Schedule.class.getSimpleName(), Id.Worker.class.getSimpleName(), Id.Workflow.class.getSimpleName(), Id.DatasetInstance.class.getSimpleName(), Id.Stream.class.getSimpleName(), Id.Stream.View.class.getSimpleName(), Id.Artifact.class.getSimpleName() ) ); } } private Id.Application deserializeApplicationId(JsonObject id) { Id.Namespace namespace = deserializeNamespace(id); String applicationId = id.get("applicationId").getAsString(); return Id.Application.from(namespace, applicationId); } private Id.Artifact deserializeArtifactId(JsonObject id) { Id.Namespace namespace = deserializeNamespace(id); String artifactName = id.get("name").getAsString(); ArtifactVersion artifactVersion = new ArtifactVersion( id.get("version").getAsJsonObject().get("version").getAsString()); return Id.Artifact.from(namespace, artifactName, artifactVersion); } private Id.Namespace deserializeNamespace(JsonObject id) { String namespace = id.getAsJsonObject("namespace").get("id").getAsString(); return Id.Namespace.from(namespace); } private Id.Program deserializeProgramId(JsonObject id) { Id.Application app = deserializeApplicationId(id.getAsJsonObject("application")); ProgramType programType = ProgramType.valueOf(id.get("type").getAsString().toUpperCase()); String programId = id.get("id").getAsString(); return Id.Program.from(app, programType, programId); } private Id.Flow deserializeFlowId(JsonObject id) { Id.Program program = deserializeProgramId(id); return Id.Flow.from(program.getApplication(), program.getId()); } private Id.Flow.Flowlet deserializeFlowletId(JsonObject id) { Id.Flow flow = deserializeFlowId(id.getAsJsonObject("flow")); String flowletId = id.get("id").getAsString(); return Id.Flow.Flowlet.from(flow, flowletId); } private Id.Service deserializeServiceId(JsonObject id) { Id.Program program = deserializeProgramId(id); return Id.Service.from(program.getApplication(), program.getId()); } private Id.Schedule deserializeSchedule(JsonObject id) { Id.Application app = deserializeApplicationId(id.getAsJsonObject("application")); String scheduleId = id.get("id").getAsString(); return Id.Schedule.from(app, scheduleId); } private Id.Worker deserializeWorkerId(JsonObject id) { Id.Program program = deserializeProgramId(id); return Id.Worker.from(program.getApplication(), program.getId()); } private Id.Workflow deserializeWorkflowId(JsonObject id) { Id.Program program = deserializeProgramId(id); return Id.Workflow.from(program.getApplication(), program.getId()); } private Id.DatasetInstance deserializeDatasetInstanceId(JsonObject id) { Id.Namespace namespace = deserializeNamespace(id); String instanceId = id.get("instanceId").getAsString(); return Id.DatasetInstance.from(namespace, instanceId); } private Id.Stream deserializeStreamId(JsonObject id) { Id.Namespace namespace = deserializeNamespace(id); String streamName = id.get("streamName").getAsString(); return Id.Stream.from(namespace, streamName); } private Id.Stream.View deserializeViewId(JsonObject id) { Id.Stream streamId = deserializeStreamId(id.getAsJsonObject("stream")); String view = id.get("id").getAsString(); return Id.Stream.View.from(streamId, view); } }