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.BluePrintPropertiesService
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,
45 BluePrintPropertiesService::class])
46 @TestPropertySource(properties =
47 ["blueprintsprocessor.restclient.sample.type=basic-auth",
48 "blueprintsprocessor.restclient.sample.url=http://localhost:8080",
49 "blueprintsprocessor.restclient.sample.userId=sampleuser",
50 "blueprintsprocessor.restclient.sslbasic.type=ssl-basic-auth",
51 "blueprintsprocessor.restclient.sslbasic.url=https://localhost:8443",
52 "blueprintsprocessor.restclient.sslbasic.username=admin",
53 "blueprintsprocessor.restclient.sslbasic.password=cds",
54 "blueprintsprocessor.restclient.sslbasic.keyStoreInstance=PKCS12",
55 "blueprintsprocessor.restclient.sslbasic.sslTrust=src/test/resources/keystore.p12",
56 "blueprintsprocessor.restclient.sslbasic.sslTrustPassword=changeit",
57 "blueprintsprocessor.restclient.ssltoken.type=ssl-token-auth",
58 "blueprintsprocessor.restclient.ssltoken.url=https://localhost:8443",
59 "blueprintsprocessor.restclient.ssltoken.token=72178473kjshdkjgvbsdkjv903274908",
60 "blueprintsprocessor.restclient.ssltoken.keyStoreInstance=PKCS12",
61 "blueprintsprocessor.restclient.ssltoken.sslTrust=src/test/resources/keystore.p12",
62 "blueprintsprocessor.restclient.ssltoken.sslTrustPassword=changeit",
63 "blueprintsprocessor.restclient.ssl.type=ssl-no-auth",
64 "blueprintsprocessor.restclient.ssl.url=https://localhost:8443",
65 "blueprintsprocessor.restclient.ssl.keyStoreInstance=PKCS12",
66 "blueprintsprocessor.restclient.ssl.sslTrust=src/test/resources/keystore.p12",
67 "blueprintsprocessor.restclient.ssl.sslTrustPassword=changeit",
68 "blueprintsprocessor.restclient.ssl.sslKey=src/test/resources/keystore.p12",
69 "blueprintsprocessor.restclient.ssl.sslKeyPassword=changeit"
71 class BluePrintRestLibPropertyServiceTest {
73 lateinit var bluePrintRestLibPropertyService: BluePrintRestLibPropertyService
76 fun testRestClientProperties() {
77 val properties = bluePrintRestLibPropertyService.restClientProperties(
78 "blueprintsprocessor.restclient.sample")
79 assertNotNull(properties, "failed to create property bean")
80 assertNotNull(properties.url, "failed to get url property in" +
85 fun testSSLBasicProperties() {
86 val properties = bluePrintRestLibPropertyService.restClientProperties(
87 "blueprintsprocessor.restclient.sslbasic")
88 assertNotNull(properties, "failed to create property bean")
89 val p: SSLBasicAuthRestClientProperties =
90 properties as SSLBasicAuthRestClientProperties
92 assertEquals(p.basicAuth!!.username, "admin")
93 assertEquals(p.basicAuth!!.password, "cds")
94 assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
95 assertEquals(p.sslTrustPassword, "changeit")
96 assertEquals(p.keyStoreInstance, "PKCS12")
100 fun testSSLTokenProperties() {
101 val properties = bluePrintRestLibPropertyService.restClientProperties(
102 "blueprintsprocessor.restclient.ssltoken")
103 assertNotNull(properties, "failed to create property bean")
105 val p: SSLTokenAuthRestClientProperties =
106 properties as SSLTokenAuthRestClientProperties
108 assertEquals(p.tokenAuth!!.token!!, "72178473kjshdkjgvbsdkjv903274908")
109 assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
110 assertEquals(p.sslTrustPassword, "changeit")
111 assertEquals(p.keyStoreInstance, "PKCS12")
115 fun testSSLNoAuthProperties() {
116 val properties = bluePrintRestLibPropertyService.restClientProperties(
117 "blueprintsprocessor.restclient.ssl")
118 assertNotNull(properties, "failed to create property bean")
120 val p: SSLRestClientProperties =
121 properties as SSLRestClientProperties
123 assertEquals(p.sslTrust, "src/test/resources/keystore.p12")
124 assertEquals(p.sslTrustPassword, "changeit")
125 assertEquals(p.keyStoreInstance, "PKCS12")
126 assertEquals(p.sslKey, "src/test/resources/keystore.p12")
127 assertEquals(p.sslKeyPassword, "changeit")
132 fun testSSLBasicPropertiesAsJson() {
133 val actualObj: JsonNode = defaultMapper.readTree(sslBasicAuthEndpointWithHeadersField())
134 val properties = bluePrintRestLibPropertyService.restClientProperties(
136 assertNotNull(properties, "failed to create property bean")
137 val p: SSLBasicAuthRestClientProperties = properties as SSLBasicAuthRestClientProperties
139 assertEquals("admin", p.basicAuth!!.username)
140 assertEquals("cds", p.basicAuth!!.password)
141 assertEquals("src/test/resources/keystore.p12", p.sslTrust)
142 assertEquals("changeit", p.sslTrustPassword)
143 assertEquals("PKCS12", p.keyStoreInstance)
144 assertEquals("ssl-basic-auth", p.type)
145 assertEquals("https://localhost:8443", p.url)
149 fun testSSLTokenPropertiesAsJson() {
150 val actualObj: JsonNode = defaultMapper.readTree(sslTokenAuthEndpointWithHeadersField())
152 bluePrintRestLibPropertyService.restClientProperties(actualObj)
153 assertNotNull(properties, "failed to create property bean")
155 val p: SSLTokenAuthRestClientProperties = properties as SSLTokenAuthRestClientProperties
157 assertEquals("72178473kjshdkjgvbsdkjv903274908", p.tokenAuth!!.token!!)
158 assertEquals("src/test/resources/keystore.p12", p.sslTrust)
159 assertEquals("changeit", p.sslTrustPassword)
160 assertEquals("PKCS12", p.keyStoreInstance)
161 assertEquals("ssl-token-auth", p.type)
162 assertEquals("https://localhost:8443", p.url)
166 fun testSSLNoAuthPropertiesAsJson() {
167 val actualObj: JsonNode = defaultMapper.readTree(sslNoAuthEndpointWithHeadersField())
168 val properties = bluePrintRestLibPropertyService.restClientProperties(
170 assertNotNull(properties, "failed to create property bean")
172 val p: SSLRestClientProperties =
173 properties as SSLRestClientProperties
175 assertEquals("src/test/resources/keystore.p12", p.sslTrust)
176 assertEquals("changeit", p.sslTrustPassword)
177 assertEquals("PKCS12", p.keyStoreInstance)
178 assertEquals("src/test/resources/keystore.p12", p.sslKey)
179 assertEquals("changeit", p.sslKeyPassword)
180 assertEquals("ssl-no-auth", p.type)
181 assertEquals("https://localhost:8443", p.url)
185 fun testBlueprintWebClientService() {
186 val blueprintWebClientService = bluePrintRestLibPropertyService
187 .blueprintWebClientService("sample")
188 assertNotNull(blueprintWebClientService,
189 "failed to create blueprintWebClientService")
193 fun testBlueprintWebClientServiceWithJsonNode() {
194 val actualObj: JsonNode = defaultMapper.readTree(sslBasicAuthEndpointWithHeadersField())
195 val blueprintWebClientService = bluePrintRestLibPropertyService
196 .blueprintWebClientService(actualObj)
197 assertNotNull(blueprintWebClientService, "failed to create blueprintWebClientService")
200 //pass the result of $typeEndpointWithHeadersField() output with and without headers to compare.
201 private fun validateHeadersDidNotChangeWithEmptyAdditionalHeaders(noHeaders: String, withHeaders: String) {
202 val parsedObj: JsonNode = defaultMapper.readTree(noHeaders)
203 val bpWebClientService =
204 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
205 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
207 val parsedObjWithHeaders: JsonNode = defaultMapper.readTree(withHeaders)
208 val bpWebClientServiceWithHeaders =
209 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObjWithHeaders)
210 val extractedHeadersWithAdditionalHeaders = bpWebClientServiceWithHeaders.convertToBasicHeaders(mapOf())
211 //Array<BasicHeader<>> -> Map<String,String>
212 val headersMap = extractedHeaders.map { it.name to it.value }.toMap()
213 val additionalHeadersMap = extractedHeadersWithAdditionalHeaders.map { it.name to it.value }.toMap()
214 assertEquals(headersMap, additionalHeadersMap)
218 fun `BasicAuth WebClientService with empty additionalHeaders does not modify headers`() {
219 val endPointJson = basicAuthEndpointWithHeadersField()
220 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(emptyAdditionalHeaders)
221 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
224 private fun acceptsOneAdditionalHeadersTest(endPointWithHeadersJson: String) {
225 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
226 val bpWebClientService =
227 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
228 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
229 assertEquals(1, extractedHeaders.filter { it.name == "key1" }.count())
233 fun `BasicAuth WebClientService accepts one additionalHeaders`() {
234 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(oneAdditionalParameter)
235 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
238 private fun acceptsMultipleAdditionalHeaders(endPointWithHeadersJson: String) {
239 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
240 val bpWebClientService =
241 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
242 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
243 assertEquals(1, extractedHeaders.filter { it.name == "key1" }.count())
244 assertEquals(1, extractedHeaders.filter { it.name == "key2" }.count())
245 assertEquals(1, extractedHeaders.filter { it.name == "key3" }.count())
249 fun `BasicAuth WebClientService accepts multiple additionalHeaders`() {
250 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(threeAdditionalHeaders)
251 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
254 private fun additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson: String) {
255 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
256 val bpWebClientService =
257 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
258 val extractedHeaders = bpWebClientService.convertToBasicHeaders(mapOf())
259 assertEquals(MediaType.APPLICATION_XML.toString(),
260 extractedHeaders.filter { it.name == HttpHeaders.CONTENT_TYPE }[0].value!!)
264 fun `BasicAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
265 //default content type is application/json
266 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
267 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
270 //called from within "assertFailsWith(exceptionClass = BluePrintProcessorException::class) {"
271 private fun attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson: String) {
272 val parsedObj: JsonNode = defaultMapper.readTree(endPointWithHeadersJson)
273 val bpWebClientService =
274 bluePrintRestLibPropertyService.blueprintWebClientService(parsedObj)
275 bpWebClientService.convertToBasicHeaders(mapOf())
279 fun `BasicAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
280 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
281 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(additionalHeadersWithAuth)
282 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
284 //spec says headers are case insensitive...
285 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
286 val endPointWithHeadersJson = basicAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
287 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
292 fun `TokenAuth WebClientService with empty additionalHeaders does not modify headers`() {
293 val endPointJson = sslTokenAuthEndpointWithHeadersField()
294 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(emptyAdditionalHeaders)
295 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
299 fun `TokenAuth WebClientService accepts one additionalHeaders`() {
300 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(oneAdditionalParameter)
301 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
305 fun `TokenAuth WebClientService accepts multiple additionalHeaders`() {
306 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(threeAdditionalHeaders)
307 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
311 fun `TokenAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
312 //default content type is application/json
313 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
314 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
318 fun `TokenAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
319 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
320 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(additionalHeadersWithAuth)
321 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
323 //spec says headers are case insensitive...
324 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
325 val endPointWithHeadersJson = sslTokenAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
326 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
330 //TESTS FOR SSL BASIC AUTH headers
332 fun `SSLBasicAuth WebClientService with empty additionalHeaders does not modify headers`() {
333 val endPointJson = sslBasicAuthEndpointWithHeadersField()
334 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(emptyAdditionalHeaders)
335 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
339 fun `SSLBasicAuth WebClientService accepts one additionalHeaders`() {
340 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(oneAdditionalParameter)
341 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
345 fun `SSLBasicAuth WebClientService accepts multiple additionalHeaders`() {
346 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(threeAdditionalHeaders)
347 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
351 fun `SSLBasicAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
352 //default content type is application/json
353 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
354 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
358 fun `SSLBasicAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
359 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
360 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(additionalHeadersWithAuth)
361 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
363 //spec says headers are case insensitive...
364 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
365 val endPointWithHeadersJson = sslBasicAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
366 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
370 //SSL-NO-AUTH headers tests
372 fun `SSLNoAuth WebClientService with empty additionalHeaders does not modify headers`() {
373 val endPointJson = sslNoAuthEndpointWithHeadersField()
374 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(emptyAdditionalHeaders)
375 validateHeadersDidNotChangeWithEmptyAdditionalHeaders(endPointJson, endPointWithHeadersJson)
379 fun `SSLNoAuth WebClientService accepts one additionalHeaders`() {
380 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(oneAdditionalParameter)
381 acceptsOneAdditionalHeadersTest(endPointWithHeadersJson)
385 fun `SSLNoAuth WebClientService accepts multiple additionalHeaders`() {
386 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(threeAdditionalHeaders)
387 acceptsMultipleAdditionalHeaders(endPointWithHeadersJson)
391 fun `SSLNoAuth WebClientService additionalHeaders can overwrite default Content-Type`() {
392 //default content type is application/json
393 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(contentTypeAdditionalHeader)
394 additionalHeadersChangedContentTypeToAPPLICATION_XML(endPointWithHeadersJson)
398 fun `SSLNoAuth WebClientService throws BlueprintProcessorException if additionalHeaders contain Authorization`() {
399 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
400 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(additionalHeadersWithAuth)
401 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
403 //spec says headers are case insensitive...
404 assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
405 val endPointWithHeadersJson = sslNoAuthEndpointWithHeadersField(additionalHeadersWithAuthLowercased)
406 attemptToPutAuthorizationHeaderIntoAdditionalHeaders(endPointWithHeadersJson)
410 companion object BluePrintRestLibPropertyServiceTest {
411 val defaultMapper = ObjectMapper()
412 val expectedTokenAuthDefaultHeaders = mapOf<String, String>(
413 "Content-Type" to "application/json",
414 "Accept" to "application/json",
415 "Authorization" to "72178473kjshdkjgvbsdkjv903274908")
417 val endPointWithHeadersJsonWithBasicAuthHeader = basicAuthEndpointWithHeadersField(""",
418 "additionalHeaders" : {
419 "authorization": "Basic aGF2ZTphbmljZWRheQo="
422 private fun sslTokenAuthEndpointWithHeadersField(headers: String = ""): String =
424 "type" : "ssl-token-auth",
425 "url" : "https://localhost:8443",
426 "keyStoreInstance" : "PKCS12",
427 "sslTrust" : "src/test/resources/keystore.p12",
428 "sslTrustPassword" : "changeit",
430 "token" : "72178473kjshdkjgvbsdkjv903274908"
435 private fun sslBasicAuthEndpointWithHeadersField(headers: String = ""): String =
437 "type" : "ssl-basic-auth",
438 "url" : "https://localhost:8443",
439 "keyStoreInstance" : "PKCS12",
440 "sslTrust" : "src/test/resources/keystore.p12",
441 "sslTrustPassword" : "changeit",
443 "username" : "admin",
448 private fun sslNoAuthEndpointWithHeadersField(headers: String = ""): String = """{
449 "type" : "ssl-no-auth",
450 "url" : "https://localhost:8443",
451 "keyStoreInstance" : "PKCS12",
452 "sslTrust" : "src/test/resources/keystore.p12",
453 "sslTrustPassword" : "changeit",
454 "sslKey" : "src/test/resources/keystore.p12",
455 "sslKeyPassword" : "changeit"$headers
458 //Don't forget to supply "," as the first char to make valid JSON
459 private fun basicAuthEndpointWithHeadersField(headers: String = ""): String =
461 "type": "basic-auth",
462 "url": "http://127.0.0.1:8000",
464 "password": "pass"$headers
467 private val emptyAdditionalHeaders = """,
468 "additionalHeaders" : {
471 private val oneAdditionalParameter = """,
472 "additionalHeaders" : {
476 private val threeAdditionalHeaders = """,
477 "additionalHeaders" : {
483 private val contentTypeAdditionalHeader = """,
484 "additionalHeaders" : {
485 "${HttpHeaders.CONTENT_TYPE}": "${MediaType.APPLICATION_XML}"
488 private val additionalHeadersWithAuth = """,
489 "additionalHeaders" : {
490 "Authorization": "Basic aGF2ZTphbmljZWRheQo="
493 private val additionalHeadersWithAuthLowercased = """,
494 "additionalHeaders" : {
495 "authorization": "Basic aGF2ZTphbmljZWRheQo="