From 70f9f24e6ed39a6ddb4afef02516af624f50079d Mon Sep 17 00:00:00 2001 From: Lianhao Lu Date: Fri, 9 Nov 2018 14:57:30 +0800 Subject: Make FileSystemReceptionHandler more tolerant Make FileSystemReceptionHandler tolerant of exceptions thrown when parsing tosca template and be able to handle new incoming csar. Also added the unit test for FileSystemReceptionHandler. Change-Id: I0f1647f6f952576a8e61adca4d027990706d1411 Issue-ID: POLICY-837 Signed-off-by: Lianhao Lu --- .../handling/sdc/FileSystemReceptionHandler.java | 25 ++-- ...eceptionHandlerConfigurationParameterGroup.java | 10 +- .../sdc/TestFileSystemReceptionHandler.java | 145 +++++++++++++++++++++ ...eceptionHandlerConfigurationParameterGroup.java | 102 +++++++++++++++ .../src/test/resources/handling-filesystem.json | 5 + .../test/resources/handling-filesystemInvalid.json | 4 + 6 files changed, 280 insertions(+), 11 deletions(-) create mode 100644 plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandler.java create mode 100644 plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandlerConfigurationParameterGroup.java create mode 100644 plugins/reception-plugins/src/test/resources/handling-filesystem.json create mode 100644 plugins/reception-plugins/src/test/resources/handling-filesystemInvalid.json (limited to 'plugins/reception-plugins/src') diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandler.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandler.java index 9ac21550..b1a95fac 100644 --- a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandler.java +++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandler.java @@ -23,6 +23,7 @@ package org.onap.policy.distribution.reception.handling.sdc; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import java.io.File; +import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; @@ -52,9 +53,10 @@ public class FileSystemReceptionHandler extends AbstractReceptionHandler { final FileSystemReceptionHandlerConfigurationParameterGroup handlerParameters = ParameterService.get(parameterGroupName); main(handlerParameters.getWatchPath()); - } catch (final PolicyDecodingException ex) { - LOGGER.debug(ex); + } catch (final Exception ex) { + LOGGER.error(ex); } + LOGGER.debug("FileSystemReceptionHandler main loop exited..."); } @Override @@ -67,10 +69,9 @@ public class FileSystemReceptionHandler extends AbstractReceptionHandler { * Main entry point. * * @param watchPath Path to watch - * @throws PolicyDecodingException Decoding exception */ @SuppressWarnings("unchecked") - public void main(String watchPath) throws PolicyDecodingException { + public void main(String watchPath) { try (final WatchService watcher = FileSystems.getDefault().newWatchService()) { final Path dir = Paths.get(watchPath); @@ -85,25 +86,31 @@ public class FileSystemReceptionHandler extends AbstractReceptionHandler { Thread.currentThread().interrupt(); return; } + for (final WatchEvent event : key.pollEvents()) { final WatchEvent.Kind kind = event.kind(); final WatchEvent ev = (WatchEvent) event; final Path fileName = ev.context(); - LOGGER.debug("new CSAR found: " + kind.name() + ": " + fileName); - createPolicyInputAndCallHandler(dir.toString() + File.separator + fileName.toString()); - LOGGER.debug("CSAR complete: " + kind.name() + ": " + fileName); + try { + LOGGER.debug("new CSAR found: " + kind.name() + ": " + fileName); + createPolicyInputAndCallHandler(dir.toString() + File.separator + fileName.toString()); + LOGGER.debug("CSAR complete: " + kind.name() + ": " + fileName); + } catch (final PolicyDecodingException ex) { + LOGGER.error(ex); + } } final boolean valid = key.reset(); if (!valid) { + LOGGER.error("Watch key no longer valid!"); break; } } - } catch (final Exception ex) { + } catch (final IOException ex) { LOGGER.error(ex); } } - private void createPolicyInputAndCallHandler(final String fileName) throws PolicyDecodingException { + protected void createPolicyInputAndCallHandler(final String fileName) throws PolicyDecodingException { final Csar csarObject = new Csar(fileName); inputReceived(csarObject); } diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandlerConfigurationParameterGroup.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandlerConfigurationParameterGroup.java index 98f3c6a4..457cd5ea 100644 --- a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandlerConfigurationParameterGroup.java +++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/FileSystemReceptionHandlerConfigurationParameterGroup.java @@ -68,8 +68,14 @@ public class FileSystemReceptionHandlerConfigurationParameterGroup extends Recep */ private void validatePathElement(final GroupValidationResult validationResult, final String element, final String elementName) { - File file = new File(element); - if (!(file.exists() && file.isDirectory())) { + boolean valid = false; + if (element != null) { + File file = new File(element); + if (file.exists() && file.isDirectory()) { + valid = true; + } + } + if (!valid) { validationResult.setResult(elementName, ValidationStatus.INVALID, elementName + " must be a valid directory"); } diff --git a/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandler.java b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandler.java new file mode 100644 index 00000000..8edca74e --- /dev/null +++ b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandler.java @@ -0,0 +1,145 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Intel. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.distribution.reception.handling.sdc; + +import static org.junit.Assert.fail; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.common.parameters.ParameterService; +import org.onap.policy.distribution.forwarding.PolicyForwarder; +import org.onap.policy.distribution.reception.decoding.PolicyDecodingException; +import org.onap.policy.distribution.reception.statistics.DistributionStatisticsManager; + +/** + * Class to perform unit test of {@link FileSystemReceptionHandler}. + */ +@RunWith(MockitoJUnitRunner.class) +public class TestFileSystemReceptionHandler { + + private static final Logger LOGGER = FlexLogger.getLogger(TestFileSystemReceptionHandler.class); + private static final String DUMMY_SERVICE_CSAR = "dummyService.csar"; + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + private FileSystemReceptionHandlerConfigurationParameterGroup pssdConfigParameters; + private FileSystemReceptionHandler fileSystemHandler; + + + /** + * Setup for the test cases. + * + * @throws IOException if it occurs + * @throws SecurityException if it occurs + * @throws NoSuchFieldException if it occurs + * @throws IllegalAccessException if it occurs + * @throws IllegalArgumentException if it occurs + */ + @Before + public final void init() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException { + DistributionStatisticsManager.resetAllStatistics(); + + final Gson gson = new GsonBuilder().create(); + String json = "{ \"name\": \"parameterConfig9\", \"watchPath\": \""; + json += tempFolder.getRoot().getAbsolutePath() + "\"}"; + pssdConfigParameters = gson.fromJson(json, + FileSystemReceptionHandlerConfigurationParameterGroup.class); + ParameterService.register(pssdConfigParameters); + fileSystemHandler = new FileSystemReceptionHandler(); + } + + @After + public void teardown() { + ParameterService.deregister(pssdConfigParameters); + } + + @Test + public final void testInit() { + final FileSystemReceptionHandler sypHandler = Mockito.spy(fileSystemHandler); + Mockito.doNothing().when(sypHandler).main(Mockito.isA(String.class)); + sypHandler.initializeReception(pssdConfigParameters.getName()); + Mockito.verify(sypHandler, Mockito.times(1)).main(Mockito.isA(String.class)); + } + + @Test + public final void testDestroy() { + try { + final FileSystemReceptionHandler sypHandler = Mockito.spy(fileSystemHandler); + Mockito.doNothing().when(sypHandler).main(Mockito.isA(String.class)); + sypHandler.initializeReception(pssdConfigParameters.getName()); + sypHandler.destroy(); + } catch (final Exception exp) { + LOGGER.error(exp); + fail("Test should not throw any exception"); + } + + } + + @Test + public void testMain() throws IOException, PolicyDecodingException { + + final FileSystemReceptionHandler sypHandler = Mockito.spy(fileSystemHandler); + Mockito.doNothing().when(sypHandler).createPolicyInputAndCallHandler(Mockito.isA(String.class)); + + final String watchPath = tempFolder.getRoot().getAbsolutePath().toString(); + Thread th = new Thread(() -> { + sypHandler.main(watchPath); + }); + + th.start(); + try { + // yield to main thread + Thread.sleep(1000); + Files.copy(Paths.get("src/test/resources/hpaPolicyHugePage.csar"), + Paths.get(watchPath + File.separator + "hpaPolicyHugePage.csar")); + // wait enough time + Thread.sleep(1000); + sypHandler.destroy(); + th.interrupt(); + th.join(); + } catch (final InterruptedException ex) { + LOGGER.error(ex); + } + Mockito.verify(sypHandler, Mockito.times(1)) + .createPolicyInputAndCallHandler(Mockito.isA(String.class)); + + } +} + diff --git a/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandlerConfigurationParameterGroup.java b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandlerConfigurationParameterGroup.java new file mode 100644 index 00000000..b4b905c5 --- /dev/null +++ b/plugins/reception-plugins/src/test/java/org/onap/policy/distribution/reception/handling/sdc/TestFileSystemReceptionHandlerConfigurationParameterGroup.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Intel. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.distribution.reception.handling.sdc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.FileReader; +import java.io.IOException; +import java.util.Arrays; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import org.onap.policy.common.parameters.GroupValidationResult; + +/** + * Class to perform unit test of {@link FileSystemReceptionHandlerConfigurationParameterGroup}. + * + */ +public class TestFileSystemReceptionHandlerConfigurationParameterGroup { + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + @Test + public void testFileSystemConfiguration() throws IOException { + FileSystemReceptionHandlerConfigurationParameterGroup configParameters = null; + try { + final Gson gson = new GsonBuilder().create(); + configParameters = gson.fromJson(new FileReader("src/test/resources/handling-filesystem.json"), + FileSystemReceptionHandlerConfigurationParameterGroup.class); + } catch (final Exception e) { + fail("test should not thrown an exception here: " + e.getMessage()); + } + final GroupValidationResult validationResult = configParameters.validate(); + assertTrue(validationResult.isValid()); + assertEquals("/tmp", configParameters.getWatchPath()); + } + + @Test + public void testInvalidFileSystemConfiguration() throws IOException { + FileSystemReceptionHandlerConfigurationParameterGroup configParameters = null; + try { + final Gson gson = new GsonBuilder().create(); + configParameters = gson.fromJson(new FileReader("src/test/resources/handling-sdcInvalid.json"), + FileSystemReceptionHandlerConfigurationParameterGroup.class); + } catch (final Exception e) { + fail("test should not thrown an exception here: " + e.getMessage()); + } + final GroupValidationResult validationResult = configParameters.validate(); + assertFalse(validationResult.isValid()); + } + + @Test + public void testFileSystemReceptionHandlerConfigurationParameterBuilder() { + + final FileSystemReceptionHandlerConfigurationParameterBuilder builder = + new FileSystemReceptionHandlerConfigurationParameterBuilder().setWatchPath("/foo/bar"); + final FileSystemReceptionHandlerConfigurationParameterGroup configParameters = + new FileSystemReceptionHandlerConfigurationParameterGroup(builder); + + assertEquals("/foo/bar", configParameters.getWatchPath()); + } + + @Test + public void testFileSystemReceptionHandlerConfigurationParameterBuilderWithInvalidPath() throws IOException { + final String invalidPath = tempFolder.newFile("foobar").getAbsolutePath(); + + final FileSystemReceptionHandlerConfigurationParameterBuilder builder = + new FileSystemReceptionHandlerConfigurationParameterBuilder().setWatchPath(invalidPath); + final FileSystemReceptionHandlerConfigurationParameterGroup configParameters = + new FileSystemReceptionHandlerConfigurationParameterGroup(builder); + + final GroupValidationResult validateResult = configParameters.validate(); + assertFalse(validateResult.isValid()); + assertTrue(validateResult.getResult().contains("must be a valid directory")); + } +} diff --git a/plugins/reception-plugins/src/test/resources/handling-filesystem.json b/plugins/reception-plugins/src/test/resources/handling-filesystem.json new file mode 100644 index 00000000..6a402a7a --- /dev/null +++ b/plugins/reception-plugins/src/test/resources/handling-filesystem.json @@ -0,0 +1,5 @@ +{ + "name": "parameterConfig1", + "watchPath": "/tmp" +} + diff --git a/plugins/reception-plugins/src/test/resources/handling-filesystemInvalid.json b/plugins/reception-plugins/src/test/resources/handling-filesystemInvalid.json new file mode 100644 index 00000000..871b61c2 --- /dev/null +++ b/plugins/reception-plugins/src/test/resources/handling-filesystemInvalid.json @@ -0,0 +1,4 @@ +{ + "invalidKey": "/tmp" +} + -- cgit 1.2.3-korg