X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fyang-prototype%2Fsal%2Fsal-binding-broker-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2FBindingAwareBrokerImpl.xtend;fp=opendaylight%2Fsal%2Fyang-prototype%2Fsal%2Fsal-binding-broker-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2FBindingAwareBrokerImpl.xtend;h=74ef87ae5afd4713f135a8feb05d2a4e306f58a5;hb=42183ad5bfefff7d6de9df467cdaa600a450af29;hp=0000000000000000000000000000000000000000;hpb=f3bdffc96f0c221111faeef07db2a6b975f56463;p=controller.git diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend new file mode 100644 index 0000000000..74ef87ae5a --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl + +import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider +import org.opendaylight.yangtools.yang.binding.RpcService +import javassist.ClassPool +import javassist.CtMethod +import javassist.CtField +import org.osgi.framework.BundleContext +import java.util.Map +import java.util.HashMap +import javassist.LoaderClassPath +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker +import java.util.Hashtable + +import static extension org.opendaylight.controller.sal.binding.impl.utils.PropertiesUtils.* +import static extension org.opendaylight.controller.sal.binding.impl.utils.GeneratorUtils.* +import org.opendaylight.controller.sal.binding.api.NotificationProviderService +import org.osgi.framework.ServiceRegistration +import org.opendaylight.controller.sal.binding.impl.utils.PropertiesUtils +import org.opendaylight.controller.sal.binding.api.NotificationService +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext +import javassist.Modifier +import org.slf4j.LoggerFactory + +class BindingAwareBrokerImpl implements BindingAwareBroker { + private static val DELEGATE_FIELD = "_delegate" + private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl) + + private val clsPool = ClassPool.getDefault() + private Map, RpcProxyContext> managedProxies = new HashMap(); + private var NotificationBrokerImpl notifyBroker + private var ServiceRegistration notifyBrokerRegistration + + @Property + var BundleContext brokerBundleContext + + def start() { + initGenerator(); + + // Initialization of notificationBroker + notifyBroker = new NotificationBrokerImpl(null); + val brokerProperties = PropertiesUtils.newProperties(); + notifyBrokerRegistration = brokerBundleContext.registerService(NotificationProviderService, notifyBroker, + brokerProperties) + brokerBundleContext.registerService(NotificationService, notifyBroker, brokerProperties) + } + + def initGenerator() { + + // YANG Binding Class Loader + clsPool.appendClassPath(new LoaderClassPath(RpcService.classLoader)) + } + + override registerConsumer(BindingAwareConsumer consumer, BundleContext bundleCtx) { + val ctx = consumer.createContext(bundleCtx) + consumer.onSessionInitialized(ctx) + return ctx + } + + override registerProvider(BindingAwareProvider provider, BundleContext bundleCtx) { + val ctx = provider.createContext(bundleCtx) + provider.onSessionInitialized(ctx) + provider.onSessionInitiated(ctx as ProviderContext) + return ctx + } + + private def createContext(BindingAwareConsumer consumer, BundleContext consumerCtx) { + new OsgiConsumerContext(consumerCtx, this) + } + + private def createContext(BindingAwareProvider provider, BundleContext providerCtx) { + new OsgiProviderContext(providerCtx, this) + } + + def getManagedDirectProxy(Class service) { + + var RpcProxyContext existing = null + if ((existing = managedProxies.get(service)) != null) { + return existing.proxy + } + val proxyClass = service.generateDirectProxy() + val rpcProxyCtx = new RpcProxyContext(proxyClass) + val properties = new Hashtable() + rpcProxyCtx.proxy = proxyClass.newInstance as RpcService + + properties.salServiceType = Constants.SAL_SERVICE_TYPE_CONSUMER_PROXY + rpcProxyCtx.registration = brokerBundleContext.registerService(service, rpcProxyCtx.proxy as T, properties) + managedProxies.put(service, rpcProxyCtx) + return rpcProxyCtx.proxy + } + + protected def generateDirectProxy(Class delegate) { + val targetFqn = delegate.generatedName(Constants.PROXY_DIRECT_SUFFIX) + log.debug("Generating DirectProxy for {} Proxy name: {}",delegate,targetFqn); + val objCls = clsPool.get(Object) + val delegateCls = clsPool.get(delegate) + val proxyCls = clsPool.makeClass(targetFqn) + proxyCls.addInterface(delegateCls) + val delField = new CtField(delegateCls, DELEGATE_FIELD, proxyCls); + delField.modifiers = Modifier.PUBLIC + proxyCls.addField(delField) + delegateCls.methods.filter[it.declaringClass != objCls].forEach [ + val proxyMethod = new CtMethod(it, proxyCls, null); + proxyMethod.body = '''return ($r) «DELEGATE_FIELD».«it.name»($$);''' + proxyCls.addMethod(proxyMethod) + ] + return proxyCls.toClass(delegate.classLoader) + } + + def registerRpcImplementation(Class type, T service, OsgiProviderContext context, + Hashtable properties) { + val proxy = getManagedDirectProxy(type) + if(proxy.delegate != null) { + throw new IllegalStateException("Service " + type + "is already registered"); + } + val osgiReg = context.bundleContext.registerService(type, service, properties); + proxy.delegate = service; + return new RpcServiceRegistrationImpl(type, service, osgiReg); + } + + def getDelegate(RpcService proxy) { + val field = proxy.class.getField(DELEGATE_FIELD) + if(field == null) throw new UnsupportedOperationException("Unable to get delegate from proxy"); + return field.get(proxy) as T + } + + def void setDelegate(RpcService proxy, RpcService delegate) { + val field = proxy.class.getField(DELEGATE_FIELD) + if(field == null) throw new UnsupportedOperationException("Unable to set delegate to proxy"); + if (field.type.isAssignableFrom(delegate.class)) { + field.set(proxy,delegate) + } else throw new IllegalArgumentException("delegate class is not assignable to proxy"); + } + + +}