All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cinchapi.concourse.server.plugin.RemoteMethodRequest Maven / Gradle / Ivy

/*
 * Copyright (c) 2013-2018 Cinchapi 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 com.cinchapi.concourse.server.plugin;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.annotation.concurrent.Immutable;

import com.cinchapi.concourse.annotate.PackagePrivate;
import com.cinchapi.concourse.thrift.AccessToken;
import com.cinchapi.concourse.thrift.ComplexTObject;
import com.cinchapi.concourse.thrift.TransactionToken;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.atomix.catalyst.buffer.Buffer;

/**
 * A message that is sent from one process to another via a
 * {@link InterProcessCommunication} segment with a request to invoke a remote
 * method.
 * 
 * @author Jeff Nelson
 */
@Immutable
@PackagePrivate
final class RemoteMethodRequest extends RemoteMessage {

    /**
     * The non-thrift arguments to pass to the method.
     */
    public List args;

    /**
     * The credentials for the session that is making the request.
     */
    public AccessToken creds;

    /**
     * The session's current environment.
     */
    public String environment;

    /**
     * The name of the method to invoke.
     */
    public String method;

    /**
     * The session's current transaction token.
     */
    public TransactionToken transaction;

    /**
     * Construct a new instance.
     * 
     * @param method
     * @param creds
     * @param transaction
     * @param environment
     * @param args
     */
    public RemoteMethodRequest(String method, AccessToken creds,
            TransactionToken transaction, String environment,
            ComplexTObject... args) {
        this(method, creds, transaction, environment, Arrays.asList(args));
    }

    /**
     * Construct a new instance.
     * 
     * @param method
     * @param creds
     * @param transaction
     * @param environment
     * @param args
     */
    public RemoteMethodRequest(String method, AccessToken creds,
            TransactionToken transaction, String environment,
            List args) {
        this.method = method;
        this.creds = creds;
        this.transaction = transaction;
        this.environment = environment;
        this.args = args;
    }

    /**
     * DO NOT CALL. Only here for deserialization.
     */
    RemoteMethodRequest() {/* no-op */}

    @Override
    public void deserialize(Buffer buffer) {
        this.method = buffer.readUTF8();
        byte[] creds0 = new byte[buffer.readInt()];
        buffer.read(creds0);
        this.creds = new AccessToken(ByteBuffer.wrap(creds0));
        boolean transaction0 = buffer.readByte() == 1 ? true : false;
        this.transaction = null;
        if(transaction0) {
            long timestamp = buffer.readLong();
            this.transaction = new TransactionToken(creds, timestamp);
        }
        this.environment = buffer.readUTF8();
        this.args = Lists.newArrayList();
        while (buffer.hasRemaining()) {
            int length = buffer.readInt();
            byte[] arg = new byte[length];
            buffer.read(arg);
            args.add(ComplexTObject.fromByteBuffer(ByteBuffer.wrap(arg)));
        }

    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof RemoteMethodRequest) {
            return Objects.equals(args, ((RemoteMethodRequest) obj).args)
                    && Objects.equals(creds, ((RemoteMethodRequest) obj).creds)
                    && Objects.equals(environment,
                            ((RemoteMethodRequest) obj).environment)
                    && Objects.equals(method,
                            ((RemoteMethodRequest) obj).method)
                    && Objects.equals(transaction,
                            ((RemoteMethodRequest) obj).transaction);
        }
        else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return Objects.hash(args, creds, environment, method, transaction);
    }

    @Override
    public String toString() {
        Map data = Maps.newHashMap();
        data.put("method", method);
        data.put("args", args);
        data.put("creds", creds);
        data.put("transaction", transaction);
        data.put("environment", environment);
        return data.toString();
    }

    @Override
    public Type type() {
        return Type.REQUEST;
    }

    @Override
    protected void serialize(Buffer buffer) {
        buffer.writeUTF8(method);
        byte[] creds = this.creds.getData();
        buffer.writeInt(creds.length);
        buffer.write(creds);
        buffer.writeBoolean(transaction != null);
        if(transaction != null) {
            buffer.writeLong(transaction.getTimestamp());
            // NOTE: Will need the AccessToken to re-create the
            // TransactionToken, but there is no need to re-write it since it
            // was previously written
        }
        buffer.writeUTF8(environment);
        args.forEach((arg) -> {
            ByteBuffer bytes = arg.toByteBuffer();
            buffer.writeInt(bytes.remaining());
            buffer.write(bytes.array());
        });
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy