Skip to content

Commit d002d49

Browse files
Check json when adding backend (#141)
* Add check on json keys for add backend instance * Add check for values to not be null * Removed hard coded logging levels in frontend application
1 parent 2609d15 commit d002d49

File tree

7 files changed

+161
-36
lines changed

7 files changed

+161
-36
lines changed

src/main/java/com/ericsson/ei/frontend/BackEndInformationController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@
2929
import org.springframework.web.bind.annotation.RequestMapping;
3030
import org.springframework.web.bind.annotation.RequestMethod;
3131

32-
import com.ericsson.ei.frontend.utils.BackEndInfoirmationControllerUtils;
32+
import com.ericsson.ei.frontend.utils.BackEndInformationControllerUtils;
3333

3434
@Controller
3535
public class BackEndInformationController {
3636

3737
public static final Logger LOG = LoggerFactory.getLogger(BackEndInformationController.class);
3838

3939
@Autowired
40-
private BackEndInfoirmationControllerUtils backEndInfoContUtils;
40+
private BackEndInformationControllerUtils backEndInfoContUtils;
4141

4242
@CrossOrigin
4343
@RequestMapping(value = "/backend", method = RequestMethod.GET)

src/main/java/com/ericsson/ei/frontend/EIFrontendApplication.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
16-
*/
16+
*/
1717
package com.ericsson.ei.frontend;
1818

1919
import java.util.ArrayList;
@@ -46,10 +46,6 @@ public static void main(String[] args) {
4646
System.setProperty("logging.level.root", args[0]);
4747
System.setProperty("logging.level.org.springframework.web", args[0]);
4848
System.setProperty("logging.level.com.ericsson.ei", args[0]);
49-
} else {
50-
System.setProperty("logging.level.root", "INFO");
51-
System.setProperty("logging.level.org.springframework.web", "INFO");
52-
System.setProperty("logging.level.com.ericsson.ei", "INFO");
5349
}
5450

5551
SpringApplication.run(EIFrontendApplication.class, args);

src/main/java/com/ericsson/ei/frontend/utils/BackEndInfoirmationControllerUtils.java renamed to src/main/java/com/ericsson/ei/frontend/utils/BackEndInformationControllerUtils.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@
3737
import com.google.gson.JsonParser;
3838

3939
@Component
40-
public class BackEndInfoirmationControllerUtils {
40+
public class BackEndInformationControllerUtils {
4141

42-
private static final Logger LOG = LoggerFactory.getLogger(BackEndInfoirmationControllerUtils.class);
42+
private static final Logger LOG = LoggerFactory.getLogger(BackEndInformationControllerUtils.class);
4343

4444
@Autowired
4545
private BackEndInstancesUtils backEndInstancesUtils;
@@ -134,6 +134,30 @@ public ResponseEntity<String> handleRequestToAddBackEnd(HttpServletRequest reque
134134
.collect(Collectors.joining(System.lineSeparator()));
135135
JsonObject instance = new JsonParser().parse(newInstanceAsString).getAsJsonObject();
136136

137+
final boolean hasRequiredData = backEndInstancesUtils.hasRequiredJsonKeys(instance);
138+
if (!hasRequiredData) {
139+
LOG.debug("Json data is missing required keys");
140+
return new ResponseEntity<>(
141+
"{\"message\": \"Back-end instance is missing required data.\"}",
142+
getHeaders(), HttpStatus.BAD_REQUEST);
143+
}
144+
145+
final boolean hasNullValues = backEndInstancesUtils.containsNullValues(instance);
146+
if (hasNullValues) {
147+
LOG.debug("Json data contains null values");
148+
return new ResponseEntity<>(
149+
"{\"message\": \"Back-end instance can not have null values.\"}",
150+
getHeaders(), HttpStatus.BAD_REQUEST);
151+
}
152+
153+
final boolean containsUnrecognizedKeys = backEndInstancesUtils.containsAdditionalKeys(instance);
154+
if (containsUnrecognizedKeys) {
155+
LOG.debug("JSON data contains unrecognized keys");
156+
return new ResponseEntity<>(
157+
"{\"message\": \"Back-end instance contains unrecognized JSON keys.\"}",
158+
getHeaders(), HttpStatus.BAD_REQUEST);
159+
}
160+
137161
final boolean instanceNameAlreadyExist = backEndInstancesUtils.checkIfInstanceNameAlreadyExist(instance);
138162
if (instanceNameAlreadyExist) {
139163
LOG.debug("Not a unique name.");
@@ -160,7 +184,6 @@ public ResponseEntity<String> handleRequestToAddBackEnd(HttpServletRequest reque
160184
return new ResponseEntity<>(
161185
"{\"message\": \"Back-end instance with given values already exist.\"}",
162186
getHeaders(), HttpStatus.BAD_REQUEST);
163-
164187
}
165188

166189
backEndInstancesUtils.addNewBackEnd(instance);

src/main/java/com/ericsson/ei/frontend/utils/BackEndInstancesUtils.java

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,18 @@
1717
package com.ericsson.ei.frontend.utils;
1818

1919
import java.io.IOException;
20-
import java.util.ArrayList;
21-
import java.util.List;
20+
import java.util.*;
2221

22+
import com.google.gson.JsonArray;
23+
import com.google.gson.JsonElement;
24+
import com.google.gson.JsonObject;
2325
import org.slf4j.Logger;
2426
import org.slf4j.LoggerFactory;
2527
import org.springframework.beans.factory.annotation.Autowired;
2628
import org.springframework.stereotype.Component;
2729

2830
import com.ericsson.ei.frontend.model.BackEndInformation;
2931
import com.fasterxml.jackson.databind.ObjectMapper;
30-
import com.google.gson.JsonArray;
31-
import com.google.gson.JsonElement;
32-
import com.google.gson.JsonObject;
3332

3433
import lombok.Getter;
3534
import lombok.Setter;
@@ -47,6 +46,8 @@ public class BackEndInstancesUtils {
4746
public static final String CONTEXT_PATH = "contextPath";
4847
public static final String HTTPS = "https";
4948
public static final String DEFAULT = "defaultBackend";
49+
public static final List<String> ALLOWED_JSON_KEYS = Arrays.asList("name",
50+
"host", "port", "contextPath", "https", "defaultBackend");
5051

5152
private static final long SECONDS_BETWEEN_PARSING = 20;
5253

@@ -64,6 +65,57 @@ public class BackEndInstancesUtils {
6465
private long nextTimeToParse = 0;
6566
private boolean savedSinceLastParsing = false;
6667

68+
/**
69+
* Checks that all required keys exist in the incoming json object.
70+
*
71+
* @param JsonObject instance
72+
* @return boolean
73+
* */
74+
public boolean hasRequiredJsonKeys(JsonObject instance) {
75+
if (instance.has(HOST) && instance.has(PORT) && instance.has(NAME)
76+
&& instance.has(CONTEXT_PATH) && instance.has(HTTPS)) {
77+
return true;
78+
}
79+
return false;
80+
}
81+
82+
/**
83+
* Checks if json values in backend instance are null.
84+
*
85+
* @param JsonObject instance
86+
* @return boolean
87+
* */
88+
public boolean containsNullValues(JsonObject instance) {
89+
for (Map.Entry<String, JsonElement> entrySet : instance.entrySet()) {
90+
if (entrySet.getValue().isJsonNull() || entrySet.getValue() == null) {
91+
LOG.debug(entrySet.toString() + " can not be null!");
92+
return true;
93+
}
94+
}
95+
return false;
96+
}
97+
98+
/**
99+
* Checks that the incoming json data does not contain additional keys. Any
100+
* unrecognized keys are logged.
101+
*
102+
* @param JsonObject instance
103+
* @return boolean
104+
* */
105+
public boolean containsAdditionalKeys(JsonObject instance) {
106+
if (instance.size() > ALLOWED_JSON_KEYS.size()) {
107+
for (Map.Entry<String, JsonElement> entrySet : instance.entrySet()) {
108+
109+
boolean hasUnrecognizedKeys = !ALLOWED_JSON_KEYS.contains(entrySet.getKey());
110+
if (hasUnrecognizedKeys) {
111+
LOG.debug("Unrecognized key " + entrySet.getKey());
112+
return true;
113+
}
114+
}
115+
}
116+
return false;
117+
}
118+
67119
/**
68120
* Returns true or false depending if instance host, port, contextPath or https already exist.
69121
* Will return true if all values are the same, false if any value is different, thus input instance
@@ -107,7 +159,6 @@ public boolean checkIfInstanceNameAlreadyExist(JsonObject instance) {
107159
/**
108160
* Returns true or false depending if default instance exist.
109161
*
110-
* @param instance
111162
* @return boolean
112163
*/
113164
public boolean hasDefaultBackend() {
@@ -122,7 +173,7 @@ public boolean hasDefaultBackend() {
122173
/**
123174
* Returns the BackEndInformation based on input name.
124175
*
125-
* @param String name
176+
* @param String backEndName
126177
* @return backendInformation if exist null if no backendInformation exist
127178
*/
128179
public BackEndInformation getBackEndInformationByName(String backEndName) {
@@ -156,13 +207,9 @@ public BackEndInformation getBackEndInformationByName(String backEndName) {
156207
*
157208
* @param instance back end information as JsonObject
158209
*/
159-
public void addNewBackEnd(JsonObject instance) {
210+
public void addNewBackEnd(JsonObject instance) throws IOException {
160211
parseBackEndInstances();
161-
try {
162-
backEndInformationList.add(new ObjectMapper().readValue(instance.toString(), BackEndInformation.class));
163-
} catch (IOException e) {
164-
LOG.error("Failure when trying to add instance " + e.getMessage());
165-
}
212+
backEndInformationList.add(new ObjectMapper().readValue(instance.toString(), BackEndInformation.class));
166213
saveBackEndInformationList();
167214
}
168215

@@ -205,7 +252,7 @@ public void setDefaultBackEndInstanceToNull() {
205252
}
206253

207254
/**
208-
* Tunction that may be used to set default back end.
255+
* Function that may be used to set default back end.
209256
*
210257
* @param name
211258
* @param host

src/test/java/com/ericsson/ei/frontend/BackendInformationControllerTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ public void testSwitchInstance() throws Exception {
9797

9898
@Test
9999
public void testAddInstance() throws Exception {
100+
when(utils.hasRequiredJsonKeys(any())).thenReturn(true);
101+
when(utils.containsNullValues(any())).thenReturn(false);
102+
when(utils.containsAdditionalKeys(any())).thenReturn(false);
100103
when(utils.checkIfInstanceAlreadyExist(any())).thenReturn(false);
101104
when(utils.getBackEndsAsJsonArray()).thenReturn(new JsonArray());
102105
mockMvc.perform(MockMvcRequestBuilders.post(PATH_FOR_BACK_END_INFORMATION)

src/test/java/com/ericsson/ei/frontend/BackendInformationControllerUtilsTest.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,10 @@
1515

1616
import static org.mockito.ArgumentMatchers.any;
1717
import static org.mockito.Mockito.when;
18-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
19-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
2018

2119
import java.io.BufferedReader;
2220
import java.io.FileReader;
2321
import java.net.URI;
24-
import java.util.ArrayList;
2522
import java.util.List;
2623
import java.util.stream.Stream;
2724

@@ -33,8 +30,6 @@
3330
import org.junit.Test;
3431
import org.junit.runner.RunWith;
3532
import org.mockito.Mockito;
36-
import org.slf4j.Logger;
37-
import org.slf4j.LoggerFactory;
3833
import org.springframework.beans.factory.annotation.Autowired;
3934
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
4035
import org.springframework.boot.test.context.SpringBootTest;
@@ -44,15 +39,11 @@
4439
import org.springframework.http.MediaType;
4540
import org.springframework.http.ResponseEntity;
4641
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
47-
import org.springframework.test.web.servlet.MockMvc;
48-
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
4942

5043
import com.ericsson.ei.frontend.model.BackEndInformation;
51-
import com.ericsson.ei.frontend.utils.BackEndInfoirmationControllerUtils;
44+
import com.ericsson.ei.frontend.utils.BackEndInformationControllerUtils;
5245
import com.ericsson.ei.frontend.utils.BackEndInstancesUtils;
53-
import com.fasterxml.jackson.databind.ObjectMapper;
5446
import com.google.gson.JsonArray;
55-
import com.google.gson.JsonElement;
5647
import com.google.gson.JsonObject;
5748
import com.google.gson.JsonParser;
5849

@@ -70,7 +61,7 @@ public class BackendInformationControllerUtilsTest {
7061
private BackEndInstancesUtils backEndInstancesUtils;
7162

7263
@Autowired
73-
private BackEndInfoirmationControllerUtils backendInfoContrUtils;
64+
private BackEndInformationControllerUtils backendInfoContrUtils;
7465

7566
private JsonObject instance;
7667
private JsonArray instances;
@@ -166,20 +157,54 @@ public void testHandleRequestToAddBackEnd() throws Exception {
166157
// Test successfully added.
167158
when(backEndInstancesUtils.checkIfInstanceNameAlreadyExist(any())).thenReturn(false);
168159
when(backEndInstancesUtils.checkIfInstanceAlreadyExist(any())).thenReturn(false);
160+
when(backEndInstancesUtils.hasRequiredJsonKeys(any())).thenReturn(true);
169161
expectedResponse = createExpectedResponse(
170162
"{\"message\": \"Back-end instance with name 'someName' was successfully added to the back-end instance list.\"}",
171163
HttpStatus.OK);
172164
response = backendInfoContrUtils.handleRequestToAddBackEnd(mockedRequest);
173165
assertEquals(expectedResponse, response);
174166

167+
// Test with missing keys
168+
when(backEndInstancesUtils.hasRequiredJsonKeys(any())).thenReturn(false);
169+
expectedResponse = createExpectedResponse(
170+
"{\"message\": \"Back-end instance is missing required data.\"}",
171+
HttpStatus.BAD_REQUEST);
172+
response = backendInfoContrUtils.handleRequestToAddBackEnd(mockedRequest);
173+
assertEquals(expectedResponse, response);
174+
175+
// Test with null values
176+
when(backEndInstancesUtils.hasRequiredJsonKeys(any())).thenReturn(true);
177+
when(backEndInstancesUtils.containsNullValues(any())).thenReturn(true);
178+
expectedResponse = createExpectedResponse(
179+
"{\"message\": \"Back-end instance can not have null values.\"}",
180+
HttpStatus.BAD_REQUEST);
181+
response = backendInfoContrUtils.handleRequestToAddBackEnd(mockedRequest);
182+
assertEquals(expectedResponse, response);
183+
184+
// Test with additional unrecognized keys
185+
when(backEndInstancesUtils.hasRequiredJsonKeys(any())).thenReturn(true);
186+
when(backEndInstancesUtils.containsNullValues(any())).thenReturn(false);
187+
when(backEndInstancesUtils.containsAdditionalKeys(any())).thenReturn(true);
188+
expectedResponse = createExpectedResponse(
189+
"{\"message\": \"Back-end instance contains unrecognized JSON keys.\"}",
190+
HttpStatus.BAD_REQUEST);
191+
response = backendInfoContrUtils.handleRequestToAddBackEnd(mockedRequest);
192+
assertEquals(expectedResponse, response);
193+
175194
// Test back end name already exist
195+
when(backEndInstancesUtils.hasRequiredJsonKeys(any())).thenReturn(true);
196+
when(backEndInstancesUtils.containsNullValues(any())).thenReturn(false);
197+
when(backEndInstancesUtils.containsAdditionalKeys(any())).thenReturn(false);
176198
when(backEndInstancesUtils.checkIfInstanceNameAlreadyExist(any())).thenReturn(true);
177199
expectedResponse = createExpectedResponse(
178200
"{\"message\": \"Back-end instance with name 'someName' already exists.\"}", HttpStatus.BAD_REQUEST);
179201
response = backendInfoContrUtils.handleRequestToAddBackEnd(mockedRequest);
180202
assertEquals(expectedResponse, response);
181203

182204
// Test instance already exist
205+
when(backEndInstancesUtils.hasRequiredJsonKeys(any())).thenReturn(true);
206+
when(backEndInstancesUtils.containsNullValues(any())).thenReturn(false);
207+
when(backEndInstancesUtils.containsAdditionalKeys(any())).thenReturn(false);
183208
when(backEndInstancesUtils.checkIfInstanceNameAlreadyExist(any())).thenReturn(false);
184209
when(backEndInstancesUtils.checkIfInstanceAlreadyExist(any())).thenReturn(true);
185210
expectedResponse = createExpectedResponse("{\"message\": \"Back-end instance with given values already exist.\"}",
@@ -188,6 +213,9 @@ public void testHandleRequestToAddBackEnd() throws Exception {
188213
assertEquals(expectedResponse, response);
189214

190215
// Test failure to add new default instance.
216+
when(backEndInstancesUtils.hasRequiredJsonKeys(any())).thenReturn(true);
217+
when(backEndInstancesUtils.containsNullValues(any())).thenReturn(false);
218+
when(backEndInstancesUtils.containsAdditionalKeys(any())).thenReturn(false);
191219
when(backEndInstancesUtils.checkIfInstanceNameAlreadyExist(any())).thenReturn(false);
192220
when(backEndInstancesUtils.checkIfInstanceAlreadyExist(any())).thenReturn(false);
193221
when(backEndInstancesUtils.hasDefaultBackend()).thenReturn(true);

src/test/java/com/ericsson/ei/frontend/BackendInstancesUtilsTest.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,34 @@ public void before() throws IOException {
6060
utils.getDefaultBackendInformation().setHost(null);
6161
}
6262

63+
@Test
64+
public void testHasRequiredJsonKeys() {
65+
// removing required key port and the json object should not be valid
66+
instance.remove("port");
67+
assertEquals(false, utils.hasRequiredJsonKeys(instance));
68+
69+
// adding the key port with a value and it should pass
70+
instance.addProperty("port", 1234);
71+
assertEquals(true, utils.hasRequiredJsonKeys(instance));
72+
}
73+
74+
@Test
75+
public void testContainsNullValuesTrue() {
76+
instance.add("port", null);
77+
assertEquals(true, utils.containsNullValues(instance));
78+
}
79+
80+
@Test
81+
public void testContainsAdditionalKeysTrue() {
82+
// add extra random key
83+
instance.addProperty("randomKey", "randomValue");
84+
assertEquals(true, utils.containsAdditionalKeys(instance));
85+
86+
// clean up of excess JSON key
87+
instance.remove("randomKey");
88+
assertEquals(false, utils.containsAdditionalKeys(instance));
89+
}
90+
6391
@Test
6492
public void testCheckIfInstanceAlreadyExistTrue() {
6593
boolean result;
@@ -135,7 +163,7 @@ public void testGetBackEndInformationByName() {
135163
}
136164

137165
@Test
138-
public void testAddNewBackEnd() {
166+
public void testAddNewBackEnd() throws IOException {
139167
when(fileUtils.getInstancesFromFile()).thenReturn(new JsonArray());
140168
utils.addNewBackEnd(instance);
141169
assertEquals(instance, utils.getBackEndInformationList().get(0).getAsJsonObject());

0 commit comments

Comments
 (0)