Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/mate/model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
<groupId>org.opennms</groupId>
<artifactId>opennms-dao-api</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.opennms.core.mate</groupId>
<artifactId>org.opennms.core.mate.api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2019 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/

package org.opennms.core.mate.model;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.opennms.core.mate.api.EntityScopeProvider;
import org.opennms.core.mate.api.Scope;

import java.net.InetAddress;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

public class CachedEntityScopeProviderImpl implements EntityScopeProvider {

private final static class Tuple<A, B> {
final A a;
final B b;

public Tuple(A a, B b) {
this.a = a;
this.b = b;
}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Tuple<?, ?> tuple = (Tuple<?, ?>) o;
return Objects.equals(a, tuple.a) && Objects.equals(b, tuple.b);
}

@Override
public int hashCode() {
return Objects.hash(a, b);
}
}

private final static class Triple<A, B, C> {
final A a;
final B b;
final C c;

public Triple(A a, B b, C c) {
this.a = a;
this.b = b;
this.c = c;
}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Triple<?, ?, ?> triple = (Triple<?, ?, ?>) o;
return Objects.equals(a, triple.a) && Objects.equals(b, triple.b) && Objects.equals(c, triple.c);
}

@Override
public int hashCode() {
return Objects.hash(a, b, c);
}
}

private final LoadingCache<Integer, Scope> nodeScopes;
private final LoadingCache<Tuple<Integer, String>, Scope> interfaceScopes;
private final LoadingCache<Tuple<Integer, Integer>, Scope> interfaceScopesByIfIndex;
private final LoadingCache<Triple<Integer, InetAddress, String>, Scope> serviceScopes;
private final EntityScopeProvider entityScopeProvider;

public CachedEntityScopeProviderImpl(final EntityScopeProvider entityScopeProvider, final long expireAfterWrite, final long expireAfterAccess, final long refreshAfterWrite, final long maximumSize) {
this.entityScopeProvider = Objects.requireNonNull(entityScopeProvider);

this.nodeScopes = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
@Override
public Scope load(final Integer integer) {
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForNode(integer);
}
});

this.interfaceScopes = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
@Override
public Scope load(final Tuple<Integer, String> tuple) {
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForInterface(tuple.a, tuple.b);
}
});

this.interfaceScopesByIfIndex = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
@Override
public Scope load(final Tuple<Integer, Integer> tuple) {
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForInterfaceByIfIndex(tuple.a, tuple.b);
}
});

this.serviceScopes = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
@Override
public Scope load(final Triple<Integer, InetAddress, String> triple) {
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForService(triple.a, triple.b, triple.c);
}
});
}

private <K, V> LoadingCache<K, V> createCache(final long expireAfterWrite, final long expireAfterAccess, final long refreshAfterWrite, final long maximumSize, CacheLoader<K, V> loader) {
final CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();

if (expireAfterWrite >= 0) {
cacheBuilder.expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS);
}

if (expireAfterAccess >= 0) {
cacheBuilder.expireAfterAccess(expireAfterAccess, TimeUnit.SECONDS);
}

if (refreshAfterWrite >= 0) {
cacheBuilder.refreshAfterWrite(refreshAfterWrite, TimeUnit.SECONDS);
}

if (maximumSize > 0) {
cacheBuilder.maximumSize(maximumSize);
}

return cacheBuilder.build(loader);
}

@Override
public Scope getScopeForScv() {
return entityScopeProvider.getScopeForScv();
}

@Override
public Scope getScopeForNode(final Integer nodeId) {
return nodeScopes.getUnchecked(nodeId);
}

@Override
public Scope getScopeForInterface(final Integer nodeId, final String ipAddress) {
return interfaceScopes.getUnchecked(new Tuple<>(nodeId, ipAddress));
}

@Override
public Scope getScopeForInterfaceByIfIndex(final Integer nodeId, final int ifIndex) {
return interfaceScopesByIfIndex.getUnchecked(new Tuple<>(nodeId, ifIndex));
}

