toIssue.setAssigneeUuid(fromIssue.assignee());
toIssue.setAuthorLogin(fromIssue.authorLogin());
toIssue.setTags(fromIssue.tags());
- toIssue.setAttributes(fromIssue.attributes());
toIssue.setEffort(debtCalculator.calculate(toIssue));
toIssue.setOnDisabledRule(fromIssue.isOnDisabledRule());
toIssue.setSelectedAt(fromIssue.selectedAt());
defaultIssue.setResolution(next.hasResolution() ? next.getResolution() : null);
defaultIssue.setAssigneeUuid(next.hasAssigneeUuid() ? next.getAssigneeUuid() : null);
defaultIssue.setChecksum(next.hasChecksum() ? next.getChecksum() : null);
- defaultIssue.setAttributes(next.getAttributesMap());
defaultIssue.setAuthorLogin(next.hasAuthorLogin() ? next.getAuthorLogin() : null);
next.getCommentsList().forEach(c -> defaultIssue.addComment(toDefaultIssueComment(c)));
defaultIssue.setTags(ImmutableSet.copyOf(TAGS_SPLITTER.split(next.getTags())));
ofNullable(defaultIssue.resolution()).ifPresent(builder::setResolution);
ofNullable(defaultIssue.assignee()).ifPresent(builder::setAssigneeUuid);
ofNullable(defaultIssue.checksum()).ifPresent(builder::setChecksum);
- ofNullable(defaultIssue.attributes()).ifPresent(builder::putAllAttributes);
ofNullable(defaultIssue.authorLogin()).ifPresent(builder::setAuthorLogin);
defaultIssue.defaultIssueComments().forEach(c -> builder.addComments(toProtoComment(c)));
ofNullable(defaultIssue.tags()).ifPresent(t -> builder.setTags(String.join(TAGS_SEPARATOR, t)));
" i.kee, r.uuid, r.plugin_rule_key, r.plugin_name, i.issue_type," +
" i.component_uuid, i.message, i.line, i.checksum, i.status," +
" i.resolution, i.severity, i.manual_severity, i.gap, effort," +
- " i.assignee, i.author_login, i.tags, i.issue_attributes, i.issue_creation_date," +
+ " i.assignee, i.author_login, i.tags, i.issue_creation_date," +
" i.issue_update_date, i.issue_close_date, i.locations, i.project_uuid" +
" from issues i" +
" join rules r on r.uuid = i.rule_uuid and r.status <> ?" +
.setAssignee(emptyIfNull(rs, 16))
.setAuthor(emptyIfNull(rs, 17))
.setTags(emptyIfNull(rs, 18))
- .setAttributes(emptyIfNull(rs, 19))
- .setIssueCreatedAt(rs.getLong(20))
- .setIssueUpdatedAt(rs.getLong(21))
- .setIssueClosedAt(rs.getLong(22))
- .setProjectUuid(rs.getString(24));
+ .setIssueCreatedAt(rs.getLong(19))
+ .setIssueUpdatedAt(rs.getLong(20))
+ .setIssueClosedAt(rs.getLong(21))
+ .setProjectUuid(rs.getString(23));
setLocations(builder, rs, issueUuid);
return builder.build();
}
private static void setLocations(ProjectDump.Issue.Builder builder, ResultSet rs, String issueUuid) throws SQLException {
try {
- byte[] bytes = rs.getBytes(23);
+ byte[] bytes = rs.getBytes(22);
if (bytes != null) {
// fail fast, ensure we can read data from DB
DbIssues.Locations.parseFrom(bytes);
optional string resolution = 18;
optional string assigneeUuid = 19;
optional string checksum = 20;
- map<string, string> attributes = 21;
optional string authorLogin = 22;
optional string tags = 23;
optional sonarqube.db.issues.Locations locations = 24;
string author = 16;
string tags = 17;
- string attributes = 18;
+
// issue dates
int64 issue_created_at = 19;
int64 issue_updated_at = 20;
*/
package org.sonar.ce.task.projectanalysis.issue;
-import com.google.common.collect.ImmutableMap;
import java.util.Date;
import org.junit.Rule;
import org.junit.Test;
assertThat(raw.isChanged()).isTrue();
}
-
- @Test
- public void mergeExistingOpenIssue_with_attributes() {
- DefaultIssue raw = new DefaultIssue()
- .setNew(true)
- .setKey("RAW_KEY")
- .setRuleKey(XOO_X1);
- DefaultIssue base = new DefaultIssue()
- .setKey("BASE_KEY")
- .setResolution(RESOLUTION_FIXED)
- .setStatus(STATUS_CLOSED)
- .setSeverity(BLOCKER)
- .setAttributes(ImmutableMap.of("JIRA", "SONAR-01"));
-
- underTest.mergeExistingOpenIssue(raw, base);
-
- assertThat(raw.attributes()).containsEntry("JIRA", "SONAR-01");
- }
}
.setAssigneeUuid("assignee-uuid")
.setAuthorLogin("author")
.setTagsString("tags")
- .setIssueAttributes("attributes")
.setIssueCreationTime(963L)
.setIssueUpdateTime(852L)
.setIssueCloseTime(741L);
assertThat(issue.getAssignee()).isEqualTo(issueDto.getAssigneeUuid());
assertThat(issue.getAuthor()).isEqualTo(issueDto.getAuthorLogin());
assertThat(issue.getTags()).isEqualTo(issueDto.getTagsString());
- assertThat(issue.getAttributes()).isEqualTo(issueDto.getIssueAttributes());
assertThat(issue.getIssueCreatedAt()).isEqualTo(issueDto.getIssueCreationTime());
assertThat(issue.getIssueUpdatedAt()).isEqualTo(issueDto.getIssueUpdateTime());
assertThat(issue.getIssueClosedAt()).isEqualTo(issueDto.getIssueCloseTime());
package org.sonar.db.issue;
import com.google.common.base.Joiner;
-import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.Duration;
-import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.protobuf.DbIssues;
private String assigneeUuid;
private String assigneeLogin;
private String authorLogin;
- private String issueAttributes;
private String securityStandards;
private byte[] locations;
private long createdAt;
.setModuleUuidPath(issue.moduleUuidPath())
.setProjectUuid(issue.projectUuid())
.setProjectKey(issue.projectKey())
- .setIssueAttributes(KeyValueFormat.format(issue.attributes()))
.setAuthorLogin(issue.authorLogin())
.setIssueCreationDate(issue.creationDate())
.setIssueCloseDate(issue.closeDate())
.setChecksum(issue.checksum())
.setManualSeverity(issue.manualSeverity())
.setAssigneeUuid(issue.assignee())
- .setIssueAttributes(KeyValueFormat.format(issue.attributes()))
.setAuthorLogin(issue.authorLogin())
.setRuleKey(issue.ruleKey().repository(), issue.ruleKey().rule())
.setExternal(issue.isFromExternalRuleEngine())
return this;
}
- @CheckForNull
- public String getIssueAttributes() {
- return issueAttributes;
- }
-
- public IssueDto setIssueAttributes(@Nullable String s) {
- checkArgument(s == null || s.length() <= 4000, "Value is too long for issue attributes: %s", s);
- this.issueAttributes = s;
- return this;
- }
-
public IssueDto setSecurityStandards(@Nullable String s) {
this.securityStandards = s;
return this;
issue.setChecksum(checksum);
issue.setSeverity(severity);
issue.setAssigneeUuid(assigneeUuid);
- issue.setAttributes(KeyValueFormat.parse(MoreObjects.firstNonNull(issueAttributes, "")));
issue.setComponentKey(componentKey);
issue.setComponentUuid(componentUuid);
issue.setModuleUuid(moduleUuid);
i.assignee as assigneeUuid,
i.author_login as authorLogin,
i.tags as tagsString,
- i.issue_attributes as issueAttributes,
i.issue_creation_date as issueCreationTime,
i.issue_update_date as issueUpdateTime,
i.issue_close_date as issueCloseTime,
i.assignee,
i.author_login,
i.tags,
- i.issue_attributes,
i.issue_creation_date,
i.issue_update_date,
i.issue_close_date,
<insert id="insert" parameterType="Issue" useGeneratedKeys="false">
INSERT INTO issues (kee, rule_uuid, severity, manual_severity,
message, line, locations, gap, effort, status, tags,
- resolution, checksum, assignee, author_login, issue_attributes, issue_creation_date, issue_update_date,
+ resolution, checksum, assignee, author_login, issue_creation_date, issue_update_date,
issue_close_date, created_at, updated_at, component_uuid, project_uuid, issue_type, quick_fix_available)
VALUES (
#{kee,jdbcType=VARCHAR},
#{checksum,jdbcType=VARCHAR},
#{assigneeUuid,jdbcType=VARCHAR},
#{authorLogin,jdbcType=VARCHAR},
- #{issueAttributes,jdbcType=VARCHAR},
#{issueCreationTime,jdbcType=BIGINT},#{issueUpdateTime,jdbcType=BIGINT}, #{issueCloseTime,jdbcType=BIGINT},
#{createdAt,jdbcType=BIGINT}, #{updatedAt,jdbcType=BIGINT},
#{componentUuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER},
author_login=#{authorLogin,jdbcType=VARCHAR},
tags=#{tagsString,jdbcType=VARCHAR},
project_uuid=#{projectUuid,jdbcType=VARCHAR},
- issue_attributes=#{issueAttributes,jdbcType=VARCHAR},
issue_creation_date=#{issueCreationTime,jdbcType=BIGINT},
issue_update_date=#{issueUpdateTime,jdbcType=BIGINT},
issue_close_date=#{issueCloseTime,jdbcType=BIGINT},
tags=#{tagsString,jdbcType=VARCHAR},
component_uuid=#{componentUuid,jdbcType=VARCHAR},
project_uuid=#{projectUuid,jdbcType=VARCHAR},
- issue_attributes=#{issueAttributes,jdbcType=VARCHAR},
issue_creation_date=#{issueCreationTime,jdbcType=BIGINT},
issue_update_date=#{issueUpdateTime,jdbcType=BIGINT},
issue_close_date=#{issueCloseTime,jdbcType=BIGINT},
"STATUS" CHARACTER VARYING(20),
"RESOLUTION" CHARACTER VARYING(20),
"CHECKSUM" CHARACTER VARYING(1000),
- "REPORTER" CHARACTER VARYING(255),
"ASSIGNEE" CHARACTER VARYING(255),
"AUTHOR_LOGIN" CHARACTER VARYING(255),
- "ACTION_PLAN_KEY" CHARACTER VARYING(50),
- "ISSUE_ATTRIBUTES" CHARACTER VARYING(4000),
"EFFORT" INTEGER,
"CREATED_AT" BIGINT,
"UPDATED_AT" BIGINT,
assertThat(issue.getChecksum()).isEqualTo("123456789");
assertThat(issue.getAuthorLogin()).isEqualTo("morgan");
assertThat(issue.getAssigneeUuid()).isEqualTo("karadoc");
- assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
assertThat(issue.getIssueCreationDate()).isNotNull();
assertThat(issue.getIssueUpdateDate()).isNotNull();
assertThat(issue.getIssueCloseDate()).isNotNull();
dto.setSeverity("BLOCKER");
dto.setAuthorLogin("morgan");
dto.setAssigneeUuid("karadoc");
- dto.setIssueAttributes("JIRA=FOO-1234");
dto.setChecksum("123456789");
dto.setMessage("the message");
dto.setCreatedAt(1_440_000_000_000L);
public class IssueDtoTest {
-
- @Test
- public void set_data_check_maximal_length() {
- assertThatThrownBy(() -> {
- StringBuilder s = new StringBuilder(4500);
- for (int i = 0; i < 4500; i++) {
- s.append('a');
- }
- new IssueDto().setIssueAttributes(s.toString());
- })
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessageContaining("Value is too long for issue attributes:");
- }
-
@Test
public void set_issue_fields() {
Date createdAt = DateUtils.addDays(new Date(), -5);
.setMessage("message")
.setManualSeverity(true)
.setAssigneeUuid("perceval")
- .setIssueAttributes("key=value")
.setAuthorLogin("pierre")
.setIssueCreationDate(createdAt)
.setIssueUpdateDate(updatedAt)
assertThat(issue.message()).isEqualTo("message");
assertThat(issue.manualSeverity()).isTrue();
assertThat(issue.assignee()).isEqualTo("perceval");
- assertThat(issue.attribute("key")).isEqualTo("value");
assertThat(issue.authorLogin()).isEqualTo("pierre");
assertThat(issue.creationDate()).isEqualTo(DateUtils.truncate(createdAt, Calendar.SECOND));
assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(updatedAt, Calendar.SECOND));
assertThat(issueDto).extracting(IssueDto::isManualSeverity, IssueDto::getChecksum, IssueDto::getAssigneeUuid,
IssueDto::isExternal, IssueDto::getComponentUuid, IssueDto::getComponentKey, IssueDto::getModuleUuid,
- IssueDto::getModuleUuidPath, IssueDto::getProjectUuid, IssueDto::getProjectKey, IssueDto::getIssueAttributes,
+ IssueDto::getModuleUuidPath, IssueDto::getProjectUuid, IssueDto::getProjectKey,
IssueDto::getRuleUuid)
.containsExactly(true, "123", "123", true, "123", "componentKey", "moduleUuid",
- "path/to/module/uuid", "123", "projectKey", "key=value", "ruleUuid");
+ "path/to/module/uuid", "123", "projectKey", "ruleUuid");
assertThat(issueDto.isQuickFixAvailable()).isTrue();
assertThat(issueDto.isNewCodeReferenceIssue()).isTrue();
assertThat(issueDto).extracting(IssueDto::isManualSeverity, IssueDto::getChecksum, IssueDto::getAssigneeUuid,
IssueDto::isExternal, IssueDto::getComponentUuid, IssueDto::getComponentKey, IssueDto::getModuleUuid,
- IssueDto::getModuleUuidPath, IssueDto::getProjectUuid, IssueDto::getProjectKey, IssueDto::getIssueAttributes)
+ IssueDto::getModuleUuidPath, IssueDto::getProjectUuid, IssueDto::getProjectKey)
.containsExactly(true, "123", "123", true, "123", "componentKey", "moduleUuid",
- "path/to/module/uuid", "123", "projectKey", "key=value");
+ "path/to/module/uuid", "123", "projectKey");
assertThat(issueDto.isQuickFixAvailable()).isTrue();
assertThat(issueDto.isNewCodeReferenceIssue()).isTrue();
.setModuleUuidPath("path/to/module/uuid")
.setProjectUuid("123")
.setProjectKey("projectKey")
- .setAttribute("key", "value")
.setAuthorLogin("admin")
.setCreationDate(dateNow)
.setCloseDate(dateNow)
assertThat(result.getSeverity()).isEqualTo("BLOCKER");
assertThat(result.getAuthorLogin()).isEqualTo("morgan");
assertThat(result.getAssigneeUuid()).isEqualTo("karadoc");
- assertThat(result.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
assertThat(result.getChecksum()).isEqualTo("123456789");
assertThat(result.getMessage()).isEqualTo("the message");
assertThat(result.getIssueCreationTime()).isEqualTo(1_401_000_000_000L);
update.setSeverity("BLOCKER");
update.setAuthorLogin("morgan");
update.setAssigneeUuid("karadoc");
- update.setIssueAttributes("JIRA=FOO-1234");
update.setChecksum("123456789");
update.setMessage("the message");
assertThat(result.getSeverity()).isEqualTo("BLOCKER");
assertThat(result.getAuthorLogin()).isEqualTo("morgan");
assertThat(result.getAssigneeUuid()).isEqualTo("karadoc");
- assertThat(result.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
assertThat(result.getChecksum()).isEqualTo("123456789");
assertThat(result.getMessage()).isEqualTo("the message");
assertThat(result.getIssueCreationTime()).isEqualTo(1_550_000_000_000L);
.setSeverity("BLOCKER")
.setAuthorLogin("morgan")
.setAssigneeUuid("karadoc")
- .setIssueAttributes("JIRA=FOO-1234")
.setChecksum("123456789")
.setMessage("the message")
.setIssueCreationTime(1_401_000_000_000L)
import org.sonar.server.platform.db.migration.version.v91.DbVersion91;
import org.sonar.server.platform.db.migration.version.v92.DbVersion92;
import org.sonar.server.platform.db.migration.version.v93.DbVersion93;
+import org.sonar.server.platform.db.migration.version.v94.DbVersion94;
public class MigrationConfigurationModule extends Module {
@Override
DbVersion91.class,
DbVersion92.class,
DbVersion93.class,
+ DbVersion94.class,
// migration steps
MigrationStepRegistryImpl.class,
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.DatabaseUtils;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public abstract class AbstractDropColumn extends DdlChange {
+
+ private final String tableName;
+ private final String columnName;
+
+ protected AbstractDropColumn(Database db, String tableName, String columnName) {
+ super(db);
+ this.tableName = tableName;
+ this.columnName = columnName;
+ }
+
+ @Override
+ public void execute(DdlChange.Context context) throws SQLException {
+ if (!checkIfUseManagedColumnExists()) {
+ return;
+ }
+
+ context.execute(new DropColumnsBuilder(getDatabase().getDialect(), tableName, columnName).build());
+ }
+
+ private boolean checkIfUseManagedColumnExists() throws SQLException {
+ try (var connection = getDatabase().getDataSource().getConnection()) {
+ if (DatabaseUtils.tableColumnExists(connection, tableName, columnName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import org.sonar.server.platform.db.migration.step.MigrationStepRegistry;
+import org.sonar.server.platform.db.migration.version.DbVersion;
+
+public class DbVersion94 implements DbVersion {
+ @Override
+ public void addSteps(MigrationStepRegistry registry) {
+ registry
+ .add(6301, "Drop unused Issues Column REPORTER", DropReporterIssueColumn.class)
+ .add(6302, "Drop unused Issues Column ACTION_PLAN_KEY", DropActionPlanKeyIssueColumn.class)
+ .add(6303, "Drop unused Issues Column ISSUE_ATTRIBUTES", DropIssuesAttributesIssueColumn.class)
+
+ ;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import org.sonar.db.Database;
+
+public class DropActionPlanKeyIssueColumn extends AbstractDropColumn {
+
+ public static final String TABLE_NAME = "issues";
+ public static final String COLUMN_NAME = "action_plan_key";
+
+ public DropActionPlanKeyIssueColumn(Database db) {
+ super(db, TABLE_NAME, COLUMN_NAME);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import org.sonar.db.Database;
+
+public class DropIssuesAttributesIssueColumn extends AbstractDropColumn{
+
+ public static final String TABLE_NAME = "issues";
+ public static final String COLUMN_NAME = "issue_attributes";
+
+ public DropIssuesAttributesIssueColumn(Database db) {
+ super(db, TABLE_NAME, COLUMN_NAME);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import org.sonar.db.Database;
+
+public class DropReporterIssueColumn extends AbstractDropColumn {
+
+ public static final String TABLE_NAME = "issues";
+ public static final String COLUMN_NAME = "reporter";
+
+ public DropReporterIssueColumn(Database db) {
+ super(db, TABLE_NAME, COLUMN_NAME);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.platform.db.migration.version.v94;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import org.junit.Test;
+
+import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty;
+import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber;
+
+public class DbVersion94Test {
+
+ private final DbVersion94 underTest = new DbVersion94();
+
+ @Test
+ public void migrationNumber_starts_at_6301() {
+ verifyMinimumMigrationNumber(underTest, 6301);
+ }
+
+ @Test
+ public void verify_migration_count() {
+ verifyMigrationNotEmpty(underTest);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class DropActionPlanKeyIssueColumnTest {
+
+ private static final String COLUMN_NAME = "action_plan_key";
+ private static final String TABLE_NAME = "issues";
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(DropActionPlanKeyIssueColumnTest.class, "schema.sql");
+
+ private final DdlChange underTest = new DropActionPlanKeyIssueColumn(db.database());
+
+ @Test
+ public void migration_should_drop_action_plan_column() throws SQLException {
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true);
+ underTest.execute();
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ }
+
+ @Test
+ public void migration_should_be_reentrant() throws SQLException {
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true);
+ underTest.execute();
+ // re-entrant
+ underTest.execute();
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class DropIssuesAttributesIssueColumnTest {
+
+ private static final String COLUMN_NAME = "issue_attributes";
+ private static final String TABLE_NAME = "issues";
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(DropIssuesAttributesIssueColumnTest.class, "schema.sql");
+
+ private final DdlChange underTest = new DropIssuesAttributesIssueColumn(db.database());
+
+ @Test
+ public void migration_should_drop_action_plan_column() throws SQLException {
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true);
+ underTest.execute();
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ }
+
+ @Test
+ public void migration_should_be_reentrant() throws SQLException {
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true);
+ underTest.execute();
+ // re-entrant
+ underTest.execute();
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v94;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+public class DropReporterIssueColumnTest {
+
+ private static final String COLUMN_NAME = "reporter";
+ private static final String TABLE_NAME = "issues";
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(DropReporterIssueColumnTest.class, "schema.sql");
+
+ private final DdlChange underTest = new DropReporterIssueColumn(db.database());
+
+ @Test
+ public void migration_should_drop_action_plan_column() throws SQLException {
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 255, true);
+ underTest.execute();
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ }
+
+ @Test
+ public void migration_should_be_reentrant() throws SQLException {
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 255, true);
+ underTest.execute();
+ // re-entrant
+ underTest.execute();
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ }
+
+}
--- /dev/null
+CREATE TABLE "ISSUES"(
+ "KEE" CHARACTER VARYING(50) NOT NULL,
+ "RULE_UUID" CHARACTER VARYING(40),
+ "SEVERITY" CHARACTER VARYING(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" CHARACTER VARYING(4000),
+ "LINE" INTEGER,
+ "GAP" DOUBLE PRECISION,
+ "STATUS" CHARACTER VARYING(20),
+ "RESOLUTION" CHARACTER VARYING(20),
+ "CHECKSUM" CHARACTER VARYING(1000),
+ "ASSIGNEE" CHARACTER VARYING(255),
+ "AUTHOR_LOGIN" CHARACTER VARYING(255),
+ "ACTION_PLAN_KEY" CHARACTER VARYING(50),
+ "ISSUE_ATTRIBUTES" CHARACTER VARYING(4000),
+ "EFFORT" INTEGER,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT,
+ "ISSUE_CREATION_DATE" BIGINT,
+ "ISSUE_UPDATE_DATE" BIGINT,
+ "ISSUE_CLOSE_DATE" BIGINT,
+ "TAGS" CHARACTER VARYING(4000),
+ "COMPONENT_UUID" CHARACTER VARYING(50),
+ "PROJECT_UUID" CHARACTER VARYING(50),
+ "LOCATIONS" BINARY LARGE OBJECT,
+ "ISSUE_TYPE" TINYINT,
+ "FROM_HOTSPOT" BOOLEAN,
+ "QUICK_FIX_AVAILABLE" BOOLEAN
+);
+ALTER TABLE "ISSUES" ADD CONSTRAINT "PK_ISSUES" PRIMARY KEY("KEE");
+CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES"("ASSIGNEE" NULLS FIRST);
+CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES"("COMPONENT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_CREATION_DATE" ON "ISSUES"("ISSUE_CREATION_DATE" NULLS FIRST);
+CREATE INDEX "ISSUES_PROJECT_UUID" ON "ISSUES"("PROJECT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_RESOLUTION" ON "ISSUES"("RESOLUTION" NULLS FIRST);
+CREATE INDEX "ISSUES_UPDATED_AT" ON "ISSUES"("UPDATED_AT" NULLS FIRST);
+CREATE INDEX "ISSUES_RULE_UUID" ON "ISSUES"("RULE_UUID" NULLS FIRST);
\ No newline at end of file
--- /dev/null
+CREATE TABLE "ISSUES"(
+ "KEE" CHARACTER VARYING(50) NOT NULL,
+ "RULE_UUID" CHARACTER VARYING(40),
+ "SEVERITY" CHARACTER VARYING(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" CHARACTER VARYING(4000),
+ "LINE" INTEGER,
+ "GAP" DOUBLE PRECISION,
+ "STATUS" CHARACTER VARYING(20),
+ "RESOLUTION" CHARACTER VARYING(20),
+ "CHECKSUM" CHARACTER VARYING(1000),
+ "ASSIGNEE" CHARACTER VARYING(255),
+ "AUTHOR_LOGIN" CHARACTER VARYING(255),
+ "ISSUE_ATTRIBUTES" CHARACTER VARYING(4000),
+ "EFFORT" INTEGER,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT,
+ "ISSUE_CREATION_DATE" BIGINT,
+ "ISSUE_UPDATE_DATE" BIGINT,
+ "ISSUE_CLOSE_DATE" BIGINT,
+ "TAGS" CHARACTER VARYING(4000),
+ "COMPONENT_UUID" CHARACTER VARYING(50),
+ "PROJECT_UUID" CHARACTER VARYING(50),
+ "LOCATIONS" BINARY LARGE OBJECT,
+ "ISSUE_TYPE" TINYINT,
+ "FROM_HOTSPOT" BOOLEAN,
+ "QUICK_FIX_AVAILABLE" BOOLEAN
+);
+ALTER TABLE "ISSUES" ADD CONSTRAINT "PK_ISSUES" PRIMARY KEY("KEE");
+CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES"("ASSIGNEE" NULLS FIRST);
+CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES"("COMPONENT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_CREATION_DATE" ON "ISSUES"("ISSUE_CREATION_DATE" NULLS FIRST);
+CREATE INDEX "ISSUES_PROJECT_UUID" ON "ISSUES"("PROJECT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_RESOLUTION" ON "ISSUES"("RESOLUTION" NULLS FIRST);
+CREATE INDEX "ISSUES_UPDATED_AT" ON "ISSUES"("UPDATED_AT" NULLS FIRST);
+CREATE INDEX "ISSUES_RULE_UUID" ON "ISSUES"("RULE_UUID" NULLS FIRST);
--- /dev/null
+CREATE TABLE "ISSUES"(
+ "KEE" CHARACTER VARYING(50) NOT NULL,
+ "RULE_UUID" CHARACTER VARYING(40),
+ "SEVERITY" CHARACTER VARYING(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" CHARACTER VARYING(4000),
+ "LINE" INTEGER,
+ "GAP" DOUBLE PRECISION,
+ "STATUS" CHARACTER VARYING(20),
+ "RESOLUTION" CHARACTER VARYING(20),
+ "CHECKSUM" CHARACTER VARYING(1000),
+ "REPORTER" CHARACTER VARYING(255),
+ "ASSIGNEE" CHARACTER VARYING(255),
+ "AUTHOR_LOGIN" CHARACTER VARYING(255),
+ "ACTION_PLAN_KEY" CHARACTER VARYING(50),
+ "ISSUE_ATTRIBUTES" CHARACTER VARYING(4000),
+ "EFFORT" INTEGER,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT,
+ "ISSUE_CREATION_DATE" BIGINT,
+ "ISSUE_UPDATE_DATE" BIGINT,
+ "ISSUE_CLOSE_DATE" BIGINT,
+ "TAGS" CHARACTER VARYING(4000),
+ "COMPONENT_UUID" CHARACTER VARYING(50),
+ "PROJECT_UUID" CHARACTER VARYING(50),
+ "LOCATIONS" BINARY LARGE OBJECT,
+ "ISSUE_TYPE" TINYINT,
+ "FROM_HOTSPOT" BOOLEAN,
+ "QUICK_FIX_AVAILABLE" BOOLEAN
+);
+ALTER TABLE "ISSUES" ADD CONSTRAINT "PK_ISSUES" PRIMARY KEY("KEE");
+CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES"("ASSIGNEE" NULLS FIRST);
+CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES"("COMPONENT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_CREATION_DATE" ON "ISSUES"("ISSUE_CREATION_DATE" NULLS FIRST);
+CREATE INDEX "ISSUES_PROJECT_UUID" ON "ISSUES"("PROJECT_UUID" NULLS FIRST);
+CREATE INDEX "ISSUES_RESOLUTION" ON "ISSUES"("RESOLUTION" NULLS FIRST);
+CREATE INDEX "ISSUES_UPDATED_AT" ON "ISSUES"("UPDATED_AT" NULLS FIRST);
+CREATE INDEX "ISSUES_RULE_UUID" ON "ISSUES"("RULE_UUID" NULLS FIRST);
\ No newline at end of file
return setEffort(issue, currentEffort, context);
}
- public boolean setAttribute(DefaultIssue issue, String key, @Nullable String value, IssueChangeContext context) {
- String oldValue = issue.attribute(key);
- if (!Objects.equals(oldValue, value)) {
- issue.setFieldChange(context, key, oldValue, value);
- issue.setAttribute(key, value);
- issue.setUpdateDate(context.date());
- issue.setChanged(true);
- return true;
- }
- return false;
- }
-
public boolean setTags(DefaultIssue issue, Collection<String> tags, IssueChangeContext context) {
Set<String> newTags = RuleTagFormat.validate(tags);
assertThat(issue.mustSendNotifications()).isFalse();
}
- @Test
- public void set_new_attribute_value() {
- boolean updated = underTest.setAttribute(issue, "JIRA", "FOO-123", context);
- assertThat(updated).isTrue();
- assertThat(issue.attribute("JIRA")).isEqualTo("FOO-123");
- assertThat(issue.currentChange().diffs()).hasSize(1);
- assertThat(issue.currentChange().get("JIRA").oldValue()).isNull();
- assertThat(issue.currentChange().get("JIRA").newValue()).isEqualTo("FOO-123");
- assertThat(issue.mustSendNotifications()).isFalse();
- }
-
- @Test
- public void unset_attribute() {
- issue.setAttribute("JIRA", "FOO-123");
- boolean updated = underTest.setAttribute(issue, "JIRA", null, context);
- assertThat(updated).isTrue();
- assertThat(issue.attribute("JIRA")).isNull();
- assertThat(issue.currentChange().diffs()).hasSize(1);
- assertThat(issue.currentChange().get("JIRA").oldValue()).isEqualTo("FOO-123");
- assertThat(issue.currentChange().get("JIRA").newValue()).isNull();
- assertThat(issue.mustSendNotifications()).isFalse();
- }
-
- @Test
- public void not_update_attribute() {
- issue.setAttribute("JIRA", "FOO-123");
- boolean updated = underTest.setAttribute(issue, "JIRA", "FOO-123", context);
- assertThat(updated).isFalse();
- assertThat(issue.mustSendNotifications()).isFalse();
- }
-
@Test
public void set_gap_to_fix() {
boolean updated = underTest.setGap(issue, 3.14, context);
.setMessage(null)
.setLine(444)
.setRuleUuid(rule.getUuid())
- .setIssueAttributes("JIRA=http://jira.com")
.setTags(List.of("tag1", "tag2", "tag3"))
.setCreatedAt(1400000000000L)
.setUpdatedAt(1400000000000L)
t -> t
.setAssigneeUuid("uuid-of-guy1")
.setAuthorLogin("guy2")
- .setRuleUuid(rule.getUuid())
- .setIssueAttributes("JIRA=http://jira.com")
.setEffort(10L)
.setType(1));
IssueDto moduleIssue = dbTester.issues().insert(rule, project, module, t -> t
.setAssigneeUuid("uuid-of-guy2")
.setAuthorLogin("guy2")
- .setRuleUuid(rule.getUuid())
- .setIssueAttributes("JIRA=http://jira.com"));
+ .setRuleUuid(rule.getUuid()));
IssueDto dirIssue = dbTester.issues().insert(rule, project, directory);
IssueDto projectIssue = dbTester.issues().insert(rule, project, project);
.setResolution("OPEN")
.setStatus("OPEN")
.setSeverity("BLOCKER")
- .setAttribute("foo", "bar")
.addComment(comment)
.setCreationDate(date)
.setUpdateDate(date)
.setResolution("OPEN")
.setStatus("OPEN")
.setSeverity("BLOCKER")
- .setAttribute("foo", "bar")
.setCreationDate(date)
.setUpdateDate(date)
.setCloseDate(date);
.setResolution("FIXED")
.setStatus("RESOLVED")
.setSeverity("MAJOR")
- .setAttribute("fox", "bax")
.setCreationDate(DateUtils.addDays(date, 1))
.setUpdateDate(DateUtils.addDays(date, 1))
.setCloseDate(DateUtils.addDays(date, 1))
.containsEntry("CHECKSUM", updated.checksum())
.containsEntry("COMPONENT_UUID", issue.componentUuid())
.containsEntry("EFFORT", updated.effortInMinutes())
- .containsEntry("ISSUE_ATTRIBUTES", "fox=bax")
.containsEntry("ISSUE_TYPE", 3L)
.containsEntry("KEE", issue.key())
.containsEntry("LINE", (long) updated.line())
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.io.Serializable;
import java.util.ArrayList;
private String resolution;
private String assigneeUuid;
private String checksum;
- private Map<String, String> attributes = null;
private String authorLogin = null;
private List<DefaultIssueComment> comments = null;
private Set<String> tags = null;
return this;
}
+ /**
+ * @deprecated since 9.4, attribute was already not returning any element since 5.2
+ */
+ @Deprecated
@Override
@CheckForNull
public String attribute(String key) {
- return attributes == null ? null : attributes.get(key);
- }
-
- public DefaultIssue setAttribute(String key, @Nullable String value) {
- if (attributes == null) {
- attributes = new HashMap<>();
- }
- if (value == null) {
- attributes.remove(key);
- } else {
- attributes.put(key, value);
- }
- return this;
+ return null;
}
+ /**
+ * @deprecated since 9.4, attribute was already not returning any element since 5.2
+ */
+ @Deprecated
@Override
public Map<String, String> attributes() {
- return attributes == null ? Collections.emptyMap() : ImmutableMap.copyOf(attributes);
- }
-
- public DefaultIssue setAttributes(@Nullable Map<String, String> map) {
- if (map != null) {
- if (attributes == null) {
- attributes = new HashMap<>();
- }
- attributes.putAll(map);
- }
- return this;
+ return new HashMap<>();
}
@Override
assertThat(issue.selectedAt()).isNull();
}
- @Test
- public void test_attributes() {
- assertThat(issue.attribute("foo")).isNull();
- issue.setAttribute("foo", "bar");
- assertThat(issue.attribute("foo")).isEqualTo("bar");
- issue.setAttribute("foo", "newbar");
- assertThat(issue.attribute("foo")).isEqualTo("newbar");
- issue.setAttribute("foo", null);
- assertThat(issue.attribute("foo")).isNull();
- }
-
- @Test
- public void setAttributes_should_not_clear_existing_values() {
- issue.setAttributes(ImmutableMap.of("1", "one"));
- assertThat(issue.attribute("1")).isEqualTo("one");
-
- issue.setAttributes(ImmutableMap.of("2", "two"));
- assertThat(issue.attributes()).containsOnly(entry("1", "one"), entry("2", "two"));
-
- issue.setAttributes(null);
- assertThat(issue.attributes()).containsOnly(entry("1", "one"), entry("2", "two"));
- }
-
@Test
public void fail_on_empty_status() {
try {
@CheckForNull
Date closeDate();
+ /**
+ * @deprecated since 9.4, attribute was already not returning any element since 5.2
+ */
+ @Deprecated
@CheckForNull
String attribute(String key);
* Empty on batch side since version 5.2. Attributes are moved to server's Compute Engine. No use-case for keeping them
* on batch side for now
*/
+ /**
+ * @deprecated since 9.4, attribute was already not returning any element since 5.2
+ */
+ @Deprecated
Map<String, String> attributes();
/**