/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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.alibaba.citrus.service.pipeline;
import static com.alibaba.citrus.springext.util.SpringExtUtil.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static org.junit.Assert.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
/**
* 测试pipeline的配置,以及valve的功能。
*
* @author Michael Zhou
*/
public class PipelineServiceTests extends AbstractPipelineTests {
private static ThreadLocal<Map<String, Object>> beansHolder = new ThreadLocal<Map<String, Object>>();
@BeforeClass
public static void initFactory() {
createFactory("services-pipeline.xml");
}
@Test
public void simple_pipeline() {
pipeline = getPipelineImplFromFactory("simple");
assertInvoke(pipeline, false);
assertLog("1-1", "1-2", "1-3");
}
@Test
public void scoped_pipeline() {
Pipeline pipelineProxy = assertProxy(getPipelineFromFactory("scoped"));
assertInvoke(pipelineProxy, false);
assertLog("1-1", "1-2", "1-3");
Pipeline real1 = getProxyTarget(pipelineProxy);
assertSame(real1, beansHolder.get().get("proxyTarget.scoped"));
// 清除scope,重新调用proxy
beansHolder.remove();
assertInvoke(pipelineProxy, false);
assertLog("1-1", "1-2", "1-3");
Pipeline real2 = getProxyTarget(pipelineProxy);
assertSame(real2, beansHolder.get().get("proxyTarget.scoped"));
assertNotSame(real1, real2);
}
@Test
public void inject_scoped_pipeline() {
pipeline = getPipelineImplFromFactory("injectScoped");
assertInvoke(pipeline, false);
assertLog("1-1" /* sub-pipeline */, //
"2-1", "2-2", "2-3", //
"1-3");
}
// 由于spring2和spring3的scope接口是不兼容的(后者基于generic type),所以用proxy来测试,确保在两种环境下均可编译。
public static class TestOnlyScope implements FactoryBean {
public Class<?> getObjectType() {
return Scope.class;
}
public boolean isSingleton() {
return true;
}
public Object getObject() throws Exception {
return Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] { Scope.class },
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String name = method.getName();
TestOnlyScope scope = TestOnlyScope.this;
if ("get".equals(name)) {
return scope.getClass().getMethod(name, String.class, ObjectFactory.class)
.invoke(scope, args);
} else if ("remove".equals(name)) {
return scope.getClass().getMethod(name, String.class).invoke(scope, args);
} else {
return null;
}
}
});
}
public Object get(String name, ObjectFactory objectFactory) {
Map<String, Object> beans = beansHolder.get();
if (beans == null) {
beans = createHashMap();
beansHolder.set(beans);
}
if (!beans.containsKey(name)) {
beans.put(name, objectFactory.getObject());
}
return beans.get(name);
}
public Object remove(String name) {
Map<String, Object> beans = beansHolder.get();
if (beans == null) {
return null;
} else {
return beans.remove(name);
}
}
}
}