Skip to content

Commit 0dda44c

Browse files
authored
Merge pull request #9 from intergral/auth_plugins
fix(plugins): allow plugins to act as auth providers
2 parents c00cb8d + 076dcec commit 0dda44c

File tree

13 files changed

+247
-14
lines changed

13 files changed

+247
-14
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (C) 2023 Intergral GmbH
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.intergral.deep.agent.api;
19+
20+
public class DeepRuntimeException extends RuntimeException {
21+
22+
public DeepRuntimeException(final String message) {
23+
super(message);
24+
}
25+
26+
public DeepRuntimeException(final String message, final Throwable cause) {
27+
super(message, cause);
28+
}
29+
}

agent-api/src/main/java/com/intergral/deep/agent/api/IDeep.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,25 @@
3030
*/
3131
public interface IDeep {
3232

33+
/**
34+
* Get the current state of deep.
35+
*
36+
* @return {@code true} if deep is currently enabled and sending requests, else {@code false}
37+
*/
38+
boolean isEnabled();
39+
40+
41+
/**
42+
* This method can be used to disabled or enable Deep.
43+
* <p>
44+
* Changing the state to {@code false} (ie disabled) will cause deep to uninstall all the tracepoints and clear the current config.
45+
* Meaning that when deep is enabled again it will have to reinstall the configuration. It is therefore advised to not call this function
46+
* too frequently.
47+
*
48+
* @param enabled the new state to become
49+
*/
50+
void setEnabled(final boolean enabled);
51+
3352
/**
3453
* Get the version of deep being used.
3554
*

agent-api/src/main/java/com/intergral/deep/agent/api/IRegistration.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,17 @@
2020
/**
2121
* This is a generic interface from the result of a registration.
2222
*/
23-
public interface IRegistration {
23+
public interface IRegistration<T> {
2424

2525
/**
2626
* Unregister the item registered.
2727
*/
2828
void unregister();
29+
30+
/**
31+
* Get the registered item
32+
*
33+
* @return the item that this registration is for.
34+
*/
35+
T get();
2936
}

agent-api/src/main/java/com/intergral/deep/agent/api/auth/AuthProvider.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package com.intergral.deep.agent.api.auth;
1919

20+
import com.intergral.deep.agent.api.DeepRuntimeException;
21+
import com.intergral.deep.agent.api.plugin.IPlugin;
2022
import com.intergral.deep.agent.api.settings.ISettings;
2123
import java.lang.reflect.Constructor;
2224
import java.lang.reflect.InvocationTargetException;
@@ -32,6 +34,18 @@ public static IAuthProvider provider(final ISettings settings) {
3234
if (serviceAuthProvider == null || serviceAuthProvider.trim().isEmpty()) {
3335
return NOOP_PROVIDER;
3436
}
37+
38+
// check if we have a plugin of this name that we can use
39+
final IPlugin plugin = settings.getPlugin(serviceAuthProvider);
40+
if (plugin != null) {
41+
if (plugin instanceof IAuthProvider) {
42+
return (IAuthProvider) plugin;
43+
} else {
44+
throw new DeepRuntimeException(
45+
String.format("Cannot use plugin %s as auth provider, must implement IAuthProvider interface.", plugin.name()));
46+
}
47+
}
48+
3549
try {
3650
final Class<?> aClass = Class.forName(serviceAuthProvider);
3751
final Constructor<?> constructor = aClass.getConstructor(ISettings.class);
@@ -42,7 +56,7 @@ public static IAuthProvider provider(final ISettings settings) {
4256
| InvocationTargetException
4357
| InstantiationException
4458
| IllegalAccessException e) {
45-
throw new RuntimeException(e);
59+
throw new RuntimeException(String.format("Cannot load auth provider %s", serviceAuthProvider), e);
4660
}
4761
}
4862

agent-api/src/main/java/com/intergral/deep/agent/api/plugin/IPlugin.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,14 @@ default boolean isActive(final ISettings settings) {
7070
/**
7171
* This type describes a registered plugin.
7272
*/
73-
interface IPluginRegistration extends IRegistration {
73+
interface IPluginRegistration extends IRegistration<IPlugin> {
7474

75+
/**
76+
* Indicates if this plugin is currently set to be the auth provider
77+
*
78+
* @return {@code true} if the registered plugin is an {@link com.intergral.deep.agent.api.auth.IAuthProvider} and deep is configured to
79+
* use this provider, else {@code false}
80+
*/
81+
boolean isAuthProvider();
7582
}
7683
}

agent-api/src/main/java/com/intergral/deep/agent/api/resource/ConfigurationException.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ public final class ConfigurationException extends RuntimeException {
1212

1313
/**
1414
* Create a new configuration exception with specified {@code message} and without a cause.
15+
*
16+
* @param message The exception message
1517
*/
1618
public ConfigurationException(String message) {
1719
super(message);
1820
}
1921

2022
/**
2123
* Create a new configuration exception with specified {@code message} and {@code cause}.
24+
*
25+
* @param message The exception message
26+
* @param cause The root cause of this exception
2227
*/
2328
public ConfigurationException(String message, Throwable cause) {
2429
super(message, cause);

agent-api/src/main/java/com/intergral/deep/agent/api/settings/ISettings.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,43 @@
1717

1818
package com.intergral.deep.agent.api.settings;
1919

20+
import com.intergral.deep.agent.api.plugin.IPlugin;
2021
import com.intergral.deep.agent.api.resource.Resource;
2122
import java.util.Map;
2223

2324
public interface ISettings {
2425

26+
/**
27+
* This is the settings key for the configured auth provider
28+
*/
29+
String KEY_AUTH_PROVIDER = "service.auth.provider";
30+
31+
/**
32+
* This is the setting key for enabling or disabling deep.
33+
*/
34+
String KEY_ENABLED = "enabled";
35+
36+
/**
37+
* This is the setting key for the service url
38+
*/
39+
String KEY_SERVICE_URL = "service.url";
40+
2541
<T> T getSettingAs(String key, Class<T> clazz);
2642

2743
Map<String, String> getMap(String attributeProperty);
2844

45+
/**
46+
* Returns the resource that describes this client
47+
*
48+
* @return the {@link Resource}
49+
*/
2950
Resource getResource();
51+
52+
/**
53+
* Look for a plugin with the given name or class name.
54+
*
55+
* @param name the plugin name or the plugin class name
56+
* @return the {@link IPlugin} or {@code null}
57+
*/
58+
IPlugin getPlugin(final String name);
3059
}

agent-api/src/main/java/com/intergral/deep/agent/api/spi/Ordered.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public interface Ordered {
1616
* Returns the order of applying the SPI implementing this interface. Higher values are applied
1717
* later, for example: an SPI with order=1 will run after an SPI with order=0. SPI implementations
1818
* with equal values will be run in a non-deterministic order.
19+
*
20+
* @return the order value
1921
*/
2022
default int order() {
2123
return 0;

agent-api/src/main/java/com/intergral/deep/agent/api/tracepoint/ITracepoint.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ default String id() {
4141
return UUID.randomUUID().toString();
4242
}
4343

44-
interface ITracepointRegistration extends IRegistration {
44+
interface ITracepointRegistration extends IRegistration<ITracepoint> {
4545

4646
}
4747
}

agent/src/main/java/com/intergral/deep/agent/DeepAgent.java

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919

2020
import com.intergral.deep.agent.api.DeepVersion;
2121
import com.intergral.deep.agent.api.IDeep;
22+
import com.intergral.deep.agent.api.auth.IAuthProvider;
2223
import com.intergral.deep.agent.api.plugin.IPlugin;
2324
import com.intergral.deep.agent.api.plugin.IPlugin.IPluginRegistration;
2425
import com.intergral.deep.agent.api.resource.Resource;
26+
import com.intergral.deep.agent.api.settings.ISettings;
27+
import com.intergral.deep.agent.api.tracepoint.ITracepoint;
2528
import com.intergral.deep.agent.api.tracepoint.ITracepoint.ITracepointRegistration;
2629
import com.intergral.deep.agent.grpc.GrpcService;
2730
import com.intergral.deep.agent.plugins.PluginLoader;
@@ -74,7 +77,29 @@ public String getVersion() {
7477

7578
public IPluginRegistration registerPlugin(final IPlugin plugin) {
7679
this.settings.addPlugin(plugin);
77-
return () -> this.settings.removePlugin(plugin);
80+
final boolean isAuthProvider;
81+
if (plugin instanceof IAuthProvider) {
82+
final String settingAs = this.settings.getSettingAs(ISettings.KEY_AUTH_PROVIDER, String.class);
83+
isAuthProvider = settingAs != null && settingAs.equals(plugin.getClass().getName());
84+
} else {
85+
isAuthProvider = false;
86+
}
87+
return new IPluginRegistration() {
88+
@Override
89+
public boolean isAuthProvider() {
90+
return isAuthProvider;
91+
}
92+
93+
@Override
94+
public void unregister() {
95+
settings.removePlugin(plugin);
96+
}
97+
98+
@Override
99+
public IPlugin get() {
100+
return plugin;
101+
}
102+
};
78103
}
79104

80105
@Override
@@ -86,6 +111,62 @@ public ITracepointRegistration registerTracepoint(final String path, final int l
86111
public ITracepointRegistration registerTracepoint(final String path, final int line, final Map<String, String> args,
87112
final Collection<String> watches) {
88113
final TracePointConfig tracePointConfig = this.tracepointConfig.addCustom(path, line, args, watches);
89-
return () -> this.tracepointConfig.removeCustom(tracePointConfig);
114+
return new ITracepointRegistration() {
115+
@Override
116+
public void unregister() {
117+
tracepointConfig.removeCustom(tracePointConfig);
118+
}
119+
120+
@Override
121+
public ITracepoint get() {
122+
return new ITracepoint() {
123+
@Override
124+
public String path() {
125+
return path;
126+
}
127+
128+
@Override
129+
public int line() {
130+
return line;
131+
}
132+
133+
@Override
134+
public Map<String, String> args() {
135+
return args;
136+
}
137+
138+
@Override
139+
public Collection<String> watches() {
140+
return watches;
141+
}
142+
143+
@Override
144+
public String id() {
145+
return tracePointConfig.getId();
146+
}
147+
};
148+
}
149+
};
150+
}
151+
152+
@Override
153+
public boolean isEnabled() {
154+
return this.settings.getSettingAs(ISettings.KEY_ENABLED, Boolean.class);
155+
}
156+
157+
@Override
158+
public synchronized void setEnabled(final boolean enabled) {
159+
// we are already the desired state - so do nothing
160+
if (isEnabled() == enabled) {
161+
return;
162+
}
163+
164+
// update config to new state
165+
this.settings.setActive(enabled);
166+
167+
// if we are disabling then we need to clear configs
168+
if (!enabled) {
169+
this.tracepointConfig.configUpdate(0, null, Collections.emptyList());
170+
}
90171
}
91172
}

agent/src/main/java/com/intergral/deep/agent/poll/LongPollService.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ public void start(final ITracepointConfig tracepointConfig) {
5656

5757
@Override
5858
public void run(long now) {
59+
if (!this.settings.isActive()) {
60+
// we have been disabled so skip this poll
61+
// we will pause like normal and try again later
62+
return;
63+
}
5964
final PollConfigGrpc.PollConfigBlockingStub blockingStub = this.grpcService.pollService();
6065

6166
final PollRequest.Builder builder = PollRequest.newBuilder();
@@ -69,7 +74,10 @@ public void run(long now) {
6974
.build();
7075

7176
final PollResponse response = blockingStub.poll(pollRequest);
72-
77+
// check we are still active
78+
if (!this.settings.isActive()) {
79+
return;
80+
}
7381
if (response.getResponseType() == ResponseType.NO_CHANGE) {
7482
this.tracepointConfig.noChange(response.getTsNanos());
7583
} else {

0 commit comments

Comments
 (0)