Package com.facebook.swift.service

Source Code of com.facebook.swift.service.TestThriftService

/*
* Copyright (C) 2012 Facebook, 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.facebook.swift.service;

import com.facebook.nifty.client.FramedClientConnector;
import com.facebook.nifty.core.RequestContext;
import com.facebook.nifty.processor.NiftyProcessor;
import com.facebook.nifty.processor.NiftyProcessorAdapters;
import com.facebook.swift.codec.ThriftCodecManager;
import com.facebook.swift.service.scribe.LogEntry;
import com.facebook.swift.service.scribe.ResultCode;
import com.facebook.swift.service.scribe.scribe;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.thrift.TException;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.testng.annotations.Test;

import javax.annotation.Nullable;
import java.net.InetSocketAddress;
import java.util.List;

import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.net.HostAndPort.fromParts;
import static org.testng.Assert.*;

/**
* Demonstrates creating a Thrift service using Swift.
*/
public class TestThriftService
{
    @Test
    public void testSwiftService()
            throws Exception
    {
        SwiftScribe scribeService = new SwiftScribe();
        NiftyProcessor processor = new ThriftServiceProcessor(new ThriftCodecManager(), ImmutableList.<ThriftEventHandler>of(), scribeService);

        List<LogEntry> messages = testProcessor(processor);
        assertEquals(scribeService.getMessages(), newArrayList(concat(toSwiftLogEntry(messages), toSwiftLogEntry(messages))));
    }

    @Test
    public void testThriftService()
            throws Exception
    {
        ThriftScribeService scribeService = new ThriftScribeService();
        TProcessor processor = new scribe.Processor<>(scribeService);

        List<LogEntry> messages = testProcessor(processor);
        assertEquals(scribeService.getMessages(), newArrayList(concat(messages, messages)));
    }

    @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "duplicate key.*")
    public void testConflictingServices()
            throws Exception
    {
        new ThriftServiceProcessor(new ThriftCodecManager(), ImmutableList.<ThriftEventHandler>of(),
                new SwiftScribe(), new ConflictingLogService());
    }

    private List<LogEntry> testProcessor(TProcessor processor) throws Exception
    {
        return testProcessor(NiftyProcessorAdapters.processorFromTProcessor(processor));
    }

    private List<LogEntry> testProcessor(NiftyProcessor processor)
            throws Exception
    {
        ImmutableList<LogEntry> messages = ImmutableList.of(
                new LogEntry("hello", "world"),
                new LogEntry("bye", "world")
        );

        try (ThriftServer server = new ThriftServer(processor).start()) {
            assertEquals(logThrift(server.getPort(), messages), ResultCode.OK);
            assertEquals(logSwift(server.getPort(), toSwiftLogEntry(messages)), com.facebook.swift.service.ResultCode.OK);
        }

        return messages;
    }

    private ResultCode logThrift(int port, List<LogEntry> messages)
            throws TException
    {
        TSocket socket = new TSocket("localhost", port);
        socket.open();
        try {
            TBinaryProtocol tp = new TBinaryProtocol(new TFramedTransport(socket));
            return new scribe.Client(tp).Log(messages);
        }
        finally {
            socket.close();
        }
    }

    private com.facebook.swift.service.ResultCode logSwift(int port, List<com.facebook.swift.service.LogEntry> entries)
            throws Exception
    {
        try (
                ThriftClientManager clientManager = new ThriftClientManager();
                Scribe scribe = clientManager.createClient(
                        new FramedClientConnector(fromParts("localhost", port)),
                        Scribe.class).get()
        ) {
            return scribe.log(entries);
        }
    }

    private List<com.facebook.swift.service.LogEntry> toSwiftLogEntry(List<LogEntry> messages)
    {
        return Lists.transform(messages, new Function<LogEntry, com.facebook.swift.service.LogEntry>()
        {
            @Override
            public com.facebook.swift.service.LogEntry apply(@Nullable LogEntry input)
            {
                return new com.facebook.swift.service.LogEntry(input.category, input.message);
            }
        });
    }

    @ThriftService
    public class ConflictingLogService
    {
        @ThriftMethod
        public void Log(List<String> messages) throws TException
        {
        }
    }

    static class EventHandler extends ThriftEventHandler
    {
        private final boolean niftyProcessor;
        private int getContextCounter = 0, preReadCounter = 0, postReadCounter = 0,
                preWriteCounter = 0, postWriteCounter = 0;
        private final List<Object> ctxs = newArrayList();

        EventHandler(boolean niftyProcessor)
        {
            this.niftyProcessor = niftyProcessor;
        }

        public boolean validate(int count)
        {
            return getContextCounter == count && preReadCounter == count && postReadCounter == count &&
                    preWriteCounter == count && postWriteCounter == count;
        }

        @Override
        public Object getContext(String methodName, RequestContext requestContext)
        {
            assertEquals(methodName, "scribe.Log");
            if (niftyProcessor) {
                assertNotNull(requestContext);
                assertTrue(((InetSocketAddress)requestContext.getRemoteAddress()).getAddress().isLoopbackAddress());
            } else {
                assertNull(requestContext);
            }
            Object ctx = new Object();
            ctxs.add(ctx);
            getContextCounter++;
            return ctx;
        }

        @Override
        public void preRead(Object context, String methodName)
        {
            assertEquals(methodName, "scribe.Log");
            assertEquals(context, ctxs.get(preReadCounter++));
        }

        @Override
        public void postRead(Object context, String methodName, Object[] args)
        {
            assertEquals(methodName, "scribe.Log");
            assertEquals(context, ctxs.get(postReadCounter++));
            assertEquals(args.length, 1);
            assertTrue(args[0] instanceof List);
        }

        @Override
        public void preWrite(Object context, String methodName, Object result)
        {
            assertEquals(methodName, "scribe.Log");
            assertEquals(context, ctxs.get(preWriteCounter++));
            assertTrue(result instanceof com.facebook.swift.service.ResultCode);
        }

        @Override
        public void postWrite(Object context, String methodName, Object result)
        {
            assertEquals(methodName, "scribe.Log");
            assertEquals(context, ctxs.get(postWriteCounter++));
            assertTrue(result instanceof com.facebook.swift.service.ResultCode);
        }
    }

    public void swiftEventHandlerTester(boolean niftyProcessor) throws Exception
    {
        SwiftScribe scribeService = new SwiftScribe();
        EventHandler eventHandler = new EventHandler(niftyProcessor);
        EventHandler secondHandler = new EventHandler(niftyProcessor);
        List<EventHandler> handlers = ImmutableList.of(eventHandler, secondHandler);
        final ThriftServiceProcessor processor = new ThriftServiceProcessor(new ThriftCodecManager(), handlers, scribeService);

        List<LogEntry> messages = niftyProcessor ?
                testProcessor(processor) : testProcessor(new TProcessor()
        {
            @Override
            public boolean process(TProtocol in, TProtocol out) throws TException
            {
                return processor.process(in, out, null);
            }
        });
        assertEquals(scribeService.getMessages(), newArrayList(concat(toSwiftLogEntry(messages), toSwiftLogEntry(messages))));
        assertTrue(eventHandler.validate(2));
        assertTrue(secondHandler.validate(2));
    }

    @Test
    public void testSwiftEventHandlersWithNiftyProcessor() throws Exception
    {
        swiftEventHandlerTester(true);
    }

    @Test
    public void testSwiftEventHandlersWithTProcessor() throws Exception
    {
        swiftEventHandlerTester(false);
    }
}
TOP

Related Classes of com.facebook.swift.service.TestThriftService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.