699a59004bcd746510fdc0f6442b06bb888a7c52
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / test / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / vnfm / TestCbamTokenProvider.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm;
18
19 import okhttp3.Interceptor;
20 import okhttp3.Request;
21 import org.junit.After;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.ArgumentCaptor;
25 import org.mockito.InjectMocks;
26 import org.mockito.Mockito;
27 import org.onap.vnfmdriver.model.VnfmInfo;
28 import org.springframework.http.HttpStatus;
29
30 import java.io.IOException;
31 import java.net.URI;
32
33 import static junit.framework.TestCase.*;
34 import static org.mockito.Matchers.eq;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37 import static org.springframework.test.util.ReflectionTestUtils.setField;
38
39 public class TestCbamTokenProvider extends TestBase {
40
41     private static String GOOD_RESPONSE = "{ \"access_token\" : \"myToken\", \"expires_in\" : 1000 }";
42     @InjectMocks
43     private CbamTokenProvider cbamTokenProvider;
44     private VnfmInfo vnfmInfo = new VnfmInfo();
45     private HttpTestServer testServer;
46
47     public static String extractToken(Interceptor token) throws IOException {
48         Interceptor.Chain chain = Mockito.mock(Interceptor.Chain.class);
49         Request request = new Request.Builder().url("http://127.0.0.0/").build();
50         when(chain.request()).thenReturn(request);
51         ArgumentCaptor<Request> re = ArgumentCaptor.forClass(Request.class);
52         when(chain.proceed(re.capture())).thenReturn(null);
53         token.intercept(chain);
54         return re.getValue().header("Authorization").replaceFirst("Bearer ", "");
55     }
56
57     @Before
58     public void initMocks() throws Exception {
59         setField(CbamTokenProvider.class, "logger", logger);
60         setField(cbamTokenProvider, "username", "myUserName");
61         setField(cbamTokenProvider, "password", "myPassword");
62         setField(cbamTokenProvider, "skipCertificateVerification", true);
63         setField(cbamTokenProvider, "skipHostnameVerification", true);
64         when(vnfmInfoProvider.getVnfmInfo(VNFM_ID)).thenReturn(vnfmInfo);
65         vnfmInfo.setPassword("vnfmPassword");
66         vnfmInfo.setUserName("vnfmUserName");
67         vnfmInfo.setUrl("http://127.0.0.3:12345");
68         testServer = new HttpTestServer();
69         testServer.start();
70         URI uri = testServer._server.getURI();
71         setField(cbamTokenProvider, "cbamKeyCloakBaseUrl", uri.toString());
72     }
73
74     private void addGoodTokenResponse() {
75         testServer.respones.add(GOOD_RESPONSE);
76         testServer.codes.add(HttpStatus.OK.value());
77     }
78
79     @After
80     public void testServer() throws Exception {
81         testServer.stop();
82     }
83
84     /**
85      * a new token is requested no token has been requested before
86      */
87     @Test
88     public void testBasicTokenRequest() throws Exception {
89         //given
90         addGoodTokenResponse();
91         //when
92         String token = extractToken(cbamTokenProvider.getToken(VNFM_ID));
93         //verify
94         assertEquals(1, testServer.requests.size());
95         assertTokenRequest(testServer.requests.get(0));
96         assertEquals("myToken", token);
97
98     }
99
100     /**
101      * a new token is requested if the previous token has expired
102      */
103     @Test
104     public void testTokenIsRequestedIfPreviousExpired() throws Exception {
105         //given
106         addGoodTokenResponse();
107         String firstToken = extractToken(cbamTokenProvider.getToken(VNFM_ID));
108         testServer.respones.add("{ \"access_token\" : \"myToken2\", \"expires_in\" : 2000 }");
109         testServer.codes.add(HttpStatus.OK.value());
110         when(systemFunctions.currentTimeMillis()).thenReturn(500L * 1000 + 1L);
111         //when
112         String token = extractToken(cbamTokenProvider.getToken(VNFM_ID));
113         //verify
114         assertEquals(2, testServer.requests.size());
115         assertTokenRequest(testServer.requests.get(0));
116         assertTokenRequest(testServer.requests.get(1));
117         assertEquals("myToken2", token);
118     }
119
120     /**
121      * a new token is not requested if the previous token has not expired
122      */
123     @Test
124     public void testTokenIsNotRequestedIfPreviousHasNotExpired() throws Exception {
125         //given
126         addGoodTokenResponse();
127         String firstToken = extractToken(cbamTokenProvider.getToken(VNFM_ID));
128         testServer.respones.add("{ \"access_token\" : \"myToken2\", \"expires_in\" : 2000 }");
129         testServer.codes.add(HttpStatus.OK.value());
130         when(systemFunctions.currentTimeMillis()).thenReturn(500L * 1000);
131         //when
132         String token = extractToken(cbamTokenProvider.getToken(VNFM_ID));
133         //verify
134         assertEquals(1, testServer.requests.size());
135         assertTokenRequest(testServer.requests.get(0));
136         assertEquals("myToken", token);
137     }
138
139     /**
140      * failed token requests are retried for a fixed number amount of times
141      */
142     @Test
143     public void testRetry() throws Exception {
144         //given
145         addFailedResponse();
146         addFailedResponse();
147         addFailedResponse();
148         addFailedResponse();
149         addGoodTokenResponse();
150         //cbamTokenProvider.failOnRequestNumber = 5;
151         //when
152         String token = extractToken(cbamTokenProvider.getToken(VNFM_ID));
153         //verify
154         assertEquals(5, testServer.requests.size());
155         assertTokenRequest(testServer.requests.get(0));
156         assertTokenRequest(testServer.requests.get(1));
157         assertTokenRequest(testServer.requests.get(2));
158         assertTokenRequest(testServer.requests.get(3));
159         assertTokenRequest(testServer.requests.get(4));
160         verify(logger).warn(eq("Unable to get token to access CBAM API (1/5)"), Mockito.<RuntimeException>any());
161         verify(logger).warn(eq("Unable to get token to access CBAM API (2/5)"), Mockito.<RuntimeException>any());
162         verify(logger).warn(eq("Unable to get token to access CBAM API (3/5)"), Mockito.<RuntimeException>any());
163         verify(logger).warn(eq("Unable to get token to access CBAM API (4/5)"), Mockito.<RuntimeException>any());
164         assertEquals("myToken", token);
165     }
166
167     /**
168      * failed token requests are retried for a fixed number amount of times (reacing maximal number or retries)
169      */
170     @Test
171     public void testNoMoreRetry() throws Exception {
172         //given
173         addFailedResponse();
174         addFailedResponse();
175         addFailedResponse();
176         addFailedResponse();
177         addFailedResponse();
178         //when
179         try {
180             cbamTokenProvider.getToken(VNFM_ID);
181             fail();
182         } catch (RuntimeException e) {
183             assertNotNull(e.getCause());
184         }
185         //verify
186         assertEquals(5, testServer.requests.size());
187         assertTokenRequest(testServer.requests.get(0));
188         assertTokenRequest(testServer.requests.get(1));
189         assertTokenRequest(testServer.requests.get(2));
190         assertTokenRequest(testServer.requests.get(3));
191         assertTokenRequest(testServer.requests.get(4));
192         verify(logger).warn(eq("Unable to get token to access CBAM API (1/5)"), Mockito.<RuntimeException>any());
193         verify(logger).warn(eq("Unable to get token to access CBAM API (2/5)"), Mockito.<RuntimeException>any());
194         verify(logger).warn(eq("Unable to get token to access CBAM API (3/5)"), Mockito.<RuntimeException>any());
195         verify(logger).warn(eq("Unable to get token to access CBAM API (4/5)"), Mockito.<RuntimeException>any());
196         verify(logger).error(eq("Unable to get token to access CBAM API (giving up retries)"), Mockito.<RuntimeException>any());
197     }
198
199     private void addFailedResponse() {
200         testServer.codes.add(HttpStatus.UNAUTHORIZED.value());
201         testServer.respones.add(new String());
202     }
203
204
205     private void assertTokenRequest(String body) {
206         assertContains(body, "grant_type", "password");
207         assertContains(body, "client_id", "vnfmUserName");
208         assertContains(body, "client_secret", "vnfmPassword");
209         assertContains(body, "username", "myUserName");
210         assertContains(body, "password", "myPassword");
211     }
212
213     private void assertContains(String content, String key, String value) {
214         assertTrue(content.contains(key + "=" + value));
215     }
216 }