1 package org.opendaylight.controller.sal.binding.impl.connect.dom;
3 import java.lang.ref.WeakReference;
4 import java.lang.reflect.InvocationTargetException;
5 import java.lang.reflect.Method;
6 import java.lang.reflect.ParameterizedType;
7 import java.util.Collection;
8 import java.util.Collections;
9 import java.util.HashMap;
10 import java.util.HashSet;
12 import java.util.Map.Entry;
14 import java.util.WeakHashMap;
15 import java.util.concurrent.Callable;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.ConcurrentMap;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
22 import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
23 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
24 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
25 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
27 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
28 import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
29 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
30 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
31 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
32 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
33 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
34 import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
35 import org.opendaylight.controller.sal.binding.spi.RpcRouter;
36 import org.opendaylight.controller.sal.common.util.Rpcs;
37 import org.opendaylight.controller.sal.core.api.Provider;
38 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
39 import org.opendaylight.controller.sal.core.api.RpcImplementation;
40 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
41 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
42 import org.opendaylight.yangtools.concepts.ListenerRegistration;
43 import org.opendaylight.yangtools.concepts.Registration;
44 import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
45 import org.opendaylight.yangtools.yang.binding.Augmentable;
46 import org.opendaylight.yangtools.yang.binding.Augmentation;
47 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
48 import org.opendaylight.yangtools.yang.binding.BindingMapping;
49 import org.opendaylight.yangtools.yang.binding.DataContainer;
50 import org.opendaylight.yangtools.yang.binding.DataObject;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.opendaylight.yangtools.yang.binding.RpcInput;
53 import org.opendaylight.yangtools.yang.binding.RpcService;
54 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
55 import org.opendaylight.yangtools.yang.common.QName;
56 import org.opendaylight.yangtools.yang.common.RpcError;
57 import org.opendaylight.yangtools.yang.common.RpcResult;
58 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 import com.google.common.base.Function;
63 import com.google.common.base.Optional;
64 import com.google.common.collect.FluentIterable;
65 import com.google.common.collect.ImmutableSet;
67 import static com.google.common.base.Preconditions.*;
68 import static org.opendaylight.yangtools.concepts.util.ClassLoaderUtils.*;
70 public class BindingIndependentConnector implements //
71 RuntimeDataProvider, //
75 private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
77 private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
79 private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
80 .builder().toInstance();
82 private BindingIndependentMappingService mappingService;
84 private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
86 private DataProviderService baDataService;
88 private ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions = new ConcurrentHashMap<>();
89 private ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions = new ConcurrentHashMap<>();
91 private BindingToDomCommitHandler bindingToDomCommitHandler = new BindingToDomCommitHandler();
92 private DomToBindingCommitHandler domToBindingCommitHandler = new DomToBindingCommitHandler();
94 private Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> baCommitHandlerRegistration;
96 private Registration<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
98 private RpcProvisionRegistry biRpcRegistry;
99 private RpcProviderRegistryImpl baRpcRegistry;
101 private ListenerRegistration<DomToBindingRpcForwardingManager> domToBindingRpcManager;
102 // private ListenerRegistration<BindingToDomRpcForwardingManager>
103 // bindingToDomRpcManager;
105 private Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> toDOMInstanceIdentifier = new Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier>() {
108 public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(InstanceIdentifier<?> input) {
109 return mappingService.toDataDom(input);
115 public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
117 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
118 CompositeNode result = biDataService.readOperationalData(biPath);
119 return potentialAugmentationRead(path,biPath,result);
120 } catch (DeserializationException e) {
121 throw new IllegalStateException(e);
125 private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException {
126 Class<? extends DataObject> targetType = path.getTargetType();
127 if (Augmentation.class.isAssignableFrom(targetType)) {
128 path = mappingService.fromDataDom(biPath);
129 Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
130 DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
131 if (parentTo instanceof Augmentable<?>) {
132 return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
135 return mappingService.dataObjectFromDataDom(path, result);
139 public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
141 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
142 CompositeNode result = biDataService.readConfigurationData(biPath);
143 return potentialAugmentationRead(path,biPath,result);
144 } catch (DeserializationException e) {
145 throw new IllegalStateException(e);
149 private DataModificationTransaction createBindingToDomTransaction(
150 DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
151 DataModificationTransaction target = biDataService.beginTransaction();
152 for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
154 Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
156 target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
158 for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
160 Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
162 target.putOperationalData(biEntry.getKey(), biEntry.getValue());
164 for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
165 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
166 target.removeConfigurationData(biEntry);
168 for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
169 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
170 target.removeOperationalData(biEntry);
175 private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction(
176 DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> source) {
177 org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService
179 for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
180 .getUpdatedConfigurationData().entrySet()) {
182 InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
183 DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
184 target.putConfigurationData(baKey, baData);
185 } catch (DeserializationException e) {
186 LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
189 for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
190 .getUpdatedOperationalData().entrySet()) {
193 InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
194 DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
195 target.putOperationalData(baKey, baData);
196 } catch (DeserializationException e) {
197 LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
200 for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
203 InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
204 target.removeConfigurationData(baEntry);
205 } catch (DeserializationException e) {
206 LOG.error("Ommiting from BA transaction: {}.", entry, e);
209 for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
212 InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
213 target.removeOperationalData(baEntry);
214 } catch (DeserializationException e) {
215 LOG.error("Ommiting from BA transaction: {}.", entry, e);
221 public org.opendaylight.controller.sal.core.api.data.DataProviderService getBiDataService() {
222 return biDataService;
225 public void setBiDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
226 this.biDataService = biDataService;
229 public DataProviderService getBaDataService() {
230 return baDataService;
233 public void setBaDataService(DataProviderService baDataService) {
234 this.baDataService = baDataService;
237 public RpcProviderRegistry getRpcRegistry() {
238 return baRpcRegistry;
241 public void setRpcRegistry(RpcProviderRegistryImpl rpcRegistry) {
242 this.baRpcRegistry = rpcRegistry;
245 public void start() {
246 baDataService.registerDataReader(ROOT, this);
247 baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
248 biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
249 baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
251 if (baRpcRegistry != null && biRpcRegistry != null) {
252 domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager());
257 public void setMappingService(BindingIndependentMappingService mappingService) {
258 this.mappingService = mappingService;
262 public Collection<ProviderFunctionality> getProviderFunctionality() {
263 return Collections.emptyList();
267 public void onSessionInitiated(ProviderSession session) {
268 setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
272 public <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> router) {
276 public void setDomRpcRegistry(RpcProvisionRegistry registry) {
277 biRpcRegistry = registry;
281 public void close() throws Exception {
282 if (baCommitHandlerRegistration != null) {
283 baCommitHandlerRegistration.close();
285 if (biCommitHandlerRegistration != null) {
286 biCommitHandlerRegistration.close();
291 private class DomToBindingTransaction implements
292 DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
294 private final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing;
295 private final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification;
297 public DomToBindingTransaction(
298 org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
299 DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification) {
301 this.backing = backing;
302 this.modification = modification;
303 bindingOpenedTransactions.put(backing.getIdentifier(), this);
307 public DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getModification() {
312 public RpcResult<Void> rollback() throws IllegalStateException {
314 return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
318 public RpcResult<Void> finish() throws IllegalStateException {
319 Future<RpcResult<TransactionStatus>> result = backing.commit();
321 RpcResult<TransactionStatus> baResult = result.get();
322 return Rpcs.<Void> getRpcResult(baResult.isSuccessful(), null, baResult.getErrors());
323 } catch (InterruptedException e) {
324 throw new IllegalStateException("", e);
325 } catch (ExecutionException e) {
326 throw new IllegalStateException("", e);
331 private class BindingToDomTransaction implements
332 DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
334 private DataModificationTransaction backing;
335 private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
337 public BindingToDomTransaction(DataModificationTransaction backing,
338 DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
339 this.backing = backing;
340 this.modification = modification;
341 domOpenedTransactions.put(backing.getIdentifier(), this);
345 public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
350 public RpcResult<Void> finish() throws IllegalStateException {
351 Future<RpcResult<TransactionStatus>> result = backing.commit();
353 RpcResult<TransactionStatus> biResult = result.get();
354 return Rpcs.<Void> getRpcResult(biResult.isSuccessful(), null, biResult.getErrors());
355 } catch (InterruptedException e) {
356 throw new IllegalStateException("", e);
357 } catch (ExecutionException e) {
358 throw new IllegalStateException("", e);
360 domOpenedTransactions.remove(backing.getIdentifier());
365 public RpcResult<Void> rollback() throws IllegalStateException {
366 domOpenedTransactions.remove(backing.getIdentifier());
367 return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
371 private class BindingToDomCommitHandler implements
372 DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
375 public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
376 DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
379 * Transaction was created as DOM transaction, in that case we do
380 * not need to forward it back.
382 if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
384 return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction);
386 DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
387 BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
388 LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
389 domTransaction.getIdentifier());
394 private class DomToBindingCommitHandler implements //
395 RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject>>, //
396 DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
399 public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
401 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
407 public void onUnregister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
409 // FIXME: do registration based on only active commit handlers.
412 public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> requestCommit(
413 DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
414 Object identifier = domTransaction.getIdentifier();
417 * We checks if the transcation was originated in this mapper. If it
418 * was originated in this mapper we are returing allways success
419 * commit hanlder to prevent creating loop in two-phase commit and
422 if (domOpenedTransactions.containsKey(identifier)) {
423 return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction);
426 org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
427 DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
428 LOG.info("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
429 baTransaction.getIdentifier());
430 return forwardedTransaction;
434 private class DomToBindingRpcForwardingManager implements
435 RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>> {
437 private final Map<Class<? extends RpcService>, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>();
440 public void onRouteChange(RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
441 for (Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry : change.getAnnouncements().entrySet()) {
442 bindingRoutesAdded(entry);
446 private void bindingRoutesAdded(Entry<RpcContextIdentifier, Set<InstanceIdentifier<?>>> entry) {
447 Class<? extends BaseIdentity> context = entry.getKey().getRoutingContext();
448 Class<? extends RpcService> service = entry.getKey().getRpcService();
449 if (context != null) {
450 getRpcForwarder(service, context).registerPaths(context, service, entry.getValue());
454 private DomToBindingRpcForwarder getRpcForwarder(Class<? extends RpcService> service,
455 Class<? extends BaseIdentity> context) {
456 DomToBindingRpcForwarder potential = forwarders.get(service);
457 if (potential != null) {
460 if (context == null) {
461 potential = new DomToBindingRpcForwarder(service);
463 potential = new DomToBindingRpcForwarder(service, context);
465 forwarders.put(service, potential);
471 private class DomToBindingRpcForwarder implements RpcImplementation {
473 private final Set<QName> supportedRpcs;
474 private final WeakReference<Class<? extends RpcService>> rpcServiceType;
475 private Set<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> registrations;
477 public DomToBindingRpcForwarder(Class<? extends RpcService> service) {
478 this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
479 this.supportedRpcs = mappingService.getRpcQNamesFor(service);
480 for (QName rpc : supportedRpcs) {
481 biRpcRegistry.addRpcImplementation(rpc, this);
483 registrations = ImmutableSet.of();
486 public DomToBindingRpcForwarder(Class<? extends RpcService> service, Class<? extends BaseIdentity> context) {
487 this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
488 this.supportedRpcs = mappingService.getRpcQNamesFor(service);
489 registrations = new HashSet<>();
490 for (QName rpc : supportedRpcs) {
491 registrations.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this));
493 registrations = ImmutableSet.copyOf(registrations);
496 public void registerPaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
497 Set<InstanceIdentifier<?>> set) {
498 QName ctx = BindingReflections.findQName(context);
499 for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform(
500 toDOMInstanceIdentifier)) {
501 for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) {
502 reg.registerPath(ctx, path);
507 public void removePaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
508 Set<InstanceIdentifier<?>> set) {
509 QName ctx = BindingReflections.findQName(context);
510 for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path : FluentIterable.from(set).transform(
511 toDOMInstanceIdentifier)) {
512 for (org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration reg : registrations) {
513 reg.unregisterPath(ctx, path);
519 public Set<QName> getSupportedRpcs() {
520 return supportedRpcs;
524 public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode domInput) {
525 checkArgument(rpc != null);
526 checkArgument(domInput != null);
528 Class<? extends RpcService> rpcType = rpcServiceType.get();
529 checkState(rpcType != null);
530 RpcService rpcService = baRpcRegistry.getRpcService(rpcType);
531 checkState(rpcService != null);
532 CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input"));
534 return resolveInvocationStrategy(rpc, rpcType).invokeOn(rpcService, domUnwrappedInput);
535 } catch (Exception e) {
536 throw new IllegalStateException(e);
540 private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc,
541 final Class<? extends RpcService> rpcType) throws Exception {
542 return ClassLoaderUtils.withClassLoader(rpcType.getClassLoader(), new Callable<RpcInvocationStrategy>() {
544 public RpcInvocationStrategy call() throws Exception {
545 String methodName = BindingMapping.getMethodName(rpc);
546 Method targetMethod = null;
547 for (Method possibleMethod : rpcType.getMethods()) {
548 if (possibleMethod.getName().equals(methodName)
549 && BindingReflections.isRpcMethod(possibleMethod)) {
550 targetMethod = possibleMethod;
554 checkState(targetMethod != null, "Rpc method not found");
555 Optional<Class<?>> outputClass = BindingReflections.resolveRpcOutputClass(targetMethod);
556 Optional<Class<? extends DataContainer>> inputClass = BindingReflections
557 .resolveRpcInputClass(targetMethod);
559 RpcInvocationStrategy strategy = null;
560 if (outputClass.isPresent()) {
561 if (inputClass.isPresent()) {
562 strategy = new DefaultInvocationStrategy(targetMethod, outputClass.get(), inputClass.get());
564 strategy = new NoInputNoOutputInvocationStrategy(targetMethod);
576 private abstract class RpcInvocationStrategy {
578 protected final Method targetMethod;
580 public RpcInvocationStrategy(Method targetMethod) {
581 this.targetMethod = targetMethod;
584 public abstract RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput)
587 public RpcResult<CompositeNode> invokeOn(RpcService rpcService, CompositeNode domInput) throws Exception {
588 return uncheckedInvoke(rpcService, domInput);
592 private class DefaultInvocationStrategy extends RpcInvocationStrategy {
594 @SuppressWarnings("rawtypes")
595 private WeakReference<Class> inputClass;
597 @SuppressWarnings("rawtypes")
598 private WeakReference<Class> outputClass;
600 public DefaultInvocationStrategy(Method targetMethod, Class<?> outputClass,
601 Class<? extends DataContainer> inputClass) {
603 this.outputClass = new WeakReference(outputClass);
604 this.inputClass = new WeakReference(inputClass);
608 public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
609 DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
610 Future<RpcResult<?>> result = (Future<RpcResult<?>>) targetMethod.invoke(rpcService, bindingInput);
611 if (result == null) {
612 return Rpcs.getRpcResult(false);
614 RpcResult<?> bindingResult = result.get();
615 return Rpcs.getRpcResult(true);
620 private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy {
622 public NoInputNoOutputInvocationStrategy(Method targetMethod) {
626 public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
627 Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
628 RpcResult<Void> bindingResult = result.get();
629 return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors());