Package org.hivedb.test

Source Code of org.hivedb.test.ClassServiceTest

package org.hivedb.test;

import org.junit.Assert;
import org.apache.cxf.Bus;
import org.apache.cxf.BusException;
import org.apache.cxf.BusFactory;
import org.apache.cxf.aegis.databinding.AegisDatabinding;
import org.apache.cxf.binding.BindingFactoryManager;
import org.apache.cxf.binding.soap.SoapBindingFactory;
import org.apache.cxf.binding.soap.SoapTransportFactory;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.apache.cxf.transport.ConduitInitiatorManager;
import org.apache.cxf.transport.DestinationFactoryManager;
import org.apache.cxf.transport.local.LocalTransportFactory;
import org.apache.cxf.wsdl.WSDLManager;
import org.apache.cxf.wsdl11.WSDLManagerImpl;
import org.hibernate.shards.strategy.access.SequentialShardAccessStrategy;
import org.hivedb.Schema;
import org.hivedb.configuration.EntityConfig;
import org.hivedb.configuration.EntityIndexConfig;
import org.hivedb.hibernate.ConfigurationReader;
import org.hivedb.hibernate.HiveSessionFactory;
import org.hivedb.hibernate.HiveSessionFactoryBuilderImpl;
import org.hivedb.services.Service;
import org.hivedb.services.ServiceContainer;
import org.hivedb.services.ServiceResponse;
import org.hivedb.util.Lists;
import org.hivedb.util.classgen.*;
import org.hivedb.util.database.HiveDbDialect;
import org.hivedb.util.database.test.HiveTest;
import org.hivedb.util.functional.*;
import org.junit.Test;
import org.junit.BeforeClass;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.*;


public abstract class ClassServiceTest<T,S> extends HiveTest {

  final HiveDbDialect DATABASE_DIALECT = HiveDbDialect.H2;
  protected Class<T> clazz;
  protected Class serviceClass;
  protected Class responseClass;
  protected Class containerClass;
  protected String serviceUrl;
  protected Service client;
  protected Service server;
  protected HiveSessionFactory factory;
 
  public ClassServiceTest(Class<T> clazz, Class serviceClass, Class responseClass, Class containerClass, String serviceUrl) {
    this.clazz = clazz;
    this.serviceClass = serviceClass;
    this.responseClass = responseClass;
    this.containerClass = containerClass;
    this.serviceUrl = serviceUrl;
  }
 
  public void setup() {
    factory = getSessionFactory();
    server = createService(configurationReader);
    startServer(server);
  }
 
  protected abstract Service createService(ConfigurationReader reader);
 
