Resolve critical sonarqube issues 70/141670/2
authorFiete Ostkamp <Fiete.Ostkamp@telekom.de>
Mon, 11 Aug 2025 07:18:41 +0000 (09:18 +0200)
committerFiete Ostkamp <Fiete.Ostkamp@telekom.de>
Mon, 11 Aug 2025 08:07:08 +0000 (10:07 +0200)
- add path validation for test-only controller
  (was not a real vulnerability)
- prevent resource leaks in ZipParser and Onap3gppServiceInstances classes
- add tests for ZipParser
- align packages of test classes to match the classes they are testing
  (move org.onap.asdc.activity test classes to org.onap.so.asdc.activity)

Issue-ID: SO-4222
Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de>
Change-Id: I89dc950ee158989d867d4b2a0ccb813767b0d51b

adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java
adapters/mso-catalog-db-adapter/src/main/java/org/onap/so/adapters/catalogdb/catalogrest/QueryServiceInfo.java
asdc-controller/src/main/java/org/onap/so/asdc/client/test/rest/ASDCRestInterface.java
asdc-controller/src/main/java/org/onap/so/asdc/util/ZipParser.java
asdc-controller/src/test/java/org/onap/so/asdc/activity/ActivitySpecsActionsTest.java [moved from asdc-controller/src/test/java/org/onap/asdc/activity/ActivitySpecsActionsTest.java with 98% similarity]
asdc-controller/src/test/java/org/onap/so/asdc/activity/DeployActivitySpecsITTest.java [moved from asdc-controller/src/test/java/org/onap/asdc/activity/DeployActivitySpecsITTest.java with 98% similarity]
asdc-controller/src/test/java/org/onap/so/asdc/activity/DeployActivitySpecsTest.java [moved from asdc-controller/src/test/java/org/onap/asdc/activity/DeployActivitySpecsTest.java with 96% similarity]
asdc-controller/src/test/java/org/onap/so/asdc/client/test/rest/ASDCRestInterfaceTest.java
asdc-controller/src/test/java/org/onap/so/asdc/util/ZipParserTest.java [new file with mode: 0644]
mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Onap3gppServiceInstances.java

index 14f20ca..d524214 100644 (file)
@@ -979,12 +979,12 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin {
         vduInstance.setOutputs(stackInfo.getOutputs());
 
         // Translate the status elements
-        vduInstance.setStatus(stackStatusToVduStatus(stackInfo));
+        vduInstance.setStatus(mapStackStatusToVduStatus(stackInfo));
 
         return vduInstance;
     }
 
-    private VduStatus stackStatusToVduStatus(StackInfo stackInfo) {
+    private VduStatus mapStackStatusToVduStatus(StackInfo stackInfo) {
         VduStatus vduStatus = new VduStatus();
 
         // Map the status fields to more generic VduStatus.
index d08c2e1..e7eb328 100644 (file)
@@ -77,9 +77,9 @@ public class QueryServiceInfo extends CatalogQuery {
         sb.append("\n");
         Map<String, String> valueMap = new HashMap<>();
         Service service = serviceInfo.getService();
-        put(valueMap, "ID", null == serviceInfo ? null : serviceInfo.getId());
-        put(valueMap, "SERVICE_INPUT", null == serviceInfo ? null : serviceInfo.getServiceInput());
-        put(valueMap, "SERVICE_PROPERTIES", null == serviceInfo ? null : serviceInfo.getServiceProperties());
+        put(valueMap, "ID", serviceInfo.getId());
+        put(valueMap, "SERVICE_INPUT", serviceInfo.getServiceInput());
+        put(valueMap, "SERVICE_PROPERTIES", serviceInfo.getServiceProperties());
         String subitem = new QueryServiceArtifact(service.getServiceArtifactList()).JSON2(true, true);
         valueMap.put("_SERVICEARTIFACT_", subitem.replaceAll("(?m)^", "\t\t"));
         sb.append(this.setTemplate(TEMPLATE, valueMap));
index 4277850..0cf32b9 100644 (file)
@@ -9,9 +9,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,6 +23,8 @@
 package org.onap.so.asdc.client.test.rest;
 
 
+import java.io.File;
+import java.io.IOException;
 import javax.transaction.Transactional;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.POST;
@@ -53,7 +55,7 @@ import org.springframework.stereotype.Component;
  * i.e. http://localhost:8085/test/treatNotification/v1
  * <p>
  * i.e. http://localhost:8085/test/statusData/v1
- * 
+ *
  * This interface is also used in CSIT to simulate a distribution of a service, without using SDC
  *
  * @author jm5423
@@ -76,6 +78,9 @@ public class ASDCRestInterface {
         this.toscaInstaller = toscaInstaller;
     }
 
+    private static String targetDirectory = "src/test/resources";
+    private static java.nio.file.Path targetPath = new File(targetDirectory).toPath().normalize();
+
     @POST
     @Path("/treatNotification/v1")
     @Produces(MediaType.APPLICATION_JSON)
@@ -83,11 +88,16 @@ public class ASDCRestInterface {
     public Response invokeASDCService(final NotificationDataImpl request,
             @HeaderParam("resource-location") final String resourceLocation) {
 
+        if (!isLocationValid(resourceLocation)) {
+            return Response.status(Status.BAD_REQUEST).build();
+        }
+        String validatedLocation = targetPath + resourceLocation;
+
         try {
             logger.info("Received message : {}", request);
-            logger.info("resource-location : {}", resourceLocation);
+            logger.info("resource-location : {}", validatedLocation);
             final DistributionClientEmulator distributionClientEmulator =
-                    getDistributionClientEmulator(resourceLocation);
+                    getDistributionClientEmulator(validatedLocation);
 
             asdcController.setControllerName("asdc-controller1");
             asdcController.setDistributionClient(distributionClientEmulator);
@@ -112,6 +122,19 @@ public class ASDCRestInterface {
 
     }
 
+    /**
+     * This mitigates a sonarqube issue that is marked as critical. Since this controller is only available in the test
+     * profile, there is no real vulnerability here, but this is the easiest way to resolve the issue
+     */
+    private boolean isLocationValid(String resourceLocation) {
+        File file = new File(targetPath + resourceLocation);
+
+        if (!file.toPath().normalize().startsWith(targetPath)) {
+            return false;
+        }
+        return true;
+    }
+
     private DistributionClientEmulator getDistributionClientEmulator(final String resourceLocation) {
         return new DistributionClientEmulator(resourceLocation);
     }
index c2f04dc..95dc178 100644 (file)
@@ -42,26 +42,28 @@ public class ZipParser {
     }
 
     public String parseJsonForZip(String path) throws IOException {
-        ZipFile zf = new ZipFile(path);
-        InputStream in = new BufferedInputStream(new FileInputStream(path));
-        Charset cs = Charset.forName("utf-8");
-        ZipInputStream zin = new ZipInputStream(in, cs);
-        ZipEntry ze;
-        String artifactContent = null;
-        while ((ze = zin.getNextEntry()) != null) {
-            if (ze.toString().endsWith("json")) {
-                StringBuilder jsonStr = new StringBuilder();
-                BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));
-                String line;
-                while ((line = br.readLine()) != null) {
-                    jsonStr.append(line);
+        try (ZipFile zipFile = new ZipFile(path)) {
+            InputStream inputStream = new BufferedInputStream(new FileInputStream(path));
+            Charset charset = Charset.forName("utf-8");
+            try (ZipInputStream zipInputStream = new ZipInputStream(inputStream, charset)) {
+                ZipEntry zipEntry;
+                String artifactContent = null;
+                while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+                    if (zipEntry.toString().endsWith("json")) {
+                        StringBuilder jsonStr = new StringBuilder();
+                        BufferedReader br = new BufferedReader(new InputStreamReader(zipFile.getInputStream(zipEntry)));
+                        String line;
+                        while ((line = br.readLine()) != null) {
+                            jsonStr.append(line);
+                        }
+                        br.close();
+                        artifactContent = jsonStr.toString().replace("\"", "\\\"").replaceAll("\\s", "");
+                    }
                 }
-                br.close();
-                artifactContent = jsonStr.toString().replace("\"", "\\\"").replaceAll("\\s", "");
+                zipInputStream.closeEntry();
+                return artifactContent;
             }
         }
-        zin.closeEntry();
-        return artifactContent;
     }
 
 }
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,7 @@
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
-package org.onap.asdc.activity;
+package org.onap.so.asdc.activity;
 
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
 import static com.github.tomakehurst.wiremock.client.WireMock.post;
@@ -26,7 +26,6 @@ import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
 import static org.junit.Assert.*;
 import org.junit.Test;
 import org.onap.so.asdc.BaseTest;
-import org.onap.so.asdc.activity.ActivitySpecsActions;
 import org.onap.so.asdc.activity.beans.ActivitySpec;
 import org.onap.so.asdc.activity.beans.ActivitySpecCreateResponse;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,7 @@
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
-package org.onap.asdc.activity;
+package org.onap.so.asdc.activity;
 
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
 import static com.github.tomakehurst.wiremock.client.WireMock.post;
@@ -33,7 +33,6 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
 import org.onap.so.asdc.BaseTest;
-import org.onap.so.asdc.activity.DeployActivitySpecs;
 import org.onap.so.asdc.activity.beans.ActivitySpecCreateResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,7 @@
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
-package org.onap.asdc.activity;
+package org.onap.so.asdc.activity;
 
 import java.nio.file.Files;
 import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
@@ -32,8 +32,6 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnitRunner;
-import org.onap.so.asdc.activity.ActivitySpecsActions;
-import org.onap.so.asdc.activity.DeployActivitySpecs;
 import org.onap.so.asdc.activity.beans.ActivitySpec;
 import org.onap.so.asdc.activity.beans.ActivitySpecCreateResponse;
 import org.onap.so.db.catalog.data.repository.ActivitySpecRepository;
index c6e472f..7743dc7 100644 (file)
@@ -133,7 +133,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         NotificationDataImpl request =
                 mapper.readValue(new File("src/test/resources/resource-examples/allottedresource/notif-portm.json"),
                         NotificationDataImpl.class);
-        headers.add("resource-location", "src/test/resources/resource-examples/allottedresource/");
+        headers.add("resource-location", "/resource-examples/allottedresource/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
 
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
@@ -185,7 +185,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(
                 new File("src/test/resources/resource-examples/vFW/notification.json"), NotificationDataImpl.class);
-        headers.add("resource-location", "src/test/resources/resource-examples/vFW/");
+        headers.add("resource-location", "/resource-examples/vFW/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
 
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
@@ -229,7 +229,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         NotificationDataImpl request = mapper.readValue(
                 new File("src/test/resources/resource-examples/WorkflowBpmn/workflow-distribution.json"),
                 NotificationDataImpl.class);
-        headers.add("resource-location", "src/test/resources/resource-examples/WorkflowBpmn/");
+        headers.add("resource-location", "/resource-examples/WorkflowBpmn/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
 
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
@@ -279,7 +279,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(new File(resourceLocation + "demovcpeinfra-notification.json"),
                 NotificationDataImpl.class);
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/vcpe-infra/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
 
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
@@ -324,7 +324,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(new File(resourceLocation + "demo-ccvpn-notification.json"),
                 NotificationDataImpl.class);
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/ccvpn/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
                 HttpMethod.POST, entity, String.class);
@@ -349,7 +349,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         NotificationDataImpl request;
         HttpEntity<NotificationDataImpl> entity;
         ResponseEntity<String> response;
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/e2eSlicing/");
 
         request = mapper.readValue(new File(resourceLocation + "nsst-notification.json"), NotificationDataImpl.class);
         entity = new HttpEntity<NotificationDataImpl>(request, headers);
@@ -385,7 +385,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(new File(resourceLocation + "demo-public-ns-notification.json"),
                 NotificationDataImpl.class);
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/public-ns/demo-public-ns-notification.json");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
                 HttpMethod.POST, entity, String.class);
@@ -409,7 +409,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(
                 new File(resourceLocation + "demo-vcpe-rescust-notification.json"), NotificationDataImpl.class);
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/vcpe-rescust/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
                 HttpMethod.POST, entity, String.class);
@@ -431,7 +431,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(
                 new File(resourceLocation + "service-ubuntu16test-notification.json"), NotificationDataImpl.class);
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/service-ubuntu16test/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
                 HttpMethod.POST, entity, String.class);
@@ -453,7 +453,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(
                 new File(resourceLocation + "service-BasicCnf-notification.json"), NotificationDataImpl.class);
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/service-BasicCnf/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
                 HttpMethod.POST, entity, String.class);
@@ -474,7 +474,7 @@ public class ASDCRestInterfaceTest extends BaseTest {
         ObjectMapper mapper = new ObjectMapper();
         NotificationDataImpl request = mapper.readValue(
                 new File(resourceLocation + "service-BasicNetwork-notification.json"), NotificationDataImpl.class);
-        headers.add("resource-location", resourceLocation);
+        headers.add("resource-location", "/resource-examples/service-BasicNetwork/");
         HttpEntity<NotificationDataImpl> entity = new HttpEntity<NotificationDataImpl>(request, headers);
         ResponseEntity<String> response = restTemplate.exchange(createURLWithPort("/test/treatNotification/v1"),
                 HttpMethod.POST, entity, String.class);
diff --git a/asdc-controller/src/test/java/org/onap/so/asdc/util/ZipParserTest.java b/asdc-controller/src/test/java/org/onap/so/asdc/util/ZipParserTest.java
new file mode 100644 (file)
index 0000000..dd8313c
--- /dev/null
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom AG Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.so.asdc.util;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+import java.io.*;
+import java.nio.file.*;
+import java.util.zip.*;
+
+public class ZipParserTest {
+
+    private Path tempDir;
+
+    @Before
+    public void setUp() throws IOException {
+        tempDir = Files.createTempDirectory("zipparsertest");
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        if (tempDir != null && Files.exists(tempDir)) {
+            Files.walk(tempDir).map(Path::toFile).forEach(File::delete);
+        }
+    }
+
+    @Test
+    public void testSingletonInstance() {
+        ZipParser instance1 = ZipParser.getInstance();
+        ZipParser instance2 = ZipParser.getInstance();
+        assertSame("Both instances must be same (singleton)", instance1, instance2);
+    }
+
+    @Test
+    public void testParseJsonForZip_withJsonFile() throws IOException {
+        // Create a zip file with one JSON file inside
+        Path zipFilePath = tempDir.resolve("testJson.zip");
+        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zipFilePath))) {
+            ZipEntry entry = new ZipEntry("data.json");
+            zos.putNextEntry(entry);
+            String jsonContent = "{ \"name\": \"test\", \"value\": 123 }";
+            zos.write(jsonContent.getBytes("UTF-8"));
+            zos.closeEntry();
+        }
+
+        String parsedContent = ZipParser.getInstance().parseJsonForZip(zipFilePath.toString());
+        // Expected content with quotes escaped and all whitespace removed
+        String expected = "{\\\"name\\\":\\\"test\\\",\\\"value\\\":123}";
+        assertEquals(expected, parsedContent);
+    }
+
+    @Test
+    public void testParseJsonForZip_noJsonFile() throws IOException {
+        // Create a zip file without any JSON files inside
+        Path zipFilePath = tempDir.resolve("testNoJson.zip");
+        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zipFilePath))) {
+            ZipEntry entry = new ZipEntry("readme.txt");
+            zos.putNextEntry(entry);
+            String textContent = "This is a text file, no json here.";
+            zos.write(textContent.getBytes("UTF-8"));
+            zos.closeEntry();
+        }
+
+        String parsedContent = ZipParser.getInstance().parseJsonForZip(zipFilePath.toString());
+        assertNull("No JSON file, should return null", parsedContent);
+    }
+
+    @Test(expected = IOException.class)
+    public void testParseJsonForZip_invalidPath() throws IOException {
+        // Non-existent file path should throw IOException
+        ZipParser.getInstance().parseJsonForZip("non_existent_file.zip");
+    }
+}
index 00b099b..52cc8f5 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.so.apihandlerinfra;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
+import java.io.IOException;
 import java.sql.Timestamp;
 import java.util.HashMap;
 import java.util.List;
@@ -588,16 +589,14 @@ public class Onap3gppServiceInstances {
     private Response getSubnetCapabilities(List<SubnetTypes> subnetTypes, String version) {
         String inputFileString = "";
         Map<String, Object> subnetCapability = new HashMap<>();
-        BufferedReader br = null;
-        try {
+        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(subnetCapabilityConfigFile)))) {
             logger.debug("Reading SubnetCapability file");
-            br = new BufferedReader(new FileReader(new File(subnetCapabilityConfigFile)));
             StringBuilder sb = new StringBuilder();
-            String line = br.readLine();
+            String line = bufferedReader.readLine();
             while (line != null) {
                 sb.append(line);
                 sb.append("\n");
-                line = br.readLine();
+                line = bufferedReader.readLine();
             }
             inputFileString = sb.toString();
             subnetCapability = mapper.readValue(inputFileString, Map.class);