diff options
Diffstat (limited to 'sdnr/wt/netconfnode-state-service/provider')
5 files changed, 163 insertions, 46 deletions
diff --git a/sdnr/wt/netconfnode-state-service/provider/pom.xml b/sdnr/wt/netconfnode-state-service/provider/pom.xml index 927c709d0..fe374bea8 100644 --- a/sdnr/wt/netconfnode-state-service/provider/pom.xml +++ b/sdnr/wt/netconfnode-state-service/provider/pom.xml @@ -22,13 +22,14 @@ ~ ============LICENSE_END======================================================= ~ --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.onap.ccsdk.parent</groupId> <artifactId>binding-parent</artifactId> - <version>2.4.0</version> + <version>2.4.1-SNAPSHOT</version> <relativePath/> </parent> @@ -87,6 +88,11 @@ <groupId>org.opendaylight.mdsal</groupId> <artifactId>mdsal-singleton-common-api</artifactId> <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.code.findbugs</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> </dependency> <!-- md-sal --> <dependency> @@ -105,11 +111,23 @@ <artifactId>config</artifactId> <scope>provided</scope> </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + <scope>provided</scope> + </dependency> <!-- wt --> <dependency> <groupId>${project.groupId}</groupId> <artifactId>sdnr-wt-common</artifactId> <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-data-provider-model</artifactId> + <version>${project.version}</version> + <scope>provided</scope> </dependency> <dependency> <groupId>${project.groupId}</groupId> diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java index 8605274db..988dbd257 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java @@ -18,18 +18,16 @@ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.annotation.Nullable; import org.eclipse.jdt.annotation.NonNull; import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; +import org.onap.ccsdk.features.sdnr.wt.common.threading.GenericRunnableFactory; +import org.onap.ccsdk.features.sdnr.wt.common.threading.KeyBasedThreadpool; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.StatusChangedHandler.StatusKey; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; @@ -76,7 +74,6 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.parser.api.YangParserException; import org.opendaylight.yangtools.yang.parser.api.YangParserFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -102,6 +99,7 @@ public class NetconfNodeStateServiceImpl // Name of ODL controller NETCONF instance private static final NodeId CONTROLLER = new NodeId("controller-config"); + private static final int ASYNC_EXECUTION_POOLSIZE = 20; // -- OSGi services, provided private DataBroker dataBroker; @@ -147,7 +145,8 @@ public class NetconfNodeStateServiceImpl private String clusterName; /** nodeId to threadPool (size=1) for datatreechange handling) **/ - private final Map<String, ExecutorService> handlingPool; + // private final Map<String, ExecutorService> handlingPool; + private KeyBasedThreadpool<NodeId, NetconfChangeDataHolder> handlingPool; private boolean handleDataTreeAsync; @@ -177,10 +176,8 @@ public class NetconfNodeStateServiceImpl this.netconfNodeStateListenerList = new CopyOnWriteArrayList<>(); this.vesNotificationListenerList = new CopyOnWriteArrayList<>(); this.accessorManager = null; - this.handlingPool = new HashMap<>(); - + this.handlingPool = null; } - public void setDataBroker(DataBroker dataBroker) { this.dataBroker = dataBroker; } @@ -221,13 +218,17 @@ public class NetconfNodeStateServiceImpl this.bindingNormalizedNodeSerializer = bindingNormalizedNodeSerializer; } - /** Blueprint initialization - * @throws YangParserException **/ + /** + * Blueprint initialization + * + * @throws YangParserException + **/ public void init() { LOG.info("Session Initiated start {}", APPLICATION_NAME); this.domContext = new DomContext(this.yangParserFactory, this.bindingNormalizedNodeSerializer); - this.netconfCommunicatorManager = new NetconfCommunicatorManager(mountPointService, domMountPointService, domContext); + this.netconfCommunicatorManager = + new NetconfCommunicatorManager(mountPointService, domMountPointService, domContext); this.accessorManager = new NetconfAccessorManager(netconfCommunicatorManager, domContext, this); // Start RPC Service this.rpcApiService = new NetconfnodeStateServiceRpcApiImpl(rpcProviderRegistry, vesNotificationListenerList); @@ -257,7 +258,19 @@ public class NetconfNodeStateServiceImpl listenerL1 = dataBroker.registerDataTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new L1()); listenerL2 = dataBroker.registerDataTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new L2()); - + this.handlingPool = new KeyBasedThreadpool<NodeId, NetconfChangeDataHolder>(this.config.getAsyncHandlingPoolsize(), 1, + new GenericRunnableFactory<>() { + public Runnable create(final NodeId key, final NetconfChangeDataHolder arg) { + return new Runnable() { + + @Override + public void run() { + NetconfNodeStateServiceImpl.this.handleDataTreeChange(arg.root, key, + arg.modificationTyp); + } + }; + }; + }); this.initializationSuccessful = true; LOG.info("Session Initiated end. Initialization done {}", initializationSuccessful); @@ -270,7 +283,7 @@ public class NetconfNodeStateServiceImpl } public DomContext getDomContext() { - return Objects.requireNonNull(domContext, "Initialization not completed for domContext" ); + return Objects.requireNonNull(domContext, "Initialization not completed for domContext"); } public DataBroker getDataBroker() { @@ -282,7 +295,7 @@ public class NetconfNodeStateServiceImpl } public NetconfnodeStateServiceRpcApiImpl getNetconfnodeStateServiceRpcApiImpl() { - return Objects.requireNonNull(rpcApiService, "Initialization not completed for rpcApiService" ); + return Objects.requireNonNull(rpcApiService, "Initialization not completed for rpcApiService"); } @Override @@ -418,19 +431,19 @@ public class NetconfNodeStateServiceImpl LOG.info("isNetconfNodeMaster indication {} for mountpoint {}", isNetconfNodeMaster, mountPointNodeName); if (isNetconfNodeMaster) { NetconfAccessor acessor = accessorManager.getAccessor(nNodeId, netconfNode); - /* - * --> Call Listers for onConnect() Indication - for (all) - */ - netconfNodeConnectListenerList.forEach(item -> { - try { - item.onEnterConnected(acessor); - } catch (Exception e) { - LOG.info("Exception during onEnterConnected listener call", e); - } - }); + /* + * --> Call Listers for onConnect() Indication + for (all) + */ + netconfNodeConnectListenerList.forEach(item -> { + try { + item.onEnterConnected(acessor); + } catch (Exception e) { + LOG.info("Exception during onEnterConnected listener call", e); + } + }); - LOG.info("Connect indication forwarded for {}", mountPointNodeName); + LOG.info("Connect indication forwarded for {}", mountPointNodeName); } } @@ -565,18 +578,9 @@ public class NetconfNodeStateServiceImpl if (modificationTyp == null) { LOG.warn("L1 empty modification type"); } else { + LOG.trace("handle data tree change with async={}",this.handleDataTreeAsync); if (this.handleDataTreeAsync) { - ExecutorService executor = this.handlingPool.getOrDefault(nodeId.getValue(), null); - if (executor == null) { - executor = Executors.newFixedThreadPool(5); - this.handlingPool.put(nodeId.getValue(), executor); - } - executor.execute(new Thread() { - @Override - public void run() { - handleDataTreeChange(root, nodeId, modificationTyp); - } - }); + this.handlingPool.execute(nodeId, new NetconfChangeDataHolder(root, modificationTyp)); } else { handleDataTreeChange(root, nodeId, modificationTyp); @@ -683,7 +687,20 @@ public class NetconfNodeStateServiceImpl @Override public void onConfigChanged() { this.handleDataTreeAsync = this.config.handleAsync(); + //setting poolsize is not possible atm + //this.handlingPool.setPoolSize(this.config.getAsyncHandlingPoolsize()); } + public class NetconfChangeDataHolder { + + protected final DataObjectModification<Node> root; + protected final ModificationType modificationTyp; + + public NetconfChangeDataHolder(DataObjectModification<Node> root, ModificationType modificationTyp) { + this.root = root; + this.modificationTyp = modificationTyp; + } + + } } diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java index af095372d..c781575a3 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java @@ -21,6 +21,7 @@ */ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf; +import java.util.Optional; import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration; import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; import org.slf4j.Logger; @@ -34,9 +35,11 @@ public class NetconfStateConfig implements Configuration { public static final String SECTION_MARKER_NCSTATE = "netconfstate"; private static final String PROPERTY_KEY_HANDLEASYNC = "asynchandling"; - - private static final Object DEFAULT_VALUE_TRUSTALLCERTS = false; - + private static final String PROPERTY_KEY_POOLSIZE= "poolsize"; + private static final String DEFAULT_HANDLEASYNC = "${SDNR_ASYNC_HANDLING}"; + private static final String DEFAULT_POOLSIZE = "${SDNR_ASYNC_POOLSIZE}"; + private static final boolean DEFAULT_HANDLEASYNC_IFNOTSET = false; + private static final int DEFAULT_POOLSIZE_IFNOTSET = 20; private final ConfigurationFileRepresentation configuration; @@ -50,7 +53,18 @@ public class NetconfStateConfig implements Configuration { public boolean handleAsync() { - return configuration.getPropertyBoolean(SECTION_MARKER_NCSTATE, PROPERTY_KEY_HANDLEASYNC); + final String s = this.configuration.getProperty(SECTION_MARKER_NCSTATE, PROPERTY_KEY_HANDLEASYNC); + if(s!= null && !s.isBlank()) { + return "true".equals(s); + } + return DEFAULT_HANDLEASYNC_IFNOTSET; + } + public int getAsyncHandlingPoolsize() { + Optional<Long> optional = this.configuration.getPropertyLong(SECTION_MARKER_NCSTATE,PROPERTY_KEY_POOLSIZE); + if(optional.isPresent()) { + return optional.get().intValue(); + } + return DEFAULT_POOLSIZE_IFNOTSET; } @Override @@ -62,7 +76,9 @@ public class NetconfStateConfig implements Configuration { public synchronized void defaults() { // Add default if not available configuration.setPropertyIfNotAvailable(SECTION_MARKER_NCSTATE, PROPERTY_KEY_HANDLEASYNC, - DEFAULT_VALUE_TRUSTALLCERTS); + DEFAULT_HANDLEASYNC); + configuration.setPropertyIfNotAvailable(SECTION_MARKER_NCSTATE, PROPERTY_KEY_POOLSIZE, + DEFAULT_POOLSIZE); } } diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/NetconfnodeStateServiceRpcApiImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/NetconfnodeStateServiceRpcApiImpl.java index 896f010d8..818f8a370 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/NetconfnodeStateServiceRpcApiImpl.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/NetconfnodeStateServiceRpcApiImpl.java @@ -30,7 +30,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfn import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationOutput; import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.opendaylight.yangtools.yang.common.ErrorType; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; @@ -83,7 +83,7 @@ public class NetconfnodeStateServiceRpcApiImpl implements NetconfnodeStateServic try { GetStatusOutputBuilder outputBuilder = new GetStatusOutputBuilder(); getStatusCallback.getStatus(input); - result = RpcResultBuilder.success(outputBuilder); + result = RpcResultBuilder.success(outputBuilder.build()); } catch (Exception e) { result = RpcResultBuilder.failed(); result.withError(ErrorType.APPLICATION, "Exception", e); diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestConfig.java new file mode 100644 index 000000000..d66508f1b --- /dev/null +++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestConfig.java @@ -0,0 +1,66 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH 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.ccsdk.features.sdnr.wt.netconfnodestateservice.test; + +import static org.junit.Assert.assertTrue; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes.Section; +import org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes.Section.EnvGetter; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.NetconfStateConfig; + +public class TestConfig { + + private static final String FILENAME="test.config"; + @BeforeClass + @AfterClass + public static void clearFiles(){ + try { + Files.deleteIfExists(new File(FILENAME).toPath()); + } catch (IOException e) { + + } + } + @Test + public void test() { + + ConfigurationFileRepresentation cfg = new ConfigurationFileRepresentation(FILENAME); + NetconfStateConfig config = new NetconfStateConfig(cfg); + + Section.setEnvGetter(new EnvGetter() { + + @Override + public String getenv(String env) { + if("SDNR_ASYNC_HANDLING".equals(env)) { + return "true"; + } + return null; + } + }); + assertTrue(config.handleAsync()); + } +} |