  @Test
  public void saveAndRetrieve() throws Exception {
    Object instance = getPersistentInstance();
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    validate(createServiceResponse(Arrays.asList(instance)), invoke(getClient(), "get", entityConfig.getId(instance)), Arrays.asList(new String[] {}));
  }
  protected ServiceResponse invokeWithArrayArgument(Service client, String methodName, T[] args) {
    try {
      Method method = client.getClass().getMethod(methodName, args.getClass());
      return (ServiceResponse) method.invoke(client, new Object[] {args});
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
 
  protected ServiceResponse invoke(Service client, String methodName, Object... args) {
    try {
      Collection<Class> argClasses = Transform.map(new Unary<Object, Class>() {
        public Class f(Object arg) {
          return (arg instanceof GeneratedImplementation) ? ((GeneratedImplementation)arg).retrieveUnderlyingInterface() : arg.getClass();
        }
      }, Arrays.asList(args));
      Class[] argClassArray = new Class[argClasses.size()];
      argClasses.toArray(argClassArray);
       
      Method method = client.getClass().getMethod(methodName, argClassArray);
      return (ServiceResponse) method.invoke(client, args);
    } catch (ClassCastException e) {
      return null;
      // There's a mysterious Long to Long Cast exception here
    }
     catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
 
  protected Object invokeDelete(Service client, String methodName, Object... args) {
    try {
      Collection<Class> argClasses = Transform.map(new Unary<Object, Class>() {
        public Class f(Object arg) {
          return (arg instanceof GeneratedImplementation) ? ((GeneratedImplementation)arg).retrieveUnderlyingInterface() : arg.getClass();
        }
      }, Arrays.asList(args));
      Class[] argClassArray = new Class[argClasses.size()];
      argClasses.toArray(argClassArray);
       
      Method method = client.getClass().getMethod(methodName, argClassArray);
      return method.invoke(client, args);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
 
  protected Integer invokeByCount(Service client, String methodName, Object... args) {
    try {
      Collection<Class> argClasses = Transform.map(new Unary<Object, Class>() {
        public Class f(Object arg) {
          return (arg instanceof GeneratedImplementation) ? ((GeneratedImplementation)arg).retrieveUnderlyingInterface() : arg.getClass();
        }
      }, Arrays.asList(args));
      Class[] argClassArray = new Class[argClasses.size()];
      argClasses.toArray(argClassArray);
       
      Method method = client.getClass().getMethod(methodName, argClassArray);
      return (Integer) method.invoke(client, args);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  protected boolean invokeExists(Service client, String method, Object arg) {
    try {
      return (Boolean) client.getClass().getMethod(method, new Class[] {arg.getClass()}).invoke(client, new Object[] {arg});
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
 
  @Test
  public void saveAll() throws Exception {
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    Collection<T> instances = Lists.newArrayList();
    for(int i=0; i<5; i++) {
      final T instance = getInstance();
      instances.add(instance);
    }
    Service s = getClient();
    invokeWithArrayArgument(s, "saveAll", collectionToArray(clazz, instances));
    for(Object original : instances)
      validate(
          createServiceResponse(Arrays.asList(original)),
          invoke(s, "get", entityConfig.getId(original)),
          Arrays.asList(new String[] {}));
  }
 
  @Test
  public void update() throws Exception {
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    Collection<T> instances = Lists.newArrayList();
    for(int i=0; i<5; i++) {
      final T instance = getInstance();
      instances.add(instance);
    }
    Service s = getClient();
    invokeWithArrayArgument(s, "saveAll", collectionToArray(clazz, instances));
    for(Object original : instances) {
      for (EntityIndexConfig entityIndexConfig :config.getEntityConfig(clazz).getEntityIndexConfigs()) {
        Object newValue = ReflectionTools.isCollectionProperty(clazz, entityIndexConfig.getPropertyName())
          ? new GenerateInstanceCollection(ReflectionTools.getCollectionItemType(clazz, entityIndexConfig.getPropertyName()), 3).generate()
          : new GenerateInstance(entityIndexConfig.getIndexClass()).generate();
        GeneratedInstanceInterceptor.setProperty(original, entityIndexConfig.getPropertyName(), newValue);
      }
    }
    invokeWithArrayArgument(s, "saveAll", collectionToArray(clazz, instances));
    for(Object updated : instances) {
      validate(
          createServiceResponse(Arrays.asList(updated)),
          invoke(s, "get", entityConfig.getId(updated)),
          Arrays.asList(new String[] {}));
    }
  }
 
  @Test
  public void delete() throws Exception {
    Object instance = getPersistentInstance();
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    Service s = getClient();
    final Serializable id = entityConfig.getId(instance);
    validate(createServiceResponse(Arrays.asList(instance)), invoke(s, "get",id), Arrays.asList(new String[] {}));
    Assert.assertEquals(id, invokeDelete(s, "delete", id));
    Assert.assertFalse(invokeExists(s, "exists", id));
  }
 
  @Test
  public void exists() throws Exception {
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    Service s = getClient();
    Assert.assertFalse(invokeExists(s,"exists",new GeneratePrimitiveValue<Object>((Class<Object>) entityConfig.getIdClass()).generate()));
    // Make sure that the service generates an empty response when fetching missing items
    Assert.assertEquals(0, invoke(s, "get", new GeneratePrimitiveValue<Object>((Class<Object>) entityConfig.getIdClass()).generate()).getContainers().size());
    Object p = getPersistentInstance();
    Assert.assertTrue(invokeExists(s, "exists", entityConfig.getId(p)));
  }

  @Test
  public void findByProperty() throws Exception {
    Object instance = getPersistentInstance();
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    for (EntityIndexConfig entityIndexConfig : getFilteredEntityIndexConfigs(entityConfig)) {
      if (entityIndexConfig.getIndexValues(instance).size() == 0)
        continue;
      validate(
          createServiceResponse(Arrays.asList(instance)),
          invoke(
              client,
              "findByProperty",
              entityIndexConfig.getPropertyName(),
              Atom.getFirstOrThrow(entityIndexConfig.getIndexValues(instance)).toString()),
          Arrays.asList(new String[] {entityIndexConfig.getPropertyName()}));
      Assert.assertEquals(
          (Integer)1,
          invokeByCount(
              client,
              "getCountByProperty",
              entityIndexConfig.getPropertyName(),
              Atom.getFirstOrThrow(entityIndexConfig.getIndexValues(instance)).toString()));
    }
   
  }
 
  @Test
  public void findByProperties() throws Exception {
    final Object instance = getPersistentInstance();
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    Service s = getClient();
    Collection<EntityIndexConfig> entityIndexConfigs = getFilteredEntityIndexConfigs(entityConfig);
    RingIteratorable<EntityIndexConfig> entityIndexConfigIterator2 = makeEntityIndexConfigRingIterable(instance, entityIndexConfigs);
    RingIteratorable<EntityIndexConfig> entityIndexConfigIterator3 = makeEntityIndexConfigRingIterable(instance, entityIndexConfigs);
    entityIndexConfigIterator2.next();
    entityIndexConfigIterator3.next();
    entityIndexConfigIterator3.next();
    for (EntityIndexConfig entityIndexConfig1 : entityIndexConfigs) {
      if (entityIndexConfig1.getIndexValues(instance).size() == 0)
        continue;
      EntityIndexConfig entityIndexConfig2 = entityIndexConfigIterator2.next();
      EntityIndexConfig entityIndexConfig3 = entityIndexConfigIterator3.next();
      validate(
          createServiceResponse(Arrays.asList(instance)),
          invoke(
              client,
              "findByTwoProperties",
              entityIndexConfig1.getPropertyName(),
              Atom.getFirstOrThrow(entityIndexConfig1.getIndexValues(instance)).toString(),
              entityIndexConfig2.getPropertyName(),
              Atom.getFirstOrThrow(entityIndexConfig2.getIndexValues(instance)).toString()
          ),
          Arrays.asList(new String[] {entityIndexConfig1.getPropertyName(), entityIndexConfig2.getPropertyName()}));
   
      validate(
          createServiceResponse(Arrays.asList(instance)),
          invoke(
              client,
              "findByThreeProperties",
              entityIndexConfig1.getPropertyName(),
              Atom.getFirstOrThrow(entityIndexConfig1.getIndexValues(instance)).toString(),
              entityIndexConfig2.getPropertyName(),
              Atom.getFirstOrThrow(entityIndexConfig2.getIndexValues(instance)).toString(),
              entityIndexConfig3.getPropertyName(),
              Atom.getFirstOrThrow(entityIndexConfig3.getIndexValues(instance)).toString()
          ),
          Arrays.asList(new String[] {entityIndexConfig1.getPropertyName(), entityIndexConfig2.getPropertyName(), entityIndexConfig3.getPropertyName()}));
    }
  }
  private RingIteratorable<EntityIndexConfig> makeEntityIndexConfigRingIterable(
      final Object instance,
      Collection<EntityIndexConfig> entityIndexConfigs) {
    return new RingIteratorable<EntityIndexConfig>(Filter.grep(new Predicate<EntityIndexConfig>() {
      public boolean f(EntityIndexConfig entityIndexConfig) {
        return entityIndexConfig.getIndexValues(instance).size() > 0;
      }
    }, entityIndexConfigs));
  }
 
  // Filter out EntityIndexConfig types that don't work
  private Collection<EntityIndexConfig> getFilteredEntityIndexConfigs(EntityConfig entityConfig) {
    return Filter.grep(new Predicate<EntityIndexConfig>() {
      public boolean f(EntityIndexConfig entityIndexConfig) {
        return !entityIndexConfig.getIndexClass().equals(Date.class); // I can't figure out what format CXF likes
      }}, entityConfig.getEntityIndexConfigs());
  }
 
 
  abstract protected Collection<Schema> getSchemata();
  abstract protected List<Class<?>> getEntityClasses();
 
  protected void validate(ServiceResponse expected, ServiceResponse actual, Collection<String> arguments) {
    Assert.assertEquals(
        String.format("Testing using the following arguments: %s", arguments),
        expected.getContainers().size(), actual.getContainers().size());
    Map<Object, ServiceContainer> expectedMap = getInstanceHashCodeMap(expected);
    Map<Object, ServiceContainer> actualMap = getInstanceHashCodeMap(actual);
    validate(expectedMap, actualMap, arguments);
  }
 
  protected void contains(ServiceResponse expected, ServiceResponse actual, Collection<String> arguments) {
    Assert.assertTrue(String.format("Testing using the following arguments: %s", arguments),
        expected.getContainers().size() >= actual.getContainers().size());
    Map<Object, ServiceContainer> expectedMap = getInstanceHashCodeMap(expected);
    Map<Object, ServiceContainer> actualMap = getInstanceHashCodeMap(actual);
    validate(expectedMap, actualMap, arguments);
  }
 
  private void validate(Map<Object, ServiceContainer> expectedMap, Map<Object, ServiceContainer> actualMap, Collection<String> arguments) {
    for(Object key : actualMap.keySet()) {
      Assert.assertTrue(
          String.format("Expected results did not contian a ServiceContainer with hashCode %s", key),
          expectedMap.containsKey(key));
      validate(expectedMap.get(key), actualMap.get(key), arguments);
    }
  }
 
  protected void validate(ServiceContainer expected, ServiceContainer actual, Collection<String> arguments) {
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    Assert.assertEquals(expected.getVersion(), actual.getVersion());
    Assert.assertEquals(
        ReflectionTools.getDifferingFields(expected.getInstance(), actual.getInstance(), (Class<Object>)clazz).toString(),
        expected.getInstance().hashCode(),
        actual.getInstance().hashCode());
    Assert.assertEquals(String.format("Testing using the following arguments: %s", arguments), entityConfig.getId(expected.getInstance()), entityConfig.getId(actual.getInstance()));
    //Assert.assertEquals(expected.getInstance().getDescription(), actual.getInstance().getDescription());
  }
 
 
  @BeforeClass
  public static void initializeSOAPLocalTransport() throws BusException {   
    String[] transports = new String[]{
        "http://cxf.apache.org/transports/local",
        "http://schemas.xmlsoap.org/soap/http",
        "http://schemas.xmlsoap.org/wsdl/soap/http"
      };
      LocalTransportFactory local = new LocalTransportFactory();
      local.setTransportIds(Arrays.asList(transports));
     
      Bus bus = BusFactory.newInstance().createBus();
      SoapBindingFactory bindingFactory = new SoapBindingFactory();
      bindingFactory.setBus(bus);
      bus.getExtension(BindingFactoryManager.class).registerBindingFactory("http://schemas.xmlsoap.org/wsdl/soap/", bindingFactory);
      bus.getExtension(BindingFactoryManager.class).registerBindingFactory("http://schemas.xmlsoap.org/wsdl/soap/http", bindingFactory);
     
      DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class);
     
      SoapTransportFactory soap = new SoapTransportFactory();
      soap.setBus(bus);

      dfm.registerDestinationFactory("http://schemas.xmlsoap.org/wsdl/soap/", soap);
      dfm.registerDestinationFactory("http://schemas.xmlsoap.org/soap/", soap);
      dfm.registerDestinationFactory("http://cxf.apache.org/transports/local", soap);
     
      LocalTransportFactory localTransport = new LocalTransportFactory();
      dfm.registerDestinationFactory("http://schemas.xmlsoap.org/soap/http", localTransport);
      dfm.registerDestinationFactory("http://schemas.xmlsoap.org/wsdl/soap/http", localTransport);
      dfm.registerDestinationFactory("http://cxf.apache.org/bindings/xformat", localTransport);
      dfm.registerDestinationFactory("http://cxf.apache.org/transports/local", localTransport);

      ConduitInitiatorManager extension = bus.getExtension(ConduitInitiatorManager.class);
      extension.registerConduitInitiator(LocalTransportFactory.TRANSPORT_ID, localTransport);
      extension.registerConduitInitiator("http://schemas.xmlsoap.org/wsdl/soap/", localTransport);
      extension.registerConduitInitiator("http://schemas.xmlsoap.org/soap/http", localTransport);
      extension.registerConduitInitiator("http://schemas.xmlsoap.org/soap/", localTransport);
     
      WSDLManagerImpl manager = new WSDLManagerImpl();
      manager.setBus(bus);
      bus.setExtension(manager, WSDLManager.class);
  }
 
  public JaxWsServerFactoryBean startServer(Service service) {
    JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
    sf.setAddress(serviceUrl);
    sf.setServiceBean(service);
    sf.setServiceClass(service.getClass());
    sf.setDataBinding(new AegisDatabinding());
    sf.getServiceFactory().setDataBinding(new AegisDatabinding());
    sf.create().start();
    return sf;
  }
 
 
 
  protected Object getPersistentInstance() {
    Object obj = Atom.getFirstOrThrow(getPersistentInstanceAsServiceResponse().getContainers());
    return ((ServiceContainer) obj).getInstance();
    //return ((ServiceContainer)Atom.getFirstOrThrow(getPersistentInstanceAsServiceResponse().getContainers())).getInstance();
  }
  protected ServiceResponse getPersistentInstanceAsServiceResponse() {
    Assert.assertTrue(ReflectionTools.doesImplementOrExtend(getClient().getClass(), serviceClass));
    return  invoke(getClient(), "save", getInstance());
  }
  protected T getInstance() {
    return new GenerateInstance<T>(clazz).generate();
  }
 
  protected Service getClient() {
    if(client == null)
      client = createClient();
    return client;
  }
 
  public Service createClient() {
    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    factory.setServiceClass(serviceClass);
    factory.setAddress(serviceUrl);
    factory.setDataBinding(new AegisDatabinding());
    factory.getServiceFactory().setDataBinding(new AegisDatabinding());
    return (Service)factory.create();
  }

  protected Map<Object, ServiceContainer> getInstanceHashCodeMap(ServiceResponse expected) {
    final GenerateInstance<T> g = new GenerateInstance<T>(clazz);
    final EntityConfig entityConfig = config.getEntityConfig(clazz);
    return Transform.toMap(
    new Unary<ServiceContainer, Object>(){
      public Object f(ServiceContainer item) {
        return entityConfig.getId(item.getInstance());
      }},
 
    new Unary<ServiceContainer, ServiceContainer>(){
      public ServiceContainer f(ServiceContainer item) {
        return createServiceContainer(g.generateAndCopyProperties(item.getInstance()), item.getVersion());
      }},
    expected.getContainers());
  }
 
  private HiveSessionFactory getSessionFactory() {
    return new HiveSessionFactoryBuilderImpl(
        config,
        getHive(),
        new SequentialShardAccessStrategy());
  }
 
  public ServiceResponse createServiceResponse(Collection instances) {
    ServiceResponse serviceResponse = (ServiceResponse) GeneratedClassFactory.newInstance(responseClass);
    GeneratedInstanceInterceptor.setProperty(serviceResponse, "containers", Transform.map(new Unary<Object, ServiceContainer>(){
      public ServiceContainer f(Object item) {
        return createServiceContainer(item, config.getEntityConfig(clazz).getVersion(item));
      }}, instances));
    return serviceResponse;
  }
  public ServiceContainer createServiceContainer(Object instance, Integer version) {
    ServiceContainer serviceContainer = (ServiceContainer) GeneratedClassFactory.newInstance(containerClass);
    GeneratedInstanceInterceptor.setProperty(serviceContainer, "instance", instance);
    GeneratedInstanceInterceptor.setProperty(serviceContainer, "version", version);
    return serviceContainer;
  }
  protected T[] collectionToArray(Class<T> clazz, Collection c) {
    T[] array = (T[]) Array.newInstance(clazz, c.size());
    c.toArray(array);
    return array;
  }
}
TOP

Related Classes of org.hivedb.test.ClassServiceTest

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.