2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2018 IBM.
4 * Modifications Copyright © 2019 Huawei.
5 * Modifications Copyright © 2019 Bell Canada.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 package org.onap.ccsdk.cds.blueprintsprocessor.rest.service
22 import com.fasterxml.jackson.databind.JsonNode
23 import com.fasterxml.jackson.databind.ObjectMapper
25 import org.junit.runner.RunWith
26 import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
27 import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration
28 import org.onap.ccsdk.cds.blueprintsprocessor.rest.BluePrintRestLibConfiguration
29 import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLBasicAuthRestClientProperties
30 import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLRestClientProperties
31 import org.onap.ccsdk.cds.blueprintsprocessor.rest.SSLTokenAuthRestClientProperties
32 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
33 import org.springframework.beans.factory.annotation.Autowired
34 import org.springframework.http.HttpHeaders
35 import org.springframework.http.MediaType
36 import org.springframework.test.context.ContextConfiguration
37 import org.springframework.test.context.TestPropertySource
38 import org.springframework.test.context.junit4.SpringRunner
39 import kotlin.test.assertEquals
40 import kotlin.test.assertFailsWith
41 import kotlin.test.assertNotNull
43 @RunWith(SpringRunner::class)
44 @ContextConfiguration(classes = [BluePrintRestLibConfiguration::class, BlueprintPropertyConfiguration::class, BluePrintProperties::class])
45 @TestPropertySource(properties =
46 ["blueprintsprocessor.restclient.sample.type=basic-auth",
47 "blueprintsprocessor.restclient.sample.url=http://localhost:8080",
48 "blueprintsprocessor.restclient.sample.userId=sampleuser",
49 "blueprintsprocessor.restclient.sslbasic.type=ssl-basic-auth",
50 "blueprintsprocessor.restclient.sslbasic.url=https://localhost:8443",
51 "blueprintsprocessor.restclient.sslbasic.username=admin",
52 "blueprintsprocessor.restclient.sslbasic.password=cds",
53 "blueprintsprocessor.restclient.sslbasic.keyStoreInstance=PKCS12",
54 "blueprintsprocessor.restclient.sslbasic.sslTrust=src/test/resources/keystore.p12",
55 "blueprintsprocessor.restclient.sslbasic.sslTrustPassword=changeit",
56 "blueprintsprocessor.restclient.ssltoken.type=ssl-token-auth",
57 "blueprintsprocessor.restclient.ssltoken.url=https://localhost:8443",
58 "blueprintsprocessor.restclient.ssltoken.token=72178473kjshdkjgvbsdkjv903274908",
59 "blueprintsprocessor.restclient.ssltoken.keyStoreInstance=PKCS12",
60 "blueprintsprocessor.restclient.ssltoken.sslTrust=src/test/resources/keystore.p12",
61 "blueprintsprocessor.restclient.ssltoken.sslTrustPassword=changeit",
62 "blueprintsprocessor.restclient.ssl.type=ssl-no-auth",
63 "blueprintsprocessor.restclient.ssl.url=https://localhost:8443",
64 "blueprintsprocessor.restclient.ssl.keyStoreInstance=PKCS12",
65 "blueprintsprocessor.restclient.ssl.sslTrust=src/test/resources/keystore.p12",
66 "blueprintsprocessor.restclient.ssl.sslTrustPassword=changeit",
67 "blueprintsprocessor.restclient.ssl.sslKey=src/test/resources/keystore.p12",
68 "blueprintsprocessor.restclient.ssl.sslKeyPassword=changeit"
70 class BluePrintRestLibPropertyServiceTest {
72 lateinit var bluePrintRestLibPropertyService: BluePrintRestLibPropertyService
75 fun testRestClientProperties() {
76 val properties = bluePrintRestLibPropertyService.restClientProperties(
77 "blueprintsprocessor.restclient.sample")
78 assertNotNull(properties, "failed to create property bean")
79 assertNotNull(properties.url, "failed to get url property in" +
84 fun testSSLBasicProperties() {
85 val properties = bluePrintRestLibPropertyService.restClientProperties(
86 "blueprintsprocessor.restclient.sslbasic")
87 assertNotNull(properties, "failed to create property bean")
88 val p: SSLBasicAuthRestClientProperties =
89 properties as SSLBasicAuthRestClientProperties
91 assertEquals(p.basicAuth!!.username, "admin")
92 assertEquals(p.basicAuth!!.password, "cds")
93 assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
94 assertEquals(p.sslTrustPassword, "changeit")
95 assertEquals(p.keyStoreInstance, "PKCS12")
99 fun testSSLTokenProperties() {
100 val properties = bluePrintRestLibPropertyService.restClientProperties(
101 "blueprintsprocessor.restclient.ssltoken")
102 assertNotNull(properties, "failed to create property bean")
104 val p: SSLTokenAuthRestClientProperties =
105 properties as SSLTokenAuthRestClientProperties
107 assertEquals(p.tokenAuth!!.token!!, "72178473kjshdkjgvbsdkjv903274908")
108 assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
109 assertEquals(p.sslTrustPassword, "changeit")
110 assertEquals(p.keyStoreInstance, "PKCS12")
114 fun testSSLNoAuthProperties() {
115 val properties = bluePrintRestLibPropertyService.restClientProperties(
116 "blueprintsprocessor.restclient.ssl")
117 assertNotNull(properties, "failed to create property bean")
119 val p: SSLRestClientProperties =
120 properties as SSLRestClientProperties
122 assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
123 assertEquals(p.sslTrustPassword, "changeit")
124 assertEquals(p.keyStoreInstance, "PKCS12")
125 assertEquals(p.sslKey, "src/test/resources/keystore.p12")
126 assertEquals(p.sslKeyPassword, "changeit")
131 fun testSSLBasicPropertiesAsJson() {
132 val actualObj: JsonNode = defaultMapper.readTree(sslBasicAuthEndpointWithHeadersField())
133 val properties = bluePrintRestLibPropertyService.restClientProperties(
135 assertNotNull(properties, "failed to create property bean")
136 val p: SSLBasicAuthRestClientProperties = properties as SSLBasicAuthRestClientProperties
138 assertEquals("admin", p.basicAuth!!.username)
139 assertEquals("cds", p.basicAuth!!.password)
140 assertEquals("src/test/resources/keystore.p12", p.sslTrust)
141 assertEquals("changeit", p.sslTrustPassword)
142 assertEquals("PKCS12", p.keyStoreInstance)
143 assertEquals("ssl-basic-auth", p.type)
144 assertEquals("https://localhost:8443", p.url)
148 fun testSSLTokenPropertiesAsJson() {
149 val actualObj: JsonNode = defaultMapper.readTree(sslTokenAuthEndpointWithHeadersField())
151 bluePrintRestLibPropertyService.restClientProperties(actualObj)
152 assertNotNull(properties, "failed to create property bean")
154 val p: SSLTokenAuthRestClientProperties = properties as SSLTokenAuthRestClientProperties
156 assertEquals("72178473kjshdkjgvbsdkjv903274908", p.tokenAuth!!.token!!)
157 assertEquals("src/test/resources/keystore.p12", p.sslTrust)
158 assertEquals("changeit", p.sslTrustPassword)
159 assertEquals("PKCS12", p.keyStoreInstance)
160 assertEquals("ssl-token-auth", p.type)
161 assertEquals("https://localhost:8443", p.url)
165 fun testSSLNoAuthPropertiesAsJson() {
166 val actualObj: JsonNode = defaultMapper.readTree(sslNoAuthEndpointWithHeadersField())
167 val properties = bluePrintRestLibPropertyService.restClientProperties(
169 assertNotNull(properties, "failed to create property bean")
171 val p: SSLRestClientProperties =
172 properties as SSLRestClientProperties
174 assertEquals("src/test/resources/keystore.p12", p.sslTrust)
175 assertEquals("changeit", p.sslTrustPassword)
176 assertEquals("PKCS12", p.keyStoreInstance)
177 assertEquals("src/test/resources/keystore.p12", p.sslKey)
178 assertEquals("changeit", p.sslKeyPassword)
179 assertEquals("ssl-no-auth", p.type)
180 assertEquals("https://localhost:8443", p.url)
184 fun testBlueprintWebClientService() {
185 val blueprintWebClientService = bluePrintRestLibPropertyService
186 .blueprintWebClientService("sample")
187 assertNotNull(blueprintWebClientService,
188 "failed to create blueprintWebClientService")
192 fun testBlueprintWebClientServiceWithJsonNode() {
193 val actualObj: JsonNode = defaultMapper.readTree(sslBasicAuthEndpointWithHeadersField())
194 val blueprintWebClientService = bluePrintRestLibPropertyService
195 .blueprintWebClientService(actualObj)
196 assertNotNull(blueprintWebClientService, "failed to create blueprintWebClientService")
199 //pass the result of $typeEndpointWithHeadersField() output with and without headers to compare.
200 private fun validateHeadersDidNotChangeWithEmptyAdditionalHeaders(noHeaders: String, withHeaders: String) {
201 val parsedObj: JsonNode = defaultMapper.readTree(noHeaders)
202 val bpWebClientService =
203 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
204 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
206 val parsedObjWithHeaders: JsonNode = defaultMapper.readTree(withHeaders)
207 val bpWebClientServiceWithHeaders =
208 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObjWithHeaders)
209 val extractedHeadersWithAdditionalHeaders = bpWebClientServiceWithHeaders.convertToBasicHeaders(mapOf())
210 //Array<BasicHeader<>> -> Map<String,String>
211 val headersMap = extractedHeaders.map { it.name to it.value }.toMap()
212 val additionalHeadersMap = extractedHeadersWithAdditionalHeaders.map { it.name to it.value }.toMap()
213 assertEquals(headersMap, additionalHeadersMap)
217 fun `BasicAuth WebClientService with empty additionalHeaders does not modify headers`() {
218 val endPointJson = basicAuthEndpointWithHeadersField()
219 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(emptyAdditionalHeaders)
220 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
223 private fun acceptsOneAdditionalHeadersTest(endPointWithHeadersJson: String) {
224 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
225 val bpWebClientService =
226 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
227 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
228 assertEquals(1, extractedHeaders.filter { it.name == "key1" }.count())
232 fun `BasicAuth WebClientService accepts one additionalHeaders`() {
233 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(oneAdditionalParameter)
234 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
237 private fun acceptsMultipleAdditionalHeaders(endPointWithHeadersJson: String) {
238 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
239 val bpWebClientService =
240 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
241 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
242 assertEquals(1, extractedHeaders.filter { it.name == "key1" }.count())
243 assertEquals(1, extractedHeaders.filter { it.name == "key2" }.count())
244 assertEquals(1, extractedHeaders.filter { it.name == "key3" }.count())
248 fun `BasicAuth WebClientService accepts multiple additionalHeaders`() {
249 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(threeAdditionalHeaders)
250 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
253 private fun additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson: String) {
254 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
255 val bpWebClientService =
256 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
257 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
258 assertEquals(MediaType.APPLICATION_XML.toString(),
259 extractedHeaders.filter { it.name == HttpHeaders.CONTENT_TYPE }[0].value!!)
263 fun `BasicAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
264 //default content type is application/json
265 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
266 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
269 //called from within "assertFailsWith(exceptionClass = BluePrintProcessorException::class) {"
270 private fun attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson: String) {
271 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
272 val bpWebClientService =
273 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
274 bpWebClientService.convertToBasicHeaders(mapOf())
278 fun `BasicAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
279 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
280 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(additionalHeadersWithAuth)
281 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
283 //spec says headers are case insensitive...
284 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
285 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
286 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
291 fun `TokenAuth WebClientService with empty additionalHeaders does not modify headers`() {
292 val endPointJson = sslTokenAuthEndpointWithHeadersField()
293 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(emptyAdditionalHeaders)
294 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
298 fun `TokenAuth WebClientService accepts one additionalHeaders`() {
299 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(oneAdditionalParameter)
300 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
304 fun `TokenAuth WebClientService accepts multiple additionalHeaders`() {
305 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(threeAdditionalHeaders)
306 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
310 fun `TokenAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
311 //default content type is application/json
312 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
313 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
317 fun `TokenAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
318 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
319 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(additionalHeadersWithAuth)
320 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
322 //spec says headers are case insensitive...
323 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
324 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
325 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
329 //TESTS FOR SSL BASIC AUTH headers
331 fun `SSLBasicAuth WebClientService with empty additionalHeaders does not modify headers`() {
332 val endPointJson = sslBasicAuthEndpointWithHeadersField()
333 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(emptyAdditionalHeaders)
334 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
338 fun `SSLBasicAuth WebClientService accepts one additionalHeaders`() {
339 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(oneAdditionalParameter)
340 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
344 fun `SSLBasicAuth WebClientService accepts multiple additionalHeaders`() {
345 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(threeAdditionalHeaders)
346 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
350 fun `SSLBasicAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
351 //default content type is application/json
352 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
353 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
357 fun `SSLBasicAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
358 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
359 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(additionalHeadersWithAuth)
360 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
362 //spec says headers are case insensitive...
363 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
364 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
365 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
369 //SSL-NO-AUTH headers tests
371 fun `SSLNoAuth WebClientService with empty additionalHeaders does not modify headers`() {
372 val endPointJson = sslNoAuthEndpointWithHeadersField()
373 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(emptyAdditionalHeaders)
374 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
378 fun `SSLNoAuth WebClientService accepts one additionalHeaders`() {
379 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(oneAdditionalParameter)
380 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
384 fun `SSLNoAuth WebClientService accepts multiple additionalHeaders`() {
385 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(threeAdditionalHeaders)
386 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
390 fun `SSLNoAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
391 //default content type is application/json
392 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
393 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
397 fun `SSLNoAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
398 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
399 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(additionalHeadersWithAuth)
400 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
402 //spec says headers are case insensitive...
403 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
404 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
405 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
409 companion object BluePrintRestLibPropertyServiceTest {
410 val defaultMapper = ObjectMapper()
411 val expectedTokenAuthDefaultHeaders = mapOf<String, String>(
412 "Content-Type" to "application/json",
413 "Accept" to "application/json",
414 "Authorization" to "72178473kjshdkjgvbsdkjv903274908")
416 val endPointWithHeadersJsonWithBasicAuthHeader = basicAuthEndpointWithHeadersField(""",
417 "additionalHeaders" : {
418 "authorization": "Basic aGF2ZTphbmljZWRheQo="
421 private fun sslTokenAuthEndpointWithHeadersField(headers: String = ""): String =
423 "type" : "ssl-token-auth",
424 "url" : "https://localhost:8443",
425 "keyStoreInstance" : "PKCS12",
426 "sslTrust" : "src/test/resources/keystore.p12",
427 "sslTrustPassword" : "changeit",
429 "token" : "72178473kjshdkjgvbsdkjv903274908"
434 private fun sslBasicAuthEndpointWithHeadersField(headers: String = ""): String =
436 "type" : "ssl-basic-auth",
437 "url" : "https://localhost:8443",
438 "keyStoreInstance" : "PKCS12",
439 "sslTrust" : "src/test/resources/keystore.p12",
440 "sslTrustPassword" : "changeit",
442 "username" : "admin",
447 private fun sslNoAuthEndpointWithHeadersField(headers: String = ""): String = """{
448 "type" : "ssl-no-auth",
449 "url" : "https://localhost:8443",
450 "keyStoreInstance" : "PKCS12",
451 "sslTrust" : "src/test/resources/keystore.p12",
452 "sslTrustPassword" : "changeit",
453 "sslKey" : "src/test/resources/keystore.p12",
454 "sslKeyPassword" : "changeit"$headers
457 //Don't forget to supply "," as the first char to make valid JSON
458 private fun basicAuthEndpointWithHeadersField(headers: String = ""): String =
460 "type": "basic-auth",
461 "url": "http://127.0.0.1:8000",
463 "password": "pass"$headers
466 private val emptyAdditionalHeaders = """,
467 "additionalHeaders" : {
470 private val oneAdditionalParameter = """,
471 "additionalHeaders" : {
475 private val threeAdditionalHeaders = """,
476 "additionalHeaders" : {
482 private val contentTypeAdditionalHeader = """,
483 "additionalHeaders" : {
484 "${HttpHeaders.CONTENT_TYPE}": "${MediaType.APPLICATION_XML}"
487 private val additionalHeadersWithAuth = """,
488 "additionalHeaders" : {
489 "Authorization": "Basic aGF2ZTphbmljZWRheQo="
492 private val additionalHeadersWithAuthLowercased = """,
493 "additionalHeaders" : {
494 "authorization": "Basic aGF2ZTphbmljZWRheQo="