|
| 1 | +/* |
| 2 | + * Copyright (c) Microsoft Corporation. All rights reserved. |
| 3 | + * Licensed under the MIT License. See License.txt in the project root for license information. |
| 4 | + */ |
| 5 | + |
| 6 | +package com.microsoft.azure.toolkit.intellij.containerregistry; |
| 7 | + |
| 8 | +import com.intellij.docker.registry.DockerRegistryConfiguration; |
| 9 | +import com.intellij.docker.registry.DockerRegistryManager; |
| 10 | +import com.intellij.docker.view.registry.DockerRegistryServiceViewContributor; |
| 11 | +import com.intellij.docker.view.registry.node.DockerRegistryRoot; |
| 12 | +import com.intellij.execution.services.ServiceEventListener; |
| 13 | +import com.intellij.execution.services.ServiceViewContributor; |
| 14 | +import com.intellij.execution.services.ServiceViewManager; |
| 15 | +import com.intellij.openapi.actionSystem.AnActionEvent; |
| 16 | +import com.intellij.openapi.application.ApplicationManager; |
| 17 | +import com.intellij.openapi.project.Project; |
| 18 | +import com.intellij.openapi.ui.MessageDialogBuilder; |
| 19 | +import com.intellij.openapi.wm.ToolWindow; |
| 20 | +import com.intellij.openapi.wm.ToolWindowManager; |
| 21 | +import com.intellij.util.messages.MessageBus; |
| 22 | +import com.intellij.util.messages.MessageBusConnection; |
| 23 | +import com.microsoft.azure.toolkit.ide.common.IActionsContributor; |
| 24 | +import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContributor; |
| 25 | +import com.microsoft.azure.toolkit.ide.containerregistry.ContainerRegistryActionsContributor; |
| 26 | +import com.microsoft.azure.toolkit.intellij.containerregistry.servicesview.AzureContainerRegistryProvider; |
| 27 | +import com.microsoft.azure.toolkit.lib.common.action.Action; |
| 28 | +import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager; |
| 29 | +import com.microsoft.azure.toolkit.lib.common.bundle.AzureString; |
| 30 | +import com.microsoft.azure.toolkit.lib.common.messager.AzureMessager; |
| 31 | +import com.microsoft.azure.toolkit.lib.common.messager.IAzureMessage; |
| 32 | +import com.microsoft.azure.toolkit.lib.common.model.AbstractAzResource; |
| 33 | +import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager; |
| 34 | +import com.microsoft.azure.toolkit.lib.containerregistry.ContainerRegistry; |
| 35 | +import org.apache.commons.lang3.StringUtils; |
| 36 | + |
| 37 | +import javax.annotation.Nonnull; |
| 38 | +import java.util.Objects; |
| 39 | +import java.util.Optional; |
| 40 | +import java.util.function.Predicate; |
| 41 | + |
| 42 | +import static com.microsoft.azure.toolkit.intellij.containerregistry.servicesview.AzureContainerRegistryConfigurator.ENABLE_ADMIN_USER_DOC_LINK; |
| 43 | + |
| 44 | +@SuppressWarnings("UnstableApiUsage") |
| 45 | +public class IntelliJContainerRegistryActionsContributorForDockerPlugin implements IActionsContributor { |
| 46 | + public static final String NULL_SERVICE_MESSAGE = "Failed to get Docker Registries root in \"Services\" view, please check whether \"Docker\" plugin is correctly installed."; |
| 47 | + |
| 48 | + @Override |
| 49 | + public void registerHandlers(AzureActionManager am) { |
| 50 | + am.registerHandler(ResourceCommonActionsContributor.OPEN_IN_SERVICES_VIEW, (r, e) -> r instanceof ContainerRegistry, |
| 51 | + (AbstractAzResource<?, ?, ?> r, AnActionEvent e) -> { |
| 52 | + final ContainerRegistry registry = (ContainerRegistry) r; |
| 53 | + final AzureString msg = AzureString.format("<html><body>Admin user is not enabled for (%s), but it is required to login a Azure Container Registry. <b>Do you want to enable Admin user and then open it in \"services\" view?</b> <br>You can learn more about admin user <a href='" + ENABLE_ADMIN_USER_DOC_LINK + "'>here</a>.</body></html>", registry.getName()); |
| 54 | + final IAzureMessage message = AzureMessager.getMessager().buildConfirmMessage(msg, "Enable Admin User"); |
| 55 | + final boolean[] result = new boolean[1]; |
| 56 | + if (!registry.isAdminUserEnabled()) { |
| 57 | + ApplicationManager.getApplication().invokeAndWait(() -> result[0] = MessageDialogBuilder.yesNo("Enable Admin User", message.getContent()).guessWindowAndAsk()); |
| 58 | + if (result[0]) { |
| 59 | + final Action<ContainerRegistry> enableAdminUser = AzureActionManager.getInstance().getAction(ContainerRegistryActionsContributor.ENABLE_ADMIN_USER); |
| 60 | + enableAdminUser.handleSync(registry); |
| 61 | + } |
| 62 | + } |
| 63 | + if (registry.isAdminUserEnabled()) { |
| 64 | + AzureTaskManager.getInstance().runLater(() -> openRegistryInServicesView(registry, Objects.requireNonNull(e.getProject()))); |
| 65 | + } |
| 66 | + } |
| 67 | + ); |
| 68 | + } |
| 69 | + |
| 70 | + private static void openRegistryInServicesView(@Nonnull final ContainerRegistry data, @Nonnull final Project project) { |
| 71 | + final ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Services"); |
| 72 | + if (Objects.nonNull(toolWindow) && !toolWindow.isActive()) { |
| 73 | + toolWindow.activate(() -> openRegistryInServicesView(data, project)); |
| 74 | + return; |
| 75 | + } |
| 76 | + final ServiceViewContributor<?> root = ServiceViewContributor.CONTRIBUTOR_EP_NAME.findExtension(DockerRegistryServiceViewContributor.class); |
| 77 | + if (Objects.isNull(root)) { |
| 78 | + final Action<String> installAction = AzureActionManager.getInstance().getAction(ResourceCommonActionsContributor.SEARCH_MARKETPLACE_PLUGIN).bind("Docker").withLabel("Install"); |
| 79 | + AzureMessager.getMessager().warning(NULL_SERVICE_MESSAGE, installAction); |
| 80 | + return; |
| 81 | + } |
| 82 | + final ServiceViewContributor<?> registry = getRegistryService(data, project, root).orElse(null); |
| 83 | + if (Objects.nonNull(registry)) { |
| 84 | + focusInServicesView(registry, root, project); |
| 85 | + } else { |
| 86 | + addAndFocusInServicesView(data, root, project); |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + private static void addAndFocusInServicesView(@Nonnull final ContainerRegistry data, ServiceViewContributor<?> root, @Nonnull final Project project) { |
| 91 | + final DockerRegistryManager registryManager = DockerRegistryManager.getInstance(); |
| 92 | + final Predicate<DockerRegistryConfiguration> exists = r -> r.getAddress().equals(data.getLoginServerUrl()) && r.getUsername().equalsIgnoreCase(data.getUserName()); |
| 93 | + if (registryManager.getRegistries().stream().noneMatch(exists)) { |
| 94 | + final MessageBus messageBus = project.getMessageBus(); |
| 95 | + final MessageBusConnection connect = messageBus.connect(); |
| 96 | + connect.subscribe(ServiceEventListener.TOPIC, (ServiceEventListener) serviceEvent -> { |
| 97 | + final boolean isDockerRegistryEvent = serviceEvent.contributorClass == root.getClass(); |
| 98 | + if (isDockerRegistryEvent) { |
| 99 | + getRegistryService(data, project, root).ifPresent(service -> { |
| 100 | + focusInServicesView(service, root, project); |
| 101 | + connect.disconnect(); |
| 102 | + }); |
| 103 | + } |
| 104 | + }); |
| 105 | + AzureTaskManager.getInstance().runOnPooledThread(() -> { |
| 106 | + final DockerRegistryConfiguration config = new DockerRegistryConfiguration().withName(data.getName()); |
| 107 | + config.setRegistryProviderId(AzureContainerRegistryProvider.ID); |
| 108 | + config.setAddress(data.getLoginServerUrl()); |
| 109 | + config.setUsername(data.getUserName()); |
| 110 | + config.setPasswordSafe(data.getPrimaryCredential()); |
| 111 | + |
| 112 | + registryManager.addRegistry(config); |
| 113 | + }); |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + private static void focusInServicesView(@Nonnull final ServiceViewContributor<?> service, |
| 118 | + @Nonnull final ServiceViewContributor<?> contributor, final Project project) { |
| 119 | + ServiceViewManager.getInstance(project).select(service, contributor.getClass(), true, true); |
| 120 | + ServiceViewManager.getInstance(project).expand(service, contributor.getClass()); |
| 121 | + } |
| 122 | + |
| 123 | + private static Optional<DockerRegistryRoot> getRegistryService(final @Nonnull ContainerRegistry data, final @Nonnull Project project, final ServiceViewContributor<?> root) { |
| 124 | + return root.getServices(project).stream() |
| 125 | + .filter(c -> c instanceof DockerRegistryRoot) |
| 126 | + .map(c -> (DockerRegistryRoot) c) |
| 127 | + .filter(r -> StringUtils.equals(r.getConfiguration().getAddress(), data.getLoginServerUrl()) && StringUtils.equals(r.getConfiguration().getUsername(), data.getUserName())) |
| 128 | + .findFirst(); |
| 129 | + } |
| 130 | + |
| 131 | +} |
0 commit comments