diff options
Diffstat (limited to 'infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf')
23 files changed, 874 insertions, 736 deletions
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 deleted file mode 100644 index f3ced2e3f..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.ProviderTrait -import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration -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 io.fd.honeycomb.notification.impl.TranslationUtil -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 - -@Slf4j -@ToString -class HoneycombNotification2NetconfProvider extends ProviderTrait<HoneycombNotification2Netconf> { - - @Inject - DOMNotificationRouter notificationRouter - @Inject - SchemaService schemaService - @Inject - HoneycombConfiguration cfgAttributes - @Inject - NotificationCollector hcNotificationCollector - @Inject - NetconfNotificationCollector netconfNotificationCollector - - @Override - def create() { - def streamType = new StreamNameType(cfgAttributes.netconfNotificationStreamName.get()); - - // Register as HONEYCOMB_NETCONF notification publisher under configured name - def netconfNotifReg = netconfNotificationCollector.registerNotificationPublisher(new StreamBuilder() - .setName(streamType) - .setReplaySupport(false) - .setDescription(cfgAttributes.netconfNotificationStreamName.get()).build()); - - // Notification Translator, get notification from HC producers and put into HONEYCOMB_NETCONF notification collector - def domNotificationListener = { notif -> - log.debug "Propagating notification: {} into HONEYCOMB_NETCONF", notif.type - netconfNotifReg.onNotification(streamType, TranslationUtil.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 HONEYCOMB_NETCONF - // can be configured on top of a single notification manager - log.debug "Current notifications to be exposed over HONEYCOMB_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 HONEYCOMB_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 HONEYCOMB_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/HoneycombNotification2NetconfProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.java new file mode 100644 index 000000000..3954af896 --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.java @@ -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.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration; +import io.fd.honeycomb.notification.NotificationCollector; +import io.fd.honeycomb.notification.impl.NotificationProducerRegistry; +import io.fd.honeycomb.notification.impl.TranslationUtil; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; +import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener; +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.netconf.notifications.NotificationPublisherRegistration; +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.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class HoneycombNotification2NetconfProvider + extends ProviderTrait<HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf> { + + private static final Logger LOG = LoggerFactory.getLogger(HoneycombNotification2NetconfProvider.class); + + @Inject + private DOMNotificationRouter notificationRouter; + @Inject + private SchemaService schemaService; + @Inject + private HoneycombConfiguration cfgAttributes; + @Inject + private NotificationCollector hcNotificationCollector; + @Inject + private NetconfNotificationCollector netconfNotificationCollector; + + @Override + protected HoneycombNotification2Netconf create() { + final StreamNameType streamType = new StreamNameType(cfgAttributes.netconfNotificationStreamName.get()); + + // Register as HONEYCOMB_NETCONF notification publisher under configured name + final NotificationPublisherRegistration netconfNotifReg = netconfNotificationCollector + .registerNotificationPublisher(new StreamBuilder().setName(streamType).setReplaySupport(false) + .setDescription(cfgAttributes.netconfNotificationStreamName.get()).build()); + + // Notification Translator, get notification from HC producers and put into HONEYCOMB_NETCONF notification collector + final DOMNotificationListener domNotificationListener = + new TranslatingNotificationListener(netconfNotifReg, streamType, schemaService); + + // 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 HONEYCOMB_NETCONF + // can be configured on top of a single notification manager + LOG.debug("Current notifications to be exposed over HONEYCOMB_NETCONF: {}", + hcNotificationCollector.getNotificationTypes()); + List<SchemaPath> currentNotificationSchemaPaths = hcNotificationCollector.getNotificationTypes().stream() + .map(notifType -> SchemaPath.create(true, NotificationProducerRegistry.getQName(notifType))) + .collect(Collectors.toList()); + + // Register as listener to HC'OPERATIONAL DOM notification service + // TODO This should only be triggered when HONEYCOMB_NETCONF notifications are activated + // Because this way we actually start all notification producers + // final Collection<QName> notificationQNames = + ListenerRegistration<DOMNotificationListener> domNotifListenerReg = notificationRouter + .registerNotificationListener(domNotificationListener, currentNotificationSchemaPaths); + + LOG.info("Exposing HONEYCOMB_NETCONF notification stream: {}", streamType.getValue()); + return new HoneycombNotification2Netconf(domNotifListenerReg, netconfNotifReg); + } + + public static final class HoneycombNotification2Netconf { + private final ListenerRegistration<DOMNotificationListener> domNotifListenerReg; + private final NotificationPublisherRegistration netconfNotifReg; + + public HoneycombNotification2Netconf(final ListenerRegistration<DOMNotificationListener> domNotifListenerReg, + final NotificationPublisherRegistration netconfNotifReg) { + this.domNotifListenerReg = domNotifListenerReg; + this.netconfNotifReg = netconfNotifReg; + } + + public ListenerRegistration<DOMNotificationListener> getDomNotifListenerReg() { + return domNotifListenerReg; + } + + public NotificationPublisherRegistration getNetconfNotifReg() { + return netconfNotifReg; + } + } + + private static final class TranslatingNotificationListener implements DOMNotificationListener { + + private static final Logger LOG = LoggerFactory.getLogger(TranslatingNotificationListener.class); + + private final NotificationPublisherRegistration netconfNotifReg; + private final StreamNameType streamType; + private final SchemaService schemaService; + + TranslatingNotificationListener(final NotificationPublisherRegistration netconfNotifReg, + final StreamNameType streamType, final SchemaService schemaService) { + this.netconfNotifReg = netconfNotifReg; + this.streamType = streamType; + this.schemaService = schemaService; + } + + @Override + public void onNotification(@Nonnull final DOMNotification notif) { + LOG.debug("Propagating notification: {} into HONEYCOMB_NETCONF", notif.getType()); + netconfNotifReg.onNotification(streamType, TranslationUtil.notificationToXml(notif, schemaService.getGlobalContext())); + } + } +} 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.java index f1f49700e..3d06b8d27 100644 --- 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.java @@ -14,25 +14,23 @@ * limitations under the License. */ -package io.fd.honeycomb.infra.distro.netconf +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 io.fd.honeycomb.impl.FakeBindingAwareBroker +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.impl.FakeBindingAwareBroker; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -@Slf4j -@ToString -class NetconfBindingBrokerProvider extends ProviderTrait<BindingAwareBroker> { +public final class NetconfBindingBrokerProvider extends ProviderTrait<BindingAwareBroker> { @Inject @Named(NetconfModule.HONEYCOMB_NETCONF) - DataBroker dataBroker + private DataBroker dataBroker; @Override - def create() { new FakeBindingAwareBroker(dataBroker) } + protected FakeBindingAwareBroker create() { + return new 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.java index dff5319b4..9ede54f72 100644 --- 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.java @@ -14,36 +14,32 @@ * limitations under the License. */ -package io.fd.honeycomb.infra.distro.netconf +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.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 +import com.google.inject.Inject; +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; -@Slf4j -@ToString -class NetconfMdsalMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> { +public final class NetconfMdsalMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> { @Inject - SchemaService schemaService + private SchemaService schemaService; @Inject - NetconfOperationServiceFactoryListener aggregator + private NetconfOperationServiceFactoryListener aggregator; @Inject - ModuleInfoBackedContext moduleInfoBackedContext - + private ModuleInfoBackedContext moduleInfoBackedContext; @Inject - Broker domBroker + private Broker domBroker; - def create() { - def mdsalNetconfOperationServiceFactory = - new MdsalNetconfOperationServiceFactory(schemaService, moduleInfoBackedContext) + @Override + protected MdsalNetconfOperationServiceFactory create() { + MdsalNetconfOperationServiceFactory 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 deleted file mode 100644 index 29eeae301..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfModule.groovy +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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 HONEYCOMB_NETCONF = "honeycomb-netconf" - public static final String HONEYCOMB_NETCONF_MAPPER_AGGR = "netconf-mapper-aggregator" - public static final String HONEYCOMB_NETCONF_MAPPER_NOTIF = "netconf-mapper-notification" - public static final String HONEYCOMB_NETCONF_MAPPER_CORE = "netconf-mapper-honeycomb" - public static final String HONEYCOMB_NETCONF_MAPPER_OPER = "netconf-mapper-monitoring" - - @Override - protected void configure() { - // Create inmemory data store for HONEYCOMB_NETCONF config metadata - bind(InMemoryDOMDataStore) - .annotatedWith(Names.named(CONFIG)) - .toProvider(new DataStoreProvider(type: LogicalDatastoreType.CONFIGURATION, name: CONFIG)) - .in(Singleton) - // Create inmemory data store for HONEYCOMB_NETCONF operational metadata - bind(InMemoryDOMDataStore) - .annotatedWith(Names.named(OPERATIONAL)) - .toProvider(new DataStoreProvider(type: LogicalDatastoreType.OPERATIONAL, name: OPERATIONAL)) - .in(Singleton) - // Wrap datastores as DOMDataBroker - bind(DOMDataBroker).toProvider(InmemoryDOMDataBrokerProvider).in(Singleton) - - // Wrap DOMDataBroker as BA data broker - bind(DataBroker) - .annotatedWith(Names.named(HONEYCOMB_NETCONF)) - .toProvider(BindingDataBrokerProvider) - .in(Singleton) - expose(DataBroker).annotatedWith(Names.named(HONEYCOMB_NETCONF)) - - // Wrap BA data broker as BindingAwareBroker (requied by HONEYCOMB_NETCONF) - bind(BindingAwareBroker) - .annotatedWith(Names.named(HONEYCOMB_NETCONF)) - .toProvider(NetconfBindingBrokerProvider) - .in(Singleton) - - // Create netconf operation service factory aggregator to aggregate different services - def factory = new AggregatedNetconfOperationServiceFactory() - bind(NetconfOperationServiceFactory) - .annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_AGGR)) - .toInstance(factory) - bind(NetconfOperationServiceFactoryListener).toInstance(factory) - - // Create netconf notification manager - def manager = new NetconfNotificationManager() - bind(NetconfNotificationCollector).toInstance(manager) - bind(NetconfNotificationRegistry).toInstance(manager) - bind(NetconfNotificationListener).toInstance(manager) - - // Netconf notification service factory - bind(NetconfOperationServiceFactory) - .annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_NOTIF)) - .toProvider(NetconfNotificationMapperProvider) - .in(Singleton) - expose(NetconfOperationServiceFactory).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_NOTIF)) - - // Netconf core part - mapping between Honeycomb and Netconf - bind(NetconfOperationServiceFactory) - .annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_CORE)) - .toProvider(NetconfMdsalMapperProvider) - .in(Singleton) - expose(NetconfOperationServiceFactory).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_CORE)) - - // Netconf monitoring service factory - bind(NetconfMonitoringService).toProvider(NetconfMonitoringServiceProvider).in(Singleton) - bind(NetconfOperationServiceFactory) - .annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_OPER)) - .toProvider(NetconfMonitoringMapperProvider) - .in(Singleton) - expose(NetconfOperationServiceFactory).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_OPER)) - - // Create HC notification manager + HC2Netconf translator - bind(NotificationCollector).toProvider(HoneycombNotificationManagerProvider).in(Singleton) - bind(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf) - .toProvider(HoneycombNotification2NetconfProvider) - .in(Singleton) - expose(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf) - - configureServer() - } - - /** - * Provide HONEYCOMB_NETCONF TCP and SSH servers - */ - 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/NetconfModule.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfModule.java new file mode 100644 index 000000000..9beb10dbc --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfModule.java @@ -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 static io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider.CONFIG; +import static io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider.OPERATIONAL; + +import com.google.inject.PrivateModule; +import com.google.inject.Singleton; +import com.google.inject.binder.AnnotatedElementBuilder; +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; + +public class NetconfModule extends PrivateModule { + + public static final String HONEYCOMB_NETCONF = "honeycomb-netconf"; + public static final String HONEYCOMB_NETCONF_MAPPER_AGGR = "netconf-mapper-aggregator"; + public static final String HONEYCOMB_NETCONF_MAPPER_NOTIF = "netconf-mapper-notification"; + public static final String HONEYCOMB_NETCONF_MAPPER_CORE = "netconf-mapper-honeycomb"; + public static final String HONEYCOMB_NETCONF_MAPPER_OPER = "netconf-mapper-monitoring"; + + @Override + protected void configure() { + // Create inmemory data store for HONEYCOMB_NETCONF config metadata + bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(CONFIG)) + .toProvider(new DataStoreProvider(CONFIG, LogicalDatastoreType.CONFIGURATION)) + .in(Singleton.class); + + // Create inmemory data store for HONEYCOMB_NETCONF operational metadata + bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(OPERATIONAL)) + .toProvider(new DataStoreProvider(OPERATIONAL, LogicalDatastoreType.OPERATIONAL)) + .in(Singleton.class); + // Wrap datastores as DOMDataBroker + bind(DOMDataBroker.class).toProvider(InmemoryDOMDataBrokerProvider.class).in(Singleton.class); + + // Wrap DOMDataBroker as BA data broker + bind(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_NETCONF)).toProvider(BindingDataBrokerProvider.class) + .in(Singleton.class); + expose(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_NETCONF)); + + // Wrap BA data broker as BindingAwareBroker (requied by HONEYCOMB_NETCONF) + bind(BindingAwareBroker.class).annotatedWith(Names.named(HONEYCOMB_NETCONF)) + .toProvider(NetconfBindingBrokerProvider.class).in(Singleton.class); + + // Create netconf operation service factory aggregator to aggregate different services + AggregatedNetconfOperationServiceFactory factory = new AggregatedNetconfOperationServiceFactory(); + bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_AGGR)) + .toInstance(factory); + bind(NetconfOperationServiceFactoryListener.class).toInstance(factory); + + // Create netconf notification manager + NetconfNotificationManager manager = new NetconfNotificationManager(); + bind(NetconfNotificationCollector.class).toInstance(manager); + bind(NetconfNotificationRegistry.class).toInstance(manager); + bind(NetconfNotificationListener.class).toInstance(manager); + + // Netconf notification service factory + bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_NOTIF)) + .toProvider(NetconfNotificationMapperProvider.class).in(Singleton.class); + expose(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_NOTIF)); + + // Netconf core part - mapping between Honeycomb and Netconf + bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_CORE)) + .toProvider(NetconfMdsalMapperProvider.class).in(Singleton.class); + expose(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_CORE)); + + // Netconf monitoring service factory + bind(NetconfMonitoringService.class).toProvider(NetconfMonitoringServiceProvider.class).in(Singleton.class); + bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_OPER)) + .toProvider(NetconfMonitoringMapperProvider.class).in(Singleton.class); + expose(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_OPER)); + + // Create HC notification manager + HC2Netconf translator + bind(NotificationCollector.class).toProvider(HoneycombNotificationManagerProvider.class).in(Singleton.class); + bind(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf.class) + .toProvider(HoneycombNotification2NetconfProvider.class).in(Singleton.class); + expose(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf.class); + + configureServer(); + } + + /** + * Provide HONEYCOMB_NETCONF TCP and SSH servers. + */ + private AnnotatedElementBuilder configureServer() { + bind(NioEventLoopGroup.class).toProvider(NettyThreadGroupProvider.class).in(Singleton.class); + bind(Timer.class).toProvider(NettyTimerProvider.class).in(Singleton.class); + bind(NetconfServerDispatcher.class).toProvider(NetconfServerDispatcherProvider.class).in(Singleton.class); + bind(NetconfTcpServerProvider.NetconfTcpServer.class).toProvider(NetconfTcpServerProvider.class) + .in(Singleton.class); + expose(NetconfTcpServerProvider.NetconfTcpServer.class); + bind(NetconfSshServerProvider.NetconfSshServer.class).toProvider(NetconfSshServerProvider.class) + .in(Singleton.class); + return expose(NetconfSshServerProvider.NetconfSshServer.class); + } +} 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 deleted file mode 100644 index c35a97352..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringMapperProvider.groovy +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 - -@Slf4j -@ToString -class NetconfMonitoringMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> { - - @Inject - @Named(NetconfModule.HONEYCOMB_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/NetconfMonitoringMapperProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringMapperProvider.java new file mode 100644 index 000000000..46a46ba47 --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfMonitoringMapperProvider.java @@ -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.netconf; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import java.lang.reflect.Constructor; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; +import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService; +import org.opendaylight.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory; +import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public final class NetconfMonitoringMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfMonitoringMapperProvider.class); + + @Inject + @Named(NetconfModule.HONEYCOMB_NETCONF) + private BindingAwareBroker bindingAwareBroker; + @Inject + private NetconfOperationServiceFactoryListener aggregator; + @Inject + private NetconfMonitoringService monitoringService; + + @Override + protected NetconfOperationServiceFactory create() { + try { + final Class<?> monitoringWriterCls = Class.forName( + "org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.MonitoringToMdsalWriter"); + Constructor<?> declaredConstructor = + monitoringWriterCls.getDeclaredConstructor(NetconfMonitoringService.class); + declaredConstructor.setAccessible(true); + final BindingAwareProvider o = (BindingAwareProvider) declaredConstructor.newInstance(monitoringService); + bindingAwareBroker.registerProvider(o); + + final Class<?> monitoringMapperCls = Class.forName( + "org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.NetconfMdsalMonitoringMapperModule$MdsalMonitoringMapper"); + declaredConstructor = + monitoringMapperCls.getDeclaredConstructor(NetconfMonitoringService.class); + declaredConstructor.setAccessible(true); + final NetconfOperationService mdSalMonitoringMapper = + (NetconfOperationService) declaredConstructor.newInstance(monitoringService); + + final Class<?> monitoringMpperFactory = Class.forName( + "org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.NetconfMdsalMonitoringMapperModule$MdSalMonitoringMapperFactory"); + declaredConstructor = + monitoringMpperFactory.getDeclaredConstructor(NetconfOperationService.class); + declaredConstructor.setAccessible(true); + final NetconfOperationServiceFactory mdSalMonitoringMapperFactory = + (NetconfOperationServiceFactory) declaredConstructor.newInstance(mdSalMonitoringMapper); + aggregator.onAddNetconfOperationServiceFactory(mdSalMonitoringMapperFactory); + return mdSalMonitoringMapperFactory; + } catch (final ReflectiveOperationException e) { + final String msg = "Unable to instantiate operation service factory using reflection"; + LOG.error(msg, e); + throw new IllegalStateException(msg, e); + } + } +} 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.java index 54a773a80..583b15055 100644 --- 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.java @@ -14,24 +14,24 @@ * limitations under the License. */ -package io.fd.honeycomb.infra.distro.netconf +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 io.fd.honeycomb.impl.NetconfMonitoringReaderFactory +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.impl.NetconfMonitoringReaderFactory; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.translate.read.ReaderFactory; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; -@Slf4j -@ToString -class NetconfMonitoringReaderFactoryProvider extends ProviderTrait<ReaderFactory> { + +public final class NetconfMonitoringReaderFactoryProvider extends ProviderTrait<ReaderFactory> { @Inject @Named(NetconfModule.HONEYCOMB_NETCONF) - DataBroker netconfDataBroker + private DataBroker netconfDataBroker; - def create() { new NetconfMonitoringReaderFactory(netconfDataBroker) } + @Override + protected NetconfMonitoringReaderFactory create() { + return new 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.java index cac2a13cc..9858003f5 100644 --- 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.java @@ -14,27 +14,24 @@ * limitations under the License. */ -package io.fd.honeycomb.infra.distro.netconf +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 +import com.google.inject.Inject; +import com.google.inject.name.Named; +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; -@Slf4j -@ToString -class NetconfMonitoringServiceProvider extends ProviderTrait<NetconfMonitoringService> { + +public class NetconfMonitoringServiceProvider extends ProviderTrait<NetconfMonitoringService> { @Inject @Named(NetconfModule.HONEYCOMB_NETCONF_MAPPER_AGGR) - NetconfOperationServiceFactory aggregator + private NetconfOperationServiceFactory aggregator; @Override - def create() { - new NetconfMonitoringServiceImpl(aggregator) + protected NetconfMonitoringServiceImpl create() { + return 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 deleted file mode 100644 index 74b384317..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationMapperProvider.groovy +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 - -@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.HONEYCOMB_NETCONF) - BindingAwareBroker bindingAwareBroker - @Inject - @Named(NetconfModule.HONEYCOMB_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/NetconfNotificationMapperProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationMapperProvider.java new file mode 100644 index 000000000..2c2631b0b --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationMapperProvider.java @@ -0,0 +1,96 @@ +/* + * 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 io.fd.honeycomb.infra.distro.ProviderTrait; +import java.lang.reflect.Constructor; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +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.controller.sal.binding.api.BindingAwareProvider; +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.BaseNotificationPublisherRegistration; +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.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class NetconfNotificationMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfNotificationMapperProvider.class); + + public static final InstanceIdentifier<Capabilities> capabilitiesIdentifier = + InstanceIdentifier.create(NetconfState.class).child(Capabilities.class).builder().build(); + @Inject + private NetconfNotificationCollector notificationCollector; + @Inject + private NetconfNotificationRegistry notificationRegistry; + @Inject + @Named(NetconfModule.HONEYCOMB_NETCONF) + private BindingAwareBroker bindingAwareBroker; + @Inject + @Named(NetconfModule.HONEYCOMB_NETCONF) + private DataBroker dataBroker; + @Inject + private NetconfOperationServiceFactoryListener aggregator; + + @Override + protected NetconfNotificationOperationServiceFactory create() { + try { + final Class<?> notificationWriter = Class.forName( + "org.opendaylight.controller.config.yang.netconf.mdsal.notification.NotificationToMdsalWriter"); + Constructor<?> declaredConstructor = + notificationWriter.getDeclaredConstructor(NetconfNotificationCollector.class); + declaredConstructor.setAccessible(true); + final BindingAwareProvider writer = + (BindingAwareProvider) declaredConstructor.newInstance(notificationCollector); + bindingAwareBroker.registerProvider(writer); + + final Class<?> notifPublisherCls = Class.forName( + "org.opendaylight.controller.config.yang.netconf.mdsal.notification.BaseCapabilityChangeNotificationPublisher"); + declaredConstructor = + notifPublisherCls.getDeclaredConstructor(BaseNotificationPublisherRegistration.class); + declaredConstructor.setAccessible(true); + final DataChangeListener publisher = (DataChangeListener) declaredConstructor.newInstance( + notificationCollector.registerBaseNotificationPublisher()); + + ListenerRegistration<DataChangeListener> capabilityChangeListenerRegistration = dataBroker + .registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, capabilitiesIdentifier, + publisher, AsyncDataBroker.DataChangeScope.SUBTREE); + NetconfNotificationOperationServiceFactory netconfNotificationOperationServiceFactory = + new NetconfNotificationOperationServiceFactory(notificationRegistry); + aggregator.onAddNetconfOperationServiceFactory(netconfNotificationOperationServiceFactory); + + return netconfNotificationOperationServiceFactory; + } catch (final ReflectiveOperationException e) { + final String msg = "Unable to instantiate notification mapper using reflection"; + LOG.error(msg, e); + throw new IllegalStateException(msg, e); + } + } +} 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 deleted file mode 100644 index c714cdd14..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationsReaderFactoryProvider.groovy +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 - -@Slf4j -@ToString -class NetconfNotificationsReaderFactoryProvider extends ProviderTrait<ReaderFactory> { - - @Inject - @Named(NetconfModule.HONEYCOMB_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/NetconfNotificationsReaderFactoryProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationsReaderFactoryProvider.java new file mode 100644 index 000000000..b699439b4 --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfNotificationsReaderFactoryProvider.java @@ -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.netconf; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +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 javax.annotation.Nonnull; +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; + +public final class NetconfNotificationsReaderFactoryProvider extends ProviderTrait<ReaderFactory> { + + @Inject + @Named(NetconfModule.HONEYCOMB_NETCONF) + private DataBroker netconfDataBroker; + + @Override + protected ReaderFactory create() { + return new NotificationReaderFactory(netconfDataBroker); + } + + private static final class NotificationReaderFactory implements ReaderFactory { + private final DataBroker netconfDataBroker; + + NotificationReaderFactory(final DataBroker netconfDataBroker) { + this.netconfDataBroker = netconfDataBroker; + } + + @Override + public 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.java index 917eceeac..cb45f5d6d 100644 --- 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.java @@ -14,24 +14,21 @@ * limitations under the License. */ -package io.fd.honeycomb.infra.distro.netconf +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 +import com.google.inject.AbstractModule; +import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; +import io.fd.honeycomb.translate.read.ReaderFactory; -@Slf4j -class NetconfReadersModule extends AbstractModule { +public 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 // https://github.com/google/guice/issues/906 - Multibinder.newSetBinder(binder(), ReaderFactory.class).with { - addBinding().toProvider(NetconfMonitoringReaderFactoryProvider).in(Singleton) - addBinding().toProvider(NetconfNotificationsReaderFactoryProvider).in(Singleton) - } + final Multibinder<ReaderFactory> binder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + binder.addBinding().toProvider(NetconfMonitoringReaderFactoryProvider.class).in(Singleton.class); + binder.addBinding().toProvider(NetconfNotificationsReaderFactoryProvider.class).in(Singleton.class); } } 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 deleted file mode 100644 index 10388f9c4..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfServerDispatcherProvider.groovy +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 - -@Slf4j -@ToString -class NetconfServerDispatcherProvider extends ProviderTrait<NetconfServerDispatcher> { - - // TODO make configurable - private static final long CONNECTION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(20) - - @Inject - @Named(NetconfModule.HONEYCOMB_NETCONF_MAPPER_AGGR) - 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/NetconfServerDispatcherProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfServerDispatcherProvider.java new file mode 100644 index 000000000..1f3caafa1 --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfServerDispatcherProvider.java @@ -0,0 +1,60 @@ +/* + * 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 io.fd.honeycomb.infra.distro.ProviderTrait; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.util.Timer; +import java.util.concurrent.TimeUnit; +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; + +public final class NetconfServerDispatcherProvider extends ProviderTrait<NetconfServerDispatcher> { + private static final long CONNECTION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(20); + + @Inject + @Named(NetconfModule.HONEYCOMB_NETCONF_MAPPER_AGGR) + private NetconfOperationServiceFactory aggregator; + @Inject + private NetconfMonitoringService monitoringService; + @Inject + private Timer timer; + @Inject + private NioEventLoopGroup nettyThreadgroup; + + @Override + protected NetconfServerDispatcherImpl create() { + AggregatedNetconfOperationServiceFactory netconfOperationProvider = + new AggregatedNetconfOperationServiceFactory(); + netconfOperationProvider.onAddNetconfOperationServiceFactory(aggregator); + + NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = + new NetconfServerSessionNegotiatorFactory(timer, netconfOperationProvider, new SessionIdProvider(), + CONNECTION_TIMEOUT_MILLIS, monitoringService); + NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = + new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory); + + return 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 deleted file mode 100644 index 55daca23d..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.common.util.concurrent.ThreadFactoryBuilder -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 - -@Slf4j -@ToString -class NetconfSshServerProvider extends ProviderTrait<NetconfSshServer> { - - @Inject - NetconfServerDispatcher dispatcher - @Inject - HoneycombConfiguration cfgAttributes - @Inject - NioEventLoopGroup nettyThreadgroup - - private ScheduledExecutorService pool = - Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("netconf-ssh-%d").build()) - - @Override - def create() { - def name = InetAddress.getByName(cfgAttributes.netconfSshBindingAddress.get()) - def bindingAddress = new InetSocketAddress(name, cfgAttributes.netconfSshBindingPort.get()) - - 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/NetconfSshServerProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.java new file mode 100644 index 000000000..53be6b5d9 --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.java @@ -0,0 +1,151 @@ +/* + * 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.common.util.concurrent.ThreadFactoryBuilder; +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration; +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 java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider; +import org.opendaylight.netconf.api.NetconfServerDispatcher; +import org.opendaylight.netconf.auth.AuthProvider; +import org.opendaylight.netconf.ssh.SshProxyServer; +import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public final class NetconfSshServerProvider extends ProviderTrait<NetconfSshServerProvider.NetconfSshServer> { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfSshServerProvider.class); + + @Inject + private NetconfServerDispatcher dispatcher; + @Inject + private HoneycombConfiguration cfgAttributes; + @Inject + private NioEventLoopGroup nettyThreadgroup; + + private ScheduledExecutorService pool = + Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("netconf-ssh-%d").build()); + + @Override + protected NetconfSshServer create() { + InetAddress sshBindingAddress = null; + try { + sshBindingAddress = InetAddress.getByName(cfgAttributes.netconfSshBindingAddress.get()); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Illegal binding address", e); + } + + final InetSocketAddress bindingAddress = + new InetSocketAddress(sshBindingAddress, cfgAttributes.netconfSshBindingPort.get()); + + LocalAddress localAddress = new LocalAddress(cfgAttributes.netconfSshBindingPort.toString()); + ChannelFuture localServer = dispatcher.createLocalServer(localAddress); + + final SshProxyServer sshProxyServer = new SshProxyServer(pool, nettyThreadgroup, GlobalEventExecutor.INSTANCE); + + final SshProxyServerConfigurationBuilder sshConfigBuilder = new SshProxyServerConfigurationBuilder(); + sshConfigBuilder.setBindingAddress(bindingAddress); + sshConfigBuilder.setLocalAddress(localAddress); + // TODO only simple authProvider checking ConfigAttributes + sshConfigBuilder.setAuthenticator(new SimplelAuthProvider(cfgAttributes)); + sshConfigBuilder.setIdleTimeout(Integer.MAX_VALUE); + sshConfigBuilder.setKeyPairProvider(new PEMGeneratorHostKeyProvider()); + + localServer.addListener(new SshServerBinder(sshProxyServer, sshConfigBuilder, bindingAddress)); + + return new NetconfSshServer(localServer, sshProxyServer); + } + + public static final class NetconfSshServer { + private ChannelFuture localServer; + private SshProxyServer sshProxyServer; + + NetconfSshServer(final ChannelFuture localServer, + final SshProxyServer sshProxyServer) { + this.localServer = localServer; + this.sshProxyServer = sshProxyServer; + } + + public Object getLocalServer() { + return localServer; + } + + public Object getSshProxyServer() { + return sshProxyServer; + } + } + + private static final class SimplelAuthProvider implements AuthProvider { + + private final HoneycombConfiguration cfgAttributes; + + SimplelAuthProvider(final HoneycombConfiguration cfgAttributes) { + this.cfgAttributes = cfgAttributes; + } + + @Override + public boolean authenticated(final String uname, final String passwd) { + return cfgAttributes.username.equals(uname) && cfgAttributes.password.equals(passwd); + } + } + + private static final class SshServerBinder implements GenericFutureListener<ChannelFuture> { + private final SshProxyServer sshProxyServer; + private final SshProxyServerConfigurationBuilder sshConfigBuilder; + private final InetSocketAddress bindingAddress; + + SshServerBinder(final SshProxyServer sshProxyServer, + final SshProxyServerConfigurationBuilder sshConfigBuilder, + final InetSocketAddress bindingAddress) { + this.sshProxyServer = sshProxyServer; + this.sshConfigBuilder = sshConfigBuilder; + this.bindingAddress = bindingAddress; + } + + @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()); + } + + } + + } +} 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 deleted file mode 100644 index 1b0800207..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfTcpServerProvider.groovy +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 - -@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/NetconfTcpServerProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfTcpServerProvider.java new file mode 100644 index 000000000..d6ab47446 --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfTcpServerProvider.java @@ -0,0 +1,85 @@ +/* + * 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 io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration; +import io.netty.channel.ChannelFuture; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import org.opendaylight.netconf.api.NetconfServerDispatcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class NetconfTcpServerProvider extends ProviderTrait<NetconfTcpServerProvider.NetconfTcpServer> { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfTcpServerProvider.class); + + @Inject + private NetconfServerDispatcher dispatcher; + @Inject + private HoneycombConfiguration cfgAttributes; + + @Override + protected NetconfTcpServer create() { + InetAddress name = null; + try { + name = InetAddress.getByName(cfgAttributes.netconfTcpBindingAddress.get()); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Illegal binding address", e); + } + + final InetSocketAddress unresolved = new InetSocketAddress(name, cfgAttributes.netconfTcpBindingPort.get()); + + ChannelFuture tcpServer = dispatcher.createServer(unresolved); + tcpServer.addListener(new TcpLoggingListener(unresolved)); + return new NetconfTcpServer(tcpServer); + } + + public static final class NetconfTcpServer { + private Object tcpServer; + + NetconfTcpServer(final ChannelFuture tcpServer) { + this.tcpServer = tcpServer; + } + + public Object getTcpServer() { + return tcpServer; + } + } + + private static final class TcpLoggingListener implements GenericFutureListener<ChannelFuture> { + private final InetSocketAddress unresolved; + + TcpLoggingListener(final InetSocketAddress unresolved) { + this.unresolved = unresolved; + } + + @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()); + } + } + } +} 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.java index 90948647d..e14952bba 100644 --- 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.java @@ -14,26 +14,22 @@ * limitations under the License. */ -package io.fd.honeycomb.infra.distro.netconf +package io.fd.honeycomb.infra.distro.netconf; -import com.google.common.util.concurrent.ThreadFactoryBuilder -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.infra.distro.cfgattrs.HoneycombConfiguration -import io.netty.channel.nio.NioEventLoopGroup +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration; +import io.netty.channel.nio.NioEventLoopGroup; -@Slf4j -@ToString -class NettyThreadGroupProvider extends ProviderTrait<NioEventLoopGroup> { +public final class NettyThreadGroupProvider extends ProviderTrait<NioEventLoopGroup> { @Inject - HoneycombConfiguration cfgAttributes + private HoneycombConfiguration cfgAttributes; @Override - def create() { - new NioEventLoopGroup(cfgAttributes.netconfNettyThreads, - new ThreadFactoryBuilder().setNameFormat("netconf-netty-%d").build()) + protected NioEventLoopGroup create() { + return new NioEventLoopGroup(cfgAttributes.netconfNettyThreads, + new ThreadFactoryBuilder().setNameFormat("netconf-netty-%d").build()); } } 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.java index e889633ed..6ae960cea 100644 --- 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.java @@ -14,26 +14,22 @@ * limitations under the License. */ -package io.fd.honeycomb.infra.distro.netconf +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 +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration; +import io.netty.util.HashedWheelTimer; +import io.netty.util.Timer; -@Slf4j -@ToString -class NettyTimerProvider extends ProviderTrait<Timer> { +public final class NettyTimerProvider extends ProviderTrait<Timer> { @Inject - HoneycombConfiguration cfgAttributes + private HoneycombConfiguration cfgAttributes; @Override - def create() { + protected HashedWheelTimer create() { // TODO expose configuration, - new HashedWheelTimer() + return new HashedWheelTimer(); } } |