diff options
Diffstat (limited to 'reception/src')
7 files changed, 523 insertions, 0 deletions
diff --git a/reception/src/main/java/org/onap/policy/distribution/reception/decoding/PolicyDecoder.java b/reception/src/main/java/org/onap/policy/distribution/reception/decoding/PolicyDecoder.java new file mode 100644 index 00000000..8306b630 --- /dev/null +++ b/reception/src/main/java/org/onap/policy/distribution/reception/decoding/PolicyDecoder.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. 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.decoding; + +import java.util.Collection; +import org.onap.policy.distribution.model.Policy; +import org.onap.policy.distribution.model.PolicyInput; + +/** + * Decodes polices from a given input. + * + * @param <T> the type of policy that will be created + * @param <S> the type of input to be decoded + */ +public interface PolicyDecoder<S extends PolicyInput, T extends Policy> { + + /** + * Can the decoder handle input of the specified type. + * + * @param policyInput the type + * @return <code>true</code if the decoder can handle the specified type + */ + boolean canHandle(PolicyInput policyInput); + + /** + * Decode policies from the given input + * + * @param input the input + * @return the generated policies + * @throws PolicyDecodingException if an error occurs during decoding + */ + Collection<T> decode(S input) throws PolicyDecodingException; + +} diff --git a/reception/src/main/java/org/onap/policy/distribution/reception/decoding/PolicyDecodingException.java b/reception/src/main/java/org/onap/policy/distribution/reception/decoding/PolicyDecodingException.java new file mode 100644 index 00000000..5f2923d8 --- /dev/null +++ b/reception/src/main/java/org/onap/policy/distribution/reception/decoding/PolicyDecodingException.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. 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.decoding; + +/** + * An error has occured while decoding a policy. + */ +public class PolicyDecodingException extends Exception { + + private static final long serialVersionUID = 3809376274411309160L; + + /** + * Construct an instance with the given message. + * + * @param message the error message + */ + public PolicyDecodingException(String message) { + super(message); + } + + /** + * Construct an instance with the given message and cause. + * + * @param message the error message + * @param cause the cause + */ + public PolicyDecodingException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/reception/src/main/java/org/onap/policy/distribution/reception/handling/AbstractReceptionHandler.java b/reception/src/main/java/org/onap/policy/distribution/reception/handling/AbstractReceptionHandler.java new file mode 100644 index 00000000..f728fc33 --- /dev/null +++ b/reception/src/main/java/org/onap/policy/distribution/reception/handling/AbstractReceptionHandler.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. 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; + +import java.util.ArrayList; +import java.util.Collection; +import org.onap.policy.distribution.forwarding.PolicyForwarder; +import org.onap.policy.distribution.forwarding.PolicyForwardingException; +import org.onap.policy.distribution.model.Policy; +import org.onap.policy.distribution.model.PolicyInput; +import org.onap.policy.distribution.reception.decoding.PolicyDecoder; +import org.onap.policy.distribution.reception.decoding.PolicyDecodingException; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/*** + * Base implementation of {@link ReceptionHandler}. All reception handlers should extend this base + * class by implementing the {@link #initializeReception(String)} method to perform the + * specific initialization required to receive inputs and by invoking + * {@link #inputReceived(PolicyInput)} when the reception handler receives input + */ +public abstract class AbstractReceptionHandler implements ReceptionHandler { + + private static final XLogger LOGGER = XLoggerFactory.getXLogger(AbstractReceptionHandler.class); + + private PluginHandler pluginHandler; + + @Override + public void initialize(String parameterGroupName) { + pluginHandler = new PluginHandler(parameterGroupName); + initializeReception(parameterGroupName); + } + + /** + * Sub classes must implement this method to perform the specific initialization required to + * receive inputs, for example setting up subscriptions + * + * @param parameterGroupName the parameter group name + */ + protected abstract void initializeReception(String parameterGroupName); + + /** + * Handle input that has been received. The given input shall be decoded using the + * {@link PolicyDecoder}s configured for this reception handler and forwarded using the + * {@link PolicyForwarder}s configured for this reception handler. + * + * @param policyInput the input that has been received + * @throws PolicyDecodingException if an error occurs in decoding a policy from the received + * input + */ + protected void inputReceived(PolicyInput policyInput) throws PolicyDecodingException { + + Collection<Policy> policies = new ArrayList<>(); + for (PolicyDecoder<PolicyInput, Policy> policyDecoder : getRelevantPolicyDecoders(policyInput)) { + policies.addAll(policyDecoder.decode(policyInput)); + } + + for (PolicyForwarder policyForwarder : pluginHandler.getPolicyForwarders()) { + try { + policyForwarder.forward(policies); + } catch (PolicyForwardingException policyForwardingException) { + LOGGER.error("Error when forwarding policies to " + policyForwarder, policyForwardingException); + } + } + } + + private Collection<PolicyDecoder<PolicyInput, Policy>> getRelevantPolicyDecoders(PolicyInput policyInput) + throws PolicyDecodingException { + Collection<PolicyDecoder<PolicyInput, Policy>> relevantPolicyDecoders = new ArrayList<>(); + for (PolicyDecoder<PolicyInput, Policy> policyDecoder : pluginHandler.getPolicyDecoders()) { + if (policyDecoder.canHandle(policyInput)) { + relevantPolicyDecoders.add(policyDecoder); + } + } + if (relevantPolicyDecoders.isEmpty()) { + throw new PolicyDecodingException("No decoder available matching requirements"); + } + return relevantPolicyDecoders; + } + +} diff --git a/reception/src/main/java/org/onap/policy/distribution/reception/handling/PluginHandler.java b/reception/src/main/java/org/onap/policy/distribution/reception/handling/PluginHandler.java new file mode 100644 index 00000000..d10fe0b0 --- /dev/null +++ b/reception/src/main/java/org/onap/policy/distribution/reception/handling/PluginHandler.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. 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; + +import java.util.Collection; +import org.onap.policy.distribution.forwarding.PolicyForwarder; +import org.onap.policy.distribution.model.Policy; +import org.onap.policy.distribution.model.PolicyInput; +import org.onap.policy.distribution.reception.decoding.PolicyDecoder; + +/** + * Handles the plugins to policy distribution. + */ +public class PluginHandler { + + private Collection<PolicyDecoder<PolicyInput, Policy>> policyDecoders; + private Collection<PolicyForwarder> policyForwarders; + + /** + * Create an instance to instantiate plugins based on the given parameter group. + * + * @param parameterGroupName the name of the parameter group + */ + public PluginHandler(String parameterGroupName) { + // Read configuration using common/common-parameters and instantiate decoders and forwarders + } + + /** + * Get the policy decoders. + * + * @return the policy decoders + */ + public Collection<PolicyDecoder<PolicyInput, Policy>> getPolicyDecoders() { + return policyDecoders; + } + + /** + * Get the policy forwarders. + * + * @return the policy forwarders + */ + public Collection<PolicyForwarder> getPolicyForwarders() { + return policyForwarders; + } + + + +} diff --git a/reception/src/main/java/org/onap/policy/distribution/reception/handling/ReceptionHandler.java b/reception/src/main/java/org/onap/policy/distribution/reception/handling/ReceptionHandler.java new file mode 100644 index 00000000..85cc1db1 --- /dev/null +++ b/reception/src/main/java/org/onap/policy/distribution/reception/handling/ReceptionHandler.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. 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; + +/** + * Handles input into Policy Distribution which may be decoded into a Policy. + */ +public interface ReceptionHandler { + + /** + * Initialize the reception handler with the given parameters + * + * @param parameterGroupName the name of the parameter group containing the configuration for + * the reception handler + */ + void initialize(String parameterGroupName); + + /** + * Destroy the reception handler, removing any subscriptions and releasing all resources + */ + void destroy(); + +} diff --git a/reception/src/test/java/org/onap/policy/distribution/reception/decoding/PolicyDecodingExceptionTest.java b/reception/src/test/java/org/onap/policy/distribution/reception/decoding/PolicyDecodingExceptionTest.java new file mode 100644 index 00000000..eba19503 --- /dev/null +++ b/reception/src/test/java/org/onap/policy/distribution/reception/decoding/PolicyDecodingExceptionTest.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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.decoding; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class PolicyDecodingExceptionTest { + + @Test + public void testPolicyDecodingExceptionString() { + PolicyDecodingException policyDecodingException = new PolicyDecodingException("error message"); + assertEquals("error message", policyDecodingException.getMessage()); + } + + @Test + public void testPolicyDecodingExceptionStringThrowable() { + Exception cause = new IllegalArgumentException(); + PolicyDecodingException policyDecodingException = new PolicyDecodingException("error message", cause); + assertEquals("error message", policyDecodingException.getMessage()); + assertEquals(cause, policyDecodingException.getCause()); + } + +} diff --git a/reception/src/test/java/org/onap/policy/distribution/reception/handling/AbstractReceptionHandlerTest.java b/reception/src/test/java/org/onap/policy/distribution/reception/handling/AbstractReceptionHandlerTest.java new file mode 100644 index 00000000..3f033eb0 --- /dev/null +++ b/reception/src/test/java/org/onap/policy/distribution/reception/handling/AbstractReceptionHandlerTest.java @@ -0,0 +1,174 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import org.junit.Test; +import org.onap.policy.distribution.forwarding.PolicyForwarder; +import org.onap.policy.distribution.forwarding.PolicyForwardingException; +import org.onap.policy.distribution.model.Policy; +import org.onap.policy.distribution.model.PolicyInput; +import org.onap.policy.distribution.reception.decoding.PolicyDecoder; +import org.onap.policy.distribution.reception.decoding.PolicyDecodingException; + +public class AbstractReceptionHandlerTest { + + @Test + public void testInputReceived() throws PolicyDecodingException, NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + AbstractReceptionHandler handler = new DummyReceptionHandler(); + + Policy generatedPolicy1 = new DummyPolicy1(); + Policy generatedPolicy2 = new DummyPolicy2(); + + PolicyDecoder<PolicyInput, Policy> policyDecoder1 = + new DummyDecoder(true, Collections.singletonList(generatedPolicy1)); + PolicyDecoder<PolicyInput, Policy> policyDecoder2 = + new DummyDecoder(true, Collections.singletonList(generatedPolicy2)); + + Collection<PolicyDecoder<PolicyInput, Policy>> policyDecoders = new ArrayList<>(); + policyDecoders.add(policyDecoder1); + policyDecoders.add(policyDecoder2); + + DummyPolicyForwarder policyForwarder1 = new DummyPolicyForwarder(); + DummyPolicyForwarder policyForwarder2 = new DummyPolicyForwarder(); + + Collection<PolicyForwarder> policyForwarders = new ArrayList<>(); + policyForwarders.add(policyForwarder1); + policyForwarders.add(policyForwarder2); + + setUpPlugins(handler, policyDecoders, policyForwarders); + + handler.inputReceived(new DummyPolicyInput()); + + assertEquals(2, policyForwarder1.getNumberOfPoliciesReceived()); + assertTrue(policyForwarder1.receivedPolicy(generatedPolicy1)); + assertTrue(policyForwarder1.receivedPolicy(generatedPolicy2)); + assertEquals(2, policyForwarder2.getNumberOfPoliciesReceived()); + assertTrue(policyForwarder2.receivedPolicy(generatedPolicy1)); + assertTrue(policyForwarder2.receivedPolicy(generatedPolicy2)); + } + + @Test(expected = PolicyDecodingException.class) + public void testInputReceivedNoSupportingDecoder() throws PolicyDecodingException, NoSuchFieldException, + SecurityException, IllegalArgumentException, IllegalAccessException { + AbstractReceptionHandler handler = new DummyReceptionHandler(); + + PolicyDecoder<PolicyInput, Policy> policyDecoder = new DummyDecoder(false, Collections.emptyList()); + DummyPolicyForwarder policyForwarder = new DummyPolicyForwarder(); + setUpPlugins(handler, Collections.singleton(policyDecoder), Collections.singleton(policyForwarder)); + + handler.inputReceived(new DummyPolicyInput()); + } + + @Test(expected = PolicyDecodingException.class) + public void testInputReceivedNoDecoder() throws PolicyDecodingException, NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + AbstractReceptionHandler handler = new DummyReceptionHandler(); + + DummyPolicyForwarder policyForwarder = new DummyPolicyForwarder(); + setUpPlugins(handler, Collections.emptySet(), Collections.singleton(policyForwarder)); + + handler.inputReceived(new DummyPolicyInput()); + } + + class DummyReceptionHandler extends AbstractReceptionHandler { + @Override + protected void initializeReception(String parameterGroupName) {} + + @Override + public void destroy() {} + } + + class DummyPolicyInput implements PolicyInput { + } + class DummyPolicy1 implements Policy { + } + class DummyPolicy2 implements Policy { + } + + public class DummyDecoder implements PolicyDecoder<PolicyInput, Policy> { + + private boolean canHandleValue; + private Collection<Policy> policesToReturn; + + public DummyDecoder(boolean canHandleValue, Collection<Policy> policesToReturn) { + this.canHandleValue = canHandleValue; + this.policesToReturn = policesToReturn; + } + + @Override + public boolean canHandle(PolicyInput policyInput) { + return canHandleValue; + } + + @Override + public Collection<Policy> decode(PolicyInput input) throws PolicyDecodingException { + return policesToReturn; + } + } + + public class DummyPolicyForwarder implements PolicyForwarder { + private int numberOfPoliciesReceived = 0; + private Collection<Policy> policiesReceived = new ArrayList<>(); + + @Override + public void forward(Collection<Policy> policies) throws PolicyForwardingException { + numberOfPoliciesReceived += policies.size(); + policiesReceived.addAll(policies); + } + + public int getNumberOfPoliciesReceived() { + return numberOfPoliciesReceived; + } + + public boolean receivedPolicy(Policy policy) { + return policiesReceived.contains(policy); + } + } + + /** + * Only needed until code is added for instantiating plugins from paramater file + */ + private void setUpPlugins(AbstractReceptionHandler receptionHandler, + Collection<PolicyDecoder<PolicyInput, Policy>> decoders, Collection<PolicyForwarder> forwarders) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + PluginHandler pluginHandler = new PluginHandler(""); + + Field decodersField = pluginHandler.getClass().getDeclaredField("policyDecoders"); + decodersField.setAccessible(true); + decodersField.set(pluginHandler, decoders); + + Field forwardersField = pluginHandler.getClass().getDeclaredField("policyForwarders"); + forwardersField.setAccessible(true); + forwardersField.set(pluginHandler, forwarders); + + Field pluginHandlerField = AbstractReceptionHandler.class.getDeclaredField("pluginHandler"); + pluginHandlerField.setAccessible(true); + pluginHandlerField.set(receptionHandler, pluginHandler); + } + +} |