Skip to content

Commit

Permalink
Merge feature settings (#42)
Browse files Browse the repository at this point in the history
* EPMRPP-66071 Removed unused files. Update description

* EPMRPP-66071 Fix plugin icon.

* Update plugin id. Change plugin name. Update readme. Add jar

* Add integration bts group

* Update jar

* EPMRPP-67335 Add space to plugin description

* EPMRPP-66075: Add test connection command based on api token, email and project

* EPMRPP-66075: Remove built plugins

* EPMRPP-66075-Fix init listeners

* EPMRPP-66091 - add intergation form

* EPMRPP-67027 - remove credentials

* EPMRPP-67031 - add common component to edit integration

* EPMRPP-66951-Add issue types and issue type fields commands

* EPMRPP-67644 - rename project field

* EPMRPP-66076: Introduce validation command

* EPMRPP-66076: Add headers

* EPMRPP-67476 - change email field validation

* Add listeners init

* EPMRPP-67709 Add issue form fields

* EPMRPP-66076: Add missed suppliers

* EPMRPP-66076: Add missed command

* EPMRPP-66076 || Refactor create and update validation of cloud jira (#14)

* Fix incorrect plugin command name

* Fix incorrect plugin command name

* EPMRPP-66076 || Refactor auth encryption (#15)

* EPMRPP-68407 || Implement post issue command (#17)

* EPMRPP-68407 || Fix compilation errors

* EPMRPP-68407 || Skip reporter field as it is resolved from creds

* EPMRPP-68559 || fix bts project key validation (#18)

Co-authored-by: Mikhail Sidarkevich <mikhail_sidarkevich@epam.com>

* EPMRPP-68630 || Add build github action

* EPMRPP-68947 || Information about Jira Cloud issue (#19)

* EPMRPP-68947 || Refactor according to new common comands without existed integration

* EPMRPP-68947 || Add get issue command

* EPMRPP-68947 || Fix common commands

* EPMRPP-73595 || Handle 500 error on get non-existent Jira cloud ticket (#20)

* Update version

* 5.7.0 || Update plugin version

* 5.7.0 || Add release scripts

* 5.7.0 || Add release scripts

* 5.7.0 || Add release scripts

* 5.7.0 || Add release scripts

* 5.7.0 || Add release scripts

* EPMRPP-78159 || Update plugin description Jira Cloud (#27)

* EPMRPP-78099 || Redesign Integrations. Update modal windows

* EPMRPP-79259 || Astericks to mandatory fields, EPMRPP-79263 || Unnecessary placeholders remove (#30)

Co-authored-by: Artsiom Sadouski <artsiom_sadouski@epam.com>

* EPMRPP-81278 || Bump Node.js version for UI build (#31)

* EPMRPP-82260 || Use new modal for Edit integration form (#38)

* EPMRPP-78914 || Redesign integrations. Link updates

(cherry picked from commit 65845a0)

* EPMRPP-86229 || Adjust to new plugin mechanism

* EPMRPP-86229 || Update build.gradle to use new node plugin

* EPMRPP-86229 || Adjust Jira Cloud plugin structure according to the new plugins mechanism (#40)

* EPMRPP-87092 || Update version

---------

Co-authored-by: Ilya Hancharyk <Ilya_Hancharyk@epam.com>
Co-authored-by: Pavel Bortnik <pavel_bortnik@epam.com>
Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: Mikhail Sidarkevich <mikhail_sidarkevich@epam.com>
Co-authored-by: Mikhail Sidarkevich <42434528+chivekrodis@users.noreply.github.com>
Co-authored-by: RuslanLyubimov <105453422+RuslanLyubimov@users.noreply.github.com>
Co-authored-by: Ruslan Lyubimov <ruslan_lyubimov@epam.com>
Co-authored-by: tr1ble <43150561+tr1ble@users.noreply.github.com>
Co-authored-by: Artsiom Sadouski <artsiom_sadouski@epam.com>
Co-authored-by: Ivan_Kustau <Ivan_Kustau@epam.com>
Co-authored-by: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Co-authored-by: Vadim73i <55870906+Vadim73i@users.noreply.github.com>
  • Loading branch information
13 people authored Oct 27, 2023
1 parent 9a34bbb commit 5c56faf
Show file tree
Hide file tree
Showing 19 changed files with 2,892 additions and 901 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id 'java'
id 'jacoco'
id "com.github.spotbugs" version "3.0.0"
id "com.moowork.node" version "1.3.1"
id "com.github.node-gradle.node" version "2.2.1"
id 'nu.studer.jooq' version '3.0.3'
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
version=5.7.3
version=5.7.4
description=EPAM Report Portal. Cloud Jira plugin
pluginId = JIRA Cloud
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.epam.reportportal.extension.jira;

import com.epam.reportportal.extension.*;
import com.epam.reportportal.extension.CommonPluginCommand;
import com.epam.reportportal.extension.IntegrationGroupEnum;
import com.epam.reportportal.extension.NamedPluginCommand;
import com.epam.reportportal.extension.PluginCommand;
import com.epam.reportportal.extension.ReportPortalExtensionPoint;
import com.epam.reportportal.extension.common.IntegrationTypeProperties;
import com.epam.reportportal.extension.event.PluginEvent;
import com.epam.reportportal.extension.event.StartLaunchEvent;
import com.epam.reportportal.extension.jira.command.*;
import com.epam.reportportal.extension.jira.command.GetIssueCommand;
import com.epam.reportportal.extension.jira.command.GetIssueFieldsCommand;
import com.epam.reportportal.extension.jira.command.GetIssueTypesCommand;
import com.epam.reportportal.extension.jira.command.PostTicketCommand;
import com.epam.reportportal.extension.jira.command.RetrieveCreationParamsCommand;
import com.epam.reportportal.extension.jira.command.atlassian.CloudJiraClientProviderExtended;
import com.epam.reportportal.extension.jira.command.binary.GetFileCommand;
import com.epam.reportportal.extension.jira.command.RetrieveUpdateParamsCommand;
import com.epam.reportportal.extension.jira.command.connection.TestConnectionCommand;
import com.epam.reportportal.extension.jira.command.utils.CloudJiraClientProvider;
import com.epam.reportportal.extension.jira.command.utils.JIRATicketDescriptionService;
Expand All @@ -32,12 +41,25 @@
import com.epam.reportportal.extension.jira.utils.MemoizingSupplier;
import com.epam.reportportal.extension.util.RequestEntityConverter;
import com.epam.ta.reportportal.binary.DataStoreService;
import com.epam.ta.reportportal.dao.*;
import com.epam.ta.reportportal.dao.IntegrationRepository;
import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
import com.epam.ta.reportportal.dao.LaunchRepository;
import com.epam.ta.reportportal.dao.LogRepository;
import com.epam.ta.reportportal.dao.ProjectRepository;
import com.epam.ta.reportportal.dao.TestItemRepository;
import com.epam.ta.reportportal.dao.TicketRepository;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import org.jasypt.util.text.BasicTextEncryptor;
import org.jooq.DSLContext;
import org.pf4j.Extension;
Expand All @@ -49,170 +71,168 @@
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
* @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
*/
@Extension
public class CloudJiraExtension implements ReportPortalExtensionPoint, DisposableBean {

private static final String DOCUMENTATION_LINK_FIELD = "documentationLink";
private static final String DOCUMENTATION_LINK = "https://reportportal.io/docs/plugins/JiraCloud";
public static final String BINARY_DATA_PROPERTIES_FILE_ID = "binary-data.properties";
private static final String DOCUMENTATION_LINK_FIELD = "documentationLink";
private static final String DOCUMENTATION_LINK = "https://reportportal.io/docs/plugins/JiraCloud";
public static final String BINARY_DATA_PROPERTIES_FILE_ID = "binary-data.properties";

private static final String PLUGIN_ID = "JIRA Cloud";
private static final String PLUGIN_ID = "JIRA Cloud";

private final String resourcesDir;
private final String resourcesDir;

private final Supplier<Map<String, PluginCommand<?>>> pluginCommandMapping = new MemoizingSupplier<>(this::getCommands);
private final Supplier<Map<String, CommonPluginCommand<?>>> commonPluginCommandMapping = new MemoizingSupplier<>(this::getCommonCommands);
private final Supplier<Map<String, PluginCommand<?>>> pluginCommandMapping =
new MemoizingSupplier<>(this::getCommands);
private final Supplier<Map<String, CommonPluginCommand<?>>> commonPluginCommandMapping =
new MemoizingSupplier<>(this::getCommonCommands);

private final ObjectMapper objectMapper;
private final RequestEntityConverter requestEntityConverter;
private final ObjectMapper objectMapper;
private final RequestEntityConverter requestEntityConverter;

private final Supplier<ApplicationListener<PluginEvent>> pluginLoadedListenerSupplier;
private final Supplier<ApplicationListener<StartLaunchEvent>> startLaunchEventListenerSupplier;
private final Supplier<ApplicationListener<PluginEvent>> pluginLoadedListenerSupplier;
private final Supplier<ApplicationListener<StartLaunchEvent>> startLaunchEventListenerSupplier;

private final Supplier<CloudJiraClientProvider> cloudJiraClientProviderSupplier;
private final Supplier<CloudJiraClientProvider> cloudJiraClientProviderSupplier;
private final Supplier<CloudJiraClientProvider> cloudJiraClientProviderExtendedSupplier;

private final Supplier<JIRATicketDescriptionService> jiraTicketDescriptionServiceSupplier;
private final Supplier<JIRATicketDescriptionService> jiraTicketDescriptionServiceSupplier;

@Autowired
private ApplicationContext applicationContext;
@Autowired
private ApplicationContext applicationContext;

@Autowired
private DSLContext dsl;
@Autowired
private DSLContext dsl;

@Autowired
private IntegrationTypeRepository integrationTypeRepository;
@Autowired
private IntegrationTypeRepository integrationTypeRepository;

@Autowired
private IntegrationRepository integrationRepository;
@Autowired
private IntegrationRepository integrationRepository;

@Autowired
private TicketRepository ticketRepository;
@Autowired
private TicketRepository ticketRepository;

@Autowired
private ProjectRepository projectRepository;
@Autowired
private ProjectRepository projectRepository;

@Autowired
private LaunchRepository launchRepository;
@Autowired
private LaunchRepository launchRepository;

@Autowired
private LogRepository logRepository;
@Autowired
private LogRepository logRepository;

@Autowired
private TestItemRepository testItemRepository;
@Autowired
private TestItemRepository testItemRepository;

@Autowired
private BasicTextEncryptor textEncryptor;
@Autowired
private BasicTextEncryptor textEncryptor;

@Autowired
@Qualifier("attachmentDataStoreService")
private DataStoreService dataStoreService;
@Autowired
@Qualifier("attachmentDataStoreService")
private DataStoreService dataStoreService;

public CloudJiraExtension(Map<String, Object> initParams) {
resourcesDir = IntegrationTypeProperties.RESOURCES_DIRECTORY.getValue(initParams).map(String::valueOf).orElse("");
objectMapper = configureObjectMapper();
public CloudJiraExtension(Map<String, Object> initParams) {
resourcesDir =
IntegrationTypeProperties.RESOURCES_DIRECTORY.getValue(initParams).map(String::valueOf)
.orElse("");
objectMapper = configureObjectMapper();

pluginLoadedListenerSupplier = new MemoizingSupplier<>(() -> new PluginEventListener(PLUGIN_ID, new PluginEventHandlerFactory(
integrationTypeRepository,
integrationRepository,
new PluginInfoProviderImpl(resourcesDir, BINARY_DATA_PROPERTIES_FILE_ID)
)));
startLaunchEventListenerSupplier = new MemoizingSupplier<>(() -> new StartLaunchEventListener(launchRepository));
pluginLoadedListenerSupplier = new MemoizingSupplier<>(() -> new PluginEventListener(
PLUGIN_ID, new PluginEventHandlerFactory(integrationTypeRepository, integrationRepository,
new PluginInfoProviderImpl(resourcesDir, BINARY_DATA_PROPERTIES_FILE_ID)
)));
startLaunchEventListenerSupplier =
new MemoizingSupplier<>(() -> new StartLaunchEventListener(launchRepository));

requestEntityConverter = new RequestEntityConverter(objectMapper);
requestEntityConverter = new RequestEntityConverter(objectMapper);

cloudJiraClientProviderSupplier = new MemoizingSupplier<>(() -> new CloudJiraClientProvider(textEncryptor));
cloudJiraClientProviderSupplier =
new MemoizingSupplier<>(() -> new CloudJiraClientProvider(textEncryptor));
cloudJiraClientProviderExtendedSupplier = new MemoizingSupplier<>(() -> new CloudJiraClientProviderExtended(textEncryptor));

jiraTicketDescriptionServiceSupplier = new MemoizingSupplier<>(() -> new JIRATicketDescriptionService(logRepository,
testItemRepository
));
}

protected ObjectMapper configureObjectMapper() {
ObjectMapper om = new ObjectMapper();
om.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
om.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
om.registerModule(new JavaTimeModule());
return om;
}

@Override
public Map<String, ?> getPluginParams() {
Map<String, Object> params = new HashMap<>();
params.put(ALLOWED_COMMANDS, new ArrayList<>(pluginCommandMapping.get().keySet()));
params.put(DOCUMENTATION_LINK_FIELD, DOCUMENTATION_LINK);
params.put(COMMON_COMMANDS, new ArrayList<>(commonPluginCommandMapping.get().keySet()));
return params;
}

@Override
public PluginCommand<?> getIntegrationCommand(String commandName) {
return pluginCommandMapping.get().get(commandName);
}

@Override
public CommonPluginCommand<?> getCommonCommand(String commandName) {
return commonPluginCommandMapping.get().get(commandName);
}

@Override
public IntegrationGroupEnum getIntegrationGroup() {
return IntegrationGroupEnum.BTS;
}

@PostConstruct
public void createIntegration() {
initListeners();
}

private void initListeners() {
ApplicationEventMulticaster applicationEventMulticaster = applicationContext.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
ApplicationEventMulticaster.class
);
applicationEventMulticaster.addApplicationListener(pluginLoadedListenerSupplier.get());
applicationEventMulticaster.addApplicationListener(startLaunchEventListenerSupplier.get());
}

@Override
public void destroy() {
removeListeners();
}

private void removeListeners() {
ApplicationEventMulticaster applicationEventMulticaster = applicationContext.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
ApplicationEventMulticaster.class
);
applicationEventMulticaster.removeApplicationListener(pluginLoadedListenerSupplier.get());
applicationEventMulticaster.removeApplicationListener(startLaunchEventListenerSupplier.get());
}

private Map<String, CommonPluginCommand<?>> getCommonCommands() {
List<CommonPluginCommand<?>> commands = new ArrayList<>();
commands.add(new RetrieveCreationParamsCommand(textEncryptor));
commands.add(new RetrieveUpdateParamsCommand(textEncryptor));
commands.add(new GetFileCommand(resourcesDir, BINARY_DATA_PROPERTIES_FILE_ID));
commands.add(new GetIssueCommand(ticketRepository, integrationRepository, cloudJiraClientProviderSupplier.get()));
return commands.stream().collect(Collectors.toMap(NamedPluginCommand::getName, it -> it));
}
jiraTicketDescriptionServiceSupplier = new MemoizingSupplier<>(
() -> new JIRATicketDescriptionService(logRepository, testItemRepository));
}

protected ObjectMapper configureObjectMapper() {
ObjectMapper om = new ObjectMapper();
om.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
om.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
om.registerModule(new JavaTimeModule());
return om;
}

@Override
public Map<String, ?> getPluginParams() {
Map<String, Object> params = new HashMap<>();
params.put(ALLOWED_COMMANDS, new ArrayList<>(pluginCommandMapping.get().keySet()));
params.put(DOCUMENTATION_LINK_FIELD, DOCUMENTATION_LINK);
params.put(COMMON_COMMANDS, new ArrayList<>(commonPluginCommandMapping.get().keySet()));
return params;
}

@Override
public PluginCommand<?> getIntegrationCommand(String commandName) {
return pluginCommandMapping.get().get(commandName);
}

@Override
public CommonPluginCommand<?> getCommonCommand(String commandName) {
return commonPluginCommandMapping.get().get(commandName);
}

@Override
public IntegrationGroupEnum getIntegrationGroup() {
return IntegrationGroupEnum.BTS;
}

@PostConstruct
public void createIntegration() {
initListeners();
}

private void initListeners() {
ApplicationEventMulticaster applicationEventMulticaster = applicationContext.getBean(
AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
ApplicationEventMulticaster.class
);
applicationEventMulticaster.addApplicationListener(pluginLoadedListenerSupplier.get());
applicationEventMulticaster.addApplicationListener(startLaunchEventListenerSupplier.get());
}

@Override
public void destroy() {
removeListeners();
}

private void removeListeners() {
ApplicationEventMulticaster applicationEventMulticaster = applicationContext.getBean(
AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
ApplicationEventMulticaster.class
);
applicationEventMulticaster.removeApplicationListener(pluginLoadedListenerSupplier.get());
applicationEventMulticaster.removeApplicationListener(startLaunchEventListenerSupplier.get());
}

private Map<String, CommonPluginCommand<?>> getCommonCommands() {
List<CommonPluginCommand<?>> commands = new ArrayList<>();
commands.add(new RetrieveCreationParamsCommand(textEncryptor));
commands.add(new RetrieveUpdateParamsCommand(textEncryptor));
commands.add(new GetIssueCommand(ticketRepository, integrationRepository,
cloudJiraClientProviderSupplier.get()
));
return commands.stream().collect(Collectors.toMap(NamedPluginCommand::getName, it -> it));
}

private Map<String, PluginCommand<?>> getCommands() {
List<PluginCommand<?>> commands = new ArrayList<>();
commands.add(new TestConnectionCommand(cloudJiraClientProviderSupplier.get()));
commands.add(new GetIssueFieldsCommand(projectRepository, cloudJiraClientProviderExtendedSupplier.get()));
// commands.add(new GetFileCommand(resourcesDir, BINARY_DATA_PROPERTIES_FILE_ID));
commands.add(new GetIssueTypesCommand(projectRepository, cloudJiraClientProviderSupplier.get()));
commands.add(new PostTicketCommand(projectRepository,
requestEntityConverter,
Expand All @@ -222,5 +242,5 @@ private Map<String, PluginCommand<?>> getCommands() {
));
return commands.stream().collect(Collectors.toMap(NamedPluginCommand::getName, it -> it));

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ protected List<PostFormField> invokeCommand(Integration integration, Map<String,

GetCreateIssueMetadataOptions options = new GetCreateIssueMetadataOptionsBuilder().withExpandedIssueTypesFields()
.withProjectKeys(jiraProject.getKey())
.withIssueTypeIds(List.of(issueType.get().getId()))
.build();
Iterable<CimProject> projects = client.getIssueClient().getCreateIssueMetadata(options).claim();
CimProject project = projects.iterator().next();
Expand Down
Loading

0 comments on commit 5c56faf

Please sign in to comment.