+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-public class Activity {
-
- public enum Type {
- QPROFILE
- }
-
- private Type type;
- private String action;
- private String message;
- private String profileKey;
- private final Map<String, Object> data = new LinkedHashMap<>();
-
- public Type getType() {
- return type;
- }
-
- public void setType(Type type) {
- this.type = type;
- }
-
- public String getAction() {
- return action;
- }
-
- public void setAction(String action) {
- this.action = action;
- }
-
- @CheckForNull
- public String getMessage() {
- return message;
- }
-
- public void setMessage(@Nullable String message) {
- this.message = message;
- }
-
- public Map<String, Object> getData() {
- return data;
- }
-
- public Activity setData(String key, Object val) {
- this.data.put(key, val);
- return this;
- }
-
- public String getProfileKey() {
- return profileKey;
- }
-
- public Activity setProfileKey(String profileKey) {
- this.profileKey = profileKey;
- return this;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity;
-
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.core.util.Uuids;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.activity.ActivityDto;
-import org.sonar.server.activity.index.ActivityIndexer;
-import org.sonar.server.user.UserSession;
-
-public class ActivityService {
-
- private final DbClient dbClient;
- private final ActivityIndexer indexer;
- private final UserSession userSession;
-
- public ActivityService(DbClient dbClient, ActivityIndexer indexer, UserSession userSession) {
- this.dbClient = dbClient;
- this.indexer = indexer;
- this.userSession = userSession;
- }
-
- public void save(Activity activity) {
- ActivityDto dto = new ActivityDto()
- .setKey(Uuids.create())
- .setAuthor(userSession.getLogin())
- .setAction(activity.getAction())
- .setMessage(activity.getMessage())
- .setData(KeyValueFormat.format(activity.getData()))
- .setProfileKey(activity.getProfileKey())
- .setType(activity.getType().name());
- DbSession dbSession = dbClient.openSession(false);
- try {
- dbClient.activityDao().insert(dbSession, dto);
- dbSession.commit();
- indexer.index();
- } finally {
- dbClient.closeSession(dbSession);
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.commons.lang.builder.ReflectionToStringBuilder;
-import org.sonar.server.es.BaseDoc;
-
-public class ActivityDoc extends BaseDoc {
-
- public ActivityDoc(Map<String, Object> fields) {
- super(fields);
- }
-
- @VisibleForTesting
- ActivityDoc() {
- super(new HashMap<>());
- }
-
- @Override
- public String getId() {
- return getKey();
- }
-
- @Override
- public String getRouting() {
- return null;
- }
-
- @Override
- public String getParent() {
- return null;
- }
-
- public void setCreatedAt(Date date) {
- setField(ActivityIndexDefinition.FIELD_CREATED_AT, date);
- }
-
- public Date getCreatedAt() {
- return getFieldAsDate(ActivityIndexDefinition.FIELD_CREATED_AT);
- }
-
- public String getKey() {
- return this.getField(ActivityIndexDefinition.FIELD_KEY);
- }
-
- public void setKey(String s) {
- setField(ActivityIndexDefinition.FIELD_KEY, s);
- }
-
- @CheckForNull
- public String getLogin() {
- return this.getNullableField(ActivityIndexDefinition.FIELD_LOGIN);
- }
-
- public void setLogin(@Nullable String s) {
- setField(ActivityIndexDefinition.FIELD_LOGIN, s);
- }
-
- public String getType() {
- return (String) getField(ActivityIndexDefinition.FIELD_TYPE);
- }
-
- public void setType(String s) {
- setField(ActivityIndexDefinition.FIELD_TYPE, s);
- }
-
- @CheckForNull
- public String getAction() {
- return this.getNullableField(ActivityIndexDefinition.FIELD_ACTION);
- }
-
- public void setAction(@Nullable String s) {
- setField(ActivityIndexDefinition.FIELD_ACTION, s);
- }
-
- public Map<String, String> getDetails() {
- return this.getField(ActivityIndexDefinition.FIELD_DETAILS);
- }
-
- public void setDetails(Map<String, String> details) {
- setField(ActivityIndexDefinition.FIELD_DETAILS, details);
- }
-
- @CheckForNull
- public String getMessage() {
- return this.getNullableField(ActivityIndexDefinition.FIELD_MESSAGE);
- }
-
- public void setMessage(@Nullable String s) {
- setField(ActivityIndexDefinition.FIELD_MESSAGE, s);
- }
-
- @Override
- public String toString() {
- return ReflectionToStringBuilder.toString(this);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import com.google.common.base.Function;
-import java.util.Date;
-import java.util.Map;
-import org.elasticsearch.action.search.SearchRequestBuilder;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.index.query.AndQueryBuilder;
-import org.elasticsearch.index.query.OrQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.sort.SortOrder;
-import org.sonar.core.util.NonNullInputFunction;
-import org.sonar.server.es.BaseIndex;
-import org.sonar.server.es.EsClient;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.es.SearchResult;
-
-public class ActivityIndex extends BaseIndex {
-
- /**
- * Convert an Elasticsearch result (a map) to an {@link org.sonar.server.activity.index.ActivityDoc}. It's
- * used for {@link org.sonar.server.es.SearchResult}.
- */
- private static final Function<Map<String, Object>, ActivityDoc> DOC_CONVERTER = new NonNullInputFunction<Map<String, Object>, ActivityDoc>() {
- @Override
- protected ActivityDoc doApply(Map<String, Object> input) {
- return new ActivityDoc(input);
- }
- };
-
- public ActivityIndex(EsClient esClient) {
- super(esClient);
- }
-
- public SearchResult<ActivityDoc> search(ActivityQuery query, SearchOptions options) {
- SearchResponse response = doSearch(query, options);
- return new SearchResult<>(response, DOC_CONVERTER);
- }
-
- public SearchResponse doSearch(ActivityQuery query, SearchOptions options) {
- SearchRequestBuilder requestBuilder = getClient()
- .prepareSearch(ActivityIndexDefinition.INDEX)
- .setTypes(ActivityIndexDefinition.TYPE);
-
- requestBuilder.setFrom(options.getOffset());
- requestBuilder.setSize(options.getLimit());
- requestBuilder.addSort(ActivityIndexDefinition.FIELD_CREATED_AT, SortOrder.DESC);
-
- AndQueryBuilder filter = QueryBuilders.andQuery();
- if (!query.getTypes().isEmpty()) {
- OrQueryBuilder typeQuery = QueryBuilders.orQuery();
- for (String type : query.getTypes()) {
- typeQuery.add(QueryBuilders.termQuery(ActivityIndexDefinition.FIELD_TYPE, type));
- }
- filter.add(typeQuery);
- }
-
- if (!query.getDataOrFilters().isEmpty()) {
- for (Map.Entry<String, Object> entry : query.getDataOrFilters().entrySet()) {
- OrQueryBuilder orQuery = QueryBuilders.orQuery();
- orQuery.add(QueryBuilders.nestedQuery(ActivityIndexDefinition.FIELD_DETAILS,
- QueryBuilders.termQuery(ActivityIndexDefinition.FIELD_DETAILS + "." + entry.getKey(), entry.getValue())));
- filter.add(orQuery);
- }
- }
-
- Date since = query.getSince();
- if (since != null) {
- filter.add(QueryBuilders.rangeQuery(ActivityIndexDefinition.FIELD_CREATED_AT)
- .gt(since));
- }
- Date to = query.getTo();
- if (to != null) {
- filter.add(QueryBuilders.rangeQuery(ActivityIndexDefinition.FIELD_CREATED_AT)
- .lt(to));
- }
-
- requestBuilder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), filter));
- return requestBuilder.get();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import org.sonar.api.config.Settings;
-import org.sonar.server.es.IndexDefinition;
-import org.sonar.server.es.NewIndex;
-
-/**
- * Definition of ES index "activities", including settings and fields.
- */
-public class ActivityIndexDefinition implements IndexDefinition {
-
- public static final String INDEX = "activities";
- public static final String TYPE = "activity";
- public static final String FIELD_KEY = "key";
- public static final String FIELD_TYPE = "type";
- public static final String FIELD_ACTION = "action";
- public static final String FIELD_CREATED_AT = "createdAt";
- public static final String FIELD_LOGIN = "login";
- public static final String FIELD_DETAILS = "details";
- public static final String FIELD_MESSAGE = "message";
-
- private final Settings settings;
-
- public ActivityIndexDefinition(Settings settings) {
- this.settings = settings;
- }
-
- @Override
- public void define(IndexDefinitionContext context) {
- NewIndex index = context.create(INDEX);
- index.getSettings().put("analysis.analyzer.default.type", "keyword");
- index.configureShards(settings);
- index.refreshHandledByIndexer();
-
- // type "activity"
- NewIndex.NewIndexType mapping = index.createType(TYPE);
- mapping.stringFieldBuilder(FIELD_KEY).disableNorms().build();
- mapping.stringFieldBuilder(FIELD_TYPE).disableNorms().build();
- mapping.stringFieldBuilder(FIELD_ACTION).disableNorms().build();
- mapping.stringFieldBuilder(FIELD_LOGIN).disableNorms().build();
- mapping.createDynamicNestedField(FIELD_DETAILS);
- mapping.stringFieldBuilder(FIELD_MESSAGE).disableNorms().build();
- mapping.createDateTimeField(FIELD_CREATED_AT);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.server.es.BaseIndexer;
-import org.sonar.server.es.BulkIndexer;
-import org.sonar.server.es.EsClient;
-
-/**
- * Add to Elasticsearch index {@link org.sonar.server.activity.index.ActivityIndexDefinition} the rows of
- * db table ACTIVITIES that are not indexed yet
- * <p/>
- */
-public class ActivityIndexer extends BaseIndexer {
-
- private final DbClient dbClient;
-
- public ActivityIndexer(DbClient dbClient, EsClient esClient) {
- super(esClient, 0L, ActivityIndexDefinition.INDEX, ActivityIndexDefinition.TYPE, ActivityIndexDefinition.FIELD_CREATED_AT);
- this.dbClient = dbClient;
- }
-
- @Override
- protected long doIndex(long lastUpdatedAt) {
- BulkIndexer bulk = new BulkIndexer(esClient, ActivityIndexDefinition.INDEX);
- bulk.setLarge(lastUpdatedAt == 0L);
-
- try (
- DbSession dbSession = dbClient.openSession(false);
- ActivityResultSetIterator it = ActivityResultSetIterator.create(dbClient, dbSession, lastUpdatedAt)) {
-
- bulk.start();
- while (it.hasNext()) {
- bulk.add(it.next());
- }
- bulk.stop();
- return it.getMaxRowDate();
-
- }
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class ActivityQuery {
-
- private Date since;
- private Date to;
- private final Collection<String> types = new ArrayList<>();
- private final Map<String, Object> dataOrFilters = new LinkedHashMap<>();
-
- @CheckForNull
- public Date getSince() {
- return since;
- }
-
- public ActivityQuery setSince(@Nullable Date since) {
- this.since = since;
- return this;
- }
-
- @CheckForNull
- public Date getTo() {
- return to;
- }
-
- public ActivityQuery setTo(@Nullable Date to) {
- this.to = to;
- return this;
- }
-
- public Collection<String> getTypes() {
- return types;
- }
-
- public ActivityQuery setTypes(@Nullable Collection<String> types) {
- this.types.clear();
- if (types != null) {
- this.types.addAll(types);
- }
- return this;
- }
-
- public Map<String, Object> getDataOrFilters() {
- return dataOrFilters;
- }
-
- public ActivityQuery addDataOrFilter(String dataKey, Object dataValue) {
- dataOrFilters.put(dataKey, dataValue);
- return this;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.util.Date;
-import java.util.Map;
-import org.apache.commons.lang.StringUtils;
-import org.elasticsearch.action.update.UpdateRequest;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.ResultSetIterator;
-import org.sonar.server.es.EsUtils;
-import org.sonar.server.util.DateCollector;
-
-/**
- * Scrolls over table ACTIVITIES and reads documents to populate
- * the index "activities/activity"
- */
-class ActivityResultSetIterator extends ResultSetIterator<UpdateRequest> {
-
- private static final String[] FIELDS = {
- "log_key",
- "log_action",
- "log_message",
- "data_field",
- "user_login",
- "log_type",
- "created_at",
- "profile_key"
- };
-
- private static final String SQL_ALL = "select " + StringUtils.join(FIELDS, ",") + " from activities ";
-
- private static final String SQL_AFTER_DATE = SQL_ALL + " where created_at>=?";
-
- private final DateCollector dates = new DateCollector();
-
- private ActivityResultSetIterator(PreparedStatement stmt) throws SQLException {
- super(stmt);
- }
-
- static ActivityResultSetIterator create(DbClient dbClient, DbSession session, long afterDate) {
- try {
- String sql = afterDate > 0L ? SQL_AFTER_DATE : SQL_ALL;
- PreparedStatement stmt = dbClient.getMyBatis().newScrollingSelectStatement(session, sql);
- if (afterDate > 0L) {
- stmt.setTimestamp(1, new Timestamp(afterDate));
- }
- return new ActivityResultSetIterator(stmt);
- } catch (SQLException e) {
- throw new IllegalStateException("Fail to prepare SQL request to select activities", e);
- }
- }
-
- @Override
- protected UpdateRequest read(ResultSet rs) throws SQLException {
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- // all the fields must be present, even if value is null
- JsonWriter writer = JsonWriter.of(new OutputStreamWriter(bytes, StandardCharsets.UTF_8)).setSerializeNulls(true);
- writer.beginObject();
- String key = rs.getString(1);
- writer.prop(ActivityIndexDefinition.FIELD_KEY, key);
- writer.prop(ActivityIndexDefinition.FIELD_ACTION, rs.getString(2));
- writer.prop(ActivityIndexDefinition.FIELD_MESSAGE, rs.getString(3));
- Map<String, String> details = KeyValueFormat.parse(rs.getString(4));
- details.put("profileKey", rs.getString(8));
- writer.name(ActivityIndexDefinition.FIELD_DETAILS).valueObject(details);
- writer.prop(ActivityIndexDefinition.FIELD_LOGIN, rs.getString(5));
- writer.prop(ActivityIndexDefinition.FIELD_TYPE, rs.getString(6));
- Date createdAt = rs.getTimestamp(7);
- writer.prop(ActivityIndexDefinition.FIELD_CREATED_AT, EsUtils.formatDateTime(createdAt));
- writer.endObject().close();
- byte[] jsonDoc = bytes.toByteArray();
-
- // it's more efficient to sort programmatically than in SQL on some databases (MySQL for instance)
- dates.add(createdAt);
-
- return new UpdateRequest(ActivityIndexDefinition.INDEX, ActivityIndexDefinition.TYPE, key).doc(jsonDoc).upsert(jsonDoc);
- }
-
- long getMaxRowDate() {
- return dates.getMax();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity;
-
-import javax.annotation.ParametersAreNonnullByDefault;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.server.activity.index.ActivityIndexer;
import org.sonar.server.issue.index.IssueAuthorizationIndexer;
import org.sonar.server.issue.index.IssueIndexer;
import org.sonar.server.test.index.TestIndexer;
private final IssueIndexer issueIndexer;
private final UserIndexer userIndexer;
private final ViewIndexer viewIndexer;
- private final ActivityIndexer activityIndexer;
private final Settings settings;
/**
* {@link org.sonar.server.issue.index.IssueIndexer}
*/
public IndexerStartupTask(TestIndexer testIndexer, IssueAuthorizationIndexer issueAuthorizationIndexer, IssueIndexer issueIndexer,
- UserIndexer userIndexer, ViewIndexer viewIndexer, ActivityIndexer activityIndexer,
+ UserIndexer userIndexer, ViewIndexer viewIndexer,
Settings settings) {
this.testIndexer = testIndexer;
this.issueAuthorizationIndexer = issueAuthorizationIndexer;
this.issueIndexer = issueIndexer;
this.userIndexer = userIndexer;
this.viewIndexer = viewIndexer;
- this.activityIndexer = activityIndexer;
this.settings = settings;
}
public void execute() {
if (!settings.getBoolean("sonar.internal.es.disableIndexes")) {
- LOG.info("Index activities");
- activityIndexer.index();
LOG.info("Index issues");
issueAuthorizationIndexer.index();
import org.sonar.core.component.DefaultResourceTypes;
import org.sonar.core.timemachine.Periods;
import org.sonar.db.permission.PermissionRepository;
-import org.sonar.server.activity.ActivityService;
-import org.sonar.server.activity.index.ActivityIndex;
-import org.sonar.server.activity.index.ActivityIndexDefinition;
-import org.sonar.server.activity.index.ActivityIndexer;
import org.sonar.server.authentication.AuthenticationModule;
import org.sonar.server.batch.BatchWsModule;
import org.sonar.server.ce.ws.CeWsModule;
import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions;
import org.sonar.server.qualityprofile.ws.ChangeParentAction;
import org.sonar.server.qualityprofile.ws.ChangelogAction;
+import org.sonar.server.qualityprofile.ws.ChangelogLoader;
import org.sonar.server.qualityprofile.ws.CompareAction;
import org.sonar.server.qualityprofile.ws.CopyAction;
import org.sonar.server.qualityprofile.ws.CreateAction;
import org.sonar.server.qualityprofile.ws.ProfilesWs;
import org.sonar.server.qualityprofile.ws.ProjectAssociationActions;
import org.sonar.server.qualityprofile.ws.ProjectsAction;
+import org.sonar.server.qualityprofile.ws.QProfileFinder;
import org.sonar.server.qualityprofile.ws.QProfilesWs;
import org.sonar.server.qualityprofile.ws.RenameAction;
import org.sonar.server.qualityprofile.ws.RestoreAction;
BackendCleanup.class,
IndexDefinitions.class,
- // Activity
- ActivityService.class,
- ActivityIndexDefinition.class,
- ActivityIndexer.class,
- ActivityIndex.class,
-
// batch
BatchWsModule.class,
InheritanceAction.class,
ChangeParentAction.class,
ChangelogAction.class,
+ QProfileFinder.class,
+ ChangelogLoader.class,
CompareAction.class,
ExportAction.class,
ExportersAction.class,
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity;
-
-import java.util.List;
-import java.util.Map;
-import org.assertj.core.data.MapEntry;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.config.MapSettings;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbTester;
-import org.sonar.server.activity.index.ActivityDoc;
-import org.sonar.server.activity.index.ActivityIndexDefinition;
-import org.sonar.server.activity.index.ActivityIndexer;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.tester.UserSessionRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ActivityServiceTest {
-
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- @Rule
- public EsTester es = new EsTester(new ActivityIndexDefinition(new MapSettings()));
-
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone().login();
-
- System2 system = mock(System2.class);
- ActivityService service;
-
- @Before
- public void before() {
- DbClient dbClient = db.getDbClient();
- ActivityIndexer indexer = new ActivityIndexer(dbClient, es.client());
- // indexers are disabled by default
- service = new ActivityService(dbClient, indexer, userSession);
- }
-
- @Test
- public void insert_and_index() {
- when(system.now()).thenReturn(1_500_000_000_000L);
-
- Activity activity = new Activity();
- activity.setType(Activity.Type.QPROFILE);
- activity.setAction("THE_ACTION");
- activity.setMessage("THE_MSG");
- activity.setData("foo", "bar");
- activity.setProfileKey("PROFILE_KEY");
- service.save(activity);
-
- Map<String, Object> dbMap = db.selectFirst("select " +
- " log_type as \"type\", " +
- " log_action as \"action\", " +
- " log_message as \"msg\", " +
- " data_field as \"data\", " +
- " profile_key as \"profileKey\" " +
- "from activities");
- assertThat(dbMap).containsEntry("type", "QPROFILE");
- assertThat(dbMap).containsEntry("action", "THE_ACTION");
- assertThat(dbMap).containsEntry("msg", "THE_MSG");
- assertThat(dbMap).containsEntry("profileKey", "PROFILE_KEY");
- assertThat(dbMap.get("data")).isEqualTo("foo=bar");
-
- List<ActivityDoc> docs = es.getDocuments("activities", "activity", ActivityDoc.class);
- assertThat(docs).hasSize(1);
- assertThat(docs.get(0).getKey()).isNotEmpty();
- assertThat(docs.get(0).getAction()).isEqualTo("THE_ACTION");
- assertThat(docs.get(0).getMessage()).isEqualTo("THE_MSG");
- assertThat(docs.get(0).getDetails()).containsOnly(MapEntry.entry("foo", "bar"), MapEntry.entry("profileKey", "PROFILE_KEY"));
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import org.junit.Test;
-import org.sonar.api.config.MapSettings;
-import org.sonar.server.es.IndexDefinition;
-import org.sonar.server.es.NewIndex;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ActivityIndexDefinitionTest {
-
- IndexDefinition.IndexDefinitionContext underTest = new IndexDefinition.IndexDefinitionContext();
-
- @Test
- public void define() {
- ActivityIndexDefinition def = new ActivityIndexDefinition(new MapSettings());
- def.define(underTest);
-
- assertThat(underTest.getIndices()).hasSize(1);
- NewIndex index = underTest.getIndices().get("activities");
- assertThat(index).isNotNull();
- assertThat(index.getTypes().keySet()).containsOnly("activity");
-
- // no cluster by default
- assertThat(index.getSettings().get("index.number_of_shards")).isEqualTo(String.valueOf(NewIndex.DEFAULT_NUMBER_OF_SHARDS));
- assertThat(index.getSettings().get("index.number_of_replicas")).isEqualTo("0");
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Date;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.config.MapSettings;
-import org.sonar.server.activity.Activity;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.es.SearchResult;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ActivityIndexTest {
-
- @Rule
- public EsTester es = new EsTester(new ActivityIndexDefinition(new MapSettings()));
-
- ActivityIndex underTest;
-
- @Before
- public void before() {
- underTest = new ActivityIndex(es.client());
- }
-
- @Test
- public void search_all() throws Exception {
- es.putDocuments("activities", "activity", newDoc(1, 1_500_000_000_000L), newDoc(2, 1_600_000_000_000L));
-
- SearchResult<ActivityDoc> results = underTest.search(new ActivityQuery(), new SearchOptions());
- assertThat(results.getTotal()).isEqualTo(2L);
- assertThat(results.getDocs()).hasSize(2);
- assertThat(results.getDocs()).extracting("message").containsOnly("THE_MSG 1", "THE_MSG 2");
- }
-
- @Test
- public void search_by_data() throws Exception {
- es.putDocuments("activities", "activity", newDoc(1, 1_500_000_000_000L), newDoc(2, 1_600_000_000_000L));
-
- ActivityQuery query = new ActivityQuery();
- query.addDataOrFilter("foo", "bar2");
- SearchResult<ActivityDoc> results = underTest.search(query, new SearchOptions());
- assertThat(results.getDocs()).hasSize(1);
- assertThat(results.getDocs().get(0).getKey()).isEqualTo("UUID2");
- }
-
- @Test
- public void search_by_date() throws Exception {
- es.putDocuments("activities", "activity", newDoc(1, 1_500_000_000_000L), newDoc(2, 1_600_000_000_000L));
-
- ActivityQuery query = new ActivityQuery();
- query.setSince(new Date(1_550_000_000_000L));
- SearchResult<ActivityDoc> results = underTest.search(query, new SearchOptions());
- assertThat(results.getDocs()).hasSize(1);
- assertThat(results.getDocs().get(0).getKey()).isEqualTo("UUID2");
-
- query = new ActivityQuery();
- query.setTo(new Date(1_550_000_000_000L));
- results = underTest.search(query, new SearchOptions());
- assertThat(results.getDocs()).hasSize(1);
- assertThat(results.getDocs().get(0).getKey()).isEqualTo("UUID1");
- }
-
- ActivityDoc newDoc(int id, long date) {
- ActivityDoc doc = new ActivityDoc();
- doc.setKey("UUID" + id);
- doc.setType(Activity.Type.QPROFILE.name());
- doc.setAction("THE_ACTION " + id);
- doc.setMessage("THE_MSG " + id);
- doc.setDetails(ImmutableMap.of("foo", "bar" + id));
- doc.setLogin("THE_GUY " + id);
- doc.setCreatedAt(new Date(date));
- return doc;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.activity.index;
-
-import java.util.Map;
-import org.assertj.core.data.MapEntry;
-import org.elasticsearch.action.update.UpdateRequest;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ActivityResultSetIteratorTest {
-
- @Rule
- public DbTester dbTester = DbTester.create(System2.INSTANCE);
-
- /**
- * Iterate over two rows in table.
- */
- @Test
- public void traverse() {
- dbTester.prepareDbUnit(getClass(), "traverse.xml");
- ActivityResultSetIterator it = ActivityResultSetIterator.create(dbTester.getDbClient(), dbTester.getSession(), 0L);
-
- assertThat(it.hasNext()).isTrue();
- UpdateRequest request = it.next();
- Map<String, Object> doc = request.doc().sourceAsMap();
- assertThat(doc.get(ActivityIndexDefinition.FIELD_KEY)).isEqualTo("UUID1");
- assertThat(doc.get(ActivityIndexDefinition.FIELD_ACTION)).isEqualTo("THE_ACTION");
- assertThat(doc.get(ActivityIndexDefinition.FIELD_MESSAGE)).isEqualTo("THE_MSG");
- assertThat((Map<String, String>) doc.get(ActivityIndexDefinition.FIELD_DETAILS))
- .containsOnly(MapEntry.entry("foo", "bar"), MapEntry.entry("profileKey", "PROFILE_KEY"));
- assertThat(doc.get(ActivityIndexDefinition.FIELD_LOGIN)).isEqualTo("THE_AUTHOR");
-
- assertThat(it.hasNext()).isTrue();
- assertThat(it.next()).isNotNull();
- assertThat(it.hasNext()).isFalse();
- it.close();
-
- assertThat(formatLongDate(it.getMaxRowDate())).startsWith("2015-01-01");
- }
-
- @Test
- public void traverse_after_date() {
- dbTester.prepareDbUnit(getClass(), "traverse.xml");
- ActivityResultSetIterator it = ActivityResultSetIterator.create(dbTester.getDbClient(), dbTester.getSession(), DateUtils.parseDate("2014-12-01").getTime());
-
- assertThat(it.hasNext()).isTrue();
- UpdateRequest request = it.next();
- assertThat(request).isNotNull();
- Map<String, Object> doc = request.doc().sourceAsMap();
- assertThat(doc.get(ActivityIndexDefinition.FIELD_KEY)).isEqualTo("UUID2");
-
- assertThat(it.hasNext()).isFalse();
- it.close();
-
- assertThat(formatLongDate(it.getMaxRowDate())).startsWith("2015-01-01");
- }
-
- @Test
- public void nothing_to_traverse() {
- dbTester.prepareDbUnit(getClass(), "traverse.xml");
- ActivityResultSetIterator it = ActivityResultSetIterator.create(dbTester.getDbClient(), dbTester.getSession(), DateUtils.parseDate("2030-01-01").getTime());
-
- assertThat(it.hasNext()).isFalse();
- it.close();
-
- assertThat(it.getMaxRowDate()).isEqualTo(0L);
- }
-
- private String formatLongDate(long dateInMs) {
- return DateUtils.formatDateTime(DateUtils.longToDate(dateInMs));
- }
-}
+++ /dev/null
-<dataset>
- <activities id="1" log_key="UUID1" log_type="ANALYSIS_REPORT" log_action="THE_ACTION" log_message="THE_MSG"
- created_at="2014-01-01" data_field="foo=bar" user_login="THE_AUTHOR" profile_key="PROFILE_KEY"/>
-
- <activities id="2" log_key="UUID2" log_type="ANALYSIS_REPORT" log_action="THE_ACTION" log_message="THE_MSG"
- created_at="2015-01-01" data_field="foo=bar" user_login="THE_AUTHOR" profile_key="PROFILE_KEY"/>
-</dataset>