Skip to content
This repository was archived by the owner on Oct 20, 2022. It is now read-only.

Commit 19c77e7

Browse files
committed
cep: add multi-tenant admin controller tests
1 parent 89f4ef3 commit 19c77e7

1 file changed

Lines changed: 281 additions & 0 deletions

File tree

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
/*
2+
* Copyright (C) 2015 Orange
3+
*
4+
* This software is distributed under the terms and conditions of the 'GNU GENERAL PUBLIC LICENSE
5+
* Version 2' license which can be found in the file 'LICENSE.txt' in this package distribution or
6+
* at 'http://www.gnu.org/licenses/gpl-2.0-standalone.html'.
7+
*/
8+
9+
package com.orange.cepheus.cep.controller;
10+
11+
import com.orange.cepheus.cep.Application;
12+
import com.orange.cepheus.cep.ComplexEventProcessor;
13+
import com.orange.cepheus.cep.EventMapper;
14+
import com.orange.cepheus.cep.exception.ConfigurationException;
15+
import com.orange.cepheus.cep.exception.PersistenceException;
16+
import com.orange.cepheus.cep.model.Configuration;
17+
import com.orange.cepheus.cep.persistence.Persistence;
18+
import com.orange.cepheus.cep.tenant.TenantFilter;
19+
import org.junit.After;
20+
import org.junit.Before;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.mockito.ArgumentCaptor;
24+
import org.mockito.InjectMocks;
25+
import org.mockito.Mock;
26+
import org.mockito.MockitoAnnotations;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.boot.test.SpringApplicationConfiguration;
29+
import org.springframework.http.MediaType;
30+
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
31+
import org.springframework.test.context.ActiveProfiles;
32+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
33+
import org.springframework.test.context.web.WebAppConfiguration;
34+
import org.springframework.test.web.servlet.MockMvc;
35+
import org.springframework.web.context.WebApplicationContext;
36+
37+
import static com.orange.cepheus.cep.Util.getBasicConf;
38+
import static com.orange.cepheus.cep.Util.json;
39+
import static org.junit.Assert.assertEquals;
40+
import static org.mockito.Matchers.any;
41+
import static org.mockito.Matchers.eq;
42+
import static org.mockito.Mockito.*;
43+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
44+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
45+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
46+
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
47+
48+
49+
/**
50+
* Test the Admin controller in multi tenant mode
51+
*/
52+
@RunWith(SpringJUnit4ClassRunner.class)
53+
@SpringApplicationConfiguration(classes = {Application.class})
54+
@WebAppConfiguration
55+
@ActiveProfiles("multi-tenant")
56+
public class AdminControllerMultiTenantTest {
57+
58+
private static final String tenantService1 = "smartcity1";
59+
private static final String tenantService2 = "smartcity2";
60+
private static final String tenantServicePath1 = "/team1";
61+
private static final String tenantServicePath2 = "/team2";
62+
63+
private MockMvc mockMvc;
64+
65+
@Autowired
66+
private MappingJackson2HttpMessageConverter mapping;
67+
68+
@Autowired
69+
private WebApplicationContext webApplicationContext;
70+
71+
@Autowired
72+
private TenantFilter tenantFilter;
73+
74+
@Mock
75+
private ComplexEventProcessor complexEventProcessor;
76+
77+
@Mock
78+
private Persistence persistence;
79+
80+
@Mock
81+
private EventMapper eventMapper;
82+
83+
@Autowired
84+
@InjectMocks
85+
AdminController adminController;
86+
87+
@Before
88+
public void setup() throws Exception {
89+
MockitoAnnotations.initMocks(this);
90+
// Inject tenantFilter to webApp mock
91+
this.mockMvc = webAppContextSetup(webApplicationContext).addFilter(tenantFilter).build();
92+
}
93+
94+
@After
95+
public void resetMocks() {
96+
reset(complexEventProcessor);
97+
reset(persistence);
98+
reset(eventMapper);
99+
}
100+
101+
@Test
102+
public void checkConfigurationNotFound() throws Exception {
103+
when(complexEventProcessor.getConfiguration()).thenReturn(null);
104+
105+
mockMvc.perform(get("/v1/admin/config")
106+
.accept(MediaType.APPLICATION_JSON))
107+
.andExpect(status().isNotFound());
108+
}
109+
110+
@Test
111+
public void postConfOK() throws Exception {
112+
Configuration configuration = getBasicConf();
113+
114+
mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON))
115+
.andExpect(status().isCreated());
116+
117+
ArgumentCaptor<Configuration> configurationArg = ArgumentCaptor.forClass(Configuration.class);
118+
verify(complexEventProcessor).setConfiguration(configurationArg.capture());
119+
120+
Configuration capturedConfiguration = configurationArg.getValue();
121+
assertEquals(1, capturedConfiguration.getEventTypeIns().size());
122+
assertEquals("S.*", capturedConfiguration.getEventTypeIns().get(0).getId());
123+
assertEquals(1, capturedConfiguration.getEventTypeOuts().size());
124+
assertEquals("OUT1", capturedConfiguration.getEventTypeOuts().get(0).getId());
125+
126+
verify(persistence).saveConfiguration(eq(TenantFilter.DEFAULT_TENANTID), eq(capturedConfiguration));
127+
}
128+
129+
@Test
130+
public void postConfService() throws Exception {
131+
Configuration configuration = getBasicConf();
132+
133+
mockMvc.perform(post("/v1/admin/config")
134+
.content(json(mapping, configuration))
135+
.contentType(MediaType.APPLICATION_JSON)
136+
.header(TenantFilter.FIWARE_SERVICE, tenantService1))
137+
.andExpect(status().isCreated());
138+
139+
ArgumentCaptor<Configuration> configurationArg = ArgumentCaptor.forClass(Configuration.class);
140+
verify(complexEventProcessor).setConfiguration(configurationArg.capture());
141+
Configuration capturedConfiguration = configurationArg.getValue();
142+
143+
String tenantId = TenantFilter.tenantIdFromService(tenantService1, TenantFilter.DEFAULT_SERVICE_PATH);
144+
verify(persistence).saveConfiguration(eq(tenantId), eq(capturedConfiguration));
145+
}
146+
147+
@Test
148+
public void postConfServicePath() throws Exception {
149+
Configuration configuration = getBasicConf();
150+
151+
mockMvc.perform(post("/v1/admin/config")
152+
.content(json(mapping, configuration))
153+
.contentType(MediaType.APPLICATION_JSON)
154+
.header(TenantFilter.FIWARE_SERVICE_PATH, tenantServicePath1))
155+
.andExpect(status().isCreated());
156+
157+
ArgumentCaptor<Configuration> configurationArg = ArgumentCaptor.forClass(Configuration.class);
158+
verify(complexEventProcessor).setConfiguration(configurationArg.capture());
159+
Configuration capturedConfiguration = configurationArg.getValue();
160+
161+
String tenantId = TenantFilter.tenantIdFromService(TenantFilter.DEFAULT_SERVICE, tenantServicePath1);
162+
verify(persistence).saveConfiguration(eq(tenantId), eq(capturedConfiguration));
163+
}
164+
165+
@Test
166+
public void postConfServiceValidation() throws Exception {
167+
String jsonConfiguration = json(mapping, getBasicConf());
168+
169+
// Check * is forbidden in service
170+
mockMvc.perform(post("/v1/admin/config")
171+
.content(jsonConfiguration)
172+
.contentType(MediaType.APPLICATION_JSON)
173+
.header(TenantFilter.FIWARE_SERVICE, "*"))
174+
.andExpect(status().isBadRequest());
175+
176+
// Check / is forbidden in service
177+
mockMvc.perform(post("/v1/admin/config")
178+
.content(jsonConfiguration)
179+
.contentType(MediaType.APPLICATION_JSON)
180+
.header(TenantFilter.FIWARE_SERVICE, "/d"))
181+
.andExpect(status().isBadRequest());
182+
183+
// Check A-Za-z0-9_ is valid
184+
mockMvc.perform(post("/v1/admin/config")
185+
.content(jsonConfiguration)
186+
.contentType(MediaType.APPLICATION_JSON)
187+
.header(TenantFilter.FIWARE_SERVICE, "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz_0123456789"))
188+
.andExpect(status().isCreated());
189+
}
190+
191+
@Test
192+
public void postConfServicePathValidation() throws Exception {
193+
String jsonConfiguration = json(mapping, getBasicConf());
194+
195+
// Check / is mandatory in servicepath
196+
mockMvc.perform(post("/v1/admin/config")
197+
.content(jsonConfiguration)
198+
.contentType(MediaType.APPLICATION_JSON)
199+
.header(TenantFilter.FIWARE_SERVICE_PATH, "badservicepath"))
200+
.andExpect(status().isBadRequest());
201+
202+
// Check / is allowed in servicepath
203+
mockMvc.perform(post("/v1/admin/config")
204+
.content(jsonConfiguration)
205+
.contentType(MediaType.APPLICATION_JSON)
206+
.header(TenantFilter.FIWARE_SERVICE_PATH, "/Service_Path1"))
207+
.andExpect(status().isCreated());
208+
209+
// Check /A-Za-z0-9_ is valid
210+
mockMvc.perform(post("/v1/admin/config")
211+
.content(jsonConfiguration)
212+
.contentType(MediaType.APPLICATION_JSON)
213+
.header(TenantFilter.FIWARE_SERVICE_PATH, "/ABCDEFGHIJKLMNOPQRSTUVWXYZ/_abcdefghijklmnopqrstuvwxyz/_0123456789"))
214+
.andExpect(status().isCreated());
215+
}
216+
217+
@Test
218+
public void getConfiguration() throws Exception {
219+
Configuration configuration = getBasicConf();
220+
when(complexEventProcessor.getConfiguration()).thenReturn(configuration);
221+
222+
mockMvc.perform(get("/v1/admin/config")
223+
.accept(MediaType.APPLICATION_JSON))
224+
.andExpect(status().isOk())
225+
.andExpect(jsonPath("$.in[0].id").value(configuration.getEventTypeIns().get(0).getId()))
226+
.andExpect(jsonPath("$.out[0].id").value(configuration.getEventTypeOuts().get(0).getId()))
227+
.andExpect(jsonPath("$.statements[0]").value(configuration.getStatements().get(0)));
228+
}
229+
230+
@Test
231+
public void deleteConfiguration() throws Exception {
232+
233+
mockMvc.perform(delete("/v1/admin/config")
234+
.header(TenantFilter.FIWARE_SERVICE, tenantService1)
235+
.header(TenantFilter.FIWARE_SERVICE_PATH, tenantServicePath1))
236+
.andExpect(status().isOk());
237+
238+
verify(complexEventProcessor).reset();
239+
verify(persistence).deleteConfiguration(eq(TenantFilter.tenantIdFromService(tenantService1, tenantServicePath1)));
240+
}
241+
242+
@Test
243+
public void configurationErrorHandling() throws Exception {
244+
Configuration configuration = getBasicConf();
245+
246+
doThrow(new ConfigurationException("ERROR", new Exception("DETAIL ERROR"))).when(complexEventProcessor).setConfiguration(any(Configuration.class));
247+
248+
mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON))
249+
.andExpect(status().isBadRequest())
250+
.andExpect(jsonPath("$.code").value("400"))
251+
.andExpect(jsonPath("$.reasonPhrase").value("ERROR"))
252+
.andExpect(jsonPath("$.details").value("DETAIL ERROR"));
253+
}
254+
255+
@Test
256+
public void eventMapperErrorHandling() throws Exception {
257+
Configuration configuration = getBasicConf();
258+
259+
doThrow(new ConfigurationException("ERROR", new Exception("DETAIL ERROR"))).when(eventMapper).setConfiguration(any(Configuration.class));
260+
261+
mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON))
262+
.andExpect(status().isBadRequest())
263+
.andExpect(jsonPath("$.code").value("400"))
264+
.andExpect(jsonPath("$.reasonPhrase").value("ERROR"))
265+
.andExpect(jsonPath("$.details").value("DETAIL ERROR"));
266+
}
267+
268+
@Test
269+
public void persistenceErrorHandling() throws Exception {
270+
271+
doThrow(new PersistenceException("ERROR")).when(persistence).saveConfiguration(any(), any(Configuration.class));
272+
273+
Configuration configuration = getBasicConf();
274+
275+
mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON))
276+
.andExpect(status().isInternalServerError())
277+
.andExpect(jsonPath("$.code").value("500"))
278+
.andExpect(jsonPath("$.reasonPhrase").value("ERROR"));
279+
}
280+
281+
}

0 commit comments

Comments
 (0)