Skip to content

Commit e0d66a9

Browse files
committed
NMS-19537: Using metadata cache for thresholding
1 parent 6c48289 commit e0d66a9

File tree

5 files changed

+259
-6
lines changed

5 files changed

+259
-6
lines changed

core/mate/model/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
<groupId>org.opennms</groupId>
3232
<artifactId>opennms-dao-api</artifactId>
3333
</dependency>
34+
<dependency>
35+
<groupId>com.google.guava</groupId>
36+
<artifactId>guava</artifactId>
37+
</dependency>
3438
<dependency>
3539
<groupId>org.opennms.core.mate</groupId>
3640
<artifactId>org.opennms.core.mate.api</artifactId>
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*******************************************************************************
2+
* This file is part of OpenNMS(R).
3+
*
4+
* Copyright (C) 2019 The OpenNMS Group, Inc.
5+
* OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc.
6+
*
7+
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
8+
*
9+
* OpenNMS(R) is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as published
11+
* by the Free Software Foundation, either version 3 of the License,
12+
* or (at your option) any later version.
13+
*
14+
* OpenNMS(R) is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with OpenNMS(R). If not, see:
21+
* http://www.gnu.org/licenses/
22+
*
23+
* For more information contact:
24+
* OpenNMS(R) Licensing <license@opennms.org>
25+
* http://www.opennms.org/
26+
* http://www.opennms.com/
27+
*******************************************************************************/
28+
29+
package org.opennms.core.mate.model;
30+
31+
import com.google.common.cache.CacheBuilder;
32+
import com.google.common.cache.CacheLoader;
33+
import com.google.common.cache.LoadingCache;
34+
import org.opennms.core.mate.api.EntityScopeProvider;
35+
import org.opennms.core.mate.api.Scope;
36+
37+
import java.net.InetAddress;
38+
import java.util.Objects;
39+
import java.util.concurrent.TimeUnit;
40+
41+
public class CachedEntityScopeProviderImpl implements EntityScopeProvider {
42+
43+
private final static class Tuple<A, B> {
44+
final A a;
45+
final B b;
46+
47+
public Tuple(A a, B b) {
48+
this.a = a;
49+
this.b = b;
50+
}
51+
52+
@Override
53+
public boolean equals(Object o) {
54+
if (o == null || getClass() != o.getClass()) return false;
55+
Tuple<?, ?> tuple = (Tuple<?, ?>) o;
56+
return Objects.equals(a, tuple.a) && Objects.equals(b, tuple.b);
57+
}
58+
59+
@Override
60+
public int hashCode() {
61+
return Objects.hash(a, b);
62+
}
63+
}
64+
65+
private final static class Triple<A, B, C> {
66+
final A a;
67+
final B b;
68+
final C c;
69+
70+
public Triple(A a, B b, C c) {
71+
this.a = a;
72+
this.b = b;
73+
this.c = c;
74+
}
75+
76+
@Override
77+
public boolean equals(Object o) {
78+
if (o == null || getClass() != o.getClass()) return false;
79+
Triple<?, ?, ?> triple = (Triple<?, ?, ?>) o;
80+
return Objects.equals(a, triple.a) && Objects.equals(b, triple.b) && Objects.equals(c, triple.c);
81+
}
82+
83+
@Override
84+
public int hashCode() {
85+
return Objects.hash(a, b, c);
86+
}
87+
}
88+
89+
private final LoadingCache<Integer, Scope> nodeScopes;
90+
private final LoadingCache<Tuple<Integer, String>, Scope> interfaceScopes;
91+
private final LoadingCache<Tuple<Integer, Integer>, Scope> interfaceScopesByIfIndex;
92+
private final LoadingCache<Triple<Integer, InetAddress, String>, Scope> serviceScopes;
93+
private final EntityScopeProvider entityScopeProvider;
94+
95+
public CachedEntityScopeProviderImpl(final EntityScopeProvider entityScopeProvider, final long expireAfterWrite, final long expireAfterAccess, final long refreshAfterWrite, final long maximumSize) {
96+
this.entityScopeProvider = Objects.requireNonNull(entityScopeProvider);
97+
98+
this.nodeScopes = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
99+
@Override
100+
public Scope load(final Integer integer) {
101+
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForNode(integer);
102+
}
103+
});
104+
105+
this.interfaceScopes = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
106+
@Override
107+
public Scope load(final Tuple<Integer, String> tuple) {
108+
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForInterface(tuple.a, tuple.b);
109+
}
110+
});
111+
112+
this.interfaceScopesByIfIndex = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
113+
@Override
114+
public Scope load(final Tuple<Integer, Integer> tuple) {
115+
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForInterfaceByIfIndex(tuple.a, tuple.b);
116+
}
117+
});
118+
119+
this.serviceScopes = createCache(expireAfterWrite, expireAfterAccess, refreshAfterWrite, maximumSize, new CacheLoader<>() {
120+
@Override
121+
public Scope load(final Triple<Integer, InetAddress, String> triple) {
122+
return CachedEntityScopeProviderImpl.this.entityScopeProvider.getScopeForService(triple.a, triple.b, triple.c);
123+
}
124+
});
125+
}
126+
127+
private <K, V> LoadingCache<K, V> createCache(final long expireAfterWrite, final long expireAfterAccess, final long refreshAfterWrite, final long maximumSize, CacheLoader<K, V> loader) {
128+
final CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
129+
130+
if (expireAfterWrite >= 0) {
131+
cacheBuilder.expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS);
132+
}
133+
134+
if (expireAfterAccess >= 0) {
135+
cacheBuilder.expireAfterAccess(expireAfterAccess, TimeUnit.SECONDS);
136+
}
137+
138+
if (refreshAfterWrite >= 0) {
139+
cacheBuilder.refreshAfterWrite(refreshAfterWrite, TimeUnit.SECONDS);
140+
}
141+
142+
if (maximumSize > 0) {
143+
cacheBuilder.maximumSize(maximumSize);
144+
}
145+
146+
return cacheBuilder.build(loader);
147+
}
148+
149+
@Override
150+
public Scope getScopeForScv() {
151+
return entityScopeProvider.getScopeForScv();
152+
}
153+
154+
@Override
155+
public Scope getScopeForNode(final Integer nodeId) {
156+
return nodeScopes.getUnchecked(nodeId);
157+
}
158+
159+
@Override
160+
public Scope getScopeForInterface(final Integer nodeId, final String ipAddress) {
161+
return interfaceScopes.getUnchecked(new Tuple<>(nodeId, ipAddress));
162+
}
163+
164+
@Override
165+
public Scope getScopeForInterfaceByIfIndex(final Integer nodeId, final int ifIndex) {
166+
return interfaceScopesByIfIndex.getUnchecked(new Tuple<>(nodeId, ifIndex));
167+
}
168+
169+
@Override
170+
public Scope getScopeForService(final Integer nodeId, final InetAddress ipAddress, final String serviceName) {
171+
return serviceScopes.getUnchecked(new Triple<>(nodeId, ipAddress, serviceName));
172+
}
173+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*******************************************************************************
2+
* This file is part of OpenNMS(R).
3+
*
4+
* Copyright (C) 2019 The OpenNMS Group, Inc.
5+
* OpenNMS(R) is Copyright (C) 1999-2019 The OpenNMS Group, Inc.
6+
*
7+
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
8+
*
9+
* OpenNMS(R) is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as published
11+
* by the Free Software Foundation, either version 3 of the License,
12+
* or (at your option) any later version.
13+
*
14+
* OpenNMS(R) is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with OpenNMS(R). If not, see:
21+
* http://www.gnu.org/licenses/
22+
*
23+
* For more information contact:
24+
* OpenNMS(R) Licensing <license@opennms.org>
25+
* http://www.opennms.org/
26+
* http://www.opennms.com/
27+
*******************************************************************************/
28+
29+
package org.opennms.core.mate.model;
30+
31+
import org.junit.Before;
32+
import org.junit.runner.RunWith;
33+
import org.opennms.core.test.OpenNMSJUnit4ClassRunner;
34+
import org.opennms.core.test.db.annotations.JUnitTemporaryDatabase;
35+
import org.opennms.test.JUnitConfigurationEnvironment;
36+
import org.springframework.test.context.ContextConfiguration;
37+
38+
@RunWith(OpenNMSJUnit4ClassRunner.class)
39+
@ContextConfiguration(locations = {
40+
"classpath:/META-INF/opennms/applicationContext-commonConfigs.xml",
41+
"classpath:/META-INF/opennms/applicationContext-soa.xml",
42+
"classpath:/META-INF/opennms/applicationContext-mockDao.xml",
43+
"classpath:/META-INF/opennms/applicationContext-databasePopulator.xml",
44+
"classpath:/META-INF/opennms/applicationContext-entity-scope-provider.xml",
45+
"classpath*:/META-INF/opennms/component-dao.xml",
46+
})
47+
@JUnitConfigurationEnvironment
48+
@JUnitTemporaryDatabase
49+
public class CachedEntityScopeProviderIT extends EntityScopeProviderIT {
50+
51+
@Before
52+
@Override
53+
public void setup() {
54+
this.populator.populateDatabase();
55+
this.provider = new CachedEntityScopeProviderImpl(provider, 0, -1, -1, -1);
56+
}
57+
}

core/mate/model/src/test/java/org/opennms/core/mate/model/EntityScopeProviderIT.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ public class EntityScopeProviderIT {
7171
private SessionUtils sessionUtils;
7272

7373
@Autowired
74-
private DatabasePopulator populator;
74+
protected DatabasePopulator populator;
7575

7676
@Autowired
77-
private EntityScopeProvider provider;
77+
protected EntityScopeProvider provider;
7878

7979
@Autowired
8080
private SecureCredentialsVault secureCredentialsVault;
@@ -182,7 +182,7 @@ public final void testScopeProviders() {
182182
node.getMetaData().add(metaData);
183183
this.populator.getNodeDao().saveOrUpdate(node);
184184

185-
// get an scope provider
185+
// get a scope provider
186186
final ScopeProvider scope = this.provider.getScopeProviderForNode(this.populator.getNode1().getId());
187187

188188
// this will retrieve the meta-data set before

features/collection/thresholding/impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
1+
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.3.0">
22
<reference id="threshdDao" interface="org.opennms.netmgt.config.dao.thresholding.api.ReadableThreshdDao"/>
33
<reference id="thresholdingDao" interface="org.opennms.netmgt.config.dao.thresholding.api.ReadableThresholdingDao"/>
44
<reference id="pollOutagesDao" interface="org.opennms.netmgt.config.dao.outages.api.ReadablePollOutagesDao"/>
@@ -17,13 +17,32 @@
1717
<property name="sessionUtils" ref="sessionUtils"/>
1818
<property name="scv" ref="secureCredentialsVault"/>
1919
</bean>
20-
20+
21+
<cm:property-placeholder id="org.opennms.netmgt.threshd.metadata.cache"
22+
persistent-id="org.opennms.netmgt.threshd.metadata.cache"
23+
update-strategy="reload">
24+
<cm:default-properties>
25+
<cm:property name="expireAfterWrite" value="600"/>
26+
<cm:property name="expireAfterAccess" value="-1"/>
27+
<cm:property name="refreshAfterWrite" value="-1"/>
28+
<cm:property name="maximumSize" value="-1"/>
29+
</cm:default-properties>
30+
</cm:property-placeholder>
31+
32+
<bean id="cachedEntityScopeProvider" class="org.opennms.core.mate.model.CachedEntityScopeProviderImpl">
33+
<argument ref="entityScopeProvider"/>
34+
<argument value="${expireAfterWrite}"/>
35+
<argument value="${expireAfterAccess}"/>
36+
<argument value="${refreshAfterWrite}"/>
37+
<argument value="${maximumSize}"/>
38+
</bean>
39+
2140
<bean id="thresholdingSetPersister" class="org.opennms.netmgt.threshd.DefaultThresholdingSetPersister">
2241
<property name="threshdDao" ref="threshdDao"/>
2342
<property name="thresholdingDao" ref="thresholdingDao"/>
2443
<property name="pollOutagesDao" ref="pollOutagesDao"/>
2544
<property name="ifLabelDao" ref="ifLabelDao"/>
26-
<property name="entityScopeProvider" ref="entityScopeProvider"/>
45+
<property name="entityScopeProvider" ref="cachedEntityScopeProvider"/>
2746
</bean>
2847

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

0 commit comments

Comments
 (0)