From a9c7e7322eb09672c8dfba32503653d12e685543 Mon Sep 17 00:00:00 2001 From: Michael Mokry Date: Wed, 10 Apr 2019 09:53:44 -0500 Subject: XACML PDP DmaaP Deploy/UnDeploy Function 1. Added PDPUpdate listener 2. Added PDPUpdate Publisher 3. Added code to handle PdpUpdate messages and load policies being deployed 4. Modified Activator to register listener 5. Provided placeholder code to get policies from pdpx for return PdpStatus response to the PAP 6. Other minor modifications 7. Fix XacmlPdpApplicationManager to only load policy if supports policy type. 8. Checkstyle fixes 9. Updated applications to support loadPolicy(ToscaPolicy) and all the translators, JUnit tests. 10. Consolidated some duplicate code in the applications. Can probably do more in that area. 11. Fixed bug in Properties not really having a copy constructor. Change-Id: Ic29ad426061cbdb79c1339314667bb8ff8decb88 Issue-ID: POLICY-1451 Signed-off-by: Michael Mokry Signed-off-by: Pamela Dragosh --- .../pdpx/main/comm/XacmlPdpHearbeatPublisher.java | 86 ++++++++++++++++++++++ .../pdpx/main/comm/XacmlPdpHeartbeatPublisher.java | 83 --------------------- .../policy/pdpx/main/comm/XacmlPdpMessage.java | 54 +++++++++++++- .../pdpx/main/comm/XacmlPdpUpdatePublisher.java | 66 +++++++++++++++++ .../listeners/XacmlPdpStateChangeListener.java | 12 +-- .../comm/listeners/XacmlPdpUpdateListener.java | 62 ++++++++++++++++ .../pdpx/main/rest/XacmlPdpApplicationManager.java | 31 ++++++++ .../pdpx/main/startstop/XacmlPdpActivator.java | 18 ++++- 8 files changed, 319 insertions(+), 93 deletions(-) create mode 100644 main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java delete mode 100644 main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHeartbeatPublisher.java create mode 100644 main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java create mode 100644 main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java (limited to 'main') diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java new file mode 100644 index 00000000..0dc8bf54 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHearbeatPublisher.java @@ -0,0 +1,86 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm; + +import java.util.Timer; +import java.util.TimerTask; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpStateChange; +import org.onap.policy.models.pdp.enums.PdpState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XacmlPdpHearbeatPublisher extends TimerTask { + + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpHearbeatPublisher.class); + + private Timer timer; + private XacmlPdpMessage heartbeatMessage; + private Object message; + private static TopicSinkClient topicSinkClient; + private static volatile boolean alive = false; + public static PdpState pdpState; + + + /** + * Constructor for instantiating XacmlPdpPublisher. + * + * @param message of the PDP + * @param topicSinkClient used to send heartbeat message + */ + public XacmlPdpHearbeatPublisher(TopicSinkClient topicSinkClient, PdpStateChange message) { + this.message = message; + this.pdpState = message.getState(); + this.topicSinkClient = topicSinkClient; + this.heartbeatMessage = new XacmlPdpMessage(); + timer = new Timer(false); + timer.scheduleAtFixedRate(this, 0, 60000); // time interval temp hard coded now but will be parameterized + setAlive(true); + } + + @Override + public void run() { + topicSinkClient.send(heartbeatMessage.formatHeartbeatMessage((PdpStateChange) message)); + LOGGER.info("Sending Xacml PDP heartbeat to the PAP"); + } + + /** + * Method to terminate the heartbeat. + */ + public void terminate() { + timer.cancel(); + timer.purge(); + setAlive(false); + } + + public void updateInternalState(PdpState state) { + ((PdpStateChange) this.message).setState(state); + this.pdpState = state; + } + + public static boolean isAlive() { + return alive; + } + + public void setAlive(boolean alive) { + this.alive = alive; + } +} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHeartbeatPublisher.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHeartbeatPublisher.java deleted file mode 100644 index fe730208..00000000 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpHeartbeatPublisher.java +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019 AT&T 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.pdpx.main.comm; - -import java.util.Timer; -import java.util.TimerTask; -import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; -import org.onap.policy.models.pdp.enums.PdpState; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class XacmlPdpHeartbeatPublisher extends TimerTask { - - private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpHeartbeatPublisher.class); - - private TopicSinkClient topicSinkClient; - private Timer timer; - private XacmlPdpMessage heartbeatMessage; - private PdpState pdpState; - - private static volatile boolean alive = false; - - /** - * Constructor for instantiating XacmlPdpHeartbeatPublisher. - * - * @param state of the PDP - * @param topicSinkClient used to send heartbeat message - */ - public XacmlPdpHeartbeatPublisher(TopicSinkClient topicSinkClient, PdpState state) { - this.topicSinkClient = topicSinkClient; - this.heartbeatMessage = new XacmlPdpMessage(); - this.pdpState = state; - timer = new Timer(false); - timer.scheduleAtFixedRate(this, 0, 60000); // time interval temp hard coded now but will be parameterized - setAlive(true); - } - - @Override - public void run() { - topicSinkClient.send(heartbeatMessage.formatStatusMessage(pdpState)); - LOGGER.info("Sending Xacml PDP heartbeat to the PAP"); - } - - /** - * Method to terminate the heartbeat. - */ - public void terminate() { - timer.cancel(); - timer.purge(); - setAlive(false); - } - - public void updateInternalState(PdpState state) { - this.pdpState = state; - } - - public static boolean isAlive() { - return alive; - } - - public void setAlive(boolean alive) { - this.alive = alive; - } - -} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java index 233bd7f7..809e43d0 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpMessage.java @@ -24,7 +24,9 @@ package org.onap.policy.pdpx.main.comm; import java.net.UnknownHostException; import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.pdp.enums.PdpHealthStatus; import org.onap.policy.models.pdp.enums.PdpState; import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; @@ -42,7 +44,6 @@ public class XacmlPdpMessage { * * @param state of the PDP * @return status message of the PDP - * @throws UnknownHostException if cannot get hostname */ public PdpStatus formatStatusMessage(PdpState state) { PdpStatus status = new PdpStatus(); @@ -63,4 +64,55 @@ public class XacmlPdpMessage { return status; } + + /** + * Method used to format the heartbeat status message. + * + * @param message PdpStateChange message received from the PAP + * @return status message of the PDP + */ + public PdpStatus formatHeartbeatMessage(PdpStateChange message) { + PdpStatus status = new PdpStatus(); + status.setName(NetworkUtil.getHostname()); + + if (XacmlPdpActivator.getCurrent().isAlive()) { + status.setHealthy(PdpHealthStatus.HEALTHY); + } else { + status.setHealthy(PdpHealthStatus.NOT_HEALTHY); + } + + status.setPdpType("xacml"); + status.setState(message.getState()); + status.setPdpGroup(message.getPdpGroup()); + status.setPdpSubgroup(message.getPdpSubgroup()); + status.setSupportedPolicyTypes(XacmlPdpApplicationManager.getToscaPolicyTypeIdents()); + + return status; + } + + /** + * Method used to format the PdpUpdate message. + * + * @param message PdpUpdate message that was received from the PAP + * @return status message of the PDP + */ + public PdpStatus formatPdpUpdateMessage(PdpUpdate message, PdpState state) { + PdpStatus status = new PdpStatus(); + status.setName(NetworkUtil.getHostname()); + + if (XacmlPdpActivator.getCurrent().isAlive()) { + status.setHealthy(PdpHealthStatus.HEALTHY); + } else { + status.setHealthy(PdpHealthStatus.NOT_HEALTHY); + } + + status.setPdpType("xacml"); + status.setState(state); + status.setPdpGroup(message.getPdpGroup()); + status.setPdpSubgroup(message.getPdpSubgroup()); + status.setSupportedPolicyTypes(XacmlPdpApplicationManager.getToscaPolicyTypeIdents()); + status.setPolicies(XacmlPdpApplicationManager.getToscaPolicies()); + + return status; + } } diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java new file mode 100644 index 00000000..716421c7 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/XacmlPdpUpdatePublisher.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm; + +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.models.pdp.concepts.PdpStatus; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.pdpx.main.rest.XacmlPdpApplicationManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XacmlPdpUpdatePublisher { + + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpUpdatePublisher.class); + + private XacmlPdpUpdatePublisher() { + throw new IllegalStateException("Please do not create private instance of XacmlPdpUpdatePublisher"); + } + + /** + * Handle the PDP Update message. + * + * @param message Incoming message + * @param client TopicSinkClient + */ + public static void handlePdpUpdate(PdpUpdate message, TopicSinkClient client) { + + if (!message.getPolicies().isEmpty() || message.getPolicies() != null) { + // Load the policies on PDP applications + for (ToscaPolicy toscaPolicy : message.getPolicies()) { + XacmlPdpApplicationManager.loadDeployedPolicy(toscaPolicy); + } + } + + XacmlPdpMessage updatePdpMessage = new XacmlPdpMessage(); + PdpStatus statusMessage = updatePdpMessage.formatPdpUpdateMessage(message, XacmlPdpHearbeatPublisher.pdpState); + sendPdpUpdate(statusMessage, client); + } + + private static void sendPdpUpdate(PdpStatus status, TopicSinkClient client) { + // Send PdpStatus Change to PAP + if (!client.send(status)) { + LOGGER.error("failed to send to topic sink {}", client.getTopic()); + } + } + +} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java index f5b2fbfa..3e24c3fe 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpStateChangeListener.java @@ -28,7 +28,7 @@ import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.enums.PdpState; -import org.onap.policy.pdpx.main.comm.XacmlPdpHeartbeatPublisher; +import org.onap.policy.pdpx.main.comm.XacmlPdpHearbeatPublisher; import org.onap.policy.pdpx.main.comm.XacmlPdpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +39,7 @@ public class XacmlPdpStateChangeListener extends ScoListener { private TopicSinkClient client; - private XacmlPdpHeartbeatPublisher heartbeat; + private XacmlPdpHearbeatPublisher heartbeat; /** * Constructs the object. @@ -48,7 +48,9 @@ public class XacmlPdpStateChangeListener extends ScoListener { */ public XacmlPdpStateChangeListener(TopicSinkClient client) { super(PdpStateChange.class); - heartbeat = new XacmlPdpHeartbeatPublisher(client, PdpState.PASSIVE); + PdpStateChange message = new PdpStateChange(); + message.setState(PdpState.PASSIVE); + heartbeat = new XacmlPdpHearbeatPublisher(client, message); this.client = client; } @@ -66,10 +68,10 @@ public class XacmlPdpStateChangeListener extends ScoListener { } // Update the heartbeat internal state if publisher is running else create new publisher - if (XacmlPdpHeartbeatPublisher.isAlive()) { + if (XacmlPdpHearbeatPublisher.isAlive()) { heartbeat.updateInternalState(message.getState()); } else { - heartbeat = new XacmlPdpHeartbeatPublisher(client, message.getState()); + heartbeat = new XacmlPdpHearbeatPublisher(client, message); } } catch (final Exception e) { diff --git a/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java new file mode 100644 index 00000000..69f96a05 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pdpx/main/comm/listeners/XacmlPdpUpdateListener.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pdpx.main.comm.listeners; + +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.onap.policy.common.endpoints.listeners.ScoListener; +import org.onap.policy.common.utils.coder.StandardCoderObject; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.pdpx.main.comm.XacmlPdpUpdatePublisher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class XacmlPdpUpdateListener extends ScoListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpStateChangeListener.class); + + private TopicSinkClient client; + + /** + * Constructs the object. + * + * @param client used to send back response after receiving state change message + */ + public XacmlPdpUpdateListener(TopicSinkClient client) { + super(PdpUpdate.class); + this.client = client; + } + + @Override + public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, PdpUpdate message) { + + try { + + LOGGER.info("PDP update message has been received from the PAP - {}", message.toString()); + XacmlPdpUpdatePublisher.handlePdpUpdate(message, client); + + } catch (final Exception e) { + LOGGER.error("failed to handle the PDP Update message.", e); + } + + } + +} diff --git a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java index a5e1d030..09805593 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/rest/XacmlPdpApplicationManager.java @@ -30,6 +30,8 @@ import java.util.List; import java.util.Map; import java.util.ServiceLoader; import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException; import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider; @@ -43,6 +45,7 @@ public class XacmlPdpApplicationManager { private static ServiceLoader applicationLoader; private static Map providerActionMap = new HashMap<>(); private static List toscaPolicyTypeIdents = new ArrayList<>(); + private static List toscaPolicies = new ArrayList<>(); private XacmlPdpApplicationManager() { super(); @@ -116,6 +119,34 @@ public class XacmlPdpApplicationManager { return toscaPolicyTypeIdents; } + /** + * Finds the appropriate application and loads the policy. + * + * @param policy Incoming policy + */ + public static void loadDeployedPolicy(ToscaPolicy policy) { + + for (XacmlApplicationServiceProvider application : applicationLoader) { + try { + // + // There should be only one application per policytype. We can + // put more logic surrounding enforcement of that later. For now, + // just use the first one found. + // + if (application.canSupportPolicyType(policy.getTypeIdentifier())) { + application.loadPolicy(policy); + return; + } + } catch (XacmlApplicationException e) { + LOGGER.error("Failed to load the Tosca Policy", e); + } + } + } + + public static List getToscaPolicies() { + return toscaPolicies; + } + /** * Returns the current count of policy types supported. This could be misleading a bit * as some applications can support wildcard of policy types. Eg. onap.Monitoring.* as diff --git a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java index 9695c7b9..330fbd67 100644 --- a/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java +++ b/main/src/main/java/org/onap/policy/pdpx/main/startstop/XacmlPdpActivator.java @@ -38,6 +38,7 @@ import org.onap.policy.pdpx.main.PolicyXacmlPdpRuntimeException; import org.onap.policy.pdpx.main.comm.XacmlPdpMessage; import org.onap.policy.pdpx.main.comm.XacmlPdpPapRegistration; import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpStateChangeListener; +import org.onap.policy.pdpx.main.comm.listeners.XacmlPdpUpdateListener; import org.onap.policy.pdpx.main.parameters.XacmlPdpParameterGroup; import org.onap.policy.pdpx.main.rest.XacmlPdpRestServer; import org.slf4j.Logger; @@ -65,16 +66,20 @@ public class XacmlPdpActivator extends ServiceManagerContainer { /** * Listens for messages on the topic, decodes them into a {@link PdpStatus} message, and then - * dispatches them to {@link #pdpUpdateListener}. + * dispatches them to appropriate listener. */ private final MessageTypeDispatcher msgDispatcher; /** - * Listens for {@link PdpUpdate} messages and then routes them to the listener associated with the - * ID of the originating request. + * Listens for {@link PdpStateChange} messages from the PAP. */ private final XacmlPdpStateChangeListener pdpStateChangeListener; + /** + * Listens for {@link PdpUpdate} messages from the PAP. + */ + private final XacmlPdpUpdateListener pdpUpdateListener; + /** * The current activator. */ @@ -101,6 +106,7 @@ public class XacmlPdpActivator extends ServiceManagerContainer { this.xacmlPdpParameterGroup = xacmlPdpParameterGroup; this.msgDispatcher = new MessageTypeDispatcher(MSG_TYPE_NAMES); this.pdpStateChangeListener = new XacmlPdpStateChangeListener(sinkClient); + this.pdpUpdateListener = new XacmlPdpUpdateListener(sinkClient); this.register = new XacmlPdpPapRegistration(sinkClient); this.message = new XacmlPdpMessage(); } catch (RuntimeException | TopicSinkClientException e) { @@ -113,10 +119,14 @@ public class XacmlPdpActivator extends ServiceManagerContainer { addAction("XACML PDP parameters", () -> ParameterService.register(xacmlPdpParameterGroup), () -> ParameterService.deregister(xacmlPdpParameterGroup.getName())); - addAction("Request ID Dispatcher", + addAction("PdpStateChange Dispatcher", () -> msgDispatcher.register(PdpMessageType.PDP_STATE_CHANGE.name(), this.pdpStateChangeListener), () -> msgDispatcher.unregister(PdpMessageType.PDP_STATE_CHANGE.name())); + addAction("PdpUpdate Dispatcher", + () -> msgDispatcher.register(PdpMessageType.PDP_UPDATE.name(), this.pdpUpdateListener), + () -> msgDispatcher.unregister(PdpMessageType.PDP_UPDATE.name())); + addAction("Message Dispatcher", () -> registerMsgDispatcher(), () -> unregisterMsgDispatcher()); -- cgit 1.2.3-korg