Skip to content

Commit 99e2707

Browse files
authored
Merge pull request #2228 from maheshp/plugin_api
Admins/Group Admins PluginInfos API to list and view #1873
2 parents bb5988b + d18878b commit 99e2707

File tree

37 files changed

+2177
-7
lines changed

37 files changed

+2177
-7
lines changed

plugin-infra/go-plugin-access/src/com/thoughtworks/go/plugin/access/notification/NotificationPluginRegistrar.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public NotificationPluginRegistrar(PluginManager pluginManager, NotificationExte
4646
public void pluginLoaded(GoPluginDescriptor pluginDescriptor) {
4747
if (notificationExtension.canHandlePlugin(pluginDescriptor.id())) {
4848
try {
49+
notificationPluginRegistry.registerPlugin(pluginDescriptor.id());
4950
List<String> notificationsInterestedIn = notificationExtension.getNotificationsOfInterestFor(pluginDescriptor.id());
5051
if (notificationsInterestedIn != null && !notificationsInterestedIn.isEmpty()) {
5152
checkNotificationTypes(pluginDescriptor, notificationsInterestedIn);
@@ -69,6 +70,7 @@ private void checkNotificationTypes(GoPluginDescriptor pluginDescriptor, List<St
6970
@Override
7071
public void pluginUnLoaded(GoPluginDescriptor pluginDescriptor) {
7172
if (notificationExtension.canHandlePlugin(pluginDescriptor.id())) {
73+
notificationPluginRegistry.deregisterPlugin(pluginDescriptor.id());
7274
notificationPluginRegistry.removePluginInterests(pluginDescriptor.id());
7375
}
7476
}

plugin-infra/go-plugin-access/src/com/thoughtworks/go/plugin/access/notification/NotificationPluginRegistry.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
@Component
2828
public class NotificationPluginRegistry {
2929
private final Map<String, Set<String>> notificationNameToPluginsInterestedMap = new ConcurrentHashMap<>();
30+
private Set<String> notificationPlugins = new HashSet<>();
3031

3132
public void registerPluginInterests(String pluginId, List<String> notificationNames) {
3233
if (notificationNames != null && !notificationNames.isEmpty()) {
@@ -74,4 +75,16 @@ public Set<String> getPluginInterests(String pluginId) {
7475
public void clear() {
7576
notificationNameToPluginsInterestedMap.clear();
7677
}
78+
79+
public void registerPlugin(String pluginId) {
80+
notificationPlugins.add(pluginId);
81+
}
82+
83+
public void deregisterPlugin(String pluginId) {
84+
notificationPlugins.remove(pluginId);
85+
}
86+
87+
public Set<String> getNotificationPlugins() {
88+
return notificationPlugins;
89+
}
7790
}

plugin-infra/go-plugin-access/src/com/thoughtworks/go/plugin/access/pluggabletask/JsonBasedTaskExtension.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import java.util.List;
3434
import java.util.Map;
3535

36-
class JsonBasedTaskExtension extends AbstractExtension implements TaskExtensionContract {
36+
public class JsonBasedTaskExtension extends AbstractExtension implements TaskExtensionContract {
3737
public final static String TASK_EXTENSION = "task";
3838
private final static List<String> supportedVersions = Arrays.asList(JsonBasedTaskExtensionHandler_V1.VERSION);
3939

plugin-infra/go-plugin-access/test/com/thoughtworks/go/plugin/access/notification/NotificationPluginRegistrarTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
import org.mockito.Mock;
2626

2727
import static java.util.Arrays.asList;
28+
import static org.junit.Assert.assertFalse;
29+
import static org.junit.Assert.assertThat;
30+
import static org.junit.Assert.assertTrue;
2831
import static org.mockito.Mockito.*;
2932
import static org.mockito.MockitoAnnotations.initMocks;
3033

@@ -109,4 +112,22 @@ public void shouldLogWarningIfPluginTriesToRegisterForInvalidNotificationType()
109112
verify(logger).warn("Plugin 'plugin-id-1' is trying to register for 'pipeline-status' which is not a valid notification type. Valid notification types are: [stage-status]");
110113
verify(logger).warn("Plugin 'plugin-id-1' is trying to register for 'job-status' which is not a valid notification type. Valid notification types are: [stage-status]");
111114
}
115+
116+
@Test
117+
public void shouldRegisterPluginOnPluginLoad() {
118+
NotificationPluginRegistrar notificationPluginRegistrar = new NotificationPluginRegistrar(pluginManager, notificationExtension, notificationPluginRegistry);
119+
120+
notificationPluginRegistrar.pluginLoaded(new GoPluginDescriptor(PLUGIN_ID_1, null, null, null, null, true));
121+
122+
verify(notificationPluginRegistry).registerPlugin(PLUGIN_ID_1);
123+
}
124+
125+
@Test
126+
public void shouldUnregisterPluginOnPluginUnLoad() {
127+
NotificationPluginRegistrar notificationPluginRegistrar = new NotificationPluginRegistrar(pluginManager, notificationExtension, notificationPluginRegistry);
128+
129+
notificationPluginRegistrar.pluginUnLoaded(new GoPluginDescriptor(PLUGIN_ID_1, null, null, null, null, true));
130+
131+
verify(notificationPluginRegistry).deregisterPlugin(PLUGIN_ID_1);
132+
}
112133
}

plugin-infra/go-plugin-access/test/com/thoughtworks/go/plugin/access/notification/NotificationPluginRegistryTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.hamcrest.Matchers.containsInAnyOrder;
2525
import static org.hamcrest.core.Is.is;
2626
import static org.junit.Assert.assertThat;
27+
import static org.junit.Assert.assertTrue;
2728

2829
public class NotificationPluginRegistryTest {
2930
public static final String PLUGIN_ID_1 = "plugin-id-1";
@@ -83,4 +84,31 @@ public void should_isAnyPluginInterestedIn_Correctly() {
8384
assertThat(notificationPluginRegistry.isAnyPluginInterestedIn(PIPELINE_STATUS), is(true));
8485
assertThat(notificationPluginRegistry.isAnyPluginInterestedIn(UNKNOWN_NOTIFICATION), is(false));
8586
}
87+
88+
@Test
89+
public void shouldListRegisteredPlugins() {
90+
notificationPluginRegistry.registerPlugin("plugin_id_1");
91+
notificationPluginRegistry.registerPlugin("plugin_id_2");
92+
93+
assertThat(notificationPluginRegistry.getNotificationPlugins().size(), is(2));
94+
assertTrue(notificationPluginRegistry.getNotificationPlugins().contains("plugin_id_1"));
95+
assertTrue(notificationPluginRegistry.getNotificationPlugins().contains("plugin_id_2"));
96+
}
97+
98+
@Test
99+
public void shouldNotRegisterDuplicatePlugins() {
100+
notificationPluginRegistry.registerPlugin("plugin_id_1");
101+
notificationPluginRegistry.registerPlugin("plugin_id_1");
102+
103+
assertThat(notificationPluginRegistry.getNotificationPlugins().size(), is(1));
104+
assertTrue(notificationPluginRegistry.getNotificationPlugins().contains("plugin_id_1"));
105+
}
106+
107+
@Test
108+
public void shouldNotListDeRegisteredPlugins() {
109+
notificationPluginRegistry.registerPlugin("plugin_id_1");
110+
notificationPluginRegistry.deregisterPlugin("plugin_id_1");
111+
112+
assertTrue(notificationPluginRegistry.getNotificationPlugins().isEmpty());
113+
}
86114
}

server/src/com/thoughtworks/go/server/service/PluginService.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import com.thoughtworks.go.plugin.api.response.validation.ValidationResult;
2727
import com.thoughtworks.go.server.dao.PluginDao;
2828
import com.thoughtworks.go.server.domain.PluginSettings;
29+
import com.thoughtworks.go.server.service.plugins.builder.PluginInfoBuilder;
30+
import com.thoughtworks.go.server.ui.plugins.PluginInfo;
2931
import org.springframework.beans.factory.annotation.Autowired;
3032
import org.springframework.stereotype.Service;
3133

@@ -36,11 +38,13 @@
3638
public class PluginService {
3739
private final List<GoPluginExtension> extensions;
3840
private final PluginDao pluginDao;
41+
private PluginInfoBuilder pluginInfoBuilder;
3942

4043
@Autowired
41-
public PluginService(List<GoPluginExtension> extensions, PluginDao pluginDao) {
44+
public PluginService(List<GoPluginExtension> extensions, PluginDao pluginDao, PluginInfoBuilder pluginInfoBuilder) {
4245
this.extensions = extensions;
4346
this.pluginDao = pluginDao;
47+
this.pluginInfoBuilder = pluginInfoBuilder;
4448
}
4549

4650
public PluginSettings getPluginSettingsFor(String pluginId) {
@@ -93,6 +97,14 @@ public void savePluginSettingsFor(PluginSettings pluginSettings) {
9397
pluginDao.saveOrUpdate(plugin);
9498
}
9599

100+
public List<PluginInfo> pluginInfos(String type) {
101+
return pluginInfoBuilder.allPluginInfos(type);
102+
}
103+
104+
public PluginInfo pluginInfo(String pluginId) {
105+
return pluginInfoBuilder.pluginInfoFor(pluginId);
106+
}
107+
96108
private String toJSON(Map<String, String> settingsMap) {
97109
return new GsonBuilder().serializeNulls().create().toJson(settingsMap);
98110
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2016 ThoughtWorks, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.thoughtworks.go.server.service.plugins;
18+
19+
public class InvalidPluginTypeException extends RuntimeException {
20+
21+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2016 ThoughtWorks, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.thoughtworks.go.server.service.plugins.builder;
18+
19+
import com.thoughtworks.go.plugin.access.authentication.AuthenticationExtension;
20+
import com.thoughtworks.go.plugin.access.authentication.AuthenticationPluginRegistry;
21+
import com.thoughtworks.go.plugin.infra.PluginManager;
22+
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginDescriptor;
23+
import com.thoughtworks.go.server.ui.plugins.PluginInfo;
24+
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
28+
class AuthenticationViewModelBuilder implements ViewModelBuilder {
29+
private PluginManager pluginManager;
30+
private AuthenticationPluginRegistry registry;
31+
32+
public AuthenticationViewModelBuilder(PluginManager manager, AuthenticationPluginRegistry registry) {
33+
this.pluginManager = manager;
34+
this.registry = registry;
35+
}
36+
37+
public List<PluginInfo> allPluginInfos() {
38+
List<PluginInfo> pluginInfos = new ArrayList<>();
39+
40+
for(String pluginId : registry.getAuthenticationPlugins()) {
41+
GoPluginDescriptor descriptor = pluginManager.getPluginDescriptorFor(pluginId);
42+
43+
pluginInfos.add(new PluginInfo(pluginId, descriptor.about().name(), descriptor.about().version(),
44+
AuthenticationExtension.EXTENSION_NAME, null));
45+
}
46+
return pluginInfos;
47+
}
48+
49+
public PluginInfo pluginInfoFor(String pluginId) {
50+
if(!registry.getAuthenticationPlugins().contains(pluginId)) {
51+
return null;
52+
}
53+
54+
GoPluginDescriptor descriptor = pluginManager.getPluginDescriptorFor(pluginId);
55+
56+
return new PluginInfo(pluginId, descriptor.about().name(), descriptor.about().version(),
57+
AuthenticationExtension.EXTENSION_NAME, null, null);
58+
}
59+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2016 ThoughtWorks, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.thoughtworks.go.server.service.plugins.builder;
18+
19+
import com.thoughtworks.go.plugin.access.notification.NotificationExtension;
20+
import com.thoughtworks.go.plugin.access.notification.NotificationPluginRegistry;
21+
import com.thoughtworks.go.plugin.infra.PluginManager;
22+
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginDescriptor;
23+
import com.thoughtworks.go.server.ui.plugins.PluginInfo;
24+
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
28+
class NotificationViewModelBuilder implements ViewModelBuilder {
29+
private PluginManager pluginManager;
30+
private NotificationPluginRegistry notificationPluginRegistry;
31+
32+
public NotificationViewModelBuilder(PluginManager manager, NotificationPluginRegistry notificationPluginRegistry) {
33+
this.pluginManager = manager;
34+
this.notificationPluginRegistry = notificationPluginRegistry;
35+
}
36+
37+
public List<PluginInfo> allPluginInfos() {
38+
List<PluginInfo> pluginInfos = new ArrayList<>();
39+
40+
for(String pluginId : notificationPluginRegistry.getNotificationPlugins()) {
41+
GoPluginDescriptor descriptor = pluginManager.getPluginDescriptorFor(pluginId);
42+
43+
pluginInfos.add(new PluginInfo(pluginId, descriptor.about().name(), descriptor.about().version(),
44+
NotificationExtension.EXTENSION_NAME, null));
45+
}
46+
return pluginInfos;
47+
}
48+
49+
@Override
50+
public PluginInfo pluginInfoFor(String pluginId) {
51+
if(!notificationPluginRegistry.getNotificationPlugins().contains(pluginId)) {
52+
return null;
53+
}
54+
55+
GoPluginDescriptor descriptor = pluginManager.getPluginDescriptorFor(pluginId);
56+
57+
return new PluginInfo(pluginId, descriptor.about().name(), descriptor.about().version(),
58+
NotificationExtension.EXTENSION_NAME, null);
59+
}
60+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2016 ThoughtWorks, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.thoughtworks.go.server.service.plugins.builder;
18+
19+
import com.thoughtworks.go.plugin.access.packagematerial.JsonBasedPackageRepositoryExtension;
20+
import com.thoughtworks.go.plugin.access.packagematerial.PackageConfiguration;
21+
import com.thoughtworks.go.plugin.access.packagematerial.PackageConfigurations;
22+
import com.thoughtworks.go.plugin.access.packagematerial.PackageMetadataStore;
23+
import com.thoughtworks.go.plugin.access.packagematerial.RepositoryMetadataStore;
24+
import com.thoughtworks.go.plugin.api.config.Property;
25+
import com.thoughtworks.go.plugin.infra.PluginManager;
26+
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginDescriptor;
27+
import com.thoughtworks.go.server.ui.plugins.PluginConfiguration;
28+
import com.thoughtworks.go.server.ui.plugins.PluggableInstanceSettings;
29+
import com.thoughtworks.go.server.ui.plugins.PluginInfo;
30+
31+
import java.util.ArrayList;
32+
import java.util.HashMap;
33+
import java.util.List;
34+
import java.util.Map;
35+
36+
class PackageViewModelBuilder implements ViewModelBuilder {
37+
private PluginManager pluginManager;
38+
39+
public PackageViewModelBuilder(PluginManager manager) {
40+
this.pluginManager = manager;
41+
}
42+
43+
public List<PluginInfo> allPluginInfos() {
44+
List<PluginInfo> pluginInfos = new ArrayList<>();
45+
46+
for(String pluginId : PackageMetadataStore.getInstance().pluginIds()) {
47+
GoPluginDescriptor descriptor = pluginManager.getPluginDescriptorFor(pluginId);
48+
49+
pluginInfos.add(new PluginInfo(pluginId, descriptor.about().name(), descriptor.about().version(),
50+
JsonBasedPackageRepositoryExtension.EXTENSION_NAME, null));
51+
}
52+
return pluginInfos;
53+
}
54+
55+
public PluginInfo pluginInfoFor(String pluginId) {
56+
String PACKAGE_CONFIGRATION_TYPE = "package";
57+
String REPOSITORY_CONFIGRATION_TYPE = "repository";
58+
59+
if(!PackageMetadataStore.getInstance().hasPreferenceFor(pluginId)) {
60+
return null;
61+
}
62+
63+
GoPluginDescriptor descriptor = pluginManager.getPluginDescriptorFor(pluginId);
64+
ArrayList<PluginConfiguration> pluginConfigurations = new ArrayList<>();
65+
66+
pluginConfigurations.addAll(configurations(PackageMetadataStore.getInstance().getMetadata(pluginId), PACKAGE_CONFIGRATION_TYPE));
67+
pluginConfigurations.addAll(configurations(RepositoryMetadataStore.getInstance().getMetadata(pluginId), REPOSITORY_CONFIGRATION_TYPE));
68+
69+
return new PluginInfo(pluginId, descriptor.about().name(), descriptor.about().version(),
70+
JsonBasedPackageRepositoryExtension.EXTENSION_NAME, null, new PluggableInstanceSettings(pluginConfigurations));
71+
}
72+
73+
private List<PluginConfiguration> configurations(PackageConfigurations packageConfigurations, String type) {
74+
ArrayList<PluginConfiguration> pluginConfigurations = new ArrayList<>();
75+
76+
for(PackageConfiguration configuration: packageConfigurations.list()) {
77+
Map<String, Object> metaData = new HashMap<>();
78+
79+
metaData.put(REQUIRED_OPTION, configuration.getOption(Property.REQUIRED));
80+
metaData.put(SECURE_OPTION, configuration.getOption(Property.SECURE));
81+
metaData.put(PART_OF_IDENTITY_OPTION, configuration.getOption(Property.PART_OF_IDENTITY));
82+
83+
pluginConfigurations.add(new PluginConfiguration(configuration.getKey(), metaData, type));
84+
}
85+
return pluginConfigurations;
86+
}
87+
}

0 commit comments

Comments
 (0)