From 106fdfe560a0e76c28780eceb3362cd78b06ebf2 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Fri, 30 Jun 2017 13:11:22 +0200 Subject: HONEYCOMB-374: move BGP to minimal-distribution Separate BGP distribution was temporary workaround for HONEYCOMB-358 and (partially) HONEYCOMB-360. BGP northbound interface is disabled by default. Change-Id: I72a0f83f40ea96bee478be7d6560f2112611d80f Signed-off-by: Marek Gradzki --- infra/bgp-distribution-test/pom.xml | 2 +- .../infra/bgp/distro/BgpDistributionTest.java | 5 +- infra/bgp-distribution/asciidoc/Readme.adoc | 3 - infra/bgp-distribution/bgp_postman_collection.json | 283 --------------------- infra/bgp-distribution/pom.xml | 109 -------- .../infra/bgp/BGPDispatcherImplProvider.java | 36 --- .../bgp/BGPExtensionConsumerContextProvider.java | 46 ---- .../fd/honeycomb/infra/bgp/BgpConfiguration.java | 68 ----- .../infra/bgp/BgpConfigurationModule.java | 33 --- .../honeycomb/infra/bgp/BgpExtensionsModule.java | 67 ----- .../java/io/fd/honeycomb/infra/bgp/BgpModule.java | 94 ------- .../honeycomb/infra/bgp/BgpNeighboursProvider.java | 125 --------- .../infra/bgp/BgpNettyThreadGroupProvider.java | 34 --- .../io/fd/honeycomb/infra/bgp/BgpRIBProvider.java | 129 ---------- .../infra/bgp/BgpReaderFactoryProvider.java | 60 ----- .../fd/honeycomb/infra/bgp/BgpReadersModule.java | 33 --- .../fd/honeycomb/infra/bgp/BgpServerProvider.java | 107 -------- .../infra/bgp/BgpWriterFactoryProvider.java | 102 -------- .../fd/honeycomb/infra/bgp/BgpWritersModule.java | 33 --- .../honeycomb/infra/bgp/LocRibWriterProvider.java | 42 --- .../bgp/RIBExtensionConsumerContextProvider.java | 45 ---- .../io/fd/honeycomb/infra/bgp/distro/Main.java | 69 ----- .../config/activation.json | 4 - .../config/bgp-peers.json | 53 ---- .../honeycomb-minimal-resources/config/bgp.json | 9 - infra/minimal-distribution/pom.xml | 11 +- infra/northbound/bgp/asciidoc/Readme.adoc | 4 + infra/northbound/bgp/bgp_postman_collection.json | 283 +++++++++++++++++++++ infra/northbound/bgp/pom.xml | 111 ++++++++ .../infra/bgp/BGPDispatcherImplProvider.java | 36 +++ .../bgp/BGPExtensionConsumerContextProvider.java | 46 ++++ .../fd/honeycomb/infra/bgp/BgpConfiguration.java | 68 +++++ .../infra/bgp/BgpConfigurationModule.java | 33 +++ .../honeycomb/infra/bgp/BgpExtensionsModule.java | 79 ++++++ .../java/io/fd/honeycomb/infra/bgp/BgpModule.java | 105 ++++++++ .../honeycomb/infra/bgp/BgpNeighboursProvider.java | 125 +++++++++ .../infra/bgp/BgpNettyThreadGroupProvider.java | 34 +++ .../io/fd/honeycomb/infra/bgp/BgpRIBProvider.java | 129 ++++++++++ .../infra/bgp/BgpReaderFactoryProvider.java | 60 +++++ .../fd/honeycomb/infra/bgp/BgpReadersModule.java | 45 ++++ .../fd/honeycomb/infra/bgp/BgpServerProvider.java | 107 ++++++++ .../infra/bgp/BgpWriterFactoryProvider.java | 102 ++++++++ .../fd/honeycomb/infra/bgp/BgpWritersModule.java | 45 ++++ .../honeycomb/infra/bgp/LocRibWriterProvider.java | 42 +++ .../bgp/RIBExtensionConsumerContextProvider.java | 45 ++++ .../config/activation.json | 4 + .../config/bgp-peers.json | 53 ++++ .../honeycomb-minimal-resources/config/bgp.json | 9 + infra/northbound/pom.xml | 1 + infra/pom.xml | 1 - 50 files changed, 1580 insertions(+), 1589 deletions(-) delete mode 100644 infra/bgp-distribution/asciidoc/Readme.adoc delete mode 100644 infra/bgp-distribution/bgp_postman_collection.json delete mode 100644 infra/bgp-distribution/pom.xml delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java delete mode 100644 infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/distro/Main.java delete mode 100644 infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/activation.json delete mode 100644 infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json delete mode 100644 infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp.json create mode 100644 infra/northbound/bgp/asciidoc/Readme.adoc create mode 100644 infra/northbound/bgp/bgp_postman_collection.json create mode 100644 infra/northbound/bgp/pom.xml create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java create mode 100644 infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java create mode 100644 infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/activation.json create mode 100644 infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json create mode 100644 infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp.json diff --git a/infra/bgp-distribution-test/pom.xml b/infra/bgp-distribution-test/pom.xml index 34eeda39b..858f21ee8 100644 --- a/infra/bgp-distribution-test/pom.xml +++ b/infra/bgp-distribution-test/pom.xml @@ -32,7 +32,7 @@ io.fd.honeycomb - bgp-distribution + minimal-distribution ${project.version} test diff --git a/infra/bgp-distribution-test/src/test/java/io/fd/honeycomb/infra/bgp/distro/BgpDistributionTest.java b/infra/bgp-distribution-test/src/test/java/io/fd/honeycomb/infra/bgp/distro/BgpDistributionTest.java index be927a64e..d6f03f9a8 100644 --- a/infra/bgp-distribution-test/src/test/java/io/fd/honeycomb/infra/bgp/distro/BgpDistributionTest.java +++ b/infra/bgp-distribution-test/src/test/java/io/fd/honeycomb/infra/bgp/distro/BgpDistributionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Cisco and/or its affiliates. + * Copyright (c) 2017 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. @@ -18,6 +18,7 @@ package io.fd.honeycomb.infra.bgp.distro; import com.google.common.io.ByteStreams; import com.mashape.unirest.http.Unirest; +import io.fd.honeycomb.infra.distro.Main; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; @@ -60,7 +61,7 @@ public class BgpDistributionTest { @Test(timeout = 120000) public void test() throws Exception { - io.fd.honeycomb.infra.bgp.distro.Main.init(); + Main.init(); LOG.info("Testing Honeycomb BGP distribution"); assertBgp(); } diff --git a/infra/bgp-distribution/asciidoc/Readme.adoc b/infra/bgp-distribution/asciidoc/Readme.adoc deleted file mode 100644 index f6222d4d0..000000000 --- a/infra/bgp-distribution/asciidoc/Readme.adoc +++ /dev/null @@ -1,3 +0,0 @@ -= bgp-distribution - -Honeycomb distribution that adds BGP to NETCONF and RESTCONF northbound intrerfaces provided by minimal-distribution. \ No newline at end of file diff --git a/infra/bgp-distribution/bgp_postman_collection.json b/infra/bgp-distribution/bgp_postman_collection.json deleted file mode 100644 index 31297287d..000000000 --- a/infra/bgp-distribution/bgp_postman_collection.json +++ /dev/null @@ -1,283 +0,0 @@ -{ - "id": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "name": "Honeycomb BGP RESTCONF calls", - "description": "Examples of BGP configration based on \nhttp://docs.opendaylight.org/en/stable-boron/user-guide/bgp-user-guide.html", - "order": [ - "de49ba67-7f69-a866-62e1-3102b610a85b", - "f3f23ede-fa81-fab9-9668-55aa746dec67", - "5b4964f0-183d-33fb-fe85-c9720101ebda", - "07529ecd-4c19-b46e-b033-d98d390fda4c", - "fb3c78a8-0d4e-2cb6-fddd-8f42e0336f53", - "708b7662-c912-724d-6267-91b4ee6a95a1", - "db1e7d40-8dc8-be65-9467-22a39cde24eb", - "7dcba5fa-d007-7aab-b0b5-8d855dc3c2b9", - "a45a76ba-0d23-57b4-eaf5-0b660a7852b3", - "2a3057b5-3961-45cf-a8bb-b58e056fe1a5" - ], - "folders": [], - "timestamp": 1494477000331, - "owner": "567303", - "public": false, - "requests": [ - { - "id": "07529ecd-4c19-b46e-b033-d98d390fda4c", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes", - "preRequestScript": null, - "pathVariables": {}, - "method": "POST", - "data": [], - "dataMode": "raw", - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1494502752142, - "name": "add ipv4unicast route", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 0\n 10.0.0.11/32\n \n \n \n igp\n \n \n 100\n \n \n 10.11.1.1\n \n \n" - }, - { - "id": "2a3057b5-3961-45cf-a8bb-b58e056fe1a5", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "headerData": [ - { - "key": "Content-Type", - "value": "application/xml", - "description": "", - "enabled": true - }, - { - "key": "Authorization", - "value": "Basic YWRtaW46YWRtaW4=", - "description": "", - "enabled": true - } - ], - "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-labeled-unicast:labeled-unicast-subsequent-address-family/bgp-labeled-unicast:labeled-unicast-routes", - "queryParams": [], - "preRequestScript": null, - "pathVariables": {}, - "pathVariableData": [], - "method": "POST", - "data": [], - "dataMode": "raw", - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1497523964759, - "name": "add IPv4 labeled unicast route", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n label1\n 1.1.1.1/32\n 1\n \n 800322\n \n \n \n 199.20.160.41\n \n \n igp\n \n \n \n 100\n \n \n" - }, - { - "id": "5b4964f0-183d-33fb-fe85-c9720101ebda", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/peer/bgp:%2F%2F10.25.1.9", - "preRequestScript": null, - "pathVariables": {}, - "method": "GET", - "data": [], - "dataMode": "raw", - "version": 2, - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1495116619841, - "name": "show 127.0.0.3 app peer state", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" - }, - { - "id": "708b7662-c912-724d-6267-91b4ee6a95a1", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "headerData": [ - { - "key": "Content-Type", - "value": "application/xml", - "description": "", - "enabled": true - }, - { - "key": "Authorization", - "value": "Basic YWRtaW46YWRtaW4=", - "description": "", - "enabled": true - } - ], - "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/ipv4-route/10.0.0.12%2F32/0", - "queryParams": [], - "preRequestScript": null, - "pathVariables": {}, - "pathVariableData": [], - "method": "PUT", - "data": [], - "dataMode": "raw", - "version": 2, - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1497597573297, - "name": "update second ipv4unicast route", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 0\n 10.0.0.12/32\n \n \n \n igp\n \n \n 102\n \n \n 10.11.1.1\n \n \n" - }, - { - "id": "7dcba5fa-d007-7aab-b0b5-8d855dc3c2b9", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/loc-rib", - "preRequestScript": null, - "pathVariables": {}, - "method": "GET", - "data": [], - "dataMode": "raw", - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1495009616064, - "name": "show speeker's Loc-RIB", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 10.25.1.9\n \n application-peers\n \n" - }, - { - "id": "a45a76ba-0d23-57b4-eaf5-0b660a7852b3", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/peer/bgp:%2F%2F127.0.0.2/adj-rib-out/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes", - "preRequestScript": null, - "pathVariables": {}, - "method": "GET", - "data": [], - "dataMode": "raw", - "version": 2, - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1495009639185, - "name": "show 127.0.0.2 peer's adj-rib-out", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" - }, - { - "id": "db1e7d40-8dc8-be65-9467-22a39cde24eb", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "headerData": [ - { - "key": "Content-Type", - "value": "application/xml", - "description": "", - "enabled": true - }, - { - "key": "Authorization", - "value": "Basic YWRtaW46YWRtaW4=", - "description": "", - "enabled": true - } - ], - "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/ipv4-route/10.0.0.12%2F32/0", - "queryParams": [], - "preRequestScript": null, - "pathVariables": {}, - "pathVariableData": [], - "method": "DELETE", - "data": [], - "dataMode": "raw", - "version": 2, - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1497597304771, - "name": "remove second ipv4unicast route", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "" - }, - { - "id": "de49ba67-7f69-a866-62e1-3102b610a85b", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance", - "preRequestScript": null, - "pathVariables": {}, - "method": "GET", - "data": [], - "dataMode": "raw", - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1495116911838, - "name": "show hc-bgp-instance", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" - }, - { - "id": "f3f23ede-fa81-fab9-9668-55aa746dec67", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/peer/bgp:%2F%2F127.0.0.2", - "preRequestScript": null, - "pathVariables": {}, - "method": "GET", - "data": [], - "dataMode": "raw", - "version": 2, - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1495009591745, - "name": "show 127.0.0.2 peer state", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" - }, - { - "id": "fb3c78a8-0d4e-2cb6-fddd-8f42e0336f53", - "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", - "headerData": [ - { - "key": "Content-Type", - "value": "application/xml", - "description": "", - "enabled": true - }, - { - "key": "Authorization", - "value": "Basic YWRtaW46YWRtaW4=", - "description": "", - "enabled": true - } - ], - "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/ipv4-route/10.0.0.12%2F32/0", - "queryParams": [], - "preRequestScript": null, - "pathVariables": {}, - "pathVariableData": [], - "method": "PUT", - "data": [], - "dataMode": "raw", - "version": 2, - "tests": null, - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1497597550097, - "name": "add another ipv4unicast route", - "description": "", - "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", - "responses": [], - "rawModeData": "\n 0\n 10.0.0.12/32\n \n \n \n igp\n \n \n 100\n \n \n 10.11.1.1\n \n \n" - } - ] -} \ No newline at end of file diff --git a/infra/bgp-distribution/pom.xml b/infra/bgp-distribution/pom.xml deleted file mode 100644 index 545885933..000000000 --- a/infra/bgp-distribution/pom.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - io.fd.honeycomb.common - minimal-distribution-parent - 1.17.07-SNAPSHOT - ../../common/minimal-distribution-parent - - - 4.0.0 - io.fd.honeycomb - bgp-distribution - ${project.artifactId} - 1.17.07-SNAPSHOT - - - io.fd.honeycomb.infra.bgp.distro.Main - true - - io.fd.honeycomb.infra.bgp.BgpModule, - io.fd.honeycomb.infra.bgp.BgpExtensionsModule, - io.fd.honeycomb.infra.bgp.BgpReadersModule, - io.fd.honeycomb.infra.bgp.BgpWritersModule, - io.fd.honeycomb.infra.bgp.BgpConfigurationModule - - - - - - - maven-compiler-plugin - - - org.codehaus.gmaven - groovy-maven-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - org.apache.maven.plugins - maven-dependency-plugin - - - maven-assembly-plugin - - - - - - - io.fd.honeycomb - minimal-distribution - ${project.version} - - - io.fd.honeycomb - bgp-translate-api - ${project.version} - - - io.fd.honeycomb - bgp-translate-impl - ${project.version} - - - - - org.opendaylight.bgpcep - bgp-rib-impl - - - - org.powermock - powermock - - - - - org.opendaylight.bgpcep - bgp-openconfig-impl - - - - org.opendaylight.bgpcep - bgp-evpn - - - org.opendaylight.bgpcep - bgp-inet - - - org.opendaylight.bgpcep - bgp-labeled-unicast - - - org.opendaylight.bgpcep - bgp-linkstate - - - org.opendaylight.bgpcep - bgp-l3vpn - - - \ No newline at end of file diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java deleted file mode 100644 index c9ec39f35..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.netty.channel.EventLoopGroup; -import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext; -import org.opendaylight.protocol.bgp.rib.impl.BGPDispatcherImpl; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; - -final class BGPDispatcherImplProvider extends ProviderTrait { - @Inject - private BGPExtensionConsumerContext consumerContext; - @Inject - private EventLoopGroup threadGroup; - - @Override - protected BGPDispatcher create() { - return new BGPDispatcherImpl(consumerContext.getMessageRegistry(), threadGroup, threadGroup); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java deleted file mode 100644 index 00e99ab99..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import java.util.ArrayList; -import java.util.Set; -import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext; -import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderActivator; -import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext; -import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext; -import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContextActivator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class BGPExtensionConsumerContextProvider extends ProviderTrait { - private static final Logger LOG = LoggerFactory.getLogger(BGPExtensionConsumerContextProvider.class); - - @Inject - private Set activators; - - @Override - protected BGPExtensionConsumerContext create() { - final BGPExtensionProviderContext ctx = new SimpleBGPExtensionProviderContext(); - final SimpleBGPExtensionProviderContextActivator activator = - new SimpleBGPExtensionProviderContextActivator(ctx, new ArrayList<>(activators)); - LOG.debug("Starting BGPExtensionConsumerContext with activators: {}", activators); - activator.start(); - return ctx; - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java deleted file mode 100644 index 9182dd3a0..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.common.base.MoreObjects; -import java.util.Optional; -import net.jmob.guice.conf.core.BindConfig; -import net.jmob.guice.conf.core.InjectConfig; -import net.jmob.guice.conf.core.Syntax; - -/** - * This is the Java equivalent for bgp.json file. We use guice-config library to load all the config attributes - * into this class instance. - * - * The BindConfig annotation tells that bgp.json file should be looked up on classpath root. - */ -@BindConfig(value = "bgp", syntax = Syntax.JSON) -public class BgpConfiguration { - - public boolean isBgpEnabled() { - return Boolean.valueOf(bgpEnabled); - } - - public boolean isBgpMultiplePathsEnabled() { - return Boolean.valueOf(bgpMultiplePaths.get()); - } - - @InjectConfig("bgp-enabled") - public String bgpEnabled; - @InjectConfig("bgp-binding-address") - public Optional bgpBindingAddress; - @InjectConfig("bgp-port") - public Optional bgpPort; - @InjectConfig("bgp-as-number") - public Optional bgpAsNumber; - @InjectConfig("bgp-receive-multiple-paths") - public Optional bgpMultiplePaths; - @InjectConfig("bgp-send-max-paths") - public Optional bgpSendMaxMaths; - @InjectConfig("bgp-netty-threads") - public Integer bgpNettyThreads; - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("bgpEnabled", bgpEnabled) - .add("bgpBindingAddress", bgpBindingAddress) - .add("bgpPort", bgpPort) - .add("bgp-as-number", bgpAsNumber) - .add("bgp-netty-threads", bgpNettyThreads) - .add("bgp-receive-multiple-paths", bgpMultiplePaths) - .add("bgp-send-max-paths", bgpSendMaxMaths) - .toString(); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java deleted file mode 100644 index a1c2e765b..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.AbstractModule; -import net.jmob.guice.conf.core.ConfigurationModule; - -/** - * Load the configuration from json into HoneycombConfiguration and make it available. - */ -public class BgpConfigurationModule extends AbstractModule { - - protected void configure() { - install(ConfigurationModule.create()); - // Inject non-dependency configuration - requestInjection(BgpConfiguration.class); - } - -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java deleted file mode 100644 index 650f637e5..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.AbstractModule; -import com.google.inject.Singleton; -import com.google.inject.multibindings.Multibinder; -import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext; -import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderActivator; -import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; -import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator; - -/** - * Registers BGP extensions provided by ODL implementation. - * TODO add support for flowspec (requires some special initialization) - */ -public final class BgpExtensionsModule extends AbstractModule { - - protected void configure() { - // This should be part of BgpModule, 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 - configureRIBExtensions(); - configureBGPExtensions(); - } - - private void configureRIBExtensions() { - final Multibinder ribExtensionBinder = Multibinder.newSetBinder(binder(), - RIBExtensionProviderActivator.class); - ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.evpn.impl.RIBActivator.class); - ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.inet.RIBActivator.class); - ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.labeled.unicast.RIBActivator.class); - ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.linkstate.impl.RIBActivator.class); - ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv4.RibIpv4Activator.class); - ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv6.RibIpv6Activator.class); - bind(RIBExtensionConsumerContext.class).toProvider(RIBExtensionConsumerContextProvider.class) - .in(Singleton.class); - } - - private void configureBGPExtensions() { - final Multibinder bgpExtensionBinder = Multibinder.newSetBinder(binder(), - BGPExtensionProviderActivator.class); - bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.parser.impl.BGPActivator.class); - bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.evpn.impl.BGPActivator.class); - bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.inet.BGPActivator.class); - bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.labeled.unicast.BGPActivator.class); - bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.linkstate.impl.BGPActivator.class); - bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv4.BgpIpv4Activator.class); - bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv6.BgpIpv6Activator.class); - bind(BGPExtensionConsumerContext.class).toProvider(BGPExtensionConsumerContextProvider.class) - .in(Singleton.class); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java deleted file mode 100644 index a26b5c158..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -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.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.InmemoryDOMDataBrokerProvider; -import io.fd.honeycomb.translate.bgp.RibWriter; -import io.netty.channel.EventLoopGroup; -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.protocol.bgp.openconfig.impl.BGPOpenConfigMappingServiceImpl; -import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService; -import org.opendaylight.protocol.bgp.rib.impl.StrictBGPPeerRegistry; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry; -import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighbors; - -public final class BgpModule extends PrivateModule { - - static final String HONEYCOMB_BGP = "honeycomb-bgp"; - - protected void configure() { - // Create BGPDispatcher BGPDispatcher for creating BGP clients - bind(EventLoopGroup.class).toProvider(BgpNettyThreadGroupProvider.class).in(Singleton.class); - bind(BGPDispatcher.class).toProvider(BGPDispatcherImplProvider.class).in(Singleton.class); - - configureRIB(); - - // Configure peer registry - bind(BGPOpenConfigMappingService.class).toInstance(new BGPOpenConfigMappingServiceImpl()); - bind(BGPPeerRegistry.class).toInstance(StrictBGPPeerRegistry.instance()); - - - // Create BGP server instance - bind(BgpServerProvider.BgpServer.class).toProvider(BgpServerProvider.class).in(Singleton.class); - expose(BgpServerProvider.BgpServer.class); - - // Initialize BgpNeighbours - bind(BgpNeighbors.class).toProvider(BgpNeighboursProvider.class).in(Singleton.class); - expose(BgpNeighbors.class); - - // Listens for local RIB modifications and passes routes to translation layer - bind(RibWriter.class).toProvider(LocRibWriterProvider.class).asEagerSingleton(); - expose(RibWriter.class); - } - - private void configureRIB() { - // Create inmemory config data store for HONEYCOMB_BGP - bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(CONFIG)) - .toProvider(new DataStoreProvider(CONFIG, LogicalDatastoreType.CONFIGURATION)) - .in(Singleton.class); - - // Create inmemory operational data store for HONEYCOMB_BGP - bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(OPERATIONAL)) - .toProvider(new DataStoreProvider(OPERATIONAL, LogicalDatastoreType.OPERATIONAL)) - .in(Singleton.class); - - // Wrap datastores as DOMDataBroker - // TODO make executor service configurable - bind(DOMDataBroker.class).toProvider(InmemoryDOMDataBrokerProvider.class).in(Singleton.class); - - // Wrap DOMDataBroker as BA data broker (required by BgpReaderFactoryProvider) - bind(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_BGP)).toProvider(BindingDataBrokerProvider.class) - .in(Singleton.class); - expose(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_BGP)); - - // Create RIB instance - bind(RIB.class).toProvider(BgpRIBProvider.class).in(Singleton.class); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java deleted file mode 100644 index fab14e827..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.translate.util.JsonUtils.readContainerEntryJson; -import static org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil.APPLICATION_PEER_GROUP_NAME; -import static org.opendaylight.yangtools.sal.binding.generator.impl.BindingSchemaContextUtils.findDataNodeContainer; - -import com.google.common.base.Optional; -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import java.io.InputStream; -import java.util.Map; -import javax.annotation.Nonnull; -import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec; -import org.opendaylight.controller.sal.core.api.model.SchemaService; -import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService; -import org.opendaylight.protocol.bgp.rib.impl.StrictBGPPeerRegistry; -import org.opendaylight.protocol.bgp.rib.impl.config.AppPeer; -import org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry; -import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborPeerGroupConfig; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighbors; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class BgpNeighboursProvider extends ProviderTrait { - private static final Logger LOG = LoggerFactory.getLogger(BgpNeighboursProvider.class); - private static final String PEERS_CFG = "/bgp-peers.json"; - @Inject - private BindingToNormalizedNodeCodec codec; - @Inject - private RIB globalRib; - @Inject - private BGPOpenConfigMappingService mappingService; - @Inject - private SchemaService schemaService; - @Inject - private BGPPeerRegistry peerRegistry; - - @Override - protected BgpNeighbors create() { - final BgpNeighbors neighbors = readNeighbours(); - for (final Neighbor neighbor : neighbors.getNeighbor()) { - if (isApplicationPeer(neighbor)) { - LOG.trace("Starting AppPeer for {}", neighbor); - new AppPeer().start(globalRib, neighbor, mappingService, null); - } else { - LOG.trace("Starting BgpPeer for {}", neighbor); - new BgpPeer(null, peerRegistry).start(globalRib, neighbor, mappingService, null); - } - } - LOG.debug("BgpNeighbours initialized: {}", neighbors); - return neighbors; - } - - private Neighbors readNeighbours() { - LOG.debug("Reading BGP neighbours from {}", PEERS_CFG); - final InputStream resourceStream = this.getClass().getResourceAsStream(PEERS_CFG); - checkState(resourceStream != null, "Resource %s not found", PEERS_CFG); - - final InstanceIdentifier bgpII = InstanceIdentifier.create(NetworkInstances.class) - .child(NetworkInstance.class, new NetworkInstanceKey("dummy-value")).child(Protocols.class) - .child(Protocol.class, new ProtocolKey(BGP.class, "dummy-value")).augmentation(Protocol1.class) - .child(Bgp.class); - final InstanceIdentifier neighborsII = bgpII.child(Neighbors.class); - - final YangInstanceIdentifier neighborsYII = codec.toYangInstanceIdentifier(neighborsII); - final SchemaContext schemaContext = schemaService.getGlobalContext(); - final Optional parentNode = findDataNodeContainer(schemaContext, bgpII); - final ContainerNode parentContainer = readContainerEntryJson(schemaContext, resourceStream, - (SchemaNode) parentNode.get(), - (YangInstanceIdentifier.NodeIdentifier) neighborsYII.getLastPathArgument()); - final NormalizedNode neighborsContainer = parentContainer.getValue().iterator().next(); - - final Map.Entry, DataObject> entry = codec.fromNormalizedNode(neighborsYII, neighborsContainer); - checkNotNull(entry, "Failed to deserialize neighbours configuration at %s", PEERS_CFG); - return (Neighbors) entry.getValue(); - } - - private static boolean isApplicationPeer(@Nonnull final Neighbor neighbor) { - return java.util.Optional.of(neighbor.getConfig()) - .map(config -> config.getAugmentation(Config2.class)) - .map(BgpNeighborPeerGroupConfig::getPeerGroup) - .map(APPLICATION_PEER_GROUP_NAME::equals) - .orElse(false); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java deleted file mode 100644 index 8208a4320..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java +++ /dev/null @@ -1,34 +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.bgp; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.netty.channel.nio.NioEventLoopGroup; - -final class BgpNettyThreadGroupProvider extends ProviderTrait { - - @Inject - private BgpConfiguration cfgAttributes; - - @Override - protected NioEventLoopGroup create() { - return new NioEventLoopGroup(cfgAttributes.bgpNettyThreads, - new ThreadFactoryBuilder().setNameFormat("bgp-netty-%d").build()); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java deleted file mode 100644 index a2bd56df3..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.common.collect.ImmutableList; -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec; -import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; -import org.opendaylight.controller.md.sal.dom.broker.impl.PingPongDataBroker; -import org.opendaylight.controller.sal.core.api.model.SchemaService; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; -import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode; -import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService; -import org.opendaylight.protocol.bgp.rib.impl.RIBImpl; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; -import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; -import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4LABELLEDUNICAST; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.AfiSafi2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.AfiSafi2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class BgpRIBProvider extends ProviderTrait { - private static final Logger LOG = LoggerFactory.getLogger(BgpRIBProvider.class); - private static final String HC_BGP_INSTANCE_NAME = "hc-bgp-instance"; - - @Inject - private BgpConfiguration cfg; - @Inject - private RIBExtensionConsumerContext extensions; - @Inject - private BGPDispatcher dispatcher; - @Inject - private BindingToNormalizedNodeCodec codec; - @Inject - private DOMDataBroker domBroker; - @Inject - private BGPOpenConfigMappingService mappingService; - @Inject - private SchemaService schemaService; - - @Override - protected RIB create() { - final AsNumber asNumber = new AsNumber(cfg.bgpAsNumber.get().longValue()); - final Ipv4Address routerId = new Ipv4Address(cfg.bgpBindingAddress.get()); - final ClusterIdentifier clusterId = new ClusterIdentifier(routerId); - LOG.debug("Creating BGP RIB: routerId={}, asNumber={}", routerId, asNumber); - // TODO configure other BGP Multiprotocol extensions: - final List afiSafi = ImmutableList.of( - new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class) - .addAugmentation(AfiSafi2.class, - new AfiSafi2Builder().setReceive(cfg.isBgpMultiplePathsEnabled()) - .setSendMax(cfg.bgpSendMaxMaths.get().shortValue()).build()) - .build(), - new AfiSafiBuilder().setAfiSafiName(IPV4LABELLEDUNICAST.class) - .addAugmentation(AfiSafi2.class, - new AfiSafi2Builder().setReceive(cfg.isBgpMultiplePathsEnabled()) - .setSendMax(cfg.bgpSendMaxMaths.get().shortValue()).build()) - .build() - ); - final Map pathSelectionModes = mappingService.toPathSelectionMode(afiSafi) - .entrySet().stream().collect(Collectors.toMap(entry -> - new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue)); - // based on RIBImpl.createRib - final RIBImpl rib = - new RIBImpl(new NoopClusterSingletonServiceProvider(), new RibId(HC_BGP_INSTANCE_NAME), asNumber, - new BgpId(routerId), clusterId, extensions, dispatcher, codec, new PingPongDataBroker(domBroker), - mappingService.toTableTypes(afiSafi), pathSelectionModes, extensions.getClassLoadingStrategy(), null); - - // required for proper RIB's CodecRegistry initialization (based on RIBImpl.start) - schemaService.registerSchemaContextListener(rib); - - LOG.debug("BGP RIB created successfully: {}", rib); - return rib; - } - - /** - * HC does not support clustering, but BGP uses {@link ClusterSingletonServiceProvider} - * to initialize {@link RIBImpl}. Therefore we provide this dummy implementation. - */ - private static final class NoopClusterSingletonServiceProvider implements ClusterSingletonServiceProvider { - private static final Logger LOG = LoggerFactory.getLogger(NoopClusterSingletonServiceProvider.class); - - private static final ClusterSingletonServiceRegistration REGISTRATION = - () -> LOG.debug("Closing ClusterSingletonServiceRegistration"); - - @Override - public ClusterSingletonServiceRegistration registerClusterSingletonService( - final ClusterSingletonService clusterSingletonService) { - clusterSingletonService.instantiateServiceInstance(); - return REGISTRATION; - } - - @Override - public void close() throws Exception { - LOG.debug("Closing NoopClusterSingletonServiceProvider"); - } - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java deleted file mode 100644 index b79074f10..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -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 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.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRibBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -final class BgpReaderFactoryProvider extends ProviderTrait { - - @Inject - @Named(BgpModule.HONEYCOMB_BGP) - private DataBroker bgpDataBroker; - - @Override - protected BgpReaderFactory create() { - return new BgpReaderFactory(bgpDataBroker); - } - - /** - * {@link ReaderFactory} provides reader form BGP's dedicated data store. - * Makes BGP operational data available over NETCONF/RESTCONF. - */ - private static final class BgpReaderFactory implements ReaderFactory { - - private final DataBroker bgpDataBroker; - - BgpReaderFactory(final DataBroker bgpDataBroker) { - this.bgpDataBroker = bgpDataBroker; - } - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - registry.add(new BindingBrokerReader<>(InstanceIdentifier.create(BgpRib.class), - bgpDataBroker, LogicalDatastoreType.OPERATIONAL, BgpRibBuilder.class)); - } - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java deleted file mode 100644 index 745a94269..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.AbstractModule; -import com.google.inject.Singleton; -import com.google.inject.multibindings.Multibinder; -import io.fd.honeycomb.translate.read.ReaderFactory; - -public class BgpReadersModule extends AbstractModule { - - protected void configure() { - // This should be part of BgpModule, 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 - final Multibinder binder = Multibinder.newSetBinder(binder(), ReaderFactory.class); - binder.addBinding().toProvider(BgpReaderFactoryProvider.class).in(Singleton.class); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java deleted file mode 100644 index 27dad8840..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.netty.channel.Channel; -import io.netty.channel.ChannelConfig; -import io.netty.channel.ChannelFuture; -import io.netty.channel.epoll.Epoll; -import io.netty.channel.epoll.EpollChannelOption; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry; -import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences; -import org.opendaylight.protocol.bgp.rib.impl.spi.PeerRegistryListener; -import org.opendaylight.protocol.concepts.KeyMapping; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class BgpServerProvider extends ProviderTrait { - private static final Logger LOG = LoggerFactory.getLogger(BgpServerProvider.class); - @Inject - private BgpConfiguration cfg; - @Inject - private BGPPeerRegistry peerRegistry; - @Inject - private BGPDispatcher dispatcher; - - @Override - protected BgpServer create() { - // code based on org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerAcceptorModule from Boron-SR3 - final InetAddress bindingAddress; - try { - bindingAddress = InetAddress.getByName(cfg.bgpBindingAddress.get()); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Illegal BGP binding address", e); - } - final InetSocketAddress address = new InetSocketAddress(bindingAddress, cfg.bgpPort.get()); - LOG.debug("Creating BgpServer for {}", address); - final ChannelFuture localServer = dispatcher.createServer(peerRegistry, address); - localServer.addListener(future -> { - Preconditions.checkArgument(future.isSuccess(), "Unable to start bgp server on %s", address, future.cause()); - final Channel channel = localServer.channel(); - if (Epoll.isAvailable()) { - peerRegistry.registerPeerRegisterListener(new PeerRegistryListenerImpl(channel.config())); - } - }); - final BgpServer server = new BgpServer(localServer); - LOG.debug("BgpServer successfully created."); - return server; - } - - public static final class BgpServer { - private ChannelFuture localServer; - - BgpServer(final ChannelFuture localServer) { - this.localServer = localServer; - } - - public ChannelFuture getLocalServer() { - return localServer; - } - } - - private static final class PeerRegistryListenerImpl implements PeerRegistryListener { - private final ChannelConfig channelConfig; - private final KeyMapping keys; - - PeerRegistryListenerImpl(final ChannelConfig channelConfig) { - this.channelConfig = channelConfig; - this.keys = KeyMapping.getKeyMapping(); - } - @Override - public void onPeerAdded(final IpAddress ip, final BGPSessionPreferences prefs) { - if (prefs.getMd5Password().isPresent()) { - this.keys.put(IetfInetUtil.INSTANCE.inetAddressFor(ip), prefs.getMd5Password().get()); - this.channelConfig.setOption(EpollChannelOption.TCP_MD5SIG, this.keys); - } - } - @Override - public void onPeerRemoved(final IpAddress ip) { - if (this.keys.remove(IetfInetUtil.INSTANCE.inetAddressFor(ip)) != null) { - this.channelConfig.setOption(EpollChannelOption.TCP_MD5SIG, this.keys); - } - } - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java deleted file mode 100644 index 81faabbe5..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.fd.honeycomb.translate.util.write.BindingBrokerWriter; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.Ipv4Routes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4Route; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.LabelStack; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.routes.LabeledUnicastRoutes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.routes.list.LabeledUnicastRoute; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.LocalPref; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.Origin; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRib; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHop; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -final class BgpWriterFactoryProvider extends ProviderTrait { - @Inject - @Named(BgpModule.HONEYCOMB_BGP) - private DataBroker bgpDataBroker; - @Override - protected BgpWriterFactory create() { - return new BgpWriterFactory(bgpDataBroker); - } - - /** - * {@link WriterFactory} for BGP cfg write integration with HC writer registry. - * Using BindingBrokerWriter to write BGP configuration data via dedicated broker that, unlike - * {@link io.fd.honeycomb.data.impl.DataBroker}, supports tx chains and DOMDataChangeListener registration - * extensively used by ODL's bgp. - * - * As a bonus BGP route configuration is persisted and available for read via RESTCONF/NETCONF. - */ - private static final class BgpWriterFactory implements WriterFactory { - private final DataBroker dataBroker; - - private static final InstanceIdentifier AR_IID = - InstanceIdentifier.create(ApplicationRib.class); - private static final InstanceIdentifier TABLES_IID = AR_IID.child(Tables.class); - private static final InstanceIdentifier IPV4_ROUTES_IID = TABLES_IID.child((Class) Ipv4Routes.class); - private static final InstanceIdentifier IPV4_ROUTE_IID = IPV4_ROUTES_IID.child(Ipv4Route.class); - private static final InstanceIdentifier LABELED_UNICAST_ROUTES_IID = TABLES_IID.child((Class) LabeledUnicastRoutes.class); - private static final InstanceIdentifier LABELED_UNICAST_ROUTE_IID = LABELED_UNICAST_ROUTES_IID.child(LabeledUnicastRoute.class); - - private BgpWriterFactory(final DataBroker dataBroker) { - this.dataBroker = dataBroker; - } - - // TODO (HONEYCOMB-359): - // BGP models are huge, we need some kind of wildcarded subtree writer, that works for whole subtree. - // 1) we can either move checking handledTypes to writers (getHandledTypes, isAffected, writer.getHandedTypes, ...) - // but then precondition check in flatWriterRegistry might be slower (we need to check if we have all writers - // in order to avoid unnecessary reverts). - // - // 2) alternative is to compute all child nodes during initialization (might introduce some footprint penalty). - @Override - public void init(final ModifiableWriterRegistryBuilder registry) { - registry.subtreeAdd( - Sets.newHashSet( - TABLES_IID, - IPV4_ROUTES_IID, - IPV4_ROUTES_IID.child(Ipv4Route.class), - IPV4_ROUTE_IID.child(Attributes.class), - IPV4_ROUTE_IID.child(Attributes.class).child(Origin.class), - IPV4_ROUTE_IID.child(Attributes.class).child(LocalPref.class), - IPV4_ROUTE_IID.child(Attributes.class).child(Ipv4NextHop.class), - LABELED_UNICAST_ROUTES_IID, - LABELED_UNICAST_ROUTE_IID, - LABELED_UNICAST_ROUTE_IID.child(Attributes.class), - LABELED_UNICAST_ROUTE_IID.child(Attributes.class).child(Origin.class), - LABELED_UNICAST_ROUTE_IID.child(Attributes.class).child(LocalPref.class), - LABELED_UNICAST_ROUTE_IID.child(Attributes.class).child(Ipv4NextHop.class), - LABELED_UNICAST_ROUTE_IID.child(LabelStack.class) - ), - new BindingBrokerWriter<>(InstanceIdentifier.create(ApplicationRib.class), dataBroker) - ); - } - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java deleted file mode 100644 index f1e92c4ba..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.AbstractModule; -import com.google.inject.Singleton; -import com.google.inject.multibindings.Multibinder; -import io.fd.honeycomb.translate.write.WriterFactory; - -public class BgpWritersModule extends AbstractModule { - - protected void configure() { - // This should be part of BgpModule, 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 - final Multibinder binder = Multibinder.newSetBinder(binder(), WriterFactory.class); - binder.addBinding().toProvider(BgpWriterFactoryProvider.class).in(Singleton.class); - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java deleted file mode 100644 index 1fc6b25ed..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.bgp.translate.impl.LocRibWriter; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.fd.honeycomb.translate.bgp.RouteWriterFactory; -import java.util.HashSet; -import java.util.Set; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; - -final class LocRibWriterProvider extends ProviderTrait { - - @Inject - @Named(BgpModule.HONEYCOMB_BGP) - private DataBroker bgpDataBroker; - @Inject(optional = true) - private Set writerFactories = new HashSet<>(); - - @Override - protected LocRibWriter create() { - final LocRibWriter registry = new LocRibWriter(bgpDataBroker); - writerFactories.stream().forEach(factory -> factory.init(registry)); - return registry; - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java deleted file mode 100644 index b90b7880c..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp; - -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import java.util.ArrayList; -import java.util.Set; -import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; -import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator; -import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext; -import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext; -import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContextActivator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RIBExtensionConsumerContextProvider extends ProviderTrait { - private static final Logger LOG = LoggerFactory.getLogger(RIBExtensionConsumerContextProvider.class); - @Inject - private Set activators; - - @Override - protected RIBExtensionConsumerContext create() { - final RIBExtensionProviderContext ctx = new SimpleRIBExtensionProviderContext(); - final SimpleRIBExtensionProviderContextActivator activator = - new SimpleRIBExtensionProviderContextActivator(ctx, new ArrayList<>(activators)); - LOG.debug("Starting RIBExtensionConsumerContext with activators: {}", activators); - activator.start(); - return ctx; - } -} diff --git a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/distro/Main.java b/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/distro/Main.java deleted file mode 100644 index 8994f0415..000000000 --- a/infra/bgp-distribution/src/main/java/io/fd/honeycomb/infra/bgp/distro/Main.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017 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.bgp.distro; - -import com.google.inject.ConfigurationException; -import com.google.inject.CreationException; -import com.google.inject.Injector; -import com.google.inject.ProvisionException; -import io.fd.honeycomb.infra.bgp.BgpConfiguration; -import io.fd.honeycomb.infra.bgp.BgpServerProvider; -import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighbors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class Main { - - private static final Logger LOG = LoggerFactory.getLogger(Main.class); - - private Main() { - } - - public static void main(String[] args) { - init(); - } - - /** - * Initialize the Honeycomb with provided modules - */ - public static Injector init() { - try { - Injector injector = io.fd.honeycomb.infra.distro.Main.init(); - final BgpConfiguration bgpAttributes = injector.getInstance(BgpConfiguration.class); - - if (bgpAttributes.isBgpEnabled()) { - LOG.info("Starting BGP"); - injector.getInstance(BgpServerProvider.BgpServer.class); - LOG.info("Initializing BgpNeighbours"); - injector.getInstance(BgpNeighbors.class); - LOG.info("BGP started successfully!"); - } - - return injector; - } catch (CreationException | ProvisionException | ConfigurationException e) { - LOG.error("Failed to initialize Honeycomb components", e); - throw e; - } catch (RuntimeException e) { - LOG.error("Unexpected initialization failure", e); - throw e; - } finally { - // Trigger gc to force collect initial garbage + dedicated classloader - System.gc(); - } - } - -} diff --git a/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/activation.json b/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/activation.json deleted file mode 100644 index 8dd168702..000000000 --- a/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/activation.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "modules-resource-path": "../modules/", - "yang-modules-index-path": "../yang-mapping/" -} \ No newline at end of file diff --git a/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json b/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json deleted file mode 100644 index 93405fba6..000000000 --- a/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "bgp-openconfig-extensions:neighbors": { - "neighbor": [ - { - "neighbor-address": "10.25.1.9", - "config": { - "peer-group": "application-peers" - }, - "afi-safis": { - "afi-safi": [ - { - "afi-safi-name": "openconfig-bgp-types:IPV4-UNICAST", - "receive": true, - "send-max": 0 - }, - { - "afi-safi-name": "openconfig-bgp-types:IPV4-LABELLED-UNICAST", - "receive": true, - "send-max": 0 - } - ] - } - }, - { - "neighbor-address": "127.0.0.2", - "config": { - "peer-type": "INTERNAL" - }, - "timers": { - "config": { - "connect-retry": 10, - "hold-time": 90 - } - }, - "transport": { - "config": { - "remote-port": 17900, - "passive-mode": false - } - }, - "afi-safis": { - "afi-safi": [ - { - "afi-safi-name": "openconfig-bgp-types:IPV4-UNICAST", - "receive": true, - "send-max": 0 - } - ] - } - } - ] - } -} \ No newline at end of file diff --git a/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp.json b/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp.json deleted file mode 100644 index 2664c9ed6..000000000 --- a/infra/bgp-distribution/src/main/resources/honeycomb-minimal-resources/config/bgp.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "bgp-enabled": "true", - "bgp-binding-address": "127.0.0.1", - "bgp-port": 1790, - "bgp-as-number": 65000, - "bgp-receive-multiple-paths": "true", - "bgp-send-max-paths": 0, - "bgp-netty-threads": 2 -} \ No newline at end of file diff --git a/infra/minimal-distribution/pom.xml b/infra/minimal-distribution/pom.xml index 66f15f770..37c010f5c 100644 --- a/infra/minimal-distribution/pom.xml +++ b/infra/minimal-distribution/pom.xml @@ -40,7 +40,11 @@ io.fd.honeycomb.infra.distro.netconf.NetconfModule, io.fd.honeycomb.infra.distro.netconf.NetconfReadersModule, io.fd.honeycomb.infra.distro.restconf.RestconfModule, - io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule + io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule, + // io.fd.honeycomb.infra.bgp.BgpModule, + // io.fd.honeycomb.infra.bgp.BgpExtensionsModule, + // io.fd.honeycomb.infra.bgp.BgpReadersModule, + // io.fd.honeycomb.infra.bgp.BgpWritersModule @@ -69,5 +73,10 @@ org.eclipse.jetty jetty-server + + io.fd.honeycomb.northbound + bgp + ${project.version} + diff --git a/infra/northbound/bgp/asciidoc/Readme.adoc b/infra/northbound/bgp/asciidoc/Readme.adoc new file mode 100644 index 000000000..d125fb623 --- /dev/null +++ b/infra/northbound/bgp/asciidoc/Readme.adoc @@ -0,0 +1,4 @@ += bgp + +Adds BGP support to Honeycomb's northbound interfaces. +Depends on ODL's BGP implementation. \ No newline at end of file diff --git a/infra/northbound/bgp/bgp_postman_collection.json b/infra/northbound/bgp/bgp_postman_collection.json new file mode 100644 index 000000000..31297287d --- /dev/null +++ b/infra/northbound/bgp/bgp_postman_collection.json @@ -0,0 +1,283 @@ +{ + "id": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "name": "Honeycomb BGP RESTCONF calls", + "description": "Examples of BGP configration based on \nhttp://docs.opendaylight.org/en/stable-boron/user-guide/bgp-user-guide.html", + "order": [ + "de49ba67-7f69-a866-62e1-3102b610a85b", + "f3f23ede-fa81-fab9-9668-55aa746dec67", + "5b4964f0-183d-33fb-fe85-c9720101ebda", + "07529ecd-4c19-b46e-b033-d98d390fda4c", + "fb3c78a8-0d4e-2cb6-fddd-8f42e0336f53", + "708b7662-c912-724d-6267-91b4ee6a95a1", + "db1e7d40-8dc8-be65-9467-22a39cde24eb", + "7dcba5fa-d007-7aab-b0b5-8d855dc3c2b9", + "a45a76ba-0d23-57b4-eaf5-0b660a7852b3", + "2a3057b5-3961-45cf-a8bb-b58e056fe1a5" + ], + "folders": [], + "timestamp": 1494477000331, + "owner": "567303", + "public": false, + "requests": [ + { + "id": "07529ecd-4c19-b46e-b033-d98d390fda4c", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes", + "preRequestScript": null, + "pathVariables": {}, + "method": "POST", + "data": [], + "dataMode": "raw", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1494502752142, + "name": "add ipv4unicast route", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 0\n 10.0.0.11/32\n \n \n \n igp\n \n \n 100\n \n \n 10.11.1.1\n \n \n" + }, + { + "id": "2a3057b5-3961-45cf-a8bb-b58e056fe1a5", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "headerData": [ + { + "key": "Content-Type", + "value": "application/xml", + "description": "", + "enabled": true + }, + { + "key": "Authorization", + "value": "Basic YWRtaW46YWRtaW4=", + "description": "", + "enabled": true + } + ], + "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-labeled-unicast:labeled-unicast-subsequent-address-family/bgp-labeled-unicast:labeled-unicast-routes", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "POST", + "data": [], + "dataMode": "raw", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497523964759, + "name": "add IPv4 labeled unicast route", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n label1\n 1.1.1.1/32\n 1\n \n 800322\n \n \n \n 199.20.160.41\n \n \n igp\n \n \n \n 100\n \n \n" + }, + { + "id": "5b4964f0-183d-33fb-fe85-c9720101ebda", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/peer/bgp:%2F%2F10.25.1.9", + "preRequestScript": null, + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1495116619841, + "name": "show 127.0.0.3 app peer state", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" + }, + { + "id": "708b7662-c912-724d-6267-91b4ee6a95a1", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "headerData": [ + { + "key": "Content-Type", + "value": "application/xml", + "description": "", + "enabled": true + }, + { + "key": "Authorization", + "value": "Basic YWRtaW46YWRtaW4=", + "description": "", + "enabled": true + } + ], + "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/ipv4-route/10.0.0.12%2F32/0", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "PUT", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497597573297, + "name": "update second ipv4unicast route", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 0\n 10.0.0.12/32\n \n \n \n igp\n \n \n 102\n \n \n 10.11.1.1\n \n \n" + }, + { + "id": "7dcba5fa-d007-7aab-b0b5-8d855dc3c2b9", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/loc-rib", + "preRequestScript": null, + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1495009616064, + "name": "show speeker's Loc-RIB", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 10.25.1.9\n \n application-peers\n \n" + }, + { + "id": "a45a76ba-0d23-57b4-eaf5-0b660a7852b3", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/peer/bgp:%2F%2F127.0.0.2/adj-rib-out/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes", + "preRequestScript": null, + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1495009639185, + "name": "show 127.0.0.2 peer's adj-rib-out", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" + }, + { + "id": "db1e7d40-8dc8-be65-9467-22a39cde24eb", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "headerData": [ + { + "key": "Content-Type", + "value": "application/xml", + "description": "", + "enabled": true + }, + { + "key": "Authorization", + "value": "Basic YWRtaW46YWRtaW4=", + "description": "", + "enabled": true + } + ], + "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/ipv4-route/10.0.0.12%2F32/0", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "DELETE", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497597304771, + "name": "remove second ipv4unicast route", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "" + }, + { + "id": "de49ba67-7f69-a866-62e1-3102b610a85b", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance", + "preRequestScript": null, + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1495116911838, + "name": "show hc-bgp-instance", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" + }, + { + "id": "f3f23ede-fa81-fab9-9668-55aa746dec67", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8183/restconf/operational/bgp-rib:bgp-rib/rib/hc-bgp-instance/peer/bgp:%2F%2F127.0.0.2", + "preRequestScript": null, + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1495009591745, + "name": "show 127.0.0.2 peer state", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 192.0.2.1\n \n \n 90\n 10\n \n \n \n \n 179\n false\n \n \n \n INTERNAL\n \n" + }, + { + "id": "fb3c78a8-0d4e-2cb6-fddd-8f42e0336f53", + "headers": "Content-Type: application/xml\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "headerData": [ + { + "key": "Content-Type", + "value": "application/xml", + "description": "", + "enabled": true + }, + { + "key": "Authorization", + "value": "Basic YWRtaW46YWRtaW4=", + "description": "", + "enabled": true + } + ], + "url": "http://localhost:8183/restconf/config/bgp-rib:application-rib/10.25.1.9/tables/bgp-types:ipv4-address-family/bgp-types:unicast-subsequent-address-family/bgp-inet:ipv4-routes/ipv4-route/10.0.0.12%2F32/0", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "PUT", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497597550097, + "name": "add another ipv4unicast route", + "description": "", + "collectionId": "cb7735ac-4fe2-2de0-0c3a-298bdf17314f", + "responses": [], + "rawModeData": "\n 0\n 10.0.0.12/32\n \n \n \n igp\n \n \n 100\n \n \n 10.11.1.1\n \n \n" + } + ] +} \ No newline at end of file diff --git a/infra/northbound/bgp/pom.xml b/infra/northbound/bgp/pom.xml new file mode 100644 index 000000000..60860a50a --- /dev/null +++ b/infra/northbound/bgp/pom.xml @@ -0,0 +1,111 @@ + + + + + + impl-parent + io.fd.honeycomb.common + 1.17.07-SNAPSHOT + ../../../common/impl-parent + + + 4.0.0 + + io.fd.honeycomb.northbound + bgp + 1.17.07-SNAPSHOT + + + + + io.fd.honeycomb.northbound + common + ${project.version} + + + + + io.fd.honeycomb + minimal-distribution-core + ${project.version} + + + + + com.google.inject + guice + + + net.jmob + guice.conf + + + + + io.fd.honeycomb + bgp-translate-api + ${project.version} + + + io.fd.honeycomb + bgp-translate-impl + ${project.version} + + + + + org.opendaylight.bgpcep + bgp-rib-impl + + + + org.powermock + powermock + + + + + org.opendaylight.bgpcep + bgp-openconfig-impl + + + + + org.opendaylight.bgpcep + bgp-evpn + + + org.opendaylight.bgpcep + bgp-inet + + + org.opendaylight.bgpcep + bgp-labeled-unicast + + + org.opendaylight.bgpcep + bgp-linkstate + + + org.opendaylight.bgpcep + bgp-l3vpn + + + + \ No newline at end of file diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java new file mode 100644 index 000000000..c9ec39f35 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPDispatcherImplProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.netty.channel.EventLoopGroup; +import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext; +import org.opendaylight.protocol.bgp.rib.impl.BGPDispatcherImpl; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; + +final class BGPDispatcherImplProvider extends ProviderTrait { + @Inject + private BGPExtensionConsumerContext consumerContext; + @Inject + private EventLoopGroup threadGroup; + + @Override + protected BGPDispatcher create() { + return new BGPDispatcherImpl(consumerContext.getMessageRegistry(), threadGroup, threadGroup); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java new file mode 100644 index 000000000..00e99ab99 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BGPExtensionConsumerContextProvider.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import java.util.ArrayList; +import java.util.Set; +import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext; +import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderActivator; +import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext; +import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext; +import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContextActivator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class BGPExtensionConsumerContextProvider extends ProviderTrait { + private static final Logger LOG = LoggerFactory.getLogger(BGPExtensionConsumerContextProvider.class); + + @Inject + private Set activators; + + @Override + protected BGPExtensionConsumerContext create() { + final BGPExtensionProviderContext ctx = new SimpleBGPExtensionProviderContext(); + final SimpleBGPExtensionProviderContextActivator activator = + new SimpleBGPExtensionProviderContextActivator(ctx, new ArrayList<>(activators)); + LOG.debug("Starting BGPExtensionConsumerContext with activators: {}", activators); + activator.start(); + return ctx; + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java new file mode 100644 index 000000000..9182dd3a0 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfiguration.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.common.base.MoreObjects; +import java.util.Optional; +import net.jmob.guice.conf.core.BindConfig; +import net.jmob.guice.conf.core.InjectConfig; +import net.jmob.guice.conf.core.Syntax; + +/** + * This is the Java equivalent for bgp.json file. We use guice-config library to load all the config attributes + * into this class instance. + * + * The BindConfig annotation tells that bgp.json file should be looked up on classpath root. + */ +@BindConfig(value = "bgp", syntax = Syntax.JSON) +public class BgpConfiguration { + + public boolean isBgpEnabled() { + return Boolean.valueOf(bgpEnabled); + } + + public boolean isBgpMultiplePathsEnabled() { + return Boolean.valueOf(bgpMultiplePaths.get()); + } + + @InjectConfig("bgp-enabled") + public String bgpEnabled; + @InjectConfig("bgp-binding-address") + public Optional bgpBindingAddress; + @InjectConfig("bgp-port") + public Optional bgpPort; + @InjectConfig("bgp-as-number") + public Optional bgpAsNumber; + @InjectConfig("bgp-receive-multiple-paths") + public Optional bgpMultiplePaths; + @InjectConfig("bgp-send-max-paths") + public Optional bgpSendMaxMaths; + @InjectConfig("bgp-netty-threads") + public Integer bgpNettyThreads; + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("bgpEnabled", bgpEnabled) + .add("bgpBindingAddress", bgpBindingAddress) + .add("bgpPort", bgpPort) + .add("bgp-as-number", bgpAsNumber) + .add("bgp-netty-threads", bgpNettyThreads) + .add("bgp-receive-multiple-paths", bgpMultiplePaths) + .add("bgp-send-max-paths", bgpSendMaxMaths) + .toString(); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java new file mode 100644 index 000000000..a1c2e765b --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpConfigurationModule.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.AbstractModule; +import net.jmob.guice.conf.core.ConfigurationModule; + +/** + * Load the configuration from json into HoneycombConfiguration and make it available. + */ +public class BgpConfigurationModule extends AbstractModule { + + protected void configure() { + install(ConfigurationModule.create()); + // Inject non-dependency configuration + requestInjection(BgpConfiguration.class); + } + +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java new file mode 100644 index 000000000..d744065fb --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpExtensionsModule.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; +import io.fd.honeycomb.northbound.NorthboundAbstractModule; +import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext; +import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderActivator; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Registers BGP extensions provided by ODL implementation. + * TODO add support for flowspec (requires some special initialization) + */ +public final class BgpExtensionsModule extends NorthboundAbstractModule { + private static final Logger LOG = LoggerFactory.getLogger(BgpExtensionsModule.class); + + public BgpExtensionsModule() { + super(new BgpConfigurationModule(), BgpConfiguration.class); + } + + protected void configure() { + if (!getConfiguration().isBgpEnabled()) { + LOG.debug("BGP disabled. Skipping initialization"); + return; + } + LOG.debug("Initializing BgpExtensionsModule"); + // This should be part of BgpModule, 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 + configureRIBExtensions(); + configureBGPExtensions(); + } + + private void configureRIBExtensions() { + final Multibinder ribExtensionBinder = Multibinder.newSetBinder(binder(), + RIBExtensionProviderActivator.class); + ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.evpn.impl.RIBActivator.class); + ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.inet.RIBActivator.class); + ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.labeled.unicast.RIBActivator.class); + ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.linkstate.impl.RIBActivator.class); + ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv4.RibIpv4Activator.class); + ribExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv6.RibIpv6Activator.class); + bind(RIBExtensionConsumerContext.class).toProvider(RIBExtensionConsumerContextProvider.class) + .in(Singleton.class); + } + + private void configureBGPExtensions() { + final Multibinder bgpExtensionBinder = Multibinder.newSetBinder(binder(), + BGPExtensionProviderActivator.class); + bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.parser.impl.BGPActivator.class); + bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.evpn.impl.BGPActivator.class); + bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.inet.BGPActivator.class); + bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.labeled.unicast.BGPActivator.class); + bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.linkstate.impl.BGPActivator.class); + bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv4.BgpIpv4Activator.class); + bgpExtensionBinder.addBinding().to(org.opendaylight.protocol.bgp.l3vpn.ipv6.BgpIpv6Activator.class); + bind(BGPExtensionConsumerContext.class).toProvider(BGPExtensionConsumerContextProvider.class) + .in(Singleton.class); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java new file mode 100644 index 000000000..32c4440e0 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpModule.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017 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.bgp; + +import static io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider.CONFIG; +import static io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider.OPERATIONAL; + +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.InmemoryDOMDataBrokerProvider; +import io.fd.honeycomb.northbound.NorthboundPrivateModule; +import io.fd.honeycomb.translate.bgp.RibWriter; +import io.netty.channel.EventLoopGroup; +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.protocol.bgp.openconfig.impl.BGPOpenConfigMappingServiceImpl; +import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService; +import org.opendaylight.protocol.bgp.rib.impl.StrictBGPPeerRegistry; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry; +import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighbors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class BgpModule extends NorthboundPrivateModule { + private static final Logger LOG = LoggerFactory.getLogger(BgpModule.class); + + static final String HONEYCOMB_BGP = "honeycomb-bgp"; + + public BgpModule() { + super(new BgpConfigurationModule(), BgpConfiguration.class); + } + + protected void configure() { + if (!getConfiguration().isBgpEnabled()) { + LOG.debug("BGP disabled. Skipping initialization"); + return; + } + LOG.debug("Initializing BgpModule"); + install(getConfigurationModule()); + // Create BGPDispatcher BGPDispatcher for creating BGP clients + bind(EventLoopGroup.class).toProvider(BgpNettyThreadGroupProvider.class).in(Singleton.class); + bind(BGPDispatcher.class).toProvider(BGPDispatcherImplProvider.class).in(Singleton.class); + + configureRIB(); + + // Configure peer registry + bind(BGPOpenConfigMappingService.class).toInstance(new BGPOpenConfigMappingServiceImpl()); + bind(BGPPeerRegistry.class).toInstance(StrictBGPPeerRegistry.instance()); + + // Create BGP server instance (initialize eagerly to start BGP) + bind(BgpServerProvider.BgpServer.class).toProvider(BgpServerProvider.class).asEagerSingleton(); + + // Initialize BgpNeighbours (initialize eagerly to start BGP neighbours) + bind(BgpNeighbors.class).toProvider(BgpNeighboursProvider.class).asEagerSingleton(); + + // Listens for local RIB modifications and passes routes to translation layer + // (initialize eagerly to configure RouteWriters) + bind(RibWriter.class).toProvider(LocRibWriterProvider.class).asEagerSingleton(); + expose(RibWriter.class); + } + + private void configureRIB() { + // Create inmemory config data store for HONEYCOMB_BGP + bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(CONFIG)) + .toProvider(new DataStoreProvider(CONFIG, LogicalDatastoreType.CONFIGURATION)) + .in(Singleton.class); + + // Create inmemory operational data store for HONEYCOMB_BGP + bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(OPERATIONAL)) + .toProvider(new DataStoreProvider(OPERATIONAL, LogicalDatastoreType.OPERATIONAL)) + .in(Singleton.class); + + // Wrap datastores as DOMDataBroker + // TODO make executor service configurable + bind(DOMDataBroker.class).toProvider(InmemoryDOMDataBrokerProvider.class).in(Singleton.class); + + // Wrap DOMDataBroker as BA data broker (required by BgpReaderFactoryProvider) + bind(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_BGP)).toProvider(BindingDataBrokerProvider.class) + .in(Singleton.class); + expose(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_BGP)); + + // Create RIB instance + bind(RIB.class).toProvider(BgpRIBProvider.class).in(Singleton.class); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java new file mode 100644 index 000000000..b62444108 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNeighboursProvider.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2017 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.bgp; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.translate.util.JsonUtils.readContainerEntryJson; +import static org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil.APPLICATION_PEER_GROUP_NAME; +import static org.opendaylight.yangtools.sal.binding.generator.impl.BindingSchemaContextUtils.findDataNodeContainer; + +import com.google.common.base.Optional; +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import java.io.InputStream; +import java.util.Map; +import javax.annotation.Nonnull; +import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec; +import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService; +import org.opendaylight.protocol.bgp.rib.impl.config.AppPeer; +import org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry; +import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborPeerGroupConfig; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighbors; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class BgpNeighboursProvider extends ProviderTrait { + private static final Logger LOG = LoggerFactory.getLogger(BgpNeighboursProvider.class); + private static final String PEERS_CFG = "/bgp-peers.json"; + @Inject + private BindingToNormalizedNodeCodec codec; + @Inject + private RIB globalRib; + @Inject + private BGPOpenConfigMappingService mappingService; + @Inject + private SchemaService schemaService; + @Inject + private BGPPeerRegistry peerRegistry; + + @Override + protected BgpNeighbors create() { + LOG.info("Initializing BgpNeighbours"); + final BgpNeighbors neighbors = readNeighbours(); + for (final Neighbor neighbor : neighbors.getNeighbor()) { + if (isApplicationPeer(neighbor)) { + LOG.trace("Starting AppPeer for {}", neighbor); + new AppPeer().start(globalRib, neighbor, mappingService, null); + } else { + LOG.trace("Starting BgpPeer for {}", neighbor); + new BgpPeer(null, peerRegistry).start(globalRib, neighbor, mappingService, null); + } + } + LOG.debug("BgpNeighbours initialized: {}", neighbors); + return neighbors; + } + + private Neighbors readNeighbours() { + LOG.debug("Reading BGP neighbours from {}", PEERS_CFG); + final InputStream resourceStream = this.getClass().getResourceAsStream(PEERS_CFG); + checkState(resourceStream != null, "Resource %s not found", PEERS_CFG); + + final InstanceIdentifier bgpII = InstanceIdentifier.create(NetworkInstances.class) + .child(NetworkInstance.class, new NetworkInstanceKey("dummy-value")).child(Protocols.class) + .child(Protocol.class, new ProtocolKey(BGP.class, "dummy-value")).augmentation(Protocol1.class) + .child(Bgp.class); + final InstanceIdentifier neighborsII = bgpII.child(Neighbors.class); + + final YangInstanceIdentifier neighborsYII = codec.toYangInstanceIdentifier(neighborsII); + final SchemaContext schemaContext = schemaService.getGlobalContext(); + final Optional parentNode = findDataNodeContainer(schemaContext, bgpII); + final ContainerNode parentContainer = readContainerEntryJson(schemaContext, resourceStream, + (SchemaNode) parentNode.get(), + (YangInstanceIdentifier.NodeIdentifier) neighborsYII.getLastPathArgument()); + final NormalizedNode neighborsContainer = parentContainer.getValue().iterator().next(); + + final Map.Entry, DataObject> entry = codec.fromNormalizedNode(neighborsYII, neighborsContainer); + checkNotNull(entry, "Failed to deserialize neighbours configuration at %s", PEERS_CFG); + return (Neighbors) entry.getValue(); + } + + private static boolean isApplicationPeer(@Nonnull final Neighbor neighbor) { + return java.util.Optional.of(neighbor.getConfig()) + .map(config -> config.getAugmentation(Config2.class)) + .map(BgpNeighborPeerGroupConfig::getPeerGroup) + .map(APPLICATION_PEER_GROUP_NAME::equals) + .orElse(false); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java new file mode 100644 index 000000000..8208a4320 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpNettyThreadGroupProvider.java @@ -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.bgp; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.netty.channel.nio.NioEventLoopGroup; + +final class BgpNettyThreadGroupProvider extends ProviderTrait { + + @Inject + private BgpConfiguration cfgAttributes; + + @Override + protected NioEventLoopGroup create() { + return new NioEventLoopGroup(cfgAttributes.bgpNettyThreads, + new ThreadFactoryBuilder().setNameFormat("bgp-netty-%d").build()); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java new file mode 100644 index 000000000..a2bd56df3 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpRIBProvider.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.broker.impl.PingPongDataBroker; +import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; +import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode; +import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService; +import org.opendaylight.protocol.bgp.rib.impl.RIBImpl; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; +import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4LABELLEDUNICAST; +import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.AfiSafi2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.AfiSafi2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class BgpRIBProvider extends ProviderTrait { + private static final Logger LOG = LoggerFactory.getLogger(BgpRIBProvider.class); + private static final String HC_BGP_INSTANCE_NAME = "hc-bgp-instance"; + + @Inject + private BgpConfiguration cfg; + @Inject + private RIBExtensionConsumerContext extensions; + @Inject + private BGPDispatcher dispatcher; + @Inject + private BindingToNormalizedNodeCodec codec; + @Inject + private DOMDataBroker domBroker; + @Inject + private BGPOpenConfigMappingService mappingService; + @Inject + private SchemaService schemaService; + + @Override + protected RIB create() { + final AsNumber asNumber = new AsNumber(cfg.bgpAsNumber.get().longValue()); + final Ipv4Address routerId = new Ipv4Address(cfg.bgpBindingAddress.get()); + final ClusterIdentifier clusterId = new ClusterIdentifier(routerId); + LOG.debug("Creating BGP RIB: routerId={}, asNumber={}", routerId, asNumber); + // TODO configure other BGP Multiprotocol extensions: + final List afiSafi = ImmutableList.of( + new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class) + .addAugmentation(AfiSafi2.class, + new AfiSafi2Builder().setReceive(cfg.isBgpMultiplePathsEnabled()) + .setSendMax(cfg.bgpSendMaxMaths.get().shortValue()).build()) + .build(), + new AfiSafiBuilder().setAfiSafiName(IPV4LABELLEDUNICAST.class) + .addAugmentation(AfiSafi2.class, + new AfiSafi2Builder().setReceive(cfg.isBgpMultiplePathsEnabled()) + .setSendMax(cfg.bgpSendMaxMaths.get().shortValue()).build()) + .build() + ); + final Map pathSelectionModes = mappingService.toPathSelectionMode(afiSafi) + .entrySet().stream().collect(Collectors.toMap(entry -> + new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue)); + // based on RIBImpl.createRib + final RIBImpl rib = + new RIBImpl(new NoopClusterSingletonServiceProvider(), new RibId(HC_BGP_INSTANCE_NAME), asNumber, + new BgpId(routerId), clusterId, extensions, dispatcher, codec, new PingPongDataBroker(domBroker), + mappingService.toTableTypes(afiSafi), pathSelectionModes, extensions.getClassLoadingStrategy(), null); + + // required for proper RIB's CodecRegistry initialization (based on RIBImpl.start) + schemaService.registerSchemaContextListener(rib); + + LOG.debug("BGP RIB created successfully: {}", rib); + return rib; + } + + /** + * HC does not support clustering, but BGP uses {@link ClusterSingletonServiceProvider} + * to initialize {@link RIBImpl}. Therefore we provide this dummy implementation. + */ + private static final class NoopClusterSingletonServiceProvider implements ClusterSingletonServiceProvider { + private static final Logger LOG = LoggerFactory.getLogger(NoopClusterSingletonServiceProvider.class); + + private static final ClusterSingletonServiceRegistration REGISTRATION = + () -> LOG.debug("Closing ClusterSingletonServiceRegistration"); + + @Override + public ClusterSingletonServiceRegistration registerClusterSingletonService( + final ClusterSingletonService clusterSingletonService) { + clusterSingletonService.instantiateServiceInstance(); + return REGISTRATION; + } + + @Override + public void close() throws Exception { + LOG.debug("Closing NoopClusterSingletonServiceProvider"); + } + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java new file mode 100644 index 000000000..b79074f10 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReaderFactoryProvider.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017 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.bgp; + +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 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.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRibBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class BgpReaderFactoryProvider extends ProviderTrait { + + @Inject + @Named(BgpModule.HONEYCOMB_BGP) + private DataBroker bgpDataBroker; + + @Override + protected BgpReaderFactory create() { + return new BgpReaderFactory(bgpDataBroker); + } + + /** + * {@link ReaderFactory} provides reader form BGP's dedicated data store. + * Makes BGP operational data available over NETCONF/RESTCONF. + */ + private static final class BgpReaderFactory implements ReaderFactory { + + private final DataBroker bgpDataBroker; + + BgpReaderFactory(final DataBroker bgpDataBroker) { + this.bgpDataBroker = bgpDataBroker; + } + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + registry.add(new BindingBrokerReader<>(InstanceIdentifier.create(BgpRib.class), + bgpDataBroker, LogicalDatastoreType.OPERATIONAL, BgpRibBuilder.class)); + } + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java new file mode 100644 index 000000000..9f819614e --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpReadersModule.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; +import io.fd.honeycomb.northbound.NorthboundAbstractModule; +import io.fd.honeycomb.translate.read.ReaderFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BgpReadersModule extends NorthboundAbstractModule { + private static final Logger LOG = LoggerFactory.getLogger(BgpReadersModule.class); + + public BgpReadersModule() { + super(new BgpConfigurationModule(), BgpConfiguration.class); + } + + protected void configure() { + if (!getConfiguration().isBgpEnabled()) { + LOG.debug("BGP disabled. Skipping initialization"); + return; + } + LOG.debug("Initializing BgpReadersModule"); + // This should be part of BgpModule, 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 + final Multibinder binder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + binder.addBinding().toProvider(BgpReaderFactoryProvider.class).in(Singleton.class); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java new file mode 100644 index 000000000..b972ee297 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpServerProvider.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.common.base.Preconditions; +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.netty.channel.Channel; +import io.netty.channel.ChannelConfig; +import io.netty.channel.ChannelFuture; +import io.netty.channel.epoll.Epoll; +import io.netty.channel.epoll.EpollChannelOption; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences; +import org.opendaylight.protocol.bgp.rib.impl.spi.PeerRegistryListener; +import org.opendaylight.protocol.concepts.KeyMapping; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class BgpServerProvider extends ProviderTrait { + private static final Logger LOG = LoggerFactory.getLogger(BgpServerProvider.class); + @Inject + private BgpConfiguration cfg; + @Inject + private BGPPeerRegistry peerRegistry; + @Inject + private BGPDispatcher dispatcher; + + @Override + protected BgpServer create() { + // code based on org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerAcceptorModule from Boron-SR3 + final InetAddress bindingAddress; + try { + bindingAddress = InetAddress.getByName(cfg.bgpBindingAddress.get()); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Illegal BGP binding address", e); + } + final InetSocketAddress address = new InetSocketAddress(bindingAddress, cfg.bgpPort.get()); + LOG.debug("Creating BgpServer for {}", address); + final ChannelFuture localServer = dispatcher.createServer(peerRegistry, address); + localServer.addListener(future -> { + Preconditions.checkArgument(future.isSuccess(), "Unable to start bgp server on %s", address, future.cause()); + final Channel channel = localServer.channel(); + if (Epoll.isAvailable()) { + peerRegistry.registerPeerRegisterListener(new PeerRegistryListenerImpl(channel.config())); + } + }); + final BgpServer server = new BgpServer(localServer); + LOG.debug("BgpServer successfully started."); + return server; + } + + public static final class BgpServer { + private ChannelFuture localServer; + + BgpServer(final ChannelFuture localServer) { + this.localServer = localServer; + } + + public ChannelFuture getLocalServer() { + return localServer; + } + } + + private static final class PeerRegistryListenerImpl implements PeerRegistryListener { + private final ChannelConfig channelConfig; + private final KeyMapping keys; + + PeerRegistryListenerImpl(final ChannelConfig channelConfig) { + this.channelConfig = channelConfig; + this.keys = KeyMapping.getKeyMapping(); + } + @Override + public void onPeerAdded(final IpAddress ip, final BGPSessionPreferences prefs) { + if (prefs.getMd5Password().isPresent()) { + this.keys.put(IetfInetUtil.INSTANCE.inetAddressFor(ip), prefs.getMd5Password().get()); + this.channelConfig.setOption(EpollChannelOption.TCP_MD5SIG, this.keys); + } + } + @Override + public void onPeerRemoved(final IpAddress ip) { + if (this.keys.remove(IetfInetUtil.INSTANCE.inetAddressFor(ip)) != null) { + this.channelConfig.setOption(EpollChannelOption.TCP_MD5SIG, this.keys); + } + } + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java new file mode 100644 index 000000000..81faabbe5 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWriterFactoryProvider.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.translate.util.write.BindingBrokerWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.Ipv4Routes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4Route; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.LabelStack; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.routes.LabeledUnicastRoutes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.routes.list.LabeledUnicastRoute; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.LocalPref; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.Origin; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHop; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class BgpWriterFactoryProvider extends ProviderTrait { + @Inject + @Named(BgpModule.HONEYCOMB_BGP) + private DataBroker bgpDataBroker; + @Override + protected BgpWriterFactory create() { + return new BgpWriterFactory(bgpDataBroker); + } + + /** + * {@link WriterFactory} for BGP cfg write integration with HC writer registry. + * Using BindingBrokerWriter to write BGP configuration data via dedicated broker that, unlike + * {@link io.fd.honeycomb.data.impl.DataBroker}, supports tx chains and DOMDataChangeListener registration + * extensively used by ODL's bgp. + * + * As a bonus BGP route configuration is persisted and available for read via RESTCONF/NETCONF. + */ + private static final class BgpWriterFactory implements WriterFactory { + private final DataBroker dataBroker; + + private static final InstanceIdentifier AR_IID = + InstanceIdentifier.create(ApplicationRib.class); + private static final InstanceIdentifier TABLES_IID = AR_IID.child(Tables.class); + private static final InstanceIdentifier IPV4_ROUTES_IID = TABLES_IID.child((Class) Ipv4Routes.class); + private static final InstanceIdentifier IPV4_ROUTE_IID = IPV4_ROUTES_IID.child(Ipv4Route.class); + private static final InstanceIdentifier LABELED_UNICAST_ROUTES_IID = TABLES_IID.child((Class) LabeledUnicastRoutes.class); + private static final InstanceIdentifier LABELED_UNICAST_ROUTE_IID = LABELED_UNICAST_ROUTES_IID.child(LabeledUnicastRoute.class); + + private BgpWriterFactory(final DataBroker dataBroker) { + this.dataBroker = dataBroker; + } + + // TODO (HONEYCOMB-359): + // BGP models are huge, we need some kind of wildcarded subtree writer, that works for whole subtree. + // 1) we can either move checking handledTypes to writers (getHandledTypes, isAffected, writer.getHandedTypes, ...) + // but then precondition check in flatWriterRegistry might be slower (we need to check if we have all writers + // in order to avoid unnecessary reverts). + // + // 2) alternative is to compute all child nodes during initialization (might introduce some footprint penalty). + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + registry.subtreeAdd( + Sets.newHashSet( + TABLES_IID, + IPV4_ROUTES_IID, + IPV4_ROUTES_IID.child(Ipv4Route.class), + IPV4_ROUTE_IID.child(Attributes.class), + IPV4_ROUTE_IID.child(Attributes.class).child(Origin.class), + IPV4_ROUTE_IID.child(Attributes.class).child(LocalPref.class), + IPV4_ROUTE_IID.child(Attributes.class).child(Ipv4NextHop.class), + LABELED_UNICAST_ROUTES_IID, + LABELED_UNICAST_ROUTE_IID, + LABELED_UNICAST_ROUTE_IID.child(Attributes.class), + LABELED_UNICAST_ROUTE_IID.child(Attributes.class).child(Origin.class), + LABELED_UNICAST_ROUTE_IID.child(Attributes.class).child(LocalPref.class), + LABELED_UNICAST_ROUTE_IID.child(Attributes.class).child(Ipv4NextHop.class), + LABELED_UNICAST_ROUTE_IID.child(LabelStack.class) + ), + new BindingBrokerWriter<>(InstanceIdentifier.create(ApplicationRib.class), dataBroker) + ); + } + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java new file mode 100644 index 000000000..690a7feb2 --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/BgpWritersModule.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; +import io.fd.honeycomb.northbound.NorthboundAbstractModule; +import io.fd.honeycomb.translate.write.WriterFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BgpWritersModule extends NorthboundAbstractModule { + private static final Logger LOG = LoggerFactory.getLogger(BgpWritersModule.class); + + public BgpWritersModule() { + super(new BgpConfigurationModule(), BgpConfiguration.class); + } + + protected void configure() { + if (!getConfiguration().isBgpEnabled()) { + LOG.debug("BGP disabled. Skipping initialization"); + return; + } + LOG.debug("Initializing BgpReadersModule"); + // This should be part of BgpModule, 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 + final Multibinder binder = Multibinder.newSetBinder(binder(), WriterFactory.class); + binder.addBinding().toProvider(BgpWriterFactoryProvider.class).in(Singleton.class); + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java new file mode 100644 index 000000000..1fc6b25ed --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/LocRibWriterProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.bgp.translate.impl.LocRibWriter; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.translate.bgp.RouteWriterFactory; +import java.util.HashSet; +import java.util.Set; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; + +final class LocRibWriterProvider extends ProviderTrait { + + @Inject + @Named(BgpModule.HONEYCOMB_BGP) + private DataBroker bgpDataBroker; + @Inject(optional = true) + private Set writerFactories = new HashSet<>(); + + @Override + protected LocRibWriter create() { + final LocRibWriter registry = new LocRibWriter(bgpDataBroker); + writerFactories.stream().forEach(factory -> factory.init(registry)); + return registry; + } +} diff --git a/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java new file mode 100644 index 000000000..b90b7880c --- /dev/null +++ b/infra/northbound/bgp/src/main/java/io/fd/honeycomb/infra/bgp/RIBExtensionConsumerContextProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 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.bgp; + +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import java.util.ArrayList; +import java.util.Set; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext; +import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext; +import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContextActivator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RIBExtensionConsumerContextProvider extends ProviderTrait { + private static final Logger LOG = LoggerFactory.getLogger(RIBExtensionConsumerContextProvider.class); + @Inject + private Set activators; + + @Override + protected RIBExtensionConsumerContext create() { + final RIBExtensionProviderContext ctx = new SimpleRIBExtensionProviderContext(); + final SimpleRIBExtensionProviderContextActivator activator = + new SimpleRIBExtensionProviderContextActivator(ctx, new ArrayList<>(activators)); + LOG.debug("Starting RIBExtensionConsumerContext with activators: {}", activators); + activator.start(); + return ctx; + } +} diff --git a/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/activation.json b/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/activation.json new file mode 100644 index 000000000..8dd168702 --- /dev/null +++ b/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/activation.json @@ -0,0 +1,4 @@ +{ + "modules-resource-path": "../modules/", + "yang-modules-index-path": "../yang-mapping/" +} \ No newline at end of file diff --git a/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json b/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json new file mode 100644 index 000000000..93405fba6 --- /dev/null +++ b/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp-peers.json @@ -0,0 +1,53 @@ +{ + "bgp-openconfig-extensions:neighbors": { + "neighbor": [ + { + "neighbor-address": "10.25.1.9", + "config": { + "peer-group": "application-peers" + }, + "afi-safis": { + "afi-safi": [ + { + "afi-safi-name": "openconfig-bgp-types:IPV4-UNICAST", + "receive": true, + "send-max": 0 + }, + { + "afi-safi-name": "openconfig-bgp-types:IPV4-LABELLED-UNICAST", + "receive": true, + "send-max": 0 + } + ] + } + }, + { + "neighbor-address": "127.0.0.2", + "config": { + "peer-type": "INTERNAL" + }, + "timers": { + "config": { + "connect-retry": 10, + "hold-time": 90 + } + }, + "transport": { + "config": { + "remote-port": 17900, + "passive-mode": false + } + }, + "afi-safis": { + "afi-safi": [ + { + "afi-safi-name": "openconfig-bgp-types:IPV4-UNICAST", + "receive": true, + "send-max": 0 + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp.json b/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp.json new file mode 100644 index 000000000..c0981429f --- /dev/null +++ b/infra/northbound/bgp/src/main/resources/honeycomb-minimal-resources/config/bgp.json @@ -0,0 +1,9 @@ +{ + "bgp-enabled": "false", + "bgp-binding-address": "127.0.0.1", + "bgp-port": 1790, + "bgp-as-number": 65000, + "bgp-receive-multiple-paths": "true", + "bgp-send-max-paths": 0, + "bgp-netty-threads": 2 +} \ No newline at end of file diff --git a/infra/northbound/pom.xml b/infra/northbound/pom.xml index a768b32f6..3ae2859db 100644 --- a/infra/northbound/pom.xml +++ b/infra/northbound/pom.xml @@ -32,6 +32,7 @@ common + bgp \ No newline at end of file diff --git a/infra/pom.xml b/infra/pom.xml index 4540520c0..845cad0fa 100644 --- a/infra/pom.xml +++ b/infra/pom.xml @@ -43,7 +43,6 @@ minimal-distribution bgp-translate-api bgp-translate-impl - bgp-distribution it test-utils rpc -- cgit 1.2.3-korg