summaryrefslogtreecommitdiffstats
path: root/infra/minimal-distribution/src/main/java/io
diff options
context:
space:
mode:
Diffstat (limited to 'infra/minimal-distribution/src/main/java/io')
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java116
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ProviderTrait.groovy36
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/CfgAttrsModule.groovy31
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy74
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/BindingDataBrokerProvider.groovy39
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ConfigAndOperationalPipelineModule.groovy71
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DOMNotificationServiceProvider.groovy34
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataStoreProvider.groovy40
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataTreeProvider.groovy59
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMBrokerProvider.groovy44
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMDataBrokerProvider.groovy43
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombNotificationManagerProvider.groovy72
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/InmemoryDOMDataBrokerProvider.groovy65
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ModifiableDTDelegProvider.groovy48
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/NotificationModule.groovy45
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.groovy39
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ContextPipelineModule.groovy58
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/HoneycombContextDOMDataBrokerProvider.groovy36
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ModifiableDTMgrProvider.groovy36
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReadableDTDelegProvider.groovy48
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.groovy39
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerPipelineModule.groovy57
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryProvider.groovy73
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/PersistedFileInitializerProvider.groovy67
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy94
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfBindingBrokerProvider.groovy41
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMdsalMapperProvider.groovy55
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfModule.groovy130
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringMapperProvider.groovy55
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringReaderFactoryProvider.groovy37
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringServiceProvider.groovy42
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationMapperProvider.groovy72
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationsReaderFactoryProvider.groovy53
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfReadersModule.groovy36
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfServerDispatcherProvider.groovy68
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy98
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfTcpServerProvider.groovy65
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy42
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyTimerProvider.groovy41
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy30
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy62
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/ModuleInfoBackedCtxProvider.groovy47
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaModule.groovy35
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaServiceProvider.groovy79
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SerializerProvider.groovy47
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/YangBindingProviderModule.groovy49
46 files changed, 2548 insertions, 0 deletions
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java
new file mode 100644
index 000000000..d715c592d
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.name.Names;
+import groovy.util.logging.Slf4j;
+import io.fd.honeycomb.data.init.DataTreeInitializer;
+import io.fd.honeycomb.data.init.InitializerRegistry;
+import io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+import io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule;
+import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule;
+import io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule;
+import io.fd.honeycomb.infra.distro.netconf.HoneycombNotification2NetconfProvider;
+import io.fd.honeycomb.infra.distro.netconf.NetconfModule;
+import io.fd.honeycomb.infra.distro.netconf.NetconfReadersModule;
+import io.fd.honeycomb.infra.distro.netconf.NetconfSshServerProvider;
+import io.fd.honeycomb.infra.distro.netconf.NetconfTcpServerProvider;
+import io.fd.honeycomb.infra.distro.restconf.RestconfModule;
+import io.fd.honeycomb.infra.distro.schema.SchemaModule;
+import io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule;
+import io.fd.honeycomb.infra.distro.data.NotificationModule;
+import java.util.List;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.sal.rest.api.RestConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Slf4j
+public final class Main {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Main.class);
+
+ public static final List<Module> BASE_MODULES = ImmutableList.of(
+ // Infra
+ new YangBindingProviderModule(),
+ new SchemaModule(),
+ new NotificationModule(),
+ new ConfigAndOperationalPipelineModule(),
+ new ContextPipelineModule(),
+ new InitializerPipelineModule(),
+ new NetconfModule(),
+ new NetconfReadersModule(),
+ new RestconfModule(),
+ // Json config attributes
+ new CfgAttrsModule());
+
+ public static void main(String[] args) {
+ // TODO add "clean" argument
+ init(BASE_MODULES);
+ }
+
+ public static void init(final List<? extends Module> modules) {
+ LOG.info("Starting honeycomb");
+
+ Injector injector = Guice.createInjector(modules);
+ LOG.info("Honeycomb configuration: " + injector.getInstance(HoneycombConfiguration.class));
+
+ // Log all bindings
+ injector.getAllBindings().entrySet().stream()
+ .forEach(e -> LOG.trace("Component available under: {} is {}", e.getKey(), e.getValue()));
+
+ final HoneycombConfiguration cfgAttributes = injector.getInstance(HoneycombConfiguration.class);
+
+ // Now get instances for all dependency roots
+
+ LOG.info("Starting RESTCONF");
+ injector.getInstance(RestConnector.class);
+
+ LOG.info("Starting NETCONF");
+ injector.getInstance(
+ Key.get(NetconfOperationServiceFactory.class, Names.named(NetconfModule.NETCONF_MAPPER_HONEYCOMB)));
+ injector.getInstance(
+ Key.get(NetconfOperationServiceFactory.class, Names.named(NetconfModule.NETCONF_MAPPER_NOTIFICATION)));
+ injector.getInstance(
+ Key.get(NetconfOperationServiceFactory.class, Names.named(NetconfModule.NETCONF_MAPPER_MONITORING)));
+
+ if (cfgAttributes.isNetconfTcpServerEnabled()) {
+ injector.getInstance(NetconfTcpServerProvider.NetconfTcpServer.class);
+ }
+
+ injector.getInstance(NetconfSshServerProvider.NetconfSshServer.class);
+ injector.getInstance(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf.class);
+
+ LOG.info("Honeycomb started successfully!");
+
+ try {
+ LOG.info("Initializing configuration");
+ injector.getInstance(Key.get(InitializerRegistry.class, Names.named("honeycomb-initializer"))).initialize();
+ LOG.info("Configuration initialized successfully");
+ } catch (DataTreeInitializer.InitializeException e) {
+ LOG.error("Unable to initialize configuration", e);
+ }
+
+ LOG.info("Honeycomb started successfully!");
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ProviderTrait.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ProviderTrait.groovy
new file mode 100644
index 000000000..d1bce3176
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ProviderTrait.groovy
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro
+
+import com.google.inject.Provider
+import groovy.util.logging.Slf4j
+
+// TODO this should be a trait, but groovy compilation/stub generation sometimes fails (only) in Intellij if using trait
+
+@Slf4j
+abstract class ProviderTrait<T> implements Provider<T> {
+
+ @Override
+ T get() {
+ log.info "Providing: {}", this
+ T create = create() as T
+ log.debug "Provided: {}", create
+ create
+ }
+
+ abstract def create()
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/CfgAttrsModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/CfgAttrsModule.groovy
new file mode 100644
index 000000000..6c9b0a50a
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/CfgAttrsModule.groovy
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.cfgattrs
+
+import com.google.inject.AbstractModule
+import groovy.util.logging.Slf4j
+import net.jmob.guice.conf.core.ConfigurationModule
+
+@Slf4j
+class CfgAttrsModule extends AbstractModule {
+
+ protected void configure() {
+ install(ConfigurationModule.create())
+ // Inject non-dependency configuration
+ requestInjection(HoneycombConfiguration)
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
new file mode 100644
index 000000000..78a1a04fd
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.cfgattrs
+
+import groovy.transform.ToString
+import net.jmob.guice.conf.core.BindConfig
+import net.jmob.guice.conf.core.InjectConfig
+import net.jmob.guice.conf.core.Syntax
+
+@ToString(includeNames = true)
+@BindConfig(value = "honeycomb", syntax = Syntax.JSON)
+class HoneycombConfiguration {
+
+ // TODO break into smaller pieces, config, context, rest, netconf etc.
+
+ @InjectConfig("persisted-context-path")
+ String peristContextPath
+ @InjectConfig("persisted-context-restoration-type")
+ String persistedContextRestorationType
+
+ @InjectConfig("persisted-config-path")
+ String peristConfigPath
+ @InjectConfig("persisted-config-restoration-type")
+ String persistedConfigRestorationType
+
+ @InjectConfig("notification-service-queue-depth")
+ int notificationServiceQueueDepth
+
+ // RESTCONF
+ @InjectConfig("restconf-websocket-port")
+ int restconfWebsocketPort
+ @InjectConfig("restconf-port")
+ int restconfPort
+ @InjectConfig("restconf-root-path")
+ String restconfRootPath
+
+ // NETCONF
+ @InjectConfig("netconf-netty-threads")
+ Optional<Integer> netconfNettyThreads
+ // NETCONF TCP optional
+ @InjectConfig("netconf-tcp-binding-address")
+ Optional<String> netconfTcpBindingAddress
+ @InjectConfig("netconf-tcp-binding-port")
+ Optional<Integer> netconfTcpBindingPort
+ // NETCONF SSH
+ @InjectConfig("netconf-ssh-binding-address")
+ String netconfSshBindingAddress
+ @InjectConfig("netconf-ssh-binding-port")
+ Integer netconfSshBindingPort
+
+ @InjectConfig("netconf-notification-stream-name")
+ String netconfNotificationStreamName
+
+ boolean isNetconfTcpServerEnabled() { netconfTcpBindingAddress.isPresent() && netconfTcpBindingPort.isPresent() }
+
+ @InjectConfig("username")
+ String username
+ @InjectConfig("password")
+ String password
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/BindingDataBrokerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/BindingDataBrokerProvider.groovy
new file mode 100644
index 000000000..e73f14932
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/BindingDataBrokerProvider.groovy
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+
+@Slf4j
+@ToString
+class BindingDataBrokerProvider extends ProviderTrait<DataBroker> {
+
+ @Inject
+ DOMDataBroker domDataBroker
+ @Inject
+ BindingToNormalizedNodeCodec mappingService
+
+ @Override
+ def create() { new BindingDOMDataBrokerAdapter(domDataBroker, mappingService) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ConfigAndOperationalPipelineModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ConfigAndOperationalPipelineModule.groovy
new file mode 100644
index 000000000..01ec8c16a
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ConfigAndOperationalPipelineModule.groovy
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.PrivateModule
+import com.google.inject.Singleton
+import com.google.inject.name.Names
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.ModifiableDataManager
+import io.fd.honeycomb.data.ReadableDataManager
+import io.fd.honeycomb.data.init.DataTreeInitializer
+import io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider
+import io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider
+import io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider
+import io.fd.honeycomb.infra.distro.initializer.PersistedFileInitializerProvider
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree
+
+@Slf4j
+class ConfigAndOperationalPipelineModule extends PrivateModule {
+
+ protected void configure() {
+ // Expose registries
+ bind(ModifiableWriterRegistryBuilder).toProvider(WriterRegistryProvider).in(Singleton)
+ expose(ModifiableWriterRegistryBuilder)
+ bind(ModifiableReaderRegistryBuilder).toProvider(ReaderRegistryProvider).in(Singleton)
+ expose(ModifiableReaderRegistryBuilder)
+
+ def dataTreeProvider = new DataTreeProvider.ConfigDataTreeProvider()
+ bind(DataTree).annotatedWith(Names.named("honeycomb-config")).toProvider(dataTreeProvider).in(Singleton)
+ expose(DataTree).annotatedWith(Names.named("honeycomb-config"))
+
+ bind(ModifiableDataManager).toProvider(ModifiableDTDelegProvider).in(Singleton)
+ bind(ReadableDataManager)
+ .annotatedWith(Names.named("honeycomb-operational"))
+ .toProvider(ReadableDTDelegProvider).in(Singleton)
+ // Expose reader for initializer
+ expose(ReadableDataManager).annotatedWith(Names.named("honeycomb-operational"))
+
+ def domBrokerProvider = new HoneycombDOMDataBrokerProvider()
+ bind(DOMDataBroker).annotatedWith(Names.named("honeycomb-config")).toProvider(domBrokerProvider).in(Singleton)
+ // Bind also without annotation for easy private injection
+ bind(DOMDataBroker).toProvider(domBrokerProvider).in(Singleton)
+ expose(DOMDataBroker).annotatedWith(Names.named("honeycomb-config"))
+ bind(DataBroker).annotatedWith(Names.named("honeycomb-config")).toProvider(BindingDataBrokerProvider).in(Singleton)
+ expose(DataBroker).annotatedWith(Names.named("honeycomb-config"))
+
+ bind(DataTreeInitializer)
+ .annotatedWith(Names.named("honeycomb-config"))
+ .toProvider(PersistedFileInitializerProvider.PersistedConfigInitializerProvider)
+ .in(Singleton)
+ expose(DataTreeInitializer).annotatedWith(Names.named("honeycomb-config"))
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DOMNotificationServiceProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DOMNotificationServiceProvider.groovy
new file mode 100644
index 000000000..f8a1859e2
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DOMNotificationServiceProvider.groovy
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter
+
+@Slf4j
+@ToString
+class DOMNotificationServiceProvider extends ProviderTrait<DOMNotificationRouter> {
+
+ @Inject
+ HoneycombConfiguration cfg
+
+ def create() { DOMNotificationRouter.create(cfg.notificationServiceQueueDepth) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataStoreProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataStoreProvider.groovy
new file mode 100644
index 000000000..6d075ccc8
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataStoreProvider.groovy
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+
+@Slf4j
+@ToString
+class DataStoreProvider extends ProviderTrait<InMemoryDOMDataStore> {
+
+ @Inject
+ SchemaService schemaService
+
+ String name
+ LogicalDatastoreType type
+
+ @Override
+ def create() { InMemoryDOMDataStoreFactory.create(name, type, schemaService, false, null) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataTreeProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataTreeProvider.groovy
new file mode 100644
index 000000000..6915a3cec
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/DataTreeProvider.groovy
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.impl.PersistingDataTreeAdapter
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory
+
+import java.nio.file.Paths
+
+@Slf4j
+@ToString
+abstract class DataTreeProvider extends ProviderTrait<DataTree> {
+
+ @Inject
+ SchemaService schemaService
+ @Inject
+ HoneycombConfiguration config
+
+ def create() {
+ def delegate = InMemoryDataTreeFactory.getInstance().create(getType())
+ delegate.setSchemaContext(schemaService.getGlobalContext())
+ new PersistingDataTreeAdapter(delegate, schemaService, Paths.get(getPath()))
+ }
+
+ abstract String getPath()
+ abstract TreeType getType()
+
+ static class ConfigDataTreeProvider extends DataTreeProvider {
+ String getPath() { config.peristConfigPath }
+ TreeType getType() { TreeType.CONFIGURATION }
+ }
+
+ static class ContextDataTreeProvider extends DataTreeProvider {
+ String getPath() { config.peristContextPath }
+ TreeType getType() { TreeType.OPERATIONAL }
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMBrokerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMBrokerProvider.groovy
new file mode 100644
index 000000000..2b275f7ff
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMBrokerProvider.groovy
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.impl.NorthboundFacadeHoneycombDOMBroker
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService
+import org.opendaylight.controller.sal.core.api.Broker
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+
+@Slf4j
+@ToString
+class HoneycombDOMBrokerProvider extends ProviderTrait<Broker> {
+
+ @Inject
+ @Named("honeycomb-config")
+ DOMDataBroker domDataBroker
+ @Inject
+ SchemaService schemaService
+ @Inject
+ @Named("honeycomb")
+ DOMNotificationService domNotificationService
+
+ def create() { new NorthboundFacadeHoneycombDOMBroker(domDataBroker, schemaService, domNotificationService) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMDataBrokerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMDataBrokerProvider.groovy
new file mode 100644
index 000000000..e91054b3b
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMDataBrokerProvider.groovy
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.ModifiableDataManager
+import io.fd.honeycomb.data.ReadableDataManager
+import io.fd.honeycomb.data.impl.DataBroker
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+
+@Slf4j
+@ToString
+class HoneycombDOMDataBrokerProvider extends ProviderTrait<DOMDataBroker> {
+
+ @Inject
+ ModifiableDataManager modDataManager
+
+ @Inject
+ @Named("honeycomb-operational")
+ ReadableDataManager readDataManager
+
+ def create() {
+ readDataManager ? DataBroker.create(modDataManager, readDataManager) : DataBroker.create(modDataManager)
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombNotificationManagerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombNotificationManagerProvider.groovy
new file mode 100644
index 000000000..f150691a8
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombNotificationManagerProvider.groovy
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.notification.ManagedNotificationProducer
+import io.fd.honeycomb.notification.NotificationCollector
+import io.fd.honeycomb.notification.impl.HoneycombNotificationCollector
+import io.fd.honeycomb.notification.impl.NotificationProducerRegistry
+import io.fd.honeycomb.notification.impl.NotificationProducerTracker
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter
+
+/**
+ * Mirror of org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.notification.impl.rev160601.HoneycombNotificationManagerModule
+ */
+@Slf4j
+@ToString
+class HoneycombNotificationManagerProvider extends ProviderTrait<NotificationCollector> {
+
+ @Inject
+ @Named("honeycomb")
+ DOMNotificationRouter notificationRouter
+ @Inject(optional = true)
+ Set<ManagedNotificationProducer> notificationProducers = []
+ @Inject
+ BindingToNormalizedNodeCodec codec
+
+ @Override
+ def create() {
+ // Create the registry to keep track of what'OPERATIONAL registered
+ def notificationProducerRegistry = new NotificationProducerRegistry(notificationProducers as List);
+
+ // Create BA version of notification service (implementation is free from ODL)
+ def bindingDOMNotificationPublishServiceAdapter =
+ new BindingDOMNotificationPublishServiceAdapter(codec, notificationRouter);
+
+ // Create Collector on top of BA notification service and registry
+ def honeycombNotificationCollector =
+ new HoneycombNotificationCollector(bindingDOMNotificationPublishServiceAdapter, notificationProducerRegistry);
+
+ // Create tracker, responsible for starting and stopping registered notification producers whenever necessary
+ def notificationProducerTracker =
+ new NotificationProducerTracker(notificationProducerRegistry, honeycombNotificationCollector,
+ notificationRouter);
+
+ // TODO wire with restconf
+ // DOMNotificationService is already provided by DOMBroker injected into RESTCONF, however RESTCONF
+ // only supports data-change notification, nothing else. So currently its impossible.
+
+ honeycombNotificationCollector
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/InmemoryDOMDataBrokerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/InmemoryDOMDataBrokerProvider.groovy
new file mode 100644
index 000000000..6462baa71
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/InmemoryDOMDataBrokerProvider.groovy
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitDeadlockException
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+import org.opendaylight.controller.md.sal.dom.broker.impl.SerializedDOMDataBroker
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore
+import org.opendaylight.yangtools.util.concurrent.DeadlockDetectingListeningExecutorService
+import org.opendaylight.yangtools.util.concurrent.SpecialExecutors
+/**
+ * Mirror of org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModule
+ */
+@Slf4j
+@ToString
+class InmemoryDOMDataBrokerProvider extends ProviderTrait<DOMDataBroker> {
+
+ public static final String CONFIG = "config"
+ public static final String OPERATIONAL = "operational"
+
+ @Inject
+ @Named(InmemoryDOMDataBrokerProvider.CONFIG)
+ InMemoryDOMDataStore cfgDataStore
+
+ @Inject
+ @Named(InmemoryDOMDataBrokerProvider.OPERATIONAL)
+ InMemoryDOMDataStore operDataStore
+
+ @Override
+ def create() {
+ // This Databroker is dedicated for netconf metadata, not expected to be under heavy load
+ def listenableFutureExecutor = SpecialExecutors.newBlockingBoundedCachedThreadPool(1, 100, "commits")
+ def commitExecutor = SpecialExecutors.newBoundedSingleThreadExecutor(100, "WriteTxCommit")
+ // TODO try to provide more lightweight implementation of DataBroker, maybe a single executor would be enough
+
+ def map = [:]
+ map.put(LogicalDatastoreType.CONFIGURATION, cfgDataStore)
+ map.put(LogicalDatastoreType.OPERATIONAL, operDataStore)
+
+ new SerializedDOMDataBroker(map,
+ new DeadlockDetectingListeningExecutorService(commitExecutor,
+ TransactionCommitDeadlockException.DEADLOCK_EXCEPTION_SUPPLIER,
+ listenableFutureExecutor))
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ModifiableDTDelegProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ModifiableDTDelegProvider.groovy
new file mode 100644
index 000000000..f7ec4cc12
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/ModifiableDTDelegProvider.groovy
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.ModifiableDataManager
+import io.fd.honeycomb.data.impl.ModifiableDataTreeDelegator
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree
+
+@Slf4j
+@ToString
+class ModifiableDTDelegProvider extends ProviderTrait<ModifiableDataManager> {
+
+ @Inject
+ BindingToNormalizedNodeCodec serializer
+ @Inject
+ @Named("honeycomb-config")
+ DataTree dataTree
+ @Inject
+ ModifiableWriterRegistryBuilder registry
+ @Inject
+ @Named("honeycomb-context")
+ DataBroker contextBroker
+
+ @Override
+ def create() { new ModifiableDataTreeDelegator(serializer, dataTree, registry.build(), contextBroker) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/NotificationModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/NotificationModule.groovy
new file mode 100644
index 000000000..4836a0fbe
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/NotificationModule.groovy
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data
+
+import com.google.inject.AbstractModule
+import com.google.inject.Singleton
+import com.google.inject.name.Names
+import groovy.util.logging.Slf4j
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter
+import org.opendaylight.controller.sal.core.api.Broker
+
+@Slf4j
+class NotificationModule extends AbstractModule {
+
+ protected void configure() {
+ def provider = new DOMNotificationServiceProvider()
+ bind(DOMNotificationService)
+ .annotatedWith(Names.named("honeycomb"))
+ .toProvider(provider)
+ .in(Singleton)
+ bind(DOMNotificationRouter)
+ .annotatedWith(Names.named("honeycomb"))
+ .toProvider(provider)
+ .in(Singleton)
+ bind(Broker)
+ .annotatedWith(Names.named("honeycomb"))
+ .toProvider(HoneycombDOMBrokerProvider)
+ .in(Singleton)
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.groovy
new file mode 100644
index 000000000..3c94812ef
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.groovy
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data.config
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.translate.util.write.registry.FlatWriterRegistryBuilder
+import io.fd.honeycomb.translate.write.WriterFactory
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder
+
+@Slf4j
+@ToString
+class WriterRegistryProvider extends ProviderTrait<ModifiableWriterRegistryBuilder> {
+
+ @Inject(optional = true)
+ Set<WriterFactory> writerFactories = []
+
+ def create() {
+ def builder = new FlatWriterRegistryBuilder()
+ writerFactories.forEach { it.init(builder) }
+ builder
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ContextPipelineModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ContextPipelineModule.groovy
new file mode 100644
index 000000000..01124131f
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ContextPipelineModule.groovy
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data.context
+
+import com.google.inject.PrivateModule
+import com.google.inject.Singleton
+import com.google.inject.name.Names
+import io.fd.honeycomb.data.ModifiableDataManager
+import io.fd.honeycomb.data.init.DataTreeInitializer
+import io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider
+import io.fd.honeycomb.infra.distro.data.DataTreeProvider
+import io.fd.honeycomb.infra.distro.initializer.PersistedFileInitializerProvider
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree
+
+class ContextPipelineModule extends PrivateModule {
+
+ protected void configure() {
+ // Bind also without annotation for easy private injection
+ def dataTreeProvider = new DataTreeProvider.ContextDataTreeProvider()
+ bind(DataTree).toProvider(dataTreeProvider).in(Singleton)
+ bind(DataTree).annotatedWith(Names.named("honeycomb-context")).toProvider(dataTreeProvider).in(Singleton)
+ expose(DataTree).annotatedWith(Names.named("honeycomb-context"))
+
+ bind(ModifiableDataManager).toProvider(ModifiableDTMgrProvider).in(Singleton)
+
+ def domBrokerProvider = new HoneycombContextDOMDataBrokerProvider()
+ bind(DOMDataBroker).annotatedWith(Names.named("honeycomb-context")).toProvider(domBrokerProvider).in(Singleton)
+ // Bind also without annotation for easy private injection
+ bind(DOMDataBroker).toProvider(domBrokerProvider).in(Singleton)
+ expose(DOMDataBroker).annotatedWith(Names.named("honeycomb-context"))
+
+ bind(DataBroker).annotatedWith(Names.named("honeycomb-context")).toProvider(BindingDataBrokerProvider).in(Singleton)
+ expose(DataBroker).annotatedWith(Names.named("honeycomb-context"))
+
+ bind(DataTreeInitializer)
+ .annotatedWith(Names.named("honeycomb-context"))
+ .toProvider(PersistedFileInitializerProvider.PersistedContextInitializerProvider)
+ .in(Singleton)
+ expose(DataTreeInitializer).annotatedWith(Names.named("honeycomb-context"))
+ }
+
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/HoneycombContextDOMDataBrokerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/HoneycombContextDOMDataBrokerProvider.groovy
new file mode 100644
index 000000000..eecd87e42
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/HoneycombContextDOMDataBrokerProvider.groovy
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data.context
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.ModifiableDataManager
+import io.fd.honeycomb.data.impl.DataBroker
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+
+@Slf4j
+@ToString
+class HoneycombContextDOMDataBrokerProvider extends ProviderTrait<DOMDataBroker> {
+
+ @Inject
+ ModifiableDataManager modDataManager
+
+ def create() { DataBroker.create(modDataManager) }
+
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ModifiableDTMgrProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ModifiableDTMgrProvider.groovy
new file mode 100644
index 000000000..01d854b28
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/context/ModifiableDTMgrProvider.groovy
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data.context
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.ModifiableDataManager
+import io.fd.honeycomb.data.impl.ModifiableDataTreeManager
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree
+
+@Slf4j
+@ToString
+class ModifiableDTMgrProvider extends ProviderTrait<ModifiableDataManager> {
+
+ @Inject
+ DataTree dataTree
+
+ @Override
+ def create() { new ModifiableDataTreeManager(dataTree) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReadableDTDelegProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReadableDTDelegProvider.groovy
new file mode 100644
index 000000000..384278793
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReadableDTDelegProvider.groovy
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data.oper
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.ReadableDataManager
+import io.fd.honeycomb.data.impl.ReadableDataTreeDelegator
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+
+@Slf4j
+@ToString
+class ReadableDTDelegProvider extends ProviderTrait<ReadableDataManager> {
+
+ @Inject
+ BindingToNormalizedNodeCodec serializer
+ @Inject
+ SchemaService schemaService
+ @Inject
+ ModifiableReaderRegistryBuilder registry
+ @Inject
+ @Named("honeycomb-context")
+ DataBroker contextBroker
+
+ def create() {
+ new ReadableDataTreeDelegator(serializer, schemaService.getGlobalContext(), registry.build(), contextBroker)
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.groovy
new file mode 100644
index 000000000..36f74d948
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.groovy
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.data.oper
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.translate.read.ReaderFactory
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder
+import io.fd.honeycomb.translate.util.read.registry.CompositeReaderRegistryBuilder
+
+@Slf4j
+@ToString
+class ReaderRegistryProvider extends ProviderTrait<ModifiableReaderRegistryBuilder> {
+
+ @Inject(optional = true)
+ Set<ReaderFactory> readerFactories = []
+
+ def create() {
+ def builder = new CompositeReaderRegistryBuilder()
+ readerFactories.forEach { it.init(builder) }
+ builder
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerPipelineModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerPipelineModule.groovy
new file mode 100644
index 000000000..80b52f2b8
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerPipelineModule.groovy
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.initializer
+
+import com.google.inject.PrivateModule
+import com.google.inject.Singleton
+import com.google.inject.name.Names
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.ModifiableDataManager
+import io.fd.honeycomb.data.init.InitializerRegistry
+import io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider
+import io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider
+import io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider
+import io.fd.honeycomb.translate.util.write.NoopWriterRegistry
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+
+@Slf4j
+class InitializerPipelineModule extends PrivateModule {
+
+ protected void configure() {
+ // Initializer hierarchy uses fake writer registry to not send restored configuration from plugins back to plugins
+ def registry = new NoopWriterRegistry()
+ bind(ModifiableWriterRegistryBuilder)
+ .annotatedWith(Names.named("honeycomb-initializer"))
+ .toInstance([build: { registry }])
+
+ // Then just build data tree delegator and DataBrokers on top of it
+ bind(ModifiableDataManager).toProvider(ModifiableDTDelegProvider).in(Singleton)
+ bind(DOMDataBroker).toProvider(HoneycombDOMDataBrokerProvider).in(Singleton)
+ bind(DataBroker).annotatedWith(Names.named("honeycomb-initializer")).toProvider(BindingDataBrokerProvider).in(Singleton)
+ expose(DataBroker).annotatedWith(Names.named("honeycomb-initializer"))
+
+ // NOW do initializer registry
+ bind(InitializerRegistry)
+ .annotatedWith(Names.named("honeycomb-initializer"))
+ .toProvider(InitializerRegistryProvider)
+ .in(Singleton)
+ expose(InitializerRegistry)
+ .annotatedWith(Names.named("honeycomb-initializer"))
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryProvider.groovy
new file mode 100644
index 000000000..5f75fc026
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryProvider.groovy
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.initializer
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.init.DataTreeInitializer
+import io.fd.honeycomb.data.init.InitializerRegistry
+import io.fd.honeycomb.data.init.InitializerRegistryImpl
+import io.fd.honeycomb.infra.distro.ProviderTrait
+
+@Slf4j
+@ToString
+class InitializerRegistryProvider extends ProviderTrait<InitializerRegistry> {
+
+ @Inject
+ @Named("honeycomb-context")
+ DataTreeInitializer contextInitializer
+ @Inject
+ @Named("honeycomb-config")
+ DataTreeInitializer configInitializer
+ @Inject(optional = true)
+ Set<DataTreeInitializer> pluginInitializers = []
+
+ @Override
+ def create() {
+ return new InitializerRegistry() {
+
+ @Override
+ void initialize() throws DataTreeInitializer.InitializeException {
+ log.info("Config initialization started");
+
+ final InitializerRegistry initializer = new InitializerRegistryImpl(new ArrayList<>(pluginInitializers))
+
+ try {
+ // Initialize contexts first so that other initializers can find any relevant mapping before initializing
+ // configuration to what is already in VPP
+ contextInitializer.initialize();
+ log.info("Persisted context restored successfully");
+ // Initialize all registered initializers
+ initializer.initialize();
+ log.info("Configuration initialized successfully");
+ // Initialize stored configuration on top
+ configInitializer.initialize();
+ log.info("Persisted configuration restored successfully");
+ } catch (Exception e) {
+ log.warn("Failed to initialize config", e);
+ }
+
+ log.info("Honeycomb initialized");
+ }
+
+ @Override
+ void close() throws Exception {}
+ }
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/PersistedFileInitializerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/PersistedFileInitializerProvider.groovy
new file mode 100644
index 000000000..c2448d234
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/initializer/PersistedFileInitializerProvider.groovy
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.initializer
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.data.init.RestoringInitializer
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.init.rev160407.RestorationType
+
+import java.nio.file.Paths
+/**
+ * Mirror of org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.initializer.rev160407.PersistedFileInitializerModule
+ */
+@Slf4j
+@ToString
+abstract class PersistedFileInitializerProvider extends ProviderTrait<RestoringInitializer> {
+
+ @Inject
+ SchemaService schemaService
+ @Inject
+ HoneycombConfiguration cfgAttributes
+
+ @Inject
+ DOMDataBroker domDataBroker
+
+ @Override
+ def create() {
+ new RestoringInitializer(schemaService, Paths.get(getPersistPath()),
+ domDataBroker, RestorationType.valueOf(restorationType), getDataStoreType())
+ }
+
+ abstract String getPersistPath()
+ abstract LogicalDatastoreType getDataStoreType()
+ abstract String getRestorationType()
+
+ static class PersistedContextInitializerProvider extends PersistedFileInitializerProvider {
+ String getPersistPath() { cfgAttributes.peristContextPath }
+ LogicalDatastoreType getDataStoreType() { LogicalDatastoreType.OPERATIONAL }
+ String getRestorationType() { cfgAttributes.persistedContextRestorationType }
+ }
+
+ static class PersistedConfigInitializerProvider extends PersistedFileInitializerProvider {
+ String getPersistPath() { cfgAttributes.peristConfigPath }
+ LogicalDatastoreType getDataStoreType() { LogicalDatastoreType.CONFIGURATION }
+ String getRestorationType() { cfgAttributes.persistedConfigRestorationType }
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy
new file mode 100644
index 000000000..a18d2c4f0
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.notification.NotificationCollector
+import io.fd.honeycomb.notification.impl.NotificationProducerRegistry
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.notification.impl.rev160601.HoneycombNotificationToNetconfTranslatorModule as Mirror
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder
+import org.opendaylight.yangtools.yang.model.api.SchemaPath
+/**
+ * Mirror of org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.notification.impl.rev160601.HoneycombNotificationToNetconfTranslatorModule
+ */
+@Slf4j
+@ToString
+class HoneycombNotification2NetconfProvider extends ProviderTrait<HoneycombNotification2Netconf> {
+
+ @Inject
+ @Named("honeycomb")
+ DOMNotificationRouter notificationRouter
+ @Inject
+ SchemaService schemaService
+ @Inject
+ HoneycombConfiguration cfgAttributes
+ @Inject
+ NotificationCollector hcNotificationCollector
+ @Inject
+ NetconfNotificationCollector netconfNotificationCollector
+
+ // TODO refactor HoneycombNotificationToNetconfTranslatorModule for easier reuse here
+
+ @Override
+ def create() {
+ def streamType = new StreamNameType(cfgAttributes.netconfNotificationStreamName);
+
+ // Register as NETCONF notification publisher under configured name
+ def netconfNotifReg = netconfNotificationCollector.registerNotificationPublisher(new StreamBuilder()
+ .setName(streamType)
+ .setReplaySupport(false)
+ .setDescription(cfgAttributes.netconfNotificationStreamName).build());
+
+ // Notification Translator, get notification from HC producers and put into NETCONF notification collector
+ def domNotificationListener = { notif ->
+ log.debug "Propagating notification: {} into NETCONF", notif.type
+ netconfNotifReg.onNotification(streamType, Mirror.notificationToXml(notif, schemaService.globalContext))
+ }
+
+ // NotificationManager is used to provide list of available notifications (which are all of the notifications registered)
+ // TODO make available notifications configurable here so that any number of notification streams for NETCONF
+ // can be configured on top of a single notification manager
+ log.debug "Current notifications to be exposed over NETCONF: {}", hcNotificationCollector.notificationTypes
+ def currentNotificationSchemaPaths = hcNotificationCollector.notificationTypes
+ .collect {SchemaPath.create(true, NotificationProducerRegistry.getQName(it))}
+
+ // Register as listener to HC'OPERATIONAL DOM notification service
+ // TODO This should only be triggered when NETCONF notifications are activated
+ // Because this way we actually start all notification producers
+ // final Collection<QName> notificationQNames =
+ def domNotifListenerReg = notificationRouter
+ .registerNotificationListener(domNotificationListener, currentNotificationSchemaPaths);
+
+ log.info "Exposing NETCONF notification stream: {}", streamType.value
+
+ new HoneycombNotification2Netconf(domNotifListenerReg: domNotifListenerReg, netconfNotifReg: netconfNotifReg)
+ }
+
+ static class HoneycombNotification2Netconf {
+ def domNotifListenerReg
+ def netconfNotifReg
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfBindingBrokerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfBindingBrokerProvider.groovy
new file mode 100644
index 000000000..8226c8d9e
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfBindingBrokerProvider.groovy
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.honeycomb.impl.rev141210.NetconfBindingBrokerModule
+
+/**
+ * Mirror of {@link org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.honeycomb.impl.rev141210.NetconfBindingBrokerModule}
+ */
+@Slf4j
+@ToString
+class NetconfBindingBrokerProvider extends ProviderTrait<BindingAwareBroker> {
+
+ @Inject
+ @Named(NetconfModule.NETCONF)
+ DataBroker dataBroker
+
+ @Override
+ def create() { new NetconfBindingBrokerModule.FakeBindingAwareBroker(dataBroker) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMdsalMapperProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMdsalMapperProvider.groovy
new file mode 100644
index 000000000..d84af61a8
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMdsalMapperProvider.groovy
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.sal.core.api.Broker
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener
+import org.opendaylight.netconf.mdsal.connector.MdsalNetconfOperationServiceFactory
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext
+/**
+ * Mirror of org.opendaylight.controller.config.yang.netconf.mdsal.mapper.NetconfMdsalMapperModule
+ */
+@Slf4j
+@ToString
+class NetconfMdsalMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> {
+
+ @Inject
+ SchemaService schemaService
+ @Inject
+ NetconfOperationServiceFactoryListener aggregator
+ @Inject
+ ModuleInfoBackedContext moduleInfoBackedContext
+
+ @Inject
+ @Named("honeycomb")
+ Broker domBroker
+
+ def create() {
+ def mdsalNetconfOperationServiceFactory =
+ new MdsalNetconfOperationServiceFactory(schemaService, moduleInfoBackedContext)
+ domBroker.registerConsumer(mdsalNetconfOperationServiceFactory);
+ aggregator.onAddNetconfOperationServiceFactory(mdsalNetconfOperationServiceFactory);
+ return mdsalNetconfOperationServiceFactory;
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfModule.groovy
new file mode 100644
index 000000000..effa50cfd
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfModule.groovy
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.PrivateModule
+import com.google.inject.Singleton
+import com.google.inject.name.Names
+import io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider
+import io.fd.honeycomb.infra.distro.data.DataStoreProvider
+import io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider
+import io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider
+import io.fd.honeycomb.notification.NotificationCollector
+import io.netty.channel.nio.NioEventLoopGroup
+import io.netty.util.Timer
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
+import org.opendaylight.netconf.api.NetconfServerDispatcher
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService
+import org.opendaylight.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector
+import org.opendaylight.netconf.notifications.NetconfNotificationListener
+import org.opendaylight.netconf.notifications.NetconfNotificationRegistry
+import org.opendaylight.netconf.notifications.impl.NetconfNotificationManager
+
+import static InmemoryDOMDataBrokerProvider.CONFIG
+import static InmemoryDOMDataBrokerProvider.OPERATIONAL
+
+class NetconfModule extends PrivateModule {
+
+ public static final String NETCONF = "netconf"
+ public static final String NETCONF_MAPPER_AGGREGATOR = "netconf-mapper-aggregator"
+ public static final String NETCONF_MAPPER_NOTIFICATION = "netconf-mapper-notification"
+ public static final String NETCONF_MAPPER_MONITORING = "netconf-mapper-monitoring"
+ public static final String NETCONF_MAPPER_HONEYCOMB = "netconf-mapper-honeycomb"
+
+ @Override
+ protected void configure() {
+ bind(InMemoryDOMDataStore)
+ .annotatedWith(Names.named(CONFIG))
+ .toProvider(new DataStoreProvider(type: LogicalDatastoreType.CONFIGURATION, name: CONFIG))
+ .in(Singleton)
+ bind(InMemoryDOMDataStore)
+ .annotatedWith(Names.named(OPERATIONAL))
+ .toProvider(new DataStoreProvider(type: LogicalDatastoreType.OPERATIONAL, name: OPERATIONAL))
+ .in(Singleton)
+ bind(DOMDataBroker).toProvider(InmemoryDOMDataBrokerProvider).in(Singleton)
+
+ bind(DataBroker)
+ .annotatedWith(Names.named(NETCONF))
+ .toProvider(BindingDataBrokerProvider)
+ .in(Singleton)
+ expose(DataBroker).annotatedWith(Names.named(NETCONF))
+ bind(BindingAwareBroker)
+ .annotatedWith(Names.named(NETCONF))
+ .toProvider(NetconfBindingBrokerProvider)
+ .in(Singleton)
+
+ // Mirror of org.opendaylight.controller.config.yang.config.netconf.northbound.impl.NetconfMapperAggregatorModule
+ def factory = new AggregatedNetconfOperationServiceFactory()
+ bind(NetconfOperationServiceFactory)
+ .annotatedWith(Names.named(NETCONF_MAPPER_AGGREGATOR))
+ .toInstance(factory)
+ bind(NetconfOperationServiceFactoryListener).toInstance(factory)
+
+ // Mirror of org.opendaylight.controller.config.yang.netconf.northbound.notification.impl.NetconfNotificationManagerModule
+ def manager = new NetconfNotificationManager()
+ bind(NetconfNotificationCollector).toInstance(manager)
+ bind(NetconfNotificationRegistry).toInstance(manager)
+ bind(NetconfNotificationListener).toInstance(manager)
+
+ // Netconf notification part
+ bind(NetconfOperationServiceFactory)
+ .annotatedWith(Names.named(NETCONF_MAPPER_NOTIFICATION))
+ .toProvider(NetconfNotificationMapperProvider)
+ .in(Singleton)
+ expose(NetconfOperationServiceFactory).annotatedWith(Names.named(NETCONF_MAPPER_NOTIFICATION))
+
+ // Netconf core part - mapping between Honeycomb and Netconf
+ bind(NetconfOperationServiceFactory)
+ .annotatedWith(Names.named(NETCONF_MAPPER_HONEYCOMB))
+ .toProvider(NetconfMdsalMapperProvider)
+ .in(Singleton)
+ expose(NetconfOperationServiceFactory).annotatedWith(Names.named(NETCONF_MAPPER_HONEYCOMB))
+
+ // Netconf monitoring part
+ bind(NetconfMonitoringService).toProvider(NetconfMonitoringServiceProvider).in(Singleton)
+ bind(NetconfOperationServiceFactory)
+ .annotatedWith(Names.named(NETCONF_MAPPER_MONITORING))
+ .toProvider(NetconfMonitoringMapperProvider)
+ .in(Singleton)
+ expose(NetconfOperationServiceFactory).annotatedWith(Names.named(NETCONF_MAPPER_MONITORING))
+
+ bind(NotificationCollector).toProvider(HoneycombNotificationManagerProvider).in(Singleton)
+ bind(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf)
+ .toProvider(HoneycombNotification2NetconfProvider)
+ .in(Singleton)
+ expose(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf)
+
+ configureServer()
+ }
+
+ def configureServer() {
+ bind(NioEventLoopGroup).toProvider(NettyThreadGroupProvider).in(Singleton)
+ bind(Timer).toProvider(NettyTimerProvider).in(Singleton)
+ bind(NetconfServerDispatcher).toProvider(NetconfServerDispatcherProvider).in(Singleton)
+ bind(NetconfTcpServerProvider.NetconfTcpServer).toProvider(NetconfTcpServerProvider).in(Singleton)
+ expose(NetconfTcpServerProvider.NetconfTcpServer)
+ bind(NetconfSshServerProvider.NetconfSshServer).toProvider(NetconfSshServerProvider).in(Singleton)
+ expose(NetconfSshServerProvider.NetconfSshServer)
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringMapperProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringMapperProvider.groovy
new file mode 100644
index 000000000..8f53c9d83
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringMapperProvider.groovy
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.MonitoringToMdsalWriter
+import org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.NetconfMdsalMonitoringMapperModule
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener
+/**
+ * Mirror of org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.NetconfMdsalMonitoringMapperModule
+ */
+@Slf4j
+@ToString
+class NetconfMonitoringMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> {
+
+ @Inject
+ @Named(NetconfModule.NETCONF)
+ BindingAwareBroker bindingAwareBroker
+ @Inject
+ NetconfOperationServiceFactoryListener aggregator
+ @Inject
+ NetconfMonitoringService monitoringService
+
+ def create() {
+ def monitoringToMdsalWriter = new MonitoringToMdsalWriter(monitoringService)
+ bindingAwareBroker.registerProvider(monitoringToMdsalWriter)
+
+ def mdSalMonitoringMapperFactory = new NetconfMdsalMonitoringMapperModule.MdSalMonitoringMapperFactory(
+ new NetconfMdsalMonitoringMapperModule.MdsalMonitoringMapper(monitoringService))
+
+ aggregator.onAddNetconfOperationServiceFactory(mdSalMonitoringMapperFactory)
+ return mdSalMonitoringMapperFactory
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringReaderFactoryProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringReaderFactoryProvider.groovy
new file mode 100644
index 000000000..2945ae6d8
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringReaderFactoryProvider.groovy
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.translate.read.ReaderFactory
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.honeycomb.impl.rev141210.NetconfMonitoringReaderModule
+
+@Slf4j
+@ToString
+class NetconfMonitoringReaderFactoryProvider extends ProviderTrait<ReaderFactory> {
+
+ @Inject
+ @Named(NetconfModule.NETCONF)
+ DataBroker netconfDataBroker
+
+ def create() { new NetconfMonitoringReaderModule.NetconfMonitoringReaderFactory(netconfDataBroker) }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringServiceProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringServiceProvider.groovy
new file mode 100644
index 000000000..5762a0a7f
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringServiceProvider.groovy
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService
+import org.opendaylight.netconf.impl.osgi.NetconfMonitoringServiceImpl
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory
+/**
+ * Mirror of org.opendaylight.controller.config.yang.config.netconf.northbound.impl.NetconfServerMonitoringModule
+ */
+@Slf4j
+@ToString
+class NetconfMonitoringServiceProvider extends ProviderTrait<NetconfMonitoringService> {
+
+ @Inject
+ @Named(NetconfModule.NETCONF_MAPPER_AGGREGATOR)
+ NetconfOperationServiceFactory aggregator
+
+ @Override
+ def create() {
+ new NetconfMonitoringServiceImpl(aggregator)
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationMapperProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationMapperProvider.groovy
new file mode 100644
index 000000000..57f7038ab
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationMapperProvider.groovy
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.config.yang.netconf.mdsal.notification.BaseCapabilityChangeNotificationPublisher
+import org.opendaylight.controller.config.yang.netconf.mdsal.notification.NotificationToMdsalWriter
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener
+import org.opendaylight.netconf.mdsal.notification.NetconfNotificationOperationServiceFactory
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector
+import org.opendaylight.netconf.notifications.NetconfNotificationRegistry
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+/**
+ * Mirror of org.opendaylight.controller.config.yang.netconf.mdsal.notification.NetconfMdsalNotificationMapperModule
+ */
+@Slf4j
+@ToString
+class NetconfNotificationMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> {
+
+ public static final capabilitiesIdentifier =
+ InstanceIdentifier.create(NetconfState.class).child(Capabilities.class).builder().build()
+
+ @Inject
+ NetconfNotificationCollector notificationCollector
+ @Inject
+ NetconfNotificationRegistry notificationRegistry
+ @Inject
+ @Named(NetconfModule.NETCONF)
+ BindingAwareBroker bindingAwareBroker
+ @Inject
+ @Named(NetconfModule.NETCONF)
+ DataBroker dataBroker
+ @Inject
+ NetconfOperationServiceFactoryListener aggregator
+
+ def create() {
+ def notificationToMdsalWriter = new NotificationToMdsalWriter(notificationCollector)
+ bindingAwareBroker.registerProvider(notificationToMdsalWriter)
+
+ def capabilityChangeListenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, capabilitiesIdentifier,
+ new BaseCapabilityChangeNotificationPublisher(notificationCollector.registerBaseNotificationPublisher()), AsyncDataBroker.DataChangeScope.SUBTREE)
+
+ def netconfNotificationOperationServiceFactory = new NetconfNotificationOperationServiceFactory(notificationRegistry)
+ aggregator.onAddNetconfOperationServiceFactory(netconfNotificationOperationServiceFactory)
+ netconfNotificationOperationServiceFactory
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationsReaderFactoryProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationsReaderFactoryProvider.groovy
new file mode 100644
index 000000000..45b7a1c7e
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationsReaderFactoryProvider.groovy
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.translate.read.ReaderFactory
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder
+import io.fd.honeycomb.translate.util.read.BindingBrokerReader
+import org.opendaylight.controller.md.sal.binding.api.DataBroker
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.NetconfBuilder
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+
+import javax.annotation.Nonnull
+
+// TODO backport to karaf distro
+@Slf4j
+@ToString
+class NetconfNotificationsReaderFactoryProvider extends ProviderTrait<ReaderFactory> {
+
+ @Inject
+ @Named(NetconfModule.NETCONF)
+ DataBroker netconfDataBroker
+
+ def create() {
+ new ReaderFactory() {
+ @Override
+ void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
+ registry.add(new BindingBrokerReader<>(InstanceIdentifier.create(Netconf.class),
+ netconfDataBroker, LogicalDatastoreType.OPERATIONAL, NetconfBuilder.class));
+ }
+ }
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfReadersModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfReadersModule.groovy
new file mode 100644
index 000000000..91a280857
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfReadersModule.groovy
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.AbstractModule
+import com.google.inject.Singleton
+import com.google.inject.multibindings.Multibinder
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.translate.read.ReaderFactory
+
+@Slf4j
+class NetconfReadersModule extends AbstractModule {
+
+ protected void configure() {
+ // This should be part of NetconfModule, but that one is Private and Multibinders + private BASE_MODULES
+ // do not work together, that's why there's a dedicated module here
+ Multibinder.newSetBinder(binder(), ReaderFactory.class).with {
+ addBinding().toProvider(NetconfMonitoringReaderFactoryProvider).in(Singleton)
+ addBinding().toProvider(NetconfNotificationsReaderFactoryProvider).in(Singleton)
+ }
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfServerDispatcherProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfServerDispatcherProvider.groovy
new file mode 100644
index 000000000..072a7f6ae
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfServerDispatcherProvider.groovy
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.netty.channel.nio.NioEventLoopGroup
+import io.netty.util.Timer
+import org.opendaylight.netconf.api.NetconfServerDispatcher
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService
+import org.opendaylight.netconf.impl.NetconfServerDispatcherImpl
+import org.opendaylight.netconf.impl.NetconfServerSessionNegotiatorFactory
+import org.opendaylight.netconf.impl.SessionIdProvider
+import org.opendaylight.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory
+
+import java.util.concurrent.TimeUnit
+/**
+ * Mirror of org.opendaylight.controller.config.yang.config.netconf.northbound.impl.NetconfServerDispatcherModule
+ */
+@Slf4j
+@ToString
+class NetconfServerDispatcherProvider extends ProviderTrait<NetconfServerDispatcher> {
+
+ // TODO make configurable
+ private static final long CONNECTION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(20)
+
+ @Inject
+ @Named(NetconfModule.NETCONF_MAPPER_AGGREGATOR)
+ NetconfOperationServiceFactory aggregator
+ @Inject
+ NetconfMonitoringService monitoringService
+ @Inject
+ Timer timer
+ @Inject
+ NioEventLoopGroup nettyThreadgroup
+
+
+ def create() {
+ def netconfOperationProvider = new AggregatedNetconfOperationServiceFactory()
+ netconfOperationProvider.onAddNetconfOperationServiceFactory(aggregator)
+
+ def serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+ timer, netconfOperationProvider, new SessionIdProvider(), CONNECTION_TIMEOUT_MILLIS, monitoringService);
+ def serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
+ serverNegotiatorFactory);
+
+ new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup)
+ }
+
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy
new file mode 100644
index 000000000..bce4f261a
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.netty.channel.ChannelFuture
+import io.netty.channel.local.LocalAddress
+import io.netty.channel.nio.NioEventLoopGroup
+import io.netty.util.concurrent.GenericFutureListener
+import io.netty.util.concurrent.GlobalEventExecutor
+import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider
+import org.opendaylight.netconf.api.NetconfServerDispatcher
+import org.opendaylight.netconf.ssh.SshProxyServer
+import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder
+
+import java.util.concurrent.Executors
+import java.util.concurrent.ScheduledExecutorService
+/**
+ * Mirror of org.opendaylight.controller.config.yang.netconf.northbound.ssh.NetconfNorthboundSshModule
+ */
+@Slf4j
+@ToString
+class NetconfSshServerProvider extends ProviderTrait<NetconfSshServer> {
+
+ @Inject
+ NetconfServerDispatcher dispatcher
+ @Inject
+ HoneycombConfiguration cfgAttributes
+ @Inject
+ NioEventLoopGroup nettyThreadgroup
+
+ // TODO merge with other executors .. one of the brokers creates also 2 internal executors
+ private ScheduledExecutorService pool = Executors.newScheduledThreadPool(1)
+
+ @Override
+ def create() {
+ def name = InetAddress.getByName(cfgAttributes.netconfSshBindingAddress)
+ def bindingAddress = new InetSocketAddress(name, cfgAttributes.netconfSshBindingPort)
+
+ def localAddress = new LocalAddress(cfgAttributes.netconfSshBindingPort.toString())
+ def localServer = dispatcher.createLocalServer(localAddress)
+
+ def sshProxyServer = new SshProxyServer(pool, nettyThreadgroup, GlobalEventExecutor.INSTANCE)
+
+ def sshConfigBuilder = new SshProxyServerConfigurationBuilder()
+ sshConfigBuilder.bindingAddress = bindingAddress
+ sshConfigBuilder.localAddress = localAddress
+ // TODO only simple authProvider checking ConfigAttributes
+ sshConfigBuilder.authenticator = { String uname, String passwd ->
+ cfgAttributes.username == uname && cfgAttributes.password == passwd
+ }
+ sshConfigBuilder.idleTimeout = Integer.MAX_VALUE
+ sshConfigBuilder.keyPairProvider = new PEMGeneratorHostKeyProvider()
+
+ localServer.addListener(new GenericFutureListener<ChannelFuture>() {
+
+ @Override
+ public void operationComplete(final ChannelFuture future) {
+ if(future.isDone() && !future.isCancelled()) {
+ try {
+ sshProxyServer.bind(sshConfigBuilder.createSshProxyServerConfiguration())
+ log.info "Netconf SSH endpoint started successfully at {}", bindingAddress
+ } catch (final IOException e) {
+ throw new RuntimeException("Unable to start SSH netconf server", e)
+ }
+ } else {
+ log.warn "Unable to start SSH netconf server at {}", bindingAddress, future.cause()
+ throw new RuntimeException("Unable to start SSH netconf server", future.cause())
+ }
+ }
+ })
+
+ return new NetconfSshServer(localServer: localServer, sshProxyServer: sshProxyServer)
+ }
+
+ static class NetconfSshServer {
+ def localServer
+ def sshProxyServer
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfTcpServerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfTcpServerProvider.groovy
new file mode 100644
index 000000000..c4e3523d0
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfTcpServerProvider.groovy
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.netty.channel.ChannelFuture
+import io.netty.util.concurrent.GenericFutureListener
+import org.opendaylight.netconf.api.NetconfServerDispatcher
+/**
+ * Mirror of org.opendaylight.controller.config.yang.netconf.northbound.tcp.NetconfNorthboundTcpModule
+ */
+@Slf4j
+@ToString
+class NetconfTcpServerProvider extends ProviderTrait<NetconfTcpServer> {
+
+ @Inject
+ NetconfServerDispatcher dispatcher
+ @Inject
+ HoneycombConfiguration cfgAttributes
+
+ @Override
+ def create() {
+
+ def name = InetAddress.getByName(cfgAttributes.netconfTcpBindingAddress.get())
+ def unresolved = new InetSocketAddress(name, cfgAttributes.netconfTcpBindingPort.get())
+
+ def tcpServer = dispatcher.createServer(unresolved)
+
+ tcpServer.addListener(new GenericFutureListener<ChannelFuture>() {
+ @Override
+ public void operationComplete(ChannelFuture future) throws Exception {
+ if (future.isDone() && future.isSuccess()) {
+ log.info("Netconf TCP endpoint started successfully at {}", unresolved)
+ } else {
+ log.warn("Unable to start TCP netconf server at {}", unresolved, future.cause())
+ throw new RuntimeException("Unable to start TCP netconf server", future.cause())
+ }
+ }
+ })
+
+ new NetconfTcpServer(tcpServer: tcpServer)
+ }
+
+ static class NetconfTcpServer {
+ def tcpServer
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy
new file mode 100644
index 000000000..da5f3d5b2
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.netty.channel.nio.NioEventLoopGroup
+
+/**
+ * Mirror of org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModule
+ */
+@Slf4j
+@ToString
+class NettyThreadGroupProvider extends ProviderTrait<NioEventLoopGroup> {
+
+ @Inject
+ HoneycombConfiguration cfgAttributes
+
+ @Override
+ def create() {
+ cfgAttributes.netconfNettyThreads.isPresent() ?
+ new NioEventLoopGroup(cfgAttributes.netconfNettyThreads.get()) :
+ new NioEventLoopGroup()
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyTimerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyTimerProvider.groovy
new file mode 100644
index 000000000..347417bd2
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyTimerProvider.groovy
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.netconf
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.netty.util.HashedWheelTimer
+import io.netty.util.Timer
+/**
+ * Mirror of org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModule
+ */
+@Slf4j
+@ToString
+class NettyTimerProvider extends ProviderTrait<Timer> {
+
+ @Inject
+ HoneycombConfiguration cfgAttributes
+
+ @Override
+ def create() {
+ // TODO expose configuration,
+ new HashedWheelTimer()
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy
new file mode 100644
index 000000000..1aa4efa9f
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.restconf
+
+import com.google.inject.AbstractModule
+import com.google.inject.Singleton
+import groovy.util.logging.Slf4j
+import org.opendaylight.netconf.sal.rest.api.RestConnector
+
+@Slf4j
+class RestconfModule extends AbstractModule {
+
+ protected void configure() {
+ bind(RestConnector).toProvider(RestconfProvider).in(Singleton)
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
new file mode 100644
index 000000000..f3b0852c1
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.restconf
+
+import com.google.inject.Inject
+import com.google.inject.name.Named
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.webapp.WebAppContext
+import org.opendaylight.controller.sal.core.api.Broker
+import org.opendaylight.netconf.sal.rest.api.RestConnector
+import org.opendaylight.netconf.sal.restconf.impl.RestconfProviderImpl
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber
+
+@Slf4j
+@ToString
+class RestconfProvider extends ProviderTrait<RestConnector> {
+
+ @Inject
+ HoneycombConfiguration cfg
+
+ @Inject
+ @Named("honeycomb")
+ Broker domBroker
+
+ def create() {
+ RestconfProviderImpl instance = new RestconfProviderImpl()
+ instance.setWebsocketPort(new PortNumber(cfg.restconfWebsocketPort))
+ domBroker.registerProvider(instance)
+
+ Server server = new Server(cfg.restconfPort);
+ final URL resource = getClass().getResource("/");
+ WebAppContext webapp = new WebAppContext(resource.getPath(), cfg.restconfRootPath);
+ server.setHandler(webapp);
+
+ try {
+ server.start();
+ } catch (Exception e) {
+ log.error "Unable to start Restconf", e
+ throw new RuntimeException("Unable to start Restconf", e)
+ }
+
+ return instance
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/ModuleInfoBackedCtxProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/ModuleInfoBackedCtxProvider.groovy
new file mode 100644
index 000000000..a319bb8af
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/ModuleInfoBackedCtxProvider.groovy
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.schema
+
+import com.google.common.base.MoreObjects
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext
+import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider
+
+@Slf4j
+@ToString
+class ModuleInfoBackedCtxProvider extends ProviderTrait<ModuleInfoBackedContext> {
+
+ @Inject(optional = true)
+ Set<YangModelBindingProvider> moduleInfos = []
+
+ def create() {
+ def create = ModuleInfoBackedContext.create()
+ create.addModuleInfos(moduleInfos.collect {it.getModuleInfo()})
+ log.debug "ModuleInfoBackedContext created from {}", moduleInfos
+ create
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("writerFactories", moduleInfos)
+ .toString();
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaModule.groovy
new file mode 100644
index 000000000..8bb9fc65f
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaModule.groovy
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.schema
+
+import com.google.inject.AbstractModule
+import com.google.inject.Singleton
+import groovy.util.logging.Slf4j
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext
+
+@Slf4j
+class SchemaModule extends AbstractModule {
+
+ protected void configure() {
+ bind(ModuleInfoBackedContext).toProvider(ModuleInfoBackedCtxProvider).in(Singleton)
+ bind(SchemaService).toProvider(SchemaServiceProvider).in(Singleton)
+ bind(BindingToNormalizedNodeCodec).toProvider(SerializerProvider).in(Singleton)
+ }
+
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaServiceProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaServiceProvider.groovy
new file mode 100644
index 000000000..c020d399b
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaServiceProvider.groovy
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.schema
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.yangtools.concepts.ListenerRegistration
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext
+import org.opendaylight.yangtools.yang.model.api.Module
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener
+
+@Slf4j
+@ToString
+class SchemaServiceProvider extends ProviderTrait<SchemaService> {
+
+ @Inject
+ ModuleInfoBackedContext mibCtx;
+
+ def create() { new StaticSchemaService(mibCtx.getSchemaContext()) }
+
+ /**
+ * Static schema context provider service.
+ */
+ static class StaticSchemaService implements SchemaService {
+
+ private final SchemaContext schemaContext
+
+ StaticSchemaService(SchemaContext schemaContext) {
+ this.schemaContext = schemaContext
+ }
+
+ @Override
+ void addModule(final Module module) {
+ throw new UnsupportedOperationException("Static service")
+ }
+
+ @Override
+ void removeModule(final Module module) {
+ throw new UnsupportedOperationException("Static service")
+ }
+
+ @Override
+ SchemaContext getSessionContext() {
+ schemaContext
+ }
+
+ @Override
+ SchemaContext getGlobalContext() {
+ schemaContext
+ }
+
+ @Override
+ ListenerRegistration<SchemaContextListener> registerSchemaContextListener(final SchemaContextListener listener) {
+ listener.onGlobalContextUpdated schemaContext
+ return new ListenerRegistration<SchemaContextListener>() {
+ void close() {}
+ SchemaContextListener getInstance() { listener }
+ }
+ }
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SerializerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SerializerProvider.groovy
new file mode 100644
index 000000000..01ea006ec
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/SerializerProvider.groovy
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.schema
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import javassist.ClassPool
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils
+
+@Slf4j
+@ToString
+class SerializerProvider extends ProviderTrait<BindingToNormalizedNodeCodec> {
+
+ @Inject
+ ModuleInfoBackedContext mibCtx;
+
+ def create() {
+ def serializerGenerator = new StreamWriterGenerator(JavassistUtils.forClassPool(ClassPool.getDefault()))
+ def codecRegistry = new BindingNormalizedNodeCodecRegistry(serializerGenerator)
+ def ctx = BindingRuntimeContext.create(mibCtx, mibCtx.getSchemaContext())
+ codecRegistry.onBindingRuntimeContextUpdated(ctx)
+ def codec = new BindingToNormalizedNodeCodec(mibCtx, codecRegistry)
+ codec.onGlobalContextUpdated(mibCtx.getSchemaContext())
+ codec
+ }
+} \ No newline at end of file
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/YangBindingProviderModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/YangBindingProviderModule.groovy
new file mode 100644
index 000000000..ebf473a3b
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/schema/YangBindingProviderModule.groovy
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed 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 io.fd.honeycomb.infra.distro.schema
+
+import com.google.common.base.Charsets
+import com.google.inject.AbstractModule
+import com.google.inject.multibindings.Multibinder
+import groovy.util.logging.Slf4j
+import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider
+/**
+ * Load all YangModelBindingProvider classes from classpath.
+ * <p/>
+ * Relying on /META-INF/services/ metadata.
+ */
+@Slf4j
+class YangBindingProviderModule extends AbstractModule {
+
+ static final String YANG_BA_PROVIDER_PATH = "META-INF/services/" + YangModelBindingProvider.class.getName();
+
+ void configure() {
+ Multibinder.newSetBinder(binder(), YangModelBindingProvider.class).with {
+ def resources = Collections.list(getClass().getClassLoader().getResources(YANG_BA_PROVIDER_PATH))
+ log.debug "ModuleProviders found at {}", resources
+ resources.forEach {
+ it.getText(Charsets.UTF_8.displayName()).split("\n")
+ .findAll { it != null && !it.isEmpty() && !it.isAllWhitespace()}
+ .collect { this.getClass().forName(it) }
+ .forEach {
+ log.debug "ModuleProvider found for {}", it
+ addBinding().to(it)
+ }
+ }
+ }
+ }
+}