Merge from development repository.
[controller.git] / opendaylight / sal / yang-prototype / sal / sal-binding-broker-impl / src / main / java / org / opendaylight / controller / sal / binding / impl / BindingBrokerImpl.java
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingBrokerImpl.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingBrokerImpl.java
new file mode 100644 (file)
index 0000000..4cc23b4
--- /dev/null
@@ -0,0 +1,188 @@
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.spi.SALBindingModule;
+import org.opendaylight.controller.yang.binding.RpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BindingBrokerImpl implements BindingAwareBroker {
+
+    private static Logger log = LoggerFactory
+            .getLogger(BindingBrokerImpl.class);
+
+    private Set<ConsumerSessionImpl> sessions = new HashSet<ConsumerSessionImpl>();
+    private Set<ProviderSessionImpl> providerSessions = new HashSet<ProviderSessionImpl>();
+
+    private Set<SALBindingModule> modules = new HashSet<SALBindingModule>();
+    private Map<Class<? extends BindingAwareService>, SALBindingModule> salServiceProviders = new HashMap<Class<? extends BindingAwareService>, SALBindingModule>();
+
+    @Override
+    public ConsumerSession registerConsumer(BindingAwareConsumer consumer) {
+        checkPredicates(consumer);
+        log.info("Registering consumer " + consumer);
+
+        ConsumerSessionImpl session = newSessionFor(consumer);
+        consumer.onSessionInitialized(session);
+
+        sessions.add(session);
+
+        return session;
+
+    }
+
+    @Override
+    public ProviderSession registerProvider(BindingAwareProvider provider) {
+        checkPredicates(provider);
+
+        ProviderSessionImpl session = newSessionFor(provider);
+        provider.onSessionInitiated(session);
+
+        providerSessions.add(session);
+        return session;
+    }
+
+    public void addModule(SALBindingModule module) {
+        log.info("Registering broker module " + module);
+        if (modules.contains(module)) {
+            log.error("Module already registered");
+            throw new IllegalArgumentException("Module already exists.");
+        }
+
+        Set<Class<? extends BindingAwareService>> provServices = module
+                .getProvidedServices();
+        for (Class<? extends BindingAwareService> serviceType : provServices) {
+            log.info("  Registering session service implementation: "
+                    + serviceType.getCanonicalName());
+            salServiceProviders.put(serviceType, module);
+        }
+    }
+
+    public void consumerSessionClosed(ConsumerSessionImpl consumerSessionImpl) {
+        sessions.remove(consumerSessionImpl);
+        providerSessions.remove(consumerSessionImpl);
+    }
+
+    private void checkPredicates(BindingAwareProvider prov) {
+        if (prov == null)
+            throw new IllegalArgumentException("Provider should not be null.");
+        for (ProviderSessionImpl session : providerSessions) {
+            if (prov.equals(session.getProvider()))
+                throw new IllegalStateException("Provider already registered");
+        }
+
+    }
+
+    private void checkPredicates(BindingAwareConsumer cons) {
+        if (cons == null)
+            throw new IllegalArgumentException("Consumer should not be null.");
+        for (ConsumerSessionImpl session : sessions) {
+            if (cons.equals(session.getConsumer()))
+                throw new IllegalStateException("Consumer already registered");
+        }
+    }
+
+    private ConsumerSessionImpl newSessionFor(BindingAwareConsumer cons) {
+        return new ConsumerSessionImpl(cons);
+    }
+
+    private ProviderSessionImpl newSessionFor(BindingAwareProvider provider) {
+        return new ProviderSessionImpl(provider);
+    }
+
+    private <T extends BindingAwareService> T newSALServiceForSession(
+            Class<T> service, ConsumerSession session) {
+
+        SALBindingModule serviceProvider = salServiceProviders.get(service);
+        if (serviceProvider == null) {
+            return null;
+        }
+        return serviceProvider.getServiceForSession(service, session);
+
+    }
+
+    private class ConsumerSessionImpl implements
+            BindingAwareBroker.ConsumerSession {
+
+        private final BindingAwareConsumer consumer;
+        private Map<Class<? extends BindingAwareService>, BindingAwareService> sessionSalServices = new HashMap<Class<? extends BindingAwareService>, BindingAwareService>();
+
+        public ConsumerSessionImpl(BindingAwareConsumer cons) {
+            this.consumer = cons;
+        }
+
+        @Override
+        public <T extends BindingAwareService> T getSALService(Class<T> service) {
+
+            BindingAwareService serv = sessionSalServices.get(service);
+            if (serv != null) {
+                if (service.isInstance(serv)) {
+                    @SuppressWarnings("unchecked")
+                    T ret = (T) serv;
+                    return ret;
+                } else {
+                    log.error("Implementation for service " + service.getName()
+                            + " does not implement the service interface");
+                    throw new IllegalStateException("Service implementation "
+                            + serv.getClass().getName() + "does not implement "
+                            + service.getName());
+                }
+            } else {
+                T ret = BindingBrokerImpl.this.newSALServiceForSession(service,
+                        this);
+                if (ret != null) {
+                    sessionSalServices.put(service, ret);
+                }
+                return ret;
+            }
+        }
+
+        @Override
+        public <T extends RpcService> T getRpcService(Class<T> module) {
+            // TODO Implement this method
+            throw new UnsupportedOperationException("Not implemented");
+        }
+
+        public BindingAwareConsumer getConsumer() {
+            return this.consumer;
+        }
+
+    }
+
+    private class ProviderSessionImpl extends ConsumerSessionImpl implements
+            BindingAwareBroker.ProviderSession {
+
+        private final BindingAwareProvider provider;
+
+        public ProviderSessionImpl(BindingAwareProvider provider2) {
+            super(null);
+            this.provider = provider2;
+        }
+
+        @Override
+        public void addRpcImplementation(RpcService implementation) {
+            // TODO Implement this method
+            throw new UnsupportedOperationException("Not implemented");
+        }
+
+        @Override
+        public void removeRpcImplementation(RpcService implementation) {
+            // TODO Implement this method
+            throw new UnsupportedOperationException("Not implemented");
+        }
+
+        public BindingAwareProvider getProvider() {
+            return this.provider;
+        }
+
+    }
+
+}