org.apache.aurora.common.zookeeper.JsonCodec.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.aurora.common.zookeeper.JsonCodec.java

Source

/**
 * 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 org.apache.aurora.common.zookeeper;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Map;

import javax.annotation.Nullable;

import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.JsonParseException;

import org.apache.aurora.common.io.Codec;
import org.apache.aurora.common.thrift.Endpoint;
import org.apache.aurora.common.thrift.ServiceInstance;
import org.apache.aurora.common.thrift.Status;

import static java.util.Objects.requireNonNull;

class JsonCodec implements Codec<ServiceInstance> {

    private static void assertRequiredField(String fieldName, Object fieldValue) {
        if (fieldValue == null) {
            throw new JsonParseException(String.format("Field %s is required", fieldName));
        }
    }

    private static class EndpointSchema {
        private final String host;
        private final Integer port;

        EndpointSchema(Endpoint endpoint) {
            host = endpoint.getHost();
            port = endpoint.getPort();
        }

        Endpoint asEndpoint() {
            assertRequiredField("host", host);
            assertRequiredField("port", port);

            return new Endpoint(host, port);
        }
    }

    private static class ServiceInstanceSchema {
        private final EndpointSchema serviceEndpoint;
        private final Map<String, EndpointSchema> additionalEndpoints;
        private final Status status;
        private final @Nullable Integer shard;

        ServiceInstanceSchema(ServiceInstance instance) {
            serviceEndpoint = new EndpointSchema(instance.getServiceEndpoint());
            if (instance.isSetAdditionalEndpoints()) {
                additionalEndpoints = Maps.transformValues(instance.getAdditionalEndpoints(), EndpointSchema::new);
            } else {
                additionalEndpoints = ImmutableMap.of();
            }
            status = instance.getStatus();
            shard = instance.isSetShard() ? instance.getShard() : null;
        }

        ServiceInstance asServiceInstance() {
            assertRequiredField("serviceEndpoint", serviceEndpoint);
            assertRequiredField("status", status);

            Map<String, EndpointSchema> extraEndpoints = additionalEndpoints == null ? ImmutableMap.of()
                    : additionalEndpoints;

            ServiceInstance instance = new ServiceInstance(serviceEndpoint.asEndpoint(),
                    Maps.transformValues(extraEndpoints, EndpointSchema::asEndpoint), status);
            if (shard != null) {
                instance.setShard(shard);
            }
            return instance;
        }
    }

    private static final Charset ENCODING = Charsets.UTF_8;

    private final Gson gson;

    JsonCodec() {
        this(new Gson());
    }

    JsonCodec(Gson gson) {
        this.gson = requireNonNull(gson);
    }

    @Override
    public void serialize(ServiceInstance instance, OutputStream sink) throws IOException {
        Writer writer = new OutputStreamWriter(sink, ENCODING);
        try {
            gson.toJson(new ServiceInstanceSchema(instance), writer);
        } catch (JsonIOException e) {
            throw new IOException(String.format("Problem serializing %s to JSON", instance), e);
        }
        writer.flush();
    }

    @Override
    public ServiceInstance deserialize(InputStream source) throws IOException {
        InputStreamReader reader = new InputStreamReader(source, ENCODING);
        try {
            @Nullable
            ServiceInstanceSchema schema = gson.fromJson(reader, ServiceInstanceSchema.class);
            if (schema == null) {
                throw new IOException("JSON did not include a ServiceInstance object");
            }
            return schema.asServiceInstance();
        } catch (JsonParseException e) {
            throw new IOException("Problem parsing JSON ServiceInstance.", e);
        }
    }
}