mirror of https://github.com/apache/cloudstack.git
Add VM work job dispatcher, MethodCapturer etc
This commit is contained in:
parent
9786f7b7bb
commit
86053cd8b2
|
|
@ -30,6 +30,10 @@ public class DataCenterDeployment implements DeploymentPlan {
|
|||
boolean _recreateDisks;
|
||||
ReservationContext _context;
|
||||
|
||||
public DataCenterDeployment() {
|
||||
_dcId = 0;
|
||||
}
|
||||
|
||||
public DataCenterDeployment(long dataCenterId) {
|
||||
this(dataCenterId, null, null, null, null, null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import com.cloud.user.Account;
|
|||
*/
|
||||
public interface VirtualMachineProfile<T extends VirtualMachine> {
|
||||
|
||||
// Making Param strong-typing looks like a over-kill to me
|
||||
public static class Param {
|
||||
|
||||
public static final Param VmPassword = new Param("VmPassword");
|
||||
|
|
@ -56,6 +57,27 @@ public interface VirtualMachineProfile<T extends VirtualMachine> {
|
|||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
// Param is used in HashMap data-structure, we need to provide hashCode() and equals in order to
|
||||
// make HashMap work
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if(name != null)
|
||||
return name.hashCode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if(other == null)
|
||||
return false;
|
||||
|
||||
if(!(other instanceof Param))
|
||||
return false;
|
||||
|
||||
assert(name != null);
|
||||
return name.equals(((Param)other).getName());
|
||||
}
|
||||
}
|
||||
|
||||
String getHostName();
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class AsyncCallbackDispatcher<T, R> implements AsyncCompletionCallback {
|
|||
public T getTarget() {
|
||||
Enhancer en = new Enhancer();
|
||||
en.setSuperclass(_targetObject.getClass());
|
||||
en.setCallbacks(new Callback[]{new MethodInterceptor() {
|
||||
en.setCallbacks(new Callback[] { new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object arg0, Method arg1, Object[] arg2,
|
||||
MethodProxy arg3) throws Throwable {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import com.cloud.async.AsyncJob;
|
|||
import com.cloud.async.AsyncJobDispatcher;
|
||||
import com.cloud.async.AsyncJobManager;
|
||||
import com.cloud.async.AsyncJobResult;
|
||||
import com.cloud.async.SyncQueueManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
|
|
@ -46,7 +45,6 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
|
|||
@Inject private ApiDispatcher _dispatcher;
|
||||
|
||||
@Inject private AsyncJobManager _asyncJobMgr;
|
||||
@Inject private SyncQueueManager _queueMgr;
|
||||
@Inject private AccountDao _accountDao;
|
||||
|
||||
public ApiAsyncJobDispatcher() {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class ApiSerializerHelper {
|
|||
public static final Logger s_logger = Logger.getLogger(ApiSerializerHelper.class.getName());
|
||||
public static String token = "/";
|
||||
|
||||
public static String toSerializedStringOld(Object result) {
|
||||
public static String toSerializedString(Object result) {
|
||||
if (result != null) {
|
||||
Class<?> clz = result.getClass();
|
||||
Gson gson = ApiGsonHelper.getBuilder().create();
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
|
|||
job.setInstanceId(null);
|
||||
|
||||
if (resultObject != null) {
|
||||
job.setResult(ApiSerializerHelper.toSerializedStringOld(resultObject));
|
||||
job.setResult(ApiSerializerHelper.toSerializedString(resultObject));
|
||||
}
|
||||
|
||||
job.setLastUpdated(DateUtil.currentGMTTime());
|
||||
|
|
@ -209,7 +209,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
|
|||
|
||||
job.setProcessStatus(processStatus);
|
||||
if(resultObject != null) {
|
||||
job.setResult(ApiSerializerHelper.toSerializedStringOld(resultObject));
|
||||
job.setResult(ApiSerializerHelper.toSerializedString(resultObject));
|
||||
}
|
||||
job.setLastUpdated(DateUtil.currentGMTTime());
|
||||
_jobDao.update(jobId, job);
|
||||
|
|
@ -732,7 +732,7 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
|
|||
}
|
||||
|
||||
private static String getSerializedErrorMessage(String errorMessage) {
|
||||
return ApiSerializerHelper.toSerializedStringOld(getResetResultResponse(errorMessage));
|
||||
return ApiSerializerHelper.toSerializedString(getResetResultResponse(errorMessage));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ public class AsyncJobResult {
|
|||
}
|
||||
|
||||
public void setResultObject(Object result) {
|
||||
this.result = ApiSerializerHelper.toSerializedStringOld(result);
|
||||
this.result = ApiSerializerHelper.toSerializedString(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -597,6 +597,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
return advanceStart(vm, params, caller, account, null);
|
||||
}
|
||||
|
||||
public <T extends VMInstanceVO> T advanceStartNew(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy)
|
||||
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
|
||||
VirtualMachineGuru<T> vmGuru = getVmGuru(vm);
|
||||
vm = vmGuru.findById(vm.getId());
|
||||
|
||||
ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId());
|
||||
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy)
|
||||
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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.cloud.vm;
|
||||
|
||||
public class VmWork {
|
||||
long userId;
|
||||
long accountId;
|
||||
long vmId;
|
||||
|
||||
// VirtualMachineManagerImpl's method name that the work will be handled in the manager
|
||||
// it should be unique in the implementation class
|
||||
String targetMethodName;
|
||||
|
||||
public VmWork() {
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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.cloud.vm;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.api.ApiSerializerHelper;
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.async.AsyncJobDispatcher;
|
||||
import com.cloud.async.AsyncJobManager;
|
||||
import com.cloud.async.AsyncJobResult;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
|
||||
public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatcher {
|
||||
|
||||
@Inject private VirtualMachineManager _vmMgr;
|
||||
@Inject private AsyncJobManager _asyncJobMgr;
|
||||
@Inject private AccountDao _accountDao;
|
||||
|
||||
@Override
|
||||
public void RunJob(AsyncJob job) {
|
||||
try {
|
||||
VmWork work = (VmWork)ApiSerializerHelper.fromSerializedString(job.getCmdInfo());
|
||||
assert(work != null);
|
||||
|
||||
AccountVO account = _accountDao.findById(work.getAccountId());
|
||||
UserContext.registerContext(work.getUserId(), account, null, false);
|
||||
|
||||
try {
|
||||
|
||||
|
||||
_asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, null);
|
||||
} finally {
|
||||
UserContext.unregisterContext();
|
||||
}
|
||||
|
||||
} catch(Throwable e) {
|
||||
_asyncJobMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_FAILED, 0, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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.cloud.vm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.api.ApiSerializerHelper;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
|
||||
public class VmWorkStart extends VmWork {
|
||||
private DeploymentPlan plan;
|
||||
|
||||
// use serialization friendly map
|
||||
private Map<String, String> rawParams;
|
||||
|
||||
public VmWorkStart() {
|
||||
}
|
||||
|
||||
public DeploymentPlan getPlan() {
|
||||
return plan;
|
||||
}
|
||||
|
||||
public void setPlan(DeploymentPlan plan) {
|
||||
this.plan = plan;
|
||||
}
|
||||
|
||||
public Map<String, String> getRawParams() {
|
||||
return rawParams;
|
||||
}
|
||||
|
||||
public void setRawParams(Map<String, String> params) {
|
||||
this.rawParams = params;
|
||||
}
|
||||
|
||||
public Map<VirtualMachineProfile.Param, Object> getParams() {
|
||||
Map<VirtualMachineProfile.Param, Object> map = new HashMap<VirtualMachineProfile.Param, Object>();
|
||||
|
||||
if(rawParams != null) {
|
||||
// Strong-typing for VirtualMachineProfile.Param is really over-kill, have to deal with it anyway
|
||||
for(Map.Entry<String, String> entry : rawParams.entrySet()) {
|
||||
VirtualMachineProfile.Param key = new VirtualMachineProfile.Param(entry.getKey());
|
||||
Object val = ApiSerializerHelper.fromSerializedString(entry.getValue());
|
||||
map.put(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setParams( Map<VirtualMachineProfile.Param, Object> params) {
|
||||
if(params != null) {
|
||||
rawParams = new HashMap<String, String>();
|
||||
for(Map.Entry<VirtualMachineProfile.Param, Object> entry : params.entrySet()) {
|
||||
rawParams.put(entry.getKey().getName(), ApiSerializerHelper.toSerializedString(entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,7 +168,7 @@ public class KeystoreTest extends TestCase {
|
|||
|
||||
vm.setObjectName("virtualmachine");
|
||||
*/
|
||||
String result = ApiSerializerHelper.toSerializedStringOld(vm);
|
||||
String result = ApiSerializerHelper.toSerializedString(vm);
|
||||
// String result = "org.apache.cloudstack.api.response.UserVmResponse/virtualmachine/{\"id\":{\"_tableName\":\"vm_instance\",\"_value\":3},\"name\":\"i-2-3-KY\",\"displayname\":\"i-2-3-KY\",\"account\":\"admin\",\"projectid\":{\"_tableName\":\"projects\"},\"domainid\":{\"_tableName\":\"domain\",\"_value\":1},\"domain\":\"ROOT\",\"created\":\"2011-11-02T21:54:07-0700\",\"state\":\"Running\",\"haenable\":false,\"groupid\":{\"_tableName\":\"instance_group\"},\"zoneid\":{\"_tableName\":\"data_center\",\"_value\":1},\"zonename\":\"KY\",\"hostid\":{\"_tableName\":\"host\",\"_value\":1},\"hostname\":\"xenserver-basic\",\"templateid\":{\"_tableName\":\"vm_template\",\"_value\":2},\"templatename\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"templatedisplaytext\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"passwordenabled\":false,\"isoid\":{\"_tableName\":\"vm_template\"},\"serviceofferingid\":{\"_tableName\":\"disk_offering\",\"_value\":7},\"serviceofferingname\":\"Small Instance\",\"cpunumber\":1,\"cpuspeed\":500,\"memory\":512,\"guestosid\":{\"_tableName\":\"guest_os\",\"_value\":12},\"rootdeviceid\":0,\"rootdevicetype\":\"NetworkFilesystem\",\"securitygroup\":[],\"jobid\":{\"_tableName\":\"async_job\"},\"nic\":[{\"id\":7,\"networkid\":200,\"netmask\":\"255.255.255.0\",\"gateway\":\"10.1.1.1\",\"ipaddress\":\"10.1.1.116\",\"isolationuri\":\"vlan://1699\",\"broadcasturi\":\"vlan://1699\",\"traffictype\":\"Guest\",\"type\":\"Virtual\",\"isdefault\":true,\"macaddress\":\"02:00:39:a7:00:01\"}],\"hypervisor\":\"XenServer\"}";
|
||||
System.out.println(result);
|
||||
//Object obj = ApiSerializerHelper.fromSerializedString(result);
|
||||
|
|
@ -177,7 +177,7 @@ public class KeystoreTest extends TestCase {
|
|||
alert.setId("100");
|
||||
alert.setDescription("Hello");
|
||||
|
||||
result = ApiSerializerHelper.toSerializedStringOld(alert);
|
||||
result = ApiSerializerHelper.toSerializedString(alert);
|
||||
System.out.println(result);
|
||||
ApiSerializerHelper.fromSerializedString(result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,16 +40,12 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
public class VirtualMachineManagerImplTest {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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.cloud.vm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class VmWorkTest extends TestCase {
|
||||
Gson gson = new Gson();
|
||||
|
||||
@Test
|
||||
public void testDeployPlanSerialization() {
|
||||
DeploymentPlan plan = new DataCenterDeployment(1L);
|
||||
ExcludeList excludeList = new ExcludeList();
|
||||
|
||||
excludeList.addCluster(1);
|
||||
plan.setAvoids(excludeList);
|
||||
|
||||
String json = gson.toJson(plan);
|
||||
DeploymentPlan planClone = gson.fromJson(json, DataCenterDeployment.class);
|
||||
Assert.assertTrue(planClone.getDataCenterId() == plan.getDataCenterId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVmWorkStart() {
|
||||
VmWorkStart work = new VmWorkStart();
|
||||
Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>();
|
||||
params.put(VirtualMachineProfile.Param.HaTag, "HA");
|
||||
params.put(VirtualMachineProfile.Param.ControlNic, new Long(100));
|
||||
work.setParams(params);
|
||||
|
||||
VmWorkStart workClone = gson.fromJson(gson.toJson(work), VmWorkStart.class);
|
||||
Assert.assertTrue(work.getParams().size() == workClone.getParams().size());
|
||||
Assert.assertTrue(work.getParams().get(VirtualMachineProfile.Param.HaTag).equals(workClone.getParams().get(VirtualMachineProfile.Param.HaTag)));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -39,4 +39,17 @@ public class EnumUtils {
|
|||
}
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> T fromString(Class<T> clz, String value) {
|
||||
assert(clz != null);
|
||||
|
||||
if(value != null) {
|
||||
try {
|
||||
return Enum.valueOf(clz, value.trim());
|
||||
} catch(IllegalArgumentException ex) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// 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.cloud.utils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import net.sf.cglib.proxy.Callback;
|
||||
import net.sf.cglib.proxy.CallbackFilter;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
/*
|
||||
* This helper class provides a way to retrieve Method in a strong-type way. It takes advantage of power of
|
||||
* Intelligent IDE(Eclipse) in code-editing
|
||||
*
|
||||
* DummyImpl dummy = new DummyImpl();
|
||||
* MethodCapturer<DummyImpl> capturer = MethodCapturer.capture(dummy);
|
||||
* Method method = capturer.get(capturer.instance().foo2());
|
||||
*
|
||||
*/
|
||||
public class MethodCapturer<T> {
|
||||
|
||||
private final static int CACHE_SIZE = 1024;
|
||||
|
||||
private T _instance;
|
||||
private Method _method;
|
||||
|
||||
private static WeakHashMap<Object, Object> s_cache = new WeakHashMap<Object, Object>();
|
||||
|
||||
private MethodCapturer() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> MethodCapturer<T> capture(T obj) {
|
||||
synchronized(s_cache) {
|
||||
MethodCapturer<T> capturer = (MethodCapturer<T>)s_cache.get(obj);
|
||||
if(capturer != null) {
|
||||
return capturer;
|
||||
}
|
||||
|
||||
final MethodCapturer<T> capturerNew = new MethodCapturer<T>();
|
||||
|
||||
Enhancer en = new Enhancer();
|
||||
en.setSuperclass(obj.getClass());
|
||||
en.setCallbacks(new Callback[] { new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object arg0, Method arg1, Object[] arg2,
|
||||
MethodProxy arg3) throws Throwable {
|
||||
capturerNew.setMethod(arg1);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object arg0, Method arg1, Object[] arg2,
|
||||
MethodProxy arg3) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
en.setCallbackFilter(new CallbackFilter() {
|
||||
public int accept(Method method) {
|
||||
if (method.getParameterTypes().length == 0 && method.getName().equals("finalize")) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}}
|
||||
);
|
||||
|
||||
((MethodCapturer<T>)capturerNew).setInstance((T)en.create());
|
||||
|
||||
// We expect MethodCapturer is only used for singleton objects here, so we only maintain a limited cache
|
||||
// here
|
||||
if(s_cache.size() < CACHE_SIZE) {
|
||||
s_cache.put(obj, capturerNew);
|
||||
}
|
||||
|
||||
return capturerNew;
|
||||
}
|
||||
}
|
||||
|
||||
public T instance() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private void setInstance(T instance) {
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
public Method get(Object... useless) {
|
||||
return _method;
|
||||
}
|
||||
|
||||
private void setMethod(Method method) {
|
||||
_method = method;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,4 +25,8 @@ public class DummyImpl implements DummyInterface {
|
|||
public void foo() {
|
||||
System.out.println("Basic foo implementation");
|
||||
}
|
||||
|
||||
public int foo2() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// 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.cloud.utils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class MethodCatpurerTest {
|
||||
|
||||
public MethodCatpurerTest() {
|
||||
}
|
||||
|
||||
public void MethodCapturerTest() {
|
||||
DummyImpl dummy = new DummyImpl();
|
||||
MethodCapturer<DummyImpl> capturer = MethodCapturer.capture(dummy);
|
||||
Method method = capturer.get(capturer.instance().foo2());
|
||||
|
||||
System.out.println("Method name: " + method.getName());
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
new MethodCatpurerTest().MethodCapturerTest();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue