OAM NF Adopter Application 76/6076/6
authorClaudio D. Gasparini <claudio.gasparini@intl.att.com>
Tue, 4 May 2021 09:15:36 +0000 (11:15 +0200)
committerClaudio David Gasparini <claudio.gasparini@intl.att.com>
Tue, 18 May 2021 14:58:17 +0000 (14:58 +0000)
- Ves Application
- docker image
- docker-compose

Issue-ID: OAM-209
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@intl.att.com>
Change-Id: I6f7efddc31e03ca504c4ef30304874eb594f366f

25 files changed:
solution/docker-compose.yaml
ves-nf-oam-adopter/pom.xml
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/application.yml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/fm-ves-message-mapping.yaml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/log4j2.yml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/pm-ves-message-mapping.yaml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-cert.pem [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-key.pem [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-keystore.jks [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-truststore.jks [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter.p12 [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/docs/api/swagger/openapi.yaml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/pom.xml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/AdapterApplication.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/ServerProperties.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/SslProperties.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/HttpAsyncClientConfig.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/LoginAttemptsLogger.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/SecurityConfiguration.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/AdapterController.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/RestExceptionHandler.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/TimeZoneServiceProvider.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/http/HttpCientFactory.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-mock/docs/api/swagger/openapi.yaml
ves-nf-oam-adopter/ves-nf-oam-adopter-parent/pom.xml

index 595f1f8..9acf3e4 100644 (file)
@@ -1,18 +1,19 @@
 version: "3.5"
 
 services:
-#  ves-collector:
-#    restart: unless-stopped
-#    ports:
-#      - "8080:8080/udp"
-#    image: nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:latest
-#    container_name: vescollector
-#    environment:
-#      DMAAPHOST: 50.50.50.50
+  vescollector:
+    restart: unless-stopped
+    ports:
+      - "8080:8080/udp"
+    network_mode: host
+    image: nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:latest
+    container_name: vescollector
+    environment:
+      DMAAPHOST: 50.50.50.50
 
   ves-nf-oam-adopter-ran-mock:
     ports:
-      - "444:443/tcp"
+      - "443:443/tcp"
     network_mode: host
     restart: unless-stopped
     image: nexus3.o-ran-sc.org:10003/o-ran-sc/ves-nf-oam-adopter-ran-mock:latest
@@ -21,22 +22,23 @@ services:
       KEY_PASSWORD: nf-oam-adopter
       KEY_STORE_PASSWORD: nf-oam-adopter
       SNMP-DESTINY: 0.0.0.0/162
+      SERVER_PORT: 443
 
   ves-nf-oam-adopter:
     ports:
-      - "162:162/udp"
-      - "443:443/tcp"
+      - "443:444/tcp"
     network_mode: host
     restart: unless-stopped
     image: nexus3.o-ran-sc.org:10003/o-ran-sc/ves-nf-oam-adopter:latest
     container_name: ves-nf-oam-adopter
     environment:
+      SERVER_PORT: 444
       USERNAME: admin
       PASSWORD: admin
       KEY_PASSWORD: nf-oam-adopter
       KEY_STORE_PASSWORD: nf-oam-adopter
       TRUST_STORE_PASSWORD: nf-oam-adopter
-      VES_COLLECTOR: http://vescollector:8080/eventListener/v7
+      VES_COLLECTOR: http://0.0.0.0:8080/eventListener/v7
       VES_ENCODED_AUTH: YWRtaW46YWRtaW4=
-      PM_SYNC_TIME_START: "06:05:00"
-      PM_SYNC_TIME_FREQ: "24:00:00"
\ No newline at end of file
+      PM_SYNC_TIME_START: "14:25:00"
+      PM_SYNC_TIME_FREQ: 30
\ No newline at end of file
index 7b455cb..890d575 100644 (file)
@@ -52,5 +52,6 @@
         <module>ves-nf-oam-adopter-snmp-manager</module>
         <module>ves-nf-oam-adopter-pm-manager</module>
         <module>ves-nf-oam-adopter-pm-sb-rest-client</module>
+        <module>ves-nf-oam-adopter-app</module>
     </modules>
 </project>
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/application.yml b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/application.yml
new file mode 100644 (file)
index 0000000..fee8a56
--- /dev/null
@@ -0,0 +1,34 @@
+spring.devtools.restart.log-condition-evaluation-delta: false
+logging.config: log4j2.yml
+server:
+  port : ${SERVER_PORT:443}
+  username: ${USERNAME:admin}
+  password: ${PASSWORD:admin}
+  ssl:
+    enabled: true
+    key-store-type: JKS
+    key-alias: nf-oam-adopter
+    key-store: ${KEYSTORE_PATH:ssl/nf-oam-adopter-keystore.jks}
+    key-store-password: ${KEY_STORE_PASSWORD:nf-oam-adopter}
+    key-password: ${KEY_PASSWORD:nf-oam-adopter}
+    trust-store: ${TRUST_STORE_PATH:ssl/nf-oam-adopter-truststore.jks}
+    trust-store-password: ${TRUST_STORE_PASSWORD:nf-oam-adopter}
+    enabled-protocols: TLSv1.3
+    ciphers: TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_CCM_8_SHA256, TLS_AES_128_CCM_SHA256
+ves-collector:
+  url: ${VES_COLLECTOR}
+  vesEncodedAuth: ${VES_ENCODED_AUTH}
+http-client:
+  conection-timeout: ${CONNECTION_TIMEOUT:600}
+  response-timeout: ${RESPONSE_TIMEOUT:600}
+pm-rest-manager:
+  synchronization-time-start: ${PM_SYNC_TIME_START}
+  synchronization-time-frequency: ${PM_SYNC_TIME_FREQ}
+  mapping-config-path: ${PM_MAPPING_FILE_PATH:mapping-configuration/pm-ves-message-mapping.yaml}
+  ran-token-endpoint: /auth/token
+  ran-pm-endpoint: /pm/files
+  ran-time-zone-offset-endpoint: /system/timeZone
+snmp-manager:
+  host: "0.0.0.0"
+  port: ${SNMP_PORT:162}
+  mapping-config-path: ${FM_MAPPING_FILE_PATH:mapping-configuration/fm-ves-message-mapping.yaml}
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/fm-ves-message-mapping.yaml b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/fm-ves-message-mapping.yaml
new file mode 100644 (file)
index 0000000..24fd5d7
--- /dev/null
@@ -0,0 +1,21 @@
+reporting-entity-name: "NF-OAM-ADOPTER"
+reporting-entity-id: "NF-OAM-ADOPTER"
+nf-vendor-name: "SOME-VENDOR"
+traps:
+  - oid: "default"
+    name: "SNMP_Fault"
+    event-severity: "CRITICAL"
+    event-source-type: "Unknown"
+  - oid: "1.3.6.1.4.1.1007.0.0.1.0.1"
+    name: "PortDOWN"
+    event-severity: "MAJOR"
+    oid-event-id: "1.3.6.1.4.1.1007.2.6.9.0"
+    oid-event-sequence: "0"
+    oid-reporting-entity-id: "1.3.6.1.4.1.1007.0.0.1.0.6"
+    oid-source-name: "1.3.6.1.4.1.1007.0.0.1.0.2"
+    oid-specific-problem-desc: "1.3.6.1.4.1.1007.0.0.1.0.3"
+    oid-alarm-interface-name: "1.3.6.1.4.1.1007.0.0.1.0.7"
+    oid-start-epoch-microsec: "1.3.6.1.4.1.1007.0.0.1.0.4"
+    oid-last-epoch-microsec: "1.3.6.1.4.1.1007.0.0.1.0.5"
+    event-category: "link"
+    event-source-type: "port"
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/log4j2.yml b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/log4j2.yml
new file mode 100644 (file)
index 0000000..c10a74b
--- /dev/null
@@ -0,0 +1,48 @@
+Configuration:
+  status: debug
+
+  appenders:
+    Console:
+      name: LogToConsole
+      PatternLayout:
+        Pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
+
+    RollingFile:
+      - name: LogToRollingFile
+        fileName: logs/o-ran-ves-adapter.log
+        filePattern: "logs/$${date:yyyy-MM}/o-ran-ves-adapter-%d{MM-dd-yyyy}-%i.log.gz"
+        PatternLayout:
+          pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
+        Policies:
+          SizeBasedTriggeringPolicy:
+            size: 100MB
+        DefaultRollOverStrategy:
+          max: 10
+
+  Loggers:
+    logger:
+      - name: org.o.ran.oam.nf.oam
+        level: debug
+        additivity: false
+        AppenderRef:
+          - ref: LogToConsole
+          - ref: LogToRollingFile
+      - name: org.springframework.boot.actuate.audit.listener
+        level: info
+        additivity: false
+        AppenderRef:
+          - ref: LogToConsole
+          - ref: LogToRollingFile
+      - name: org.springframework
+        level: warn
+        additivity: false
+        AppenderRef:
+          - ref: LogToConsole
+          - ref: LogToRollingFile
+
+    Root:
+      level: info
+      AppenderRef:
+        AppenderRef:
+          - ref: LogToConsole
+          - ref: LogToRollingFile
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/pm-ves-message-mapping.yaml b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/pm-ves-message-mapping.yaml
new file mode 100644 (file)
index 0000000..073e3c7
--- /dev/null
@@ -0,0 +1,26 @@
+reporting-entity-name: "NF-OAM-ADOPTER"
+reporting-entity-id: "ONAP-NF-OAM-SOME-VENDOR-ADAPTER"
+nf-vendor-name: "SOME-VENDOR"
+event-source-type: "SNMP Agent"
+event-name: "PM_Notification"
+measurement-interval: 40
+priority: "High"
+batch-size: 200
+csv:
+  source-name: Name
+  event-id:
+    - PortId
+    - Date
+    - Time
+  additional-fields:
+    - PortId
+    - Name
+    - Date
+    - Time
+  additional-measurements-name: "Port measurements"
+  additional-measurements:
+    - A_Parameter
+    - B_Parameter
+    - C_Parameter
+    - D_Parameter
+    - E_Parameter
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-cert.pem b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-cert.pem
new file mode 100644 (file)
index 0000000..6f3a7ac
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDizCCAnOgAwIBAgIUUR7hr58NdGQKpF3gmqUJRSdYwZgwDQYJKoZIhvcNAQEL
+BQAwVTELMAkGA1UEBhMCU0sxEzARBgNVBAgMCkJyYXRpc2xhdmExEzARBgNVBAcM
+CkJyYXRpc2xhdmExDTALBgNVBAoMBEFUJlQxDTALBgNVBAsMBEFUJlQwHhcNMjEw
+NTA0MDgxNjUzWhcNMzEwNTAyMDgxNjUzWjBVMQswCQYDVQQGEwJTSzETMBEGA1UE
+CAwKQnJhdGlzbGF2YTETMBEGA1UEBwwKQnJhdGlzbGF2YTENMAsGA1UECgwEQVQm
+VDENMAsGA1UECwwEQVQmVDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ANgJZ0Vz0Aa0tFWAzJqeaVeT52zLweSWv2rbXFka/2ClAioUUSm7j0+y7lT9yTbK
+J27opYojlB0wPRBor5n587lpTP9yJYephIQvUdfsgP62xXANVcd1MVWRbI0ldxtc
+EOWaW/w2b3yDLa+o+zsG0KN7IAYmDfb7ZVc5fn+zU9oqO+UlhVbgPhJjRdlGJjoL
+zCZYP8ip6xEmRDDZZ+KTazevYZ4ZFe4VWVbOn3eRTBWVea3HAirmbNSEWG1HWZ0y
+BjGy+eI9HbHVLpuLObPUASpZCvEjwS2/IYwYkpBREwSmLUXu6qj8rp0F3GVTk8D0
+Y6xy6CtmcDFz2KOYWD9KKm8CAwEAAaNTMFEwHQYDVR0OBBYEFBALTA7uLbxLThTx
+a/R/0hcydIsjMB8GA1UdIwQYMBaAFBALTA7uLbxLThTxa/R/0hcydIsjMA8GA1Ud
+EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAD0czkrPMahhFNiJD5fmW3T
+o3QMCS/WQ4iCZ3/ROQ6P8zbNqbkZxy+yF6b1kii81wDd5jnoo1b/zhjHoUb7pUWg
+NFZXqF+zajKr0zXcDGbuksIlukVmB6Vz83jEowGxb5xakh9gluxukabkhO7yBUFY
+sc4B34n1keOKKQKdmgxG7FBS77n0Em+9NeuLzvP0S9AvkQdgDgXRX2yVjy8gVGEA
+Iz+IEIDE/oQQ3HaUQTIItnMNhg1orUzOzps5FdOtFEtd7XwjqSgu+NR77G6KOFcR
+RFw9V3uEd2XUn+sHUu81yfseBjMcneuvKBr/KIbwlj86kEAyaTedL2oRX6Ful6Q=
+-----END CERTIFICATE-----
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-key.pem b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-key.pem
new file mode 100644 (file)
index 0000000..011107e
--- /dev/null
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIbmqjaTYftFoCAggA
+MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECIAcQM6jVuDQBIIEyOixt6jiuuRv
+6IYnMnmYvaeWIxoMpqvMHSoWFSvSdyCuGdTJv+qxit+HpVOGqhVRckSv0nAAbEdE
+jw0PVyAgfWX7vQca1YK2mxw5tGrNsSyQ5LPtS5QICe4fDew8VwiGXWdQhnxvIxUW
+xORfAOTar2qEgE0OBsYVBEjdU3mS3RFRKDtCVXYxiII6/24Nsf7bmz438VxShwog
+A5Zq6sQtqOjF3sKfRgkimOGLgBw7DACI852bEVffySdt8CdGZuAAfD6PucmQSTHp
+CSdmCELBA4p6juNFgpRqvm5qlG/7ZBJhcjGU7CAN1v8oYBH0TB44ek4hOFzT9b5P
+8icBXmg4w2ysWz6OPbwcQj8pG1yRb7WDUulntlSUijI2AXFV2SWIHZ2APFdVQ1c4
+qrivre66FIfo79/I+RTo5MMp2wmJbAjsSaO4571hwY9Cap0TdeJ+KmIKpK+HYwLQ
+iwJip2TtBUmd/ANPnJmgrG2pAeiahciJ0gMGwN2L5uxoiV+FSLwEQ7JCXZn2ET9B
+ai2ZodjIHjZTAT/dtX9gS/yJyHC20HpA3mVtjkenGHaBbs0ji2u1bK9JUgNb43R1
+I7r4BfsYav3+FTq1xoU/vFlP7vxX9cgUduda4rTu7ZNu56RgxKFeqsWl5gbUIX6y
+UU2W1R3TXVpoBPHzpEo2Vcig6exEEVEaO8HXu16UD1+wvwLYkSlwWjKby1pVOdNw
++ZnZv5aLIFk2UC1yJ7AJcxHLIcmJD6jBlzpGmQOqNvVb4Qig0NyMkz0bZAJ5SI/t
+6mZZXHDmgRLfjluawVYIoIVcflm/yfRh6nELUAfh/IAIVyDvaEtEwfK3SlWXrvP4
+j+F8EacnQm7O1rFgR+p2AxMtAdAm7E4JVoNpHSWbv36EI34RaoVPng7ueBSkG3Uk
+7qrbb/lWjXveKfizkkuUUFZWKiSyXAxYiXu9sQjBlN2EWSgBAix7WpqSh2CPROO4
+gn51n7TKyer5CcUqwzMz5SLhRSNkoBY82vIyBZyf7UrRztmJPrvbr4UQSoiqLrey
+DPaT0LHtyJZWuNZS2ki+WI1nnKkFtWgl7Yv57EtBwHqTpARvH4NiF8ryJbp8rl6R
+WMz5haeuBmFz/IXZtOsRXVR+kjhShBKygKYRtUGEc3sSDL2HsA47pCCaFW8907NP
+dfv1WeKyI6d0snBIMKypzFGo17CtdcxsNiAgcrwW2cvwsDyysimZQPa7dr1uAwEX
+WU2WAaoGmxShZB9fvdIeg4bydnJAlVOjotWs+kwPzCLFk++DSQ4HiElJnwawuPfB
+XWqk7ZaKZEiZXNJMyMGIqKo8w+88uIQTd4YNbfhBgvSlgf8Y5EaYbzx68yUkPeOR
+Urli4hXpSkkB3DtmRMquUg1xPn6Ao+vvEoXwiUPg61YQIO1RvTr2vVAWVj1WYcJI
+4k6sAi6HhhlGEVL1bxFMpkX9h/Jwd0YgDYAUFJ2DPnZ+18gbdpA7QZp/SBKwZpTh
+cbNXBkwv2Wa4u/yQsoqoyrxOTzpfiRYVvr4Xmi40TuLC4JEYqTdg+HE5ovjfIFTz
+dxOMEon6JwvwXxWdqZS655hVcG0pH1JvBVouGrWB5EOElVCzDcvquacDofaemcA9
+lkve4yZbTmJRwZrUBCmTOQ==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-keystore.jks b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-keystore.jks
new file mode 100644 (file)
index 0000000..8712bd5
Binary files /dev/null and b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-keystore.jks differ
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-truststore.jks b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-truststore.jks
new file mode 100644 (file)
index 0000000..42cfc88
Binary files /dev/null and b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter-truststore.jks differ
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter.p12 b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter.p12
new file mode 100644 (file)
index 0000000..8b54595
Binary files /dev/null and b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/configuration/ssl/nf-oam-adopter.p12 differ
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/docs/api/swagger/openapi.yaml b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/docs/api/swagger/openapi.yaml
new file mode 100644 (file)
index 0000000..6a02e63
--- /dev/null
@@ -0,0 +1,124 @@
+#  ============LICENSE_START=======================================================
+#  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+#  ================================================================================
+#  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.
+#
+#  SPDX-License-Identifier: Apache-2.0
+#  ============LICENSE_END=========================================================
+openapi: 3.0.3
+info:
+  title: O-RAN OAM Adopter PM Manager
+  description: API for O-RAN OAM Adopter PM Manager service.
+  version: "1.0.0"
+  license:
+    name: "Apache 2.0"
+    url: "http://www.apache.org/licenses/LICENSE-2.0"
+
+servers:
+  - url: https://example.io/v1
+
+security:
+  - BasicAuth: []
+
+paths:
+  /:
+    get:
+      tags:
+        - controller
+      summary: Read all adapters host address
+      description: Returns a list of adapters host address
+      operationId: getAllAdapters
+      responses:
+        '200':
+          description: Successfully returned a list of adapters host address
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  type: string
+        '400':
+          $ref: '#/components/responses/400Error'
+
+
+  /adapter/{host}:
+    delete:
+      tags:
+        - controller
+      description: Delete an adapter by host address
+      operationId: removeAdapter
+      parameters:
+        - name: host
+          in: path
+          required: true
+          schema:
+            type: string
+
+      responses:
+        '200':
+          description: Successfully deleted an adapter
+        '400':
+          description: Invalid request
+        '401':
+          description: Unauthorized
+        '404':
+          description: adapter not found
+
+  /adapter:
+    post:
+      tags:
+        - controller
+      description: create an adapter instance
+      operationId: addAdapter
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Adapter'
+      responses:
+        '200':
+          description: Successfully returned a list of adapters
+        '400':
+          $ref: '#/components/responses/400Error'
+
+components:
+  schemas:
+    Adapter:
+      type: object
+      properties:
+        host:
+          type: string
+        mechId:
+          type: object
+          properties:
+            username:
+              type: string
+            password:
+              type: string
+          required:
+            - username
+            - password
+      required:
+        - host
+        - mechId
+
+  responses:
+    400Error:
+      description: Invalid request
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              message:
+                type: string
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/pom.xml b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/pom.xml
new file mode 100644 (file)
index 0000000..7ac92c7
--- /dev/null
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+* ============LICENSE_START=======================================================
+* O-RAN-SC
+* ================================================================================
+* Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+* ================================================================================
+* 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.
+* ============LICENSE_END============================================
+*
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.o-ran-sc.oam</groupId>
+        <artifactId>ves-nf-oam-adopter-parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../ves-nf-oam-adopter-parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>ves-nf-oam-adopter-app</artifactId>
+
+    <properties>
+        <minimum.coverage>0.18</minimum.coverage>
+        <!--Plugins properties-->
+        <swagger-codegen-maven-plugin.version>3.0.25</swagger-codegen-maven-plugin.version>
+        <!--Image properties-->
+        <base.image>openjdk:11-jre-slim</base.image>
+        <base.config>${project.basedir}/configuration/</base.config>
+        <image.name>ves-nf-oam-adopter</image.name>
+        <image.workdir>/o-ran-ves-adapter/</image.workdir>
+        <nexus.repository>nexus3.o-ran-sc.org:10003/o-ran-sc/</nexus.repository>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ves-nf-oam-adopter-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ves-nf-oam-adopter-event-notifier</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ves-nf-oam-adopter-snmp-manager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ves-nf-oam-adopter-pm-manager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ves-nf-oam-adopter-pm-sb-rest-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents.client5</groupId>
+            <artifactId>httpclient5</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger.core.v3</groupId>
+            <artifactId>swagger-annotations</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <!-- Swagger code generation. -->
+            <plugin>
+                <groupId>io.swagger.codegen.v3</groupId>
+                <artifactId>swagger-codegen-maven-plugin</artifactId>
+                <version>${swagger-codegen-maven-plugin.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <inputSpec>${project.basedir}/docs/api/swagger/openapi.yaml</inputSpec>
+                            <invokerPackage>org.o.ran.oam.nf.oam.adopter.app.controller</invokerPackage>
+                            <modelPackage>org.o.ran.oam.nf.oam.adopter.model</modelPackage>
+                            <apiPackage>org.o.ran.oam.nf.oam.adopter.api</apiPackage>
+                            <language>spring</language>
+                            <generateSupportingFiles>false</generateSupportingFiles>
+                            <configOptions>
+                                <sourceFolder>src/gen/java</sourceFolder>
+                                <dateLibrary>java11</dateLibrary>
+                                <interfaceOnly>true</interfaceOnly>
+                                <useTags>true</useTags>
+                                <serializableModel>true</serializableModel>
+                            </configOptions>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>docker</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>io.fabric8</groupId>
+                        <artifactId>docker-maven-plugin</artifactId>
+                        <version>0.34.1</version>
+                        <extensions>true</extensions>
+                        <configuration>
+                            <verbose>true</verbose>
+                            <images>
+                                <image>
+                                    <name>${nexus.repository}${image.name}</name>
+                                    <build>
+                                        <from>${base.image}</from>
+                                        <tags>
+                                            <tag>${project.version}</tag>
+                                        </tags>
+                                        <workdir>${image.workdir}</workdir>
+                                        <entryPoint>
+                                            <exec>
+                                                <args>java</args>
+                                                <args>-jar</args>
+                                                <args>${project.artifactId}-${project.version}.jar</args>
+                                            </exec>
+                                        </entryPoint>
+                                        <assembly>
+                                            <basedir>${image.workdir}</basedir>
+                                            <inline>
+                                                <dependencySets>
+                                                    <dependencySet>
+                                                        <useProjectArtifact>true</useProjectArtifact>
+                                                        <includes>
+                                                            <include>${project.groupId}:${project.artifactId}</include>
+                                                        </includes>
+                                                        <outputFileNameMapping>${project.build.finalName}.jar</outputFileNameMapping>
+                                                    </dependencySet>
+                                                </dependencySets>
+                                                <files>
+                                                    <file>
+                                                        <source>${base.config}application.yml</source>
+                                                        <outputDirectory>.</outputDirectory>
+                                                        <destName>application.yml</destName>
+                                                    </file>
+                                                    <file>
+                                                        <source>${base.config}fm-ves-message-mapping.yaml</source>
+                                                        <outputDirectory>./mapping-configuration</outputDirectory>
+                                                        <destName>fm-ves-message-mapping.yaml</destName>
+                                                    </file>
+                                                    <file>
+                                                        <source>${base.config}pm-ves-message-mapping.yaml</source>
+                                                        <outputDirectory>./mapping-configuration</outputDirectory>
+                                                        <destName>pm-ves-message-mapping.yaml</destName>
+                                                    </file>
+                                                    <file>
+                                                        <source>${base.config}log4j2.yml</source>
+                                                    </file>
+                                                    <file>
+                                                        <source>${base.config}/ssl/nf-oam-adopter-keystore.jks</source>
+                                                        <outputDirectory>./ssl</outputDirectory>
+                                                        <destName>nf-oam-adopter-keystore.jks</destName>
+                                                    </file>
+                                                    <file>
+                                                        <source>${base.config}/ssl/nf-oam-adopter-truststore.jks</source>
+                                                        <outputDirectory>./ssl</outputDirectory>
+                                                        <destName>nf-oam-adopter-truststore.jks</destName>
+                                                    </file>
+                                                </files>
+                                            </inline>
+                                        </assembly>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>build-docker-image</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>build</goal>
+                                </goals>
+                            </execution>
+                            <execution>
+                                <id>push-image</id>
+                                <phase>deploy</phase>
+                                <goals>
+                                    <goal>push</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/AdapterApplication.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/AdapterApplication.java
new file mode 100644 (file)
index 0000000..59ce697
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = {"org.o.ran.oam.nf.oam.adopter"})
+public class AdapterApplication {
+
+    public static void main(final String[] args) {
+        SpringApplication.run(AdapterApplication.class, args);
+    }
+}
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/ServerProperties.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/ServerProperties.java
new file mode 100644 (file)
index 0000000..0c77e44
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "server")
+@Data
+@NoArgsConstructor
+public class ServerProperties {
+    private int port;
+    private String username;
+    private String password;
+    private SslProperties ssl;
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/SslProperties.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/SslProperties.java
new file mode 100644 (file)
index 0000000..fd4e066
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class SslProperties {
+    private Boolean enabled;
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/HttpAsyncClientConfig.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/HttpAsyncClientConfig.java
new file mode 100644 (file)
index 0000000..5404ca6
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app.config;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.o.ran.oam.nf.oam.adopter.app.http.HttpCientFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class HttpAsyncClientConfig {
+
+    @Value("${server.ssl.trust-store:#{null}}")
+    private String trustStore;
+    @Value("${server.ssl.trust-store-password:#{null}}")
+    private String trustStorePassword;
+    @Value("${http-client.conection-timeout:600}")
+    private Long conectionTimeout;
+    @Value("${http-client.response-timeout:600}")
+    private Long responseTimeout;
+
+    @Bean(initMethod = "start", destroyMethod = "close")
+    public CloseableHttpAsyncClient getHttpClient()
+            throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException,
+                           KeyManagementException {
+        return HttpCientFactory.createClient(trustStore, trustStorePassword, conectionTimeout, responseTimeout);
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/LoginAttemptsLogger.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/LoginAttemptsLogger.java
new file mode 100644 (file)
index 0000000..e1222f5
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.actuate.audit.AuditEvent;
+import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository;
+import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.event.EventListener;
+import org.springframework.security.web.authentication.WebAuthenticationDetails;
+import org.springframework.stereotype.Component;
+
+@Component
+public class LoginAttemptsLogger {
+    private static final Logger LOG = LoggerFactory.getLogger(LoginAttemptsLogger.class);
+
+    /**
+     *  audit Application Event.
+     */
+    @EventListener
+    public void auditEventHappened(final AuditApplicationEvent auditApplicationEvent) {
+        final AuditEvent auditEvent = auditApplicationEvent.getAuditEvent();
+        final WebAuthenticationDetails details = (WebAuthenticationDetails) auditEvent.getData().get("details");
+        LOG.info("AUDIT: User: {} Event Type: {} Remote IP address: {}",
+                auditEvent.getPrincipal(), auditEvent.getType(), details.getRemoteAddress());
+    }
+
+    @Bean
+    public InMemoryAuditEventRepository auditEventRepository() throws Exception {
+        return new InMemoryAuditEventRepository();
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/SecurityConfiguration.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/SecurityConfiguration.java
new file mode 100644 (file)
index 0000000..18101a4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app.config;
+
+import org.o.ran.oam.nf.oam.adopter.app.ServerProperties;
+import org.o.ran.oam.nf.oam.adopter.app.SslProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@Configuration
+@EnableConfigurationProperties
+public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+    private static final String ADMIN_ROLE = "ADMIN";
+    private final ServerProperties properties;
+
+    @Autowired
+    public SecurityConfiguration(final ServerProperties properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    protected void configure(final HttpSecurity http) throws Exception {
+        final SslProperties ssl = properties.getSsl();
+        if (ssl != null && ssl.getEnabled() != null && ssl.getEnabled()) {
+            http.requiresChannel().anyRequest().requiresSecure();
+        }
+        http.csrf().disable().antMatcher("/adapters/**").authorizeRequests().anyRequest().hasRole(ADMIN_ROLE).and()
+                .httpBasic();
+    }
+
+    @Bean
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return super.authenticationManagerBean();
+    }
+
+    @Autowired
+    public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
+        auth.inMemoryAuthentication().withUser(properties.getUsername()).password("{noop}" + properties.getPassword())
+                .roles(ADMIN_ROLE);
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/AdapterController.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/AdapterController.java
new file mode 100644 (file)
index 0000000..1960af7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app.controller;
+
+import java.util.List;
+import lombok.SneakyThrows;
+import org.o.ran.oam.nf.oam.adopter.api.ControllerApi;
+import org.o.ran.oam.nf.oam.adopter.model.Adapter;
+import org.o.ran.oam.nf.oam.adopter.model.AdapterMechId;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api.PerformanceManagementAdaptersDeployer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@SpringBootApplication(scanBasePackages = {"org.o.ran.oam.adopter"})
+@RequestMapping(path = "/adapters")
+public class AdapterController implements ControllerApi {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AdapterController.class);
+
+    private final PerformanceManagementAdaptersDeployer deployer;
+
+    @Autowired
+    public AdapterController(final PerformanceManagementAdaptersDeployer deployer) {
+        this.deployer = deployer;
+    }
+
+    @Override
+    @SneakyThrows
+    public ResponseEntity<Void> addAdapter(final Adapter adapter) {
+        LOG.info("Request triggered: addAdapter");
+        final AdapterMechId mechIdDto = adapter.getMechId();
+        deployer.create(adapter.getHost(), mechIdDto.getUsername(), mechIdDto.getPassword());
+        return ResponseEntity.ok().build();
+    }
+
+    @Override
+    @SneakyThrows
+    public ResponseEntity<List<String>> getAllAdapters() {
+        LOG.info("Request triggered: getAllAdapters");
+        return ResponseEntity.ok(deployer.getAll());
+    }
+
+    @Override
+    @SneakyThrows
+    public ResponseEntity<Void> removeAdapter(final String host) {
+        LOG.info("Request triggered: removeAdapter");
+        deployer.delete(host);
+        return ResponseEntity.ok().build();
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/RestExceptionHandler.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/RestExceptionHandler.java
new file mode 100644 (file)
index 0000000..a4a7d6f
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app.controller;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.AlreadyPresentException;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.NotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class RestExceptionHandler {
+    private static final Logger LOG = LoggerFactory.getLogger(RestExceptionHandler.class);
+
+    /**
+     * Handle Already Present Exceptions.
+     */
+    @ExceptionHandler({AlreadyPresentException.class})
+    public static ResponseEntity<Object> handleBadRequestExceptions(final AlreadyPresentException exception) {
+        LOG.error("Request failed", exception);
+        return ResponseEntity
+                .badRequest()
+                .body(exception.getMessage());
+    }
+
+    /**
+     * Handle Not Found Exceptions.
+     */
+    @ExceptionHandler({NotFoundException.class})
+    public static ResponseEntity<Object> handleNotFoundExceptions(final NotFoundException exception) {
+        LOG.error("Request failed", exception);
+        return ResponseEntity.notFound().build();
+    }
+
+    /**
+     * Handle MethodArgument Not Valid Exceptions.
+     */
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public Map<String, String> handleValidationExceptions(final MethodArgumentNotValidException ex) {
+        final Map<String, String> errors = new HashMap<>();
+        ex.getBindingResult().getAllErrors().forEach((error) -> {
+            final String fieldName = ((FieldError) error).getField();
+            final String errorMessage = error.getDefaultMessage();
+            errors.put(fieldName, errorMessage);
+        });
+        return errors;
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/TimeZoneServiceProvider.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/TimeZoneServiceProvider.java
new file mode 100644 (file)
index 0000000..c201ce6
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app.controller;
+
+import java.time.ZoneId;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api.PerformanceManagementAdaptersDeployer;
+import org.o.ran.oam.nf.oam.adopter.snmp.manager.api.TimeZoneOffsetService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TimeZoneServiceProvider implements TimeZoneOffsetService {
+
+    private final PerformanceManagementAdaptersDeployer deployer;
+
+    @Autowired
+    public TimeZoneServiceProvider(final PerformanceManagementAdaptersDeployer deployer) {
+        this.deployer = deployer;
+    }
+
+    @Override
+    public ZoneId getTimeZone(final String host) {
+        return deployer.getTimeZone(host);
+    }
+}
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/http/HttpCientFactory.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/http/HttpCientFactory.java
new file mode 100644 (file)
index 0000000..073a622
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 AT&T Intellectual Property. All rights reserved.
+ *  ================================================================================
+ *  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.
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.o.ran.oam.nf.oam.adopter.app.http;
+
+import com.google.common.base.Strings;
+import java.io.File;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import javax.net.ssl.SSLContext;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.cookie.StandardCookieSpec;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
+import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
+import org.apache.hc.client5.http.ssl.TrustAllStrategy;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.ssl.SSLContextBuilder;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.util.Timeout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class HttpCientFactory {
+    private static final Logger LOG = LoggerFactory.getLogger(HttpCientFactory.class);
+
+    /**
+     * Generates a CloseableHttpAsyncClient.
+     */
+    public static CloseableHttpAsyncClient createClient(final String trustStore,
+            final String trustStorePassword, final Long conectionTimeout, final Long responseTimeout)
+            throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException,
+            CertificateException {
+        if (Strings.isNullOrEmpty(trustStore) || Strings.isNullOrEmpty(trustStorePassword)) {
+            return trustAllCertificate(conectionTimeout, responseTimeout);
+        }
+        final File trustStoreFilePath = new File(trustStore);
+        if (!trustStoreFilePath.exists() || trustStoreFilePath.isDirectory()) {
+            return trustAllCertificate(conectionTimeout, responseTimeout);
+        }
+
+        final SSLContext sslContext = getSslContext(trustStoreFilePath, trustStorePassword);
+        return trustTrustStore(sslContext, conectionTimeout, responseTimeout);
+    }
+
+    private static SSLContext getSslContext(final File trustStoreFilePath, final String trustStorePassword)
+            throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException {
+        return new SSLContextBuilder()
+                .loadTrustMaterial(trustStoreFilePath.toURI().toURL(), trustStorePassword.toCharArray())
+                .build();
+    }
+
+    private static CloseableHttpAsyncClient trustTrustStore(final SSLContext sslContext,
+            final Long conectionTimeout, final Long responseTimeout) {
+        LOG.info("Trust all certificates under truststore");
+        final PoolingAsyncClientConnectionManager connectionManager =
+                PoolingAsyncClientConnectionManagerBuilder.create().setTlsStrategy(
+                        ClientTlsStrategyBuilder.create()
+                                .setSslContext(sslContext)
+                                .setHostnameVerifier(NoopHostnameVerifier.INSTANCE)
+                                .build())
+                        .build();
+
+        return HttpAsyncClients.custom()
+                .setConnectionManager(connectionManager)
+                .setDefaultRequestConfig(createDefaultRequestConfig(conectionTimeout, responseTimeout))
+                .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+                .build();
+    }
+
+    private static RequestConfig createDefaultRequestConfig(final Long conectionTimeout, final Long responseTimeout) {
+        return RequestConfig.custom()
+                .setConnectTimeout(Timeout.ofSeconds(conectionTimeout))
+                .setResponseTimeout(Timeout.ofSeconds(responseTimeout))
+                .setCookieSpec(StandardCookieSpec.STRICT)
+                .build();
+    }
+
+    private static CloseableHttpAsyncClient trustAllCertificate(final Long conectionTimeout, final Long responseTimeout)
+            throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
+        LOG.info("Trust all SSL certificates");
+        final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustAllStrategy()).build();
+        final PoolingAsyncClientConnectionManager connectionManager =
+                PoolingAsyncClientConnectionManagerBuilder.create()
+                        .setTlsStrategy(ClientTlsStrategyBuilder.create()
+                                .setSslContext(sslContext)
+                                .setHostnameVerifier(NoopHostnameVerifier.INSTANCE)
+                                .build())
+                        .build();
+
+        return HttpAsyncClients.custom()
+                .setConnectionManager(connectionManager)
+                .setDefaultRequestConfig(createDefaultRequestConfig(conectionTimeout, responseTimeout))
+                .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+                .build();
+    }
+}
index 3f0aaaa..629703e 100644 (file)
@@ -48,7 +48,7 @@ paths:
         '401':
           $ref: '#/components/responses/401Error'
   /pm/files:
-    post:
+    get:
       tags:
         - controller
       summary: Read Performance Management Files
@@ -67,7 +67,7 @@ paths:
         '401':
           $ref: '#/components/responses/401Error'
   /system/timeZone:
-    post:
+    get:
       tags:
         - controller
       summary: Read time zone
index 393a11b..b663067 100644 (file)
                 <artifactId>spotbugs-annotations</artifactId>
                 <version>${spotbugs.version}</version>
             </dependency>
+            <dependency>
+                <groupId>io.swagger.core.v3</groupId>
+                <artifactId>swagger-annotations</artifactId>
+                <version>${swagger-annotations.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-starter</artifactId>