Skip to content

Commit

Permalink
chore: migration from BitBucket
Browse files Browse the repository at this point in the history
  • Loading branch information
grigoriev committed Jun 25, 2024
1 parent fc1201a commit 5a67d72
Show file tree
Hide file tree
Showing 39 changed files with 2,576 additions and 22 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Changelog before migration to conventional commits

| Version | Changes |
|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| v2.3.1 | Fix getting custom fields from global configuration |
| v2.3.0 | Skip unused columns during excel file parsing<br/> Excel formulas support<br/> Proper formula errors handling |
| v2.2.1 | Swagger UI has ability to upload files for import operation |
| v2.2.0 | Do not return default settings if requested name does not exists |
| v2.1.4 | Counting unchanged work items (tested types/fields: String, Boolean, Date, Integer, Float, Text, Rich Text, Enum, title, description. other fields are untested) |
| v2.1.3 | Fixed LinkColumn field overwrite: Work-Item field value is only not overwritten if the field is id |
| v2.1.2 | Error and success messages after the import don't vanish anymore<br/> Work-Item value of LinkColumn field is not overwritten anymore (faulty implementation!) |
| v2.1.1 | Multi-value enumeration & date fields fix. 'Mappings' page: 'Default' button removed |
| v2.1.0 | Multi-value enumeration fields: comma-separated values support<br/> New mapping settings feature: 'Overwrite with empty values' |
| v2.0.0 | Named mappings has been introduced<br/> Breaking change modifying the way settings stored<br/> New data types support added<br/> Import is now available for non-admin users |
| v1.2.0 | Apache POI v5.2.4 is used as external OSGi bundle |
| v1.1.1 | Enumeration support extended: standard fields are supported now |
| v1.1.0 | Enumeration support added |
| v1.0.0 | Initial version of Excel Importer |
126 changes: 114 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,138 @@
# Polarion ALM extension to <...>
# Polarion ALM extension to process WorkItems by uploading xlsx-files

This Polarion extension provides possibility to update (or create) WorkItems using xlsx-file.
Column-to-Field mapping is manageable using mapping settings.

This Polarion extension provides possibility to <...>
## Build

This extension can be produced using maven:
```
```bash
mvn clean package
```

## Installation to Polarion

To install the extension to Polarion `ch.sbb.polarion.extension.<extension_name>-<version>.jar`
should be copied to `<polarion_home>/polarion/extensions/ch.sbb.polarion.extension.<extension_name>/eclipse/plugins`
!!! WARNING
Before using this extension you have to ensure that the current Polarion instance contains Apache POI extension v.5.2.x (`<polarion_home>/polarion/extensions/ch.sbb.polarion.thirdparty.bundles.org.apache.poi/eclipse/plugins/org.apache.poi-<version>.jar`).

To install the extension to Polarion, file `ch.sbb.polarion.extension.excel-importer-<version>.jar`
should be copied to `<polarion_home>/polarion/extensions/ch.sbb.polarion.extension.excel-importer/eclipse/plugins`
It can be done manually or automated using maven build:

```bash
mvn clean install -P install-to-local-polarion
```
mvn clean install -P polarion2304,install-to-local-polarion
```

For automated installation with maven env variable `POLARION_HOME` should be defined and point to folder where Polarion is installed.

Changes only take effect after restart of Polarion.

## Polarion configuration

<...>
### Import for non-admin users

1. Open a project where you wish Excel Importer's navigation element to be available
2. On the top of the project's navigation pane click ⚙ (Actions) ➙ 🔧 Administration. Project's administration page will be opened.
3. On the administration's navigation pane select Portal ➙ Topics and click on Edit button of desired View.
4. In opened Topics Configuration editor insert following new topic:
```
<topic id="excel-importer"/>
```
5. Save changes by clicking 💾 Save

## Extension's REST API

## Extension Configuration
### Settings

<...>
Settings may be changed using `/api/settings/mappings/names/{mappingName}` endpoint.
Request body example:

```json
{
"sheetName": "Sheet 1",
"startFromRow": 1,
"columnsMapping": {
"A": "title",
"B": "docId",
"C": "docName"
},
"defaultWorkItemType": "requirement",
"linkColumn": "B"
}
```

## Usage
List of workItem types for project may be accessible using `/api/projects/{projectId}/workitem_types` endpoint.
Request body example:

<...>
```json
[
{
"sequenceNumber": 1,
"name": "User Story",
"hidden": false,
"properties": {
"color": "#F1ED92",
"description": "A functional requirement.",
"iconURL": "/polarion/icons/default/enums/type_userstory.gif"
},
"id": "userstory",
"default": true,
"enumId": "work-item-type",
"phantom": false
},
{
"sequenceNumber": 2,
"name": "Requirement",
"hidden": false,
"properties": {
"color": "#A280A9",
"description": "A nonfunctional requirement.",
"iconURL": "/polarion/icons/default/enums/type_requirement.gif"
},
"id": "requirement",
"default": false,
"enumId": "work-item-type",
"phantom": false
}
]
```

List of workItem fields for project and workitem type may be accessible using `/api/projects/{projectId}/workitem_types/{workItemType}/fields` endpoint.
Request body example:

```json
[
"approvals",
"assignee",
"attachments",
"author",
"categories",
"comments"
]
```

### Import file

Import is accessible by posting a xlsx-file to the `/api/projects/{projectId}/import` endpoint.

Response example:

```json
{
"updatedIds": [
"updated_id1",
"updated_id2"
],
"createdIds": [
"created_id1",
"created_id2"
],
"unchangedIds": [
"unchanged_id1",
"unchanged_id2"
]
}
```

4 changes: 4 additions & 0 deletions lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# tells Lombok that this is the root directory and that it shouldn’t search parent directories for more configuration files
config.stopBubbling = true
# tells Lombok to add @lombok.Generated annotation to all generated methods
lombok.addLombokGeneratedAnnotation = true
20 changes: 15 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@
<parent>
<groupId>ch.sbb.polarion.extensions</groupId>
<artifactId>ch.sbb.polarion.extension.generic.parent-pom</artifactId>
<version>2.0.0</version>
<version>4.11.0</version>
</parent>

<artifactId>ch.sbb.polarion.extension.extension-name</artifactId>
<version>0.0.0-SNAPSHOT</version>
<artifactId>ch.sbb.polarion.extension.excel-importer</artifactId>
<version>2.3.2-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
<maven-jar-plugin.Extension-Context>extension-name</maven-jar-plugin.Extension-Context>
<maven-jar-plugin.Automatic-Module-Name>ch.sbb.polarion.extension.extension_name</maven-jar-plugin.Automatic-Module-Name>
<maven-jar-plugin.Extension-Context>excel-importer</maven-jar-plugin.Extension-Context>
<maven-jar-plugin.Automatic-Module-Name>ch.sbb.polarion.extension.excel_importer</maven-jar-plugin.Automatic-Module-Name>

<web.app.name>${maven-jar-plugin.Extension-Context}</web.app.name>

<org.apache.poi.version>5.2.5</org.apache.poi.version>
</properties>

<dependencies>
Expand All @@ -25,6 +27,13 @@
<artifactId>ch.sbb.polarion.extension.generic.app</artifactId>
<version>${project.parent.version}</version>
</dependency>

<dependency>
<groupId>ch.sbb.polarion.thirdparty.bundles</groupId>
<artifactId>org.apache.poi</artifactId>
<version>${org.apache.poi.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -50,4 +59,5 @@
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ch.sbb.polarion.extension.excel_importer;

import com.polarion.alm.tracker.model.IPriorityOpt;
import com.polarion.platform.persistence.IEnumOption;
import lombok.experimental.UtilityClass;

import java.util.Optional;

@UtilityClass
public class EnumUtils {

/**
* For some options (e.g. 'priority') method getId() returns weird float-like containing strings ("90.0", "50.0" etc.) instead if proper ID.
* Was noticed that proper ID can be accessed from option properties by special key 'standardOptionId'.
*/
public String getEnumId(IEnumOption option) {
return Optional.ofNullable(option.getProperty(IPriorityOpt.PROPERTY_KEY_STD_OPTION_ID)).orElse(option.getId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ch.sbb.polarion.extension.excel_importer;

import ch.sbb.polarion.extension.generic.GenericUiServlet;

import java.io.Serial;

public class ExcelImporterAdminUiServlet extends GenericUiServlet {

@Serial
private static final long serialVersionUID = -6152967412988482486L;

public ExcelImporterAdminUiServlet() {
super("excel-importer-admin");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package ch.sbb.polarion.extension.excel_importer;

import com.polarion.alm.ui.server.navigation.NavigationExtender;
import com.polarion.alm.ui.server.navigation.NavigationExtenderNode;
import com.polarion.subterra.base.data.identification.IContextId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class ExcelImporterNavigationExtender extends NavigationExtender {

public static final String EXCEL_IMPORTER = "excel-importer";

@NotNull
@Override
public String getId() {
return EXCEL_IMPORTER;
}

@NotNull
@Override
public String getLabel() {
return "Excel Importer";
}

@Nullable
@Override
public String getIconUrl() {
return "/polarion/icons/default/topicIcons/documentsAndWiki.svg";
}

@Nullable
@Override
public String getPageUrl(@NotNull IContextId contextId) {
String contextName = contextId.getContextName();
String scope = contextName == null ? "" : "project/%s/".formatted(contextName);
return "/polarion/excel-importer-admin/pages/import_file.jsp?scope=" + scope;
}

@Override
public boolean requiresToken() {
return false;
}

@NotNull
@Override
public List<NavigationExtenderNode> getRootNodes(@NotNull IContextId contextId) {
return new ArrayList<>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ch.sbb.polarion.extension.excel_importer.rest;

import ch.sbb.polarion.extension.excel_importer.rest.controller.ExcelImportApiController;
import ch.sbb.polarion.extension.excel_importer.rest.controller.ExcelImportInternalController;
import ch.sbb.polarion.extension.excel_importer.rest.controller.WorkItemsApiController;
import ch.sbb.polarion.extension.excel_importer.rest.controller.WorkItemsInternalController;
import ch.sbb.polarion.extension.excel_importer.settings.ExcelSheetMappingSettings;
import ch.sbb.polarion.extension.generic.rest.GenericRestApplication;
import ch.sbb.polarion.extension.generic.settings.NamedSettingsRegistry;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Set;

public class ExcelImporterRestApplication extends GenericRestApplication {

public ExcelImporterRestApplication() {
NamedSettingsRegistry.INSTANCE.register(List.of(new ExcelSheetMappingSettings()));
}

@Override
@NotNull
protected Set<Class<?>> getControllerClasses() {
final Set<Class<?>> controllerClasses = super.getControllerClasses();
controllerClasses.addAll(Set.of(
ExcelImportApiController.class,
ExcelImportInternalController.class,
WorkItemsApiController.class,
WorkItemsInternalController.class
));
return controllerClasses;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ch.sbb.polarion.extension.excel_importer.rest.controller;

import ch.sbb.polarion.extension.excel_importer.service.ImportResult;
import ch.sbb.polarion.extension.generic.rest.filter.Secured;

import javax.ws.rs.Path;
import java.io.InputStream;

@Secured
@Path("/api")
public class ExcelImportApiController extends ExcelImportInternalController {

@Override
public ImportResult importExcelSheet(String projectId, String mappingName, InputStream inputStream) {
return polarionServiceExt.callPrivileged(() -> super.importExcelSheet(projectId, mappingName, inputStream));
}
}
Loading

0 comments on commit 5a67d72

Please sign in to comment.