/* * RHQ Management Platform * Copyright 2012, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.bindings.client; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; import org.testng.Assert; import org.testng.annotations.Test; import org.rhq.bindings.util.InterfaceSimplifier; import org.rhq.core.domain.auth.Subject; import org.rhq.enterprise.server.resource.ResourceManagerRemote; /** * @author Lukas Krejci */ @Test public class AbstractRhqFacadeProxyTest { public interface TestInterface { void method(); } public static class TestFacade extends AbstractRhqFacade { private Subject subject; @Override public Subject getSubject() { return subject; } public void setSubject(Subject subject) { this.subject = subject; } @Override public Subject login(String user, String password) throws Exception { return subject; } @Override public void logout() { subject = null; } @Override public boolean isLoggedIn() { return subject != null; } @Override public Map<RhqManager, Object> getScriptingAPI() { EnumMap<RhqManager, Object> ret = new EnumMap<RhqManager, Object>(RhqManager.class); for (RhqManager m : RhqManager.values()) { Class<?> iface = InterfaceSimplifier.simplify(m.remote()); Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[] { iface }, new TestProxy(this, m)); ret.put(m, proxy); } return ret; } @Override public <T> T getProxy(Class<T> remoteApiIface) { RhqManager m = RhqManager.forInterface(remoteApiIface); if (m == null) { throw new IllegalArgumentException(); } return remoteApiIface.cast(Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[] { remoteApiIface }, new TestProxy(this, m))); } } public static class InvocationRecord { public Method method; public Object[] args; } public static class TestProxy extends AbstractRhqFacadeProxy<TestFacade> { private static List<InvocationRecord> pastInvocations = new ArrayList<InvocationRecord>(); /** * @param facade * @param manager */ public TestProxy(TestFacade facade, RhqManager manager) { super(facade, manager); } @Override protected Object doInvoke(Object proxy, Method originalMethod, Object[] args) throws Throwable { InvocationRecord inv = new InvocationRecord(); inv.method = originalMethod; inv.args = args; pastInvocations.add(inv); return null; } public static List<InvocationRecord> getPastInvocations() { return pastInvocations; } public static void clearPastInvocations() { pastInvocations.clear(); } } public void testInvocationOfSimplifiedMethods() throws Exception { TestProxy.clearPastInvocations(); TestFacade facade = new TestFacade(); Subject subject = new Subject(); facade.setSubject(subject); Object resourceManager = facade.getScriptingAPI().get(RhqManager.ResourceManager); Method getResource = resourceManager.getClass().getMethod("getResource", int.class); getResource.invoke(resourceManager, 1); Assert.assertEquals(TestProxy.getPastInvocations().size(), 1, "Unexpected number of proxy invocations"); InvocationRecord inv = TestProxy.getPastInvocations().get(0); Assert.assertEquals(inv.method, ResourceManagerRemote.class.getMethod("getResource", Subject.class, int.class), "Unexpected method invoked."); Assert.assertEquals(subject, inv.args[0], "Unexpected subject passed to the invocation."); Assert.assertEquals(inv.args[1], new Integer(1), "Unexpected resource id passed to the invocation."); } public void testProxyRobustAgainstNonSimplifiedMethods() throws Exception { TestProxy.clearPastInvocations(); Class<?> iface = InterfaceSimplifier.simplify(TestInterface.class); Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] { iface }, new TestProxy(null, null)); Method charAt = proxy.getClass().getMethod("method"); charAt.invoke(proxy); Assert.assertEquals(TestProxy.getPastInvocations().size(), 1, "Unexpected number of proxy invocations"); InvocationRecord inv = TestProxy.getPastInvocations().get(0); Assert.assertEquals(inv.method, TestInterface.class.getMethod("method"), "Unexpected method invoked."); Assert.assertNull(inv.args, "Unexpected number of arguments passed to the invocation."); } }