@Override
public Scope getScopeForService(final Integer nodeId, final InetAddress ipAddress, final String serviceName) {
return serviceScopes.getUnchecked(new Triple<>(nodeId, ipAddress, serviceName));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2019 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/

package org.opennms.core.mate.model;

import org.junit.Before;
import org.junit.runner.RunWith;
import org.opennms.core.test.OpenNMSJUnit4ClassRunner;
import org.opennms.core.test.db.annotations.JUnitTemporaryDatabase;
import org.opennms.test.JUnitConfigurationEnvironment;
import org.springframework.test.context.ContextConfiguration;

@RunWith(OpenNMSJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/META-INF/opennms/applicationContext-commonConfigs.xml",
"classpath:/META-INF/opennms/applicationContext-soa.xml",
"classpath:/META-INF/opennms/applicationContext-mockDao.xml",
"classpath:/META-INF/opennms/applicationContext-databasePopulator.xml",
"classpath:/META-INF/opennms/applicationContext-entity-scope-provider.xml",
"classpath*:/META-INF/opennms/component-dao.xml",
})
@JUnitConfigurationEnvironment
@JUnitTemporaryDatabase
public class CachedEntityScopeProviderIT extends EntityScopeProviderIT {

@Before
@Override
public void setup() {
this.populator.populateDatabase();
this.provider = new CachedEntityScopeProviderImpl(provider, 0, -1, -1, -1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ public class EntityScopeProviderIT {
private SessionUtils sessionUtils;

@Autowired
private DatabasePopulator populator;
protected DatabasePopulator populator;

@Autowired
private EntityScopeProvider provider;
protected EntityScopeProvider provider;

@Autowired
private SecureCredentialsVault secureCredentialsVault;
Expand Down Expand Up @@ -182,7 +182,7 @@ public final void testScopeProviders() {
node.getMetaData().add(metaData);
this.populator.getNodeDao().saveOrUpdate(node);

// get an scope provider
// get a scope provider
final ScopeProvider scope = this.provider.getScopeProviderForNode(this.populator.getNode1().getId());

// this will retrieve the meta-data set before
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.3.0">
<reference id="threshdDao" interface="org.opennms.netmgt.config.dao.thresholding.api.ReadableThreshdDao"/>
<reference id="thresholdingDao" interface="org.opennms.netmgt.config.dao.thresholding.api.ReadableThresholdingDao"/>
<reference id="pollOutagesDao" interface="org.opennms.netmgt.config.dao.outages.api.ReadablePollOutagesDao"/>
Expand All @@ -17,13 +17,32 @@
<property name="sessionUtils" ref="sessionUtils"/>
<property name="scv" ref="secureCredentialsVault"/>
</bean>


<cm:property-placeholder id="org.opennms.netmgt.threshd.metadata.cache"
persistent-id="org.opennms.netmgt.threshd.metadata.cache"
update-strategy="reload">
<cm:default-properties>
<cm:property name="expireAfterWrite" value="600"/>
<cm:property name="expireAfterAccess" value="-1"/>
<cm:property name="refreshAfterWrite" value="-1"/>
<cm:property name="maximumSize" value="-1"/>
</cm:default-properties>
</cm:property-placeholder>

<bean id="cachedEntityScopeProvider" class="org.opennms.core.mate.model.CachedEntityScopeProviderImpl">
<argument ref="entityScopeProvider"/>
<argument value="${expireAfterWrite}"/>
<argument value="${expireAfterAccess}"/>
<argument value="${refreshAfterWrite}"/>
<argument value="${maximumSize}"/>
</bean>

<bean id="thresholdingSetPersister" class="org.opennms.netmgt.threshd.DefaultThresholdingSetPersister">
<property name="threshdDao" ref="threshdDao"/>
<property name="thresholdingDao" ref="thresholdingDao"/>
<property name="pollOutagesDao" ref="pollOutagesDao"/>
<property name="ifLabelDao" ref="ifLabelDao"/>
<property name="entityScopeProvider" ref="entityScopeProvider"/>
<property name="entityScopeProvider" ref="cachedEntityScopeProvider"/>
</bean>

<bean id="thresholdStateMonitor" class="org.opennms.netmgt.threshd.BlobStoreAwareMonitor">
Expand Down