diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java index 97c678b4f088..459750d09c63 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java @@ -66,20 +66,20 @@ private void recursivelyProcessComponent(DbSession session, ComputationContext c processEvents(session, component, context.getReportMetadata().getAnalysisDate()); createVersionEvent(session, component, context.getReportMetadata().getAnalysisDate()); - for (Integer childRef : component.getChildRefsList()) { + for (Integer childRef : component.getChildRefList()) { recursivelyProcessComponent(session, context, childRef); } } private void processEvents(DbSession session, BatchReport.Component component, Long analysisDate) { - List events = component.getEventsList(); + List events = component.getEventList(); if (!events.isEmpty()) { - for (BatchReport.Event event : component.getEventsList()) { + for (BatchReport.Event event : component.getEventList()) { dbClient.eventDao().insert(session, createBaseEvent(component, analysisDate) - .setName(event.getName()) - .setCategory(convertCategory(event.getCategory())) - .setDescription(event.hasDescription() ? event.getDescription() : null) - .setData(event.hasEventData() ? event.getEventData() : null) + .setName(event.getName()) + .setCategory(convertCategory(event.getCategory())) + .setDescription(event.hasDescription() ? event.getDescription() : null) + .setData(event.hasEventData() ? event.getEventData() : null) ); } } @@ -89,13 +89,13 @@ private void createVersionEvent(DbSession session, BatchReport.Component compone if (component.hasVersion()) { deletePreviousEventsHavingSameVersion(session, component); dbClient.eventDao().insert(session, createBaseEvent(component, analysisDate) - .setName(component.getVersion()) - .setCategory(EventDto.CATEGORY_VERSION) + .setName(component.getVersion()) + .setCategory(EventDto.CATEGORY_VERSION) ); } } - private void deletePreviousEventsHavingSameVersion(DbSession session, BatchReport.Component component){ + private void deletePreviousEventsHavingSameVersion(DbSession session, BatchReport.Component component) { for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, component.getUuid())) { if (dto.getCategory().equals(EventDto.CATEGORY_VERSION) && dto.getName().equals(component.getVersion())) { dbClient.eventDao().delete(session, dto.getId()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java index 422411269ef2..5e4d769ed77e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java @@ -121,17 +121,17 @@ public void persist_report_events() throws Exception { .setType(Constants.ComponentType.PROJECT) .setUuid("ABCD") .setSnapshotId(1000L) - .addEvents(BatchReport.Event.newBuilder() - .setName("Red (was Orange)") - .setCategory(Constants.EventCategory.ALERT) - .setDescription("Open issues > 0") - .build() + .addEvent(BatchReport.Event.newBuilder() + .setName("Red (was Orange)") + .setCategory(Constants.EventCategory.ALERT) + .setDescription("Open issues > 0") + .build() ) - .addEvents(BatchReport.Event.newBuilder() - .setName("Changes in 'Default' (Java)") - .setCategory(Constants.EventCategory.PROFILE) - .setEventData("from=2014-10-12T08:36:25+0000;key=java-default;to=2014-10-12T10:36:25+0000") - .build() + .addEvent(BatchReport.Event.newBuilder() + .setName("Changes in 'Default' (Java)") + .setCategory(Constants.EventCategory.PROFILE) + .setEventData("from=2014-10-12T08:36:25+0000;key=java-default;to=2014-10-12T10:36:25+0000") + .build() ) .build()); diff --git a/sonar-batch-protocol/src/main/gen-java/org/sonar/batch/protocol/output/BatchReport.java b/sonar-batch-protocol/src/main/gen-java/org/sonar/batch/protocol/output/BatchReport.java index 19f233b6ebb7..194512a355f1 100644 --- a/sonar-batch-protocol/src/main/gen-java/org/sonar/batch/protocol/output/BatchReport.java +++ b/sonar-batch-protocol/src/main/gen-java/org/sonar/batch/protocol/output/BatchReport.java @@ -2535,29 +2535,29 @@ org.sonar.batch.protocol.output.BatchReport.ComponentLinkOrBuilder getLinkOrBuil com.google.protobuf.ByteString getUuidBytes(); - // repeated .Event events = 11; + // repeated .Event event = 11; /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ java.util.List - getEventsList(); + getEventList(); /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - org.sonar.batch.protocol.output.BatchReport.Event getEvents(int index); + org.sonar.batch.protocol.output.BatchReport.Event getEvent(int index); /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - int getEventsCount(); + int getEventCount(); /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ java.util.List - getEventsOrBuilderList(); + getEventOrBuilderList(); /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - org.sonar.batch.protocol.output.BatchReport.EventOrBuilder getEventsOrBuilder( + org.sonar.batch.protocol.output.BatchReport.EventOrBuilder getEventOrBuilder( int index); } /** @@ -2688,10 +2688,10 @@ private Component( } case 90: { if (!((mutable_bitField0_ & 0x00000800) == 0x00000800)) { - events_ = new java.util.ArrayList(); + event_ = new java.util.ArrayList(); mutable_bitField0_ |= 0x00000800; } - events_.add(input.readMessage(org.sonar.batch.protocol.output.BatchReport.Event.PARSER, extensionRegistry)); + event_.add(input.readMessage(org.sonar.batch.protocol.output.BatchReport.Event.PARSER, extensionRegistry)); break; } case 98: { @@ -2714,7 +2714,7 @@ private Component( link_ = java.util.Collections.unmodifiableList(link_); } if (((mutable_bitField0_ & 0x00000800) == 0x00000800)) { - events_ = java.util.Collections.unmodifiableList(events_); + event_ = java.util.Collections.unmodifiableList(event_); } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); @@ -3107,40 +3107,40 @@ public java.lang.String getUuid() { } } - // repeated .Event events = 11; - public static final int EVENTS_FIELD_NUMBER = 11; - private java.util.List events_; + // repeated .Event event = 11; + public static final int EVENT_FIELD_NUMBER = 11; + private java.util.List event_; /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public java.util.List getEventsList() { - return events_; + public java.util.List getEventList() { + return event_; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ public java.util.List - getEventsOrBuilderList() { - return events_; + getEventOrBuilderList() { + return event_; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public int getEventsCount() { - return events_.size(); + public int getEventCount() { + return event_.size(); } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public org.sonar.batch.protocol.output.BatchReport.Event getEvents(int index) { - return events_.get(index); + public org.sonar.batch.protocol.output.BatchReport.Event getEvent(int index) { + return event_.get(index); } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public org.sonar.batch.protocol.output.BatchReport.EventOrBuilder getEventsOrBuilder( + public org.sonar.batch.protocol.output.BatchReport.EventOrBuilder getEventOrBuilder( int index) { - return events_.get(index); + return event_.get(index); } private void initFields() { @@ -3155,7 +3155,7 @@ private void initFields() { version_ = ""; snapshotId_ = 0L; uuid_ = ""; - events_ = java.util.Collections.emptyList(); + event_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -3203,8 +3203,8 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) for (int i = 0; i < link_.size(); i++) { output.writeMessage(10, link_.get(i)); } - for (int i = 0; i < events_.size(); i++) { - output.writeMessage(11, events_.get(i)); + for (int i = 0; i < event_.size(); i++) { + output.writeMessage(11, event_.get(i)); } if (((bitField0_ & 0x00000040) == 0x00000040)) { output.writeBytes(12, getVersionBytes()); @@ -3268,9 +3268,9 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(10, link_.get(i)); } - for (int i = 0; i < events_.size(); i++) { + for (int i = 0; i < event_.size(); i++) { size += com.google.protobuf.CodedOutputStream - .computeMessageSize(11, events_.get(i)); + .computeMessageSize(11, event_.get(i)); } if (((bitField0_ & 0x00000040) == 0x00000040)) { size += com.google.protobuf.CodedOutputStream @@ -3385,7 +3385,7 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { getLinkFieldBuilder(); - getEventsFieldBuilder(); + getEventFieldBuilder(); } } private static Builder create() { @@ -3420,11 +3420,11 @@ public Builder clear() { bitField0_ = (bitField0_ & ~0x00000200); uuid_ = ""; bitField0_ = (bitField0_ & ~0x00000400); - if (eventsBuilder_ == null) { - events_ = java.util.Collections.emptyList(); + if (eventBuilder_ == null) { + event_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000800); } else { - eventsBuilder_.clear(); + eventBuilder_.clear(); } return this; } @@ -3504,14 +3504,14 @@ public org.sonar.batch.protocol.output.BatchReport.Component buildPartial() { to_bitField0_ |= 0x00000100; } result.uuid_ = uuid_; - if (eventsBuilder_ == null) { + if (eventBuilder_ == null) { if (((bitField0_ & 0x00000800) == 0x00000800)) { - events_ = java.util.Collections.unmodifiableList(events_); + event_ = java.util.Collections.unmodifiableList(event_); bitField0_ = (bitField0_ & ~0x00000800); } - result.events_ = events_; + result.event_ = event_; } else { - result.events_ = eventsBuilder_.build(); + result.event_ = eventBuilder_.build(); } result.bitField0_ = to_bitField0_; onBuilt(); @@ -3602,29 +3602,29 @@ public Builder mergeFrom(org.sonar.batch.protocol.output.BatchReport.Component o uuid_ = other.uuid_; onChanged(); } - if (eventsBuilder_ == null) { - if (!other.events_.isEmpty()) { - if (events_.isEmpty()) { - events_ = other.events_; + if (eventBuilder_ == null) { + if (!other.event_.isEmpty()) { + if (event_.isEmpty()) { + event_ = other.event_; bitField0_ = (bitField0_ & ~0x00000800); } else { - ensureEventsIsMutable(); - events_.addAll(other.events_); + ensureEventIsMutable(); + event_.addAll(other.event_); } onChanged(); } } else { - if (!other.events_.isEmpty()) { - if (eventsBuilder_.isEmpty()) { - eventsBuilder_.dispose(); - eventsBuilder_ = null; - events_ = other.events_; + if (!other.event_.isEmpty()) { + if (eventBuilder_.isEmpty()) { + eventBuilder_.dispose(); + eventBuilder_ = null; + event_ = other.event_; bitField0_ = (bitField0_ & ~0x00000800); - eventsBuilder_ = + eventBuilder_ = com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? - getEventsFieldBuilder() : null; + getEventFieldBuilder() : null; } else { - eventsBuilder_.addAllMessages(other.events_); + eventBuilder_.addAllMessages(other.event_); } } } @@ -4506,244 +4506,244 @@ public Builder setUuidBytes( return this; } - // repeated .Event events = 11; - private java.util.List events_ = + // repeated .Event event = 11; + private java.util.List event_ = java.util.Collections.emptyList(); - private void ensureEventsIsMutable() { + private void ensureEventIsMutable() { if (!((bitField0_ & 0x00000800) == 0x00000800)) { - events_ = new java.util.ArrayList(events_); + event_ = new java.util.ArrayList(event_); bitField0_ |= 0x00000800; } } private com.google.protobuf.RepeatedFieldBuilder< - org.sonar.batch.protocol.output.BatchReport.Event, org.sonar.batch.protocol.output.BatchReport.Event.Builder, org.sonar.batch.protocol.output.BatchReport.EventOrBuilder> eventsBuilder_; + org.sonar.batch.protocol.output.BatchReport.Event, org.sonar.batch.protocol.output.BatchReport.Event.Builder, org.sonar.batch.protocol.output.BatchReport.EventOrBuilder> eventBuilder_; /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public java.util.List getEventsList() { - if (eventsBuilder_ == null) { - return java.util.Collections.unmodifiableList(events_); + public java.util.List getEventList() { + if (eventBuilder_ == null) { + return java.util.Collections.unmodifiableList(event_); } else { - return eventsBuilder_.getMessageList(); + return eventBuilder_.getMessageList(); } } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public int getEventsCount() { - if (eventsBuilder_ == null) { - return events_.size(); + public int getEventCount() { + if (eventBuilder_ == null) { + return event_.size(); } else { - return eventsBuilder_.getCount(); + return eventBuilder_.getCount(); } } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public org.sonar.batch.protocol.output.BatchReport.Event getEvents(int index) { - if (eventsBuilder_ == null) { - return events_.get(index); + public org.sonar.batch.protocol.output.BatchReport.Event getEvent(int index) { + if (eventBuilder_ == null) { + return event_.get(index); } else { - return eventsBuilder_.getMessage(index); + return eventBuilder_.getMessage(index); } } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder setEvents( + public Builder setEvent( int index, org.sonar.batch.protocol.output.BatchReport.Event value) { - if (eventsBuilder_ == null) { + if (eventBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - ensureEventsIsMutable(); - events_.set(index, value); + ensureEventIsMutable(); + event_.set(index, value); onChanged(); } else { - eventsBuilder_.setMessage(index, value); + eventBuilder_.setMessage(index, value); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder setEvents( + public Builder setEvent( int index, org.sonar.batch.protocol.output.BatchReport.Event.Builder builderForValue) { - if (eventsBuilder_ == null) { - ensureEventsIsMutable(); - events_.set(index, builderForValue.build()); + if (eventBuilder_ == null) { + ensureEventIsMutable(); + event_.set(index, builderForValue.build()); onChanged(); } else { - eventsBuilder_.setMessage(index, builderForValue.build()); + eventBuilder_.setMessage(index, builderForValue.build()); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder addEvents(org.sonar.batch.protocol.output.BatchReport.Event value) { - if (eventsBuilder_ == null) { + public Builder addEvent(org.sonar.batch.protocol.output.BatchReport.Event value) { + if (eventBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - ensureEventsIsMutable(); - events_.add(value); + ensureEventIsMutable(); + event_.add(value); onChanged(); } else { - eventsBuilder_.addMessage(value); + eventBuilder_.addMessage(value); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder addEvents( + public Builder addEvent( int index, org.sonar.batch.protocol.output.BatchReport.Event value) { - if (eventsBuilder_ == null) { + if (eventBuilder_ == null) { if (value == null) { throw new NullPointerException(); } - ensureEventsIsMutable(); - events_.add(index, value); + ensureEventIsMutable(); + event_.add(index, value); onChanged(); } else { - eventsBuilder_.addMessage(index, value); + eventBuilder_.addMessage(index, value); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder addEvents( + public Builder addEvent( org.sonar.batch.protocol.output.BatchReport.Event.Builder builderForValue) { - if (eventsBuilder_ == null) { - ensureEventsIsMutable(); - events_.add(builderForValue.build()); + if (eventBuilder_ == null) { + ensureEventIsMutable(); + event_.add(builderForValue.build()); onChanged(); } else { - eventsBuilder_.addMessage(builderForValue.build()); + eventBuilder_.addMessage(builderForValue.build()); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder addEvents( + public Builder addEvent( int index, org.sonar.batch.protocol.output.BatchReport.Event.Builder builderForValue) { - if (eventsBuilder_ == null) { - ensureEventsIsMutable(); - events_.add(index, builderForValue.build()); + if (eventBuilder_ == null) { + ensureEventIsMutable(); + event_.add(index, builderForValue.build()); onChanged(); } else { - eventsBuilder_.addMessage(index, builderForValue.build()); + eventBuilder_.addMessage(index, builderForValue.build()); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder addAllEvents( + public Builder addAllEvent( java.lang.Iterable values) { - if (eventsBuilder_ == null) { - ensureEventsIsMutable(); - super.addAll(values, events_); + if (eventBuilder_ == null) { + ensureEventIsMutable(); + super.addAll(values, event_); onChanged(); } else { - eventsBuilder_.addAllMessages(values); + eventBuilder_.addAllMessages(values); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder clearEvents() { - if (eventsBuilder_ == null) { - events_ = java.util.Collections.emptyList(); + public Builder clearEvent() { + if (eventBuilder_ == null) { + event_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000800); onChanged(); } else { - eventsBuilder_.clear(); + eventBuilder_.clear(); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public Builder removeEvents(int index) { - if (eventsBuilder_ == null) { - ensureEventsIsMutable(); - events_.remove(index); + public Builder removeEvent(int index) { + if (eventBuilder_ == null) { + ensureEventIsMutable(); + event_.remove(index); onChanged(); } else { - eventsBuilder_.remove(index); + eventBuilder_.remove(index); } return this; } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public org.sonar.batch.protocol.output.BatchReport.Event.Builder getEventsBuilder( + public org.sonar.batch.protocol.output.BatchReport.Event.Builder getEventBuilder( int index) { - return getEventsFieldBuilder().getBuilder(index); + return getEventFieldBuilder().getBuilder(index); } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public org.sonar.batch.protocol.output.BatchReport.EventOrBuilder getEventsOrBuilder( + public org.sonar.batch.protocol.output.BatchReport.EventOrBuilder getEventOrBuilder( int index) { - if (eventsBuilder_ == null) { - return events_.get(index); } else { - return eventsBuilder_.getMessageOrBuilder(index); + if (eventBuilder_ == null) { + return event_.get(index); } else { + return eventBuilder_.getMessageOrBuilder(index); } } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ public java.util.List - getEventsOrBuilderList() { - if (eventsBuilder_ != null) { - return eventsBuilder_.getMessageOrBuilderList(); + getEventOrBuilderList() { + if (eventBuilder_ != null) { + return eventBuilder_.getMessageOrBuilderList(); } else { - return java.util.Collections.unmodifiableList(events_); + return java.util.Collections.unmodifiableList(event_); } } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public org.sonar.batch.protocol.output.BatchReport.Event.Builder addEventsBuilder() { - return getEventsFieldBuilder().addBuilder( + public org.sonar.batch.protocol.output.BatchReport.Event.Builder addEventBuilder() { + return getEventFieldBuilder().addBuilder( org.sonar.batch.protocol.output.BatchReport.Event.getDefaultInstance()); } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ - public org.sonar.batch.protocol.output.BatchReport.Event.Builder addEventsBuilder( + public org.sonar.batch.protocol.output.BatchReport.Event.Builder addEventBuilder( int index) { - return getEventsFieldBuilder().addBuilder( + return getEventFieldBuilder().addBuilder( index, org.sonar.batch.protocol.output.BatchReport.Event.getDefaultInstance()); } /** - * repeated .Event events = 11; + * repeated .Event event = 11; */ public java.util.List - getEventsBuilderList() { - return getEventsFieldBuilder().getBuilderList(); + getEventBuilderList() { + return getEventFieldBuilder().getBuilderList(); } private com.google.protobuf.RepeatedFieldBuilder< org.sonar.batch.protocol.output.BatchReport.Event, org.sonar.batch.protocol.output.BatchReport.Event.Builder, org.sonar.batch.protocol.output.BatchReport.EventOrBuilder> - getEventsFieldBuilder() { - if (eventsBuilder_ == null) { - eventsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + getEventFieldBuilder() { + if (eventBuilder_ == null) { + eventBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< org.sonar.batch.protocol.output.BatchReport.Event, org.sonar.batch.protocol.output.BatchReport.Event.Builder, org.sonar.batch.protocol.output.BatchReport.EventOrBuilder>( - events_, + event_, ((bitField0_ & 0x00000800) == 0x00000800), getParentForChildren(), isClean()); - events_ = null; + event_ = null; } - return eventsBuilder_; + return eventBuilder_; } // @@protoc_insertion_point(builder_scope:Component) @@ -9308,29 +9308,29 @@ public Builder setComponentUuidBytes( "(\t\"w\n\005Event\022\025\n\rcomponent_ref\030\001 \001(\005\022\014\n\004na" + "me\030\002 \001(\t\022\023\n\013description\030\003 \001(\t\022 \n\010categor" + "y\030\004 \001(\0162\016.EventCategory\022\022\n\nevent_data\030\005 " + - "\001(\t\"\366\001\n\tComponent\022\013\n\003ref\030\001 \001(\005\022\014\n\004path\030\002", + "\001(\t\"\365\001\n\tComponent\022\013\n\003ref\030\001 \001(\005\022\014\n\004path\030\002", " \001(\t\022\014\n\004name\030\003 \001(\t\022\034\n\004type\030\004 \001(\0162\016.Compo" + "nentType\022\017\n\007is_test\030\005 \001(\010\022\020\n\010language\030\006 " + "\001(\t\022\025\n\tchild_ref\030\007 \003(\005B\002\020\001\022\034\n\004link\030\n \003(\013" + "2\016.ComponentLink\022\017\n\007version\030\014 \001(\t\022\023\n\013sna" + - "pshot_id\030\010 \001(\003\022\014\n\004uuid\030\t \001(\t\022\026\n\006events\030\013" + - " \003(\0132\006.Event\"\231\004\n\005Issue\022\027\n\017rule_repositor" + - "y\030\001 \001(\t\022\020\n\010rule_key\030\002 \001(\t\022\014\n\004line\030\003 \001(\005\022" + - "\013\n\003msg\030\004 \001(\t\022\033\n\010severity\030\005 \001(\0162\t.Severit" + - "y\022\013\n\003tag\030\006 \003(\t\022\025\n\reffort_to_fix\030\007 \001(\001\022\016\n" + - "\006is_new\030\010 \001(\010\022\014\n\004uuid\030\t \001(\t\022\027\n\017debt_in_m", - "inutes\030\n \001(\003\022\022\n\nresolution\030\013 \001(\t\022\016\n\006stat" + - "us\030\014 \001(\t\022\020\n\010checksum\030\r \001(\t\022\027\n\017manual_sev" + - "erity\030\016 \001(\010\022\020\n\010reporter\030\017 \001(\t\022\020\n\010assigne" + - "e\030\020 \001(\t\022\027\n\017action_plan_key\030\021 \001(\t\022\022\n\nattr" + - "ibutes\030\022 \001(\t\022\024\n\014author_login\030\023 \001(\t\022\025\n\rcr" + - "eation_date\030\024 \001(\003\022\022\n\nclose_date\030\025 \001(\003\022\023\n" + - "\013update_date\030\026 \001(\003\022\023\n\013selected_at\030\027 \001(\003\022" + - "\023\n\013diff_fields\030\030 \001(\t\022\022\n\nis_changed\030\031 \001(\010" + - "\022\036\n\026must_send_notification\030\032 \001(\010\"N\n\006Issu" + - "es\022\025\n\rcomponent_ref\030\001 \001(\005\022\025\n\005issue\030\002 \003(\013", - "2\006.Issue\022\026\n\016component_uuid\030\003 \001(\tB#\n\037org." + - "sonar.batch.protocol.outputH\001" + "pshot_id\030\010 \001(\003\022\014\n\004uuid\030\t \001(\t\022\025\n\005event\030\013 " + + "\003(\0132\006.Event\"\231\004\n\005Issue\022\027\n\017rule_repository" + + "\030\001 \001(\t\022\020\n\010rule_key\030\002 \001(\t\022\014\n\004line\030\003 \001(\005\022\013" + + "\n\003msg\030\004 \001(\t\022\033\n\010severity\030\005 \001(\0162\t.Severity" + + "\022\013\n\003tag\030\006 \003(\t\022\025\n\reffort_to_fix\030\007 \001(\001\022\016\n\006" + + "is_new\030\010 \001(\010\022\014\n\004uuid\030\t \001(\t\022\027\n\017debt_in_mi", + "nutes\030\n \001(\003\022\022\n\nresolution\030\013 \001(\t\022\016\n\006statu" + + "s\030\014 \001(\t\022\020\n\010checksum\030\r \001(\t\022\027\n\017manual_seve" + + "rity\030\016 \001(\010\022\020\n\010reporter\030\017 \001(\t\022\020\n\010assignee" + + "\030\020 \001(\t\022\027\n\017action_plan_key\030\021 \001(\t\022\022\n\nattri" + + "butes\030\022 \001(\t\022\024\n\014author_login\030\023 \001(\t\022\025\n\rcre" + + "ation_date\030\024 \001(\003\022\022\n\nclose_date\030\025 \001(\003\022\023\n\013" + + "update_date\030\026 \001(\003\022\023\n\013selected_at\030\027 \001(\003\022\023" + + "\n\013diff_fields\030\030 \001(\t\022\022\n\nis_changed\030\031 \001(\010\022" + + "\036\n\026must_send_notification\030\032 \001(\010\"N\n\006Issue" + + "s\022\025\n\rcomponent_ref\030\001 \001(\005\022\025\n\005issue\030\002 \003(\0132", + "\006.Issue\022\026\n\016component_uuid\030\003 \001(\tB#\n\037org.s" + + "onar.batch.protocol.outputH\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -9360,7 +9360,7 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( internal_static_Component_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_Component_descriptor, - new java.lang.String[] { "Ref", "Path", "Name", "Type", "IsTest", "Language", "ChildRef", "Link", "Version", "SnapshotId", "Uuid", "Events", }); + new java.lang.String[] { "Ref", "Path", "Name", "Type", "IsTest", "Language", "ChildRef", "Link", "Version", "SnapshotId", "Uuid", "Event", }); internal_static_Issue_descriptor = getDescriptor().getMessageTypes().get(4); internal_static_Issue_fieldAccessorTable = new diff --git a/sonar-batch-protocol/src/main/protobuf/batch_report.proto b/sonar-batch-protocol/src/main/protobuf/batch_report.proto index 4f5145cb87b8..b281fd69e570 100644 --- a/sonar-batch-protocol/src/main/protobuf/batch_report.proto +++ b/sonar-batch-protocol/src/main/protobuf/batch_report.proto @@ -77,7 +77,7 @@ message Component { // temporary fields during development of computation stack optional int64 snapshot_id = 8; optional string uuid = 9; - repeated Event events = 11; + repeated Event event = 11; } message Issue { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java index 666a6d1a95e6..0358d1428f6f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java @@ -27,7 +27,6 @@ import org.sonar.batch.maven.MavenProjectBuilder; import org.sonar.batch.maven.MavenProjectConverter; import org.sonar.batch.scan.report.*; -import org.sonar.batch.scan.sensor.VersionEventsSensor; import org.sonar.batch.scm.ScmConfiguration; import org.sonar.batch.scm.ScmSensor; import org.sonar.batch.source.LinesSensor; @@ -60,7 +59,6 @@ public static Collection all(DefaultAnalysisMode analysisMode) { ScmSensor.class, LinesSensor.class, - VersionEventsSensor.class, // Issues tracking IssueTracking.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java index 0e421a788e0e..2a70c13ac9d3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java @@ -23,7 +23,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.Event; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.fs.FileSystem; @@ -43,12 +42,8 @@ import org.sonar.batch.sensor.DefaultSensorContext; import org.sonar.batch.sensor.coverage.CoverageExclusions; -import javax.annotation.Nullable; - import java.io.Serializable; import java.util.Collection; -import java.util.Date; -import java.util.List; import java.util.Set; public class DeprecatedSensorContext extends DefaultSensorContext implements SensorContext { @@ -234,21 +229,6 @@ public void saveSource(Resource reference, String source) { // useless since 4.2. } - @Override - public List getEvents(Resource resource) { - return index.getEvents(resource); - } - - @Override - public Event createEvent(Resource resource, String name, String description, String category, @Nullable Date date) { - return index.addEvent(resource, name, description, category, date); - } - - @Override - public void deleteEvent(Event event) { - index.deleteEvent(event); - } - private Resource resourceOrProject(Resource resource) { if (resource == null) { return project; diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java index fcb0fce8ffb1..5b71a2c457d6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java +++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersion.java @@ -21,42 +21,38 @@ import org.sonar.api.BatchExtension; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.Event; import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.Snapshot; import org.sonar.batch.components.PastSnapshot; - -import java.util.List; +import org.sonar.core.event.db.EventMapper; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; import static org.sonar.api.utils.DateUtils.longToDate; public class PastSnapshotFinderByPreviousVersion implements BatchExtension { private final DatabaseSession session; + private final MyBatis mybatis; - public PastSnapshotFinderByPreviousVersion(DatabaseSession session) { + public PastSnapshotFinderByPreviousVersion(DatabaseSession session, MyBatis mybatis) { this.session = session; + this.mybatis = mybatis; } public PastSnapshot findByPreviousVersion(Snapshot projectSnapshot) { String currentVersion = projectSnapshot.getVersion(); Integer resourceId = projectSnapshot.getResourceId(); + Long snapshotId; + try (DbSession dbSession = mybatis.openSession(false)) { + snapshotId = dbSession.getMapper(EventMapper.class).findSnapshotIdOfPreviousVersion(resourceId, currentVersion); + } - String hql = "select e from " + Event.class.getSimpleName() + " e " + - " join e.resource component where e.name<>:version AND e.category='Version' AND component.id=:resourceId ORDER BY e.date DESC"; - - List events = session.createQuery(hql) - .setParameter("version", currentVersion) - .setParameter("resourceId", resourceId) - .setMaxResults(1) - .getResultList(); - - if (events.isEmpty()) { + if (snapshotId == null) { return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION); } - Event previousVersionEvent = events.get(0); - Snapshot snapshot = session.getSingleResult(Snapshot.class, "id", previousVersionEvent.getSnapshot().getId()); + Snapshot snapshot = session.getSingleResult(Snapshot.class, "id", snapshotId.intValue()); return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, longToDate(snapshot.getCreatedAtMs()), snapshot).setModeParameter(snapshot.getVersion()); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java index 67bd33d7a296..47d75f4434d1 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/decorator/DefaultDecoratorContext.java @@ -23,16 +23,10 @@ import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.Event; import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication; import org.sonar.api.design.Dependency; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.MeasuresFilter; -import org.sonar.api.measures.MeasuresFilters; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.MetricFinder; +import org.sonar.api.measures.*; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.rules.Violation; @@ -44,7 +38,6 @@ import java.util.Arrays; import java.util.Collection; -import java.util.Date; import java.util.List; import java.util.Set; @@ -222,21 +215,6 @@ public Collection getOutgoingDependencies() { return sonarIndex.getOutgoingEdges(resource); } - @Override - public List getEvents() { - return sonarIndex.getEvents(resource); - } - - @Override - public Event createEvent(String name, String description, String category, Date date) { - return sonarIndex.addEvent(resource, name, description, category, date); - } - - @Override - public void deleteEvent(Event event) { - sonarIndex.deleteEvent(event); - } - @Override public DefaultDecoratorContext saveViolation(Violation violation, boolean force) { if (violation.getResource() == null) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java index d2f26e4cecfe..ff223b4b9f45 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java @@ -28,7 +28,6 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.Event; import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.measure.Metric; @@ -90,7 +89,6 @@ public class DefaultIndex extends SonarIndex { private final MeasureCache measureCache; private final ResourceKeyMigration migration; private final DependencyPersister dependencyPersister; - private final EventPersister eventPersister; // caches private Project currentProject; private Map buckets = Maps.newLinkedHashMap(); @@ -101,11 +99,10 @@ public class DefaultIndex extends SonarIndex { private ModuleIssues moduleIssues; public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyPersister, - EventPersister eventPersister, ProjectTree projectTree, MetricFinder metricFinder, + ProjectTree projectTree, MetricFinder metricFinder, ResourceKeyMigration migration, MeasureCache measureCache) { this.resourceCache = resourceCache; this.dependencyPersister = dependencyPersister; - this.eventPersister = eventPersister; this.projectTree = projectTree; this.metricFinder = metricFinder; this.migration = migration; @@ -115,7 +112,6 @@ public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyP public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyPersister, ProjectTree projectTree, MetricFinder metricFinder, MeasureCache measureCache) { this.resourceCache = resourceCache; this.dependencyPersister = dependencyPersister; - this.eventPersister = null; this.projectTree = projectTree; this.metricFinder = metricFinder; this.migration = null; @@ -407,47 +403,6 @@ public void addViolation(Violation violation, boolean force) { moduleIssues.initAndAddViolation(violation); } - // - // - // - // EVENTS - // - // - // - - @Override - public List getEvents(Resource resource) { - // currently events are not cached in memory - Resource reload = getResource(resource); - if (reload == null) { - return Collections.emptyList(); - } - if (eventPersister == null) { - throw new UnsupportedOperationException("Event are not available in preview mode"); - } - return eventPersister.getEvents(reload); - } - - @Override - public void deleteEvent(Event event) { - if (eventPersister != null) { - eventPersister.deleteEvent(event); - } - } - - @Override - public Event addEvent(Resource resource, String name, String description, String category, @Nullable Date date) { - Event event = new Event(name, description, category); - if (date != null) { - event.setDate(date); - } - - if (eventPersister != null) { - eventPersister.saveEvent(resource, event); - } - return null; - } - @Override public String getSource(Resource reference) { Resource resource = getResource(reference); diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java deleted file mode 100644 index 3b68e8cda481..000000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.index; - -import org.sonar.api.batch.Event; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.resources.Resource; -import org.sonar.api.utils.System2; - -import java.util.Date; -import java.util.List; - -import static com.google.common.base.Preconditions.checkState; - -public class EventPersister { - private final System2 system2; - private DatabaseSession session; - private ResourceCache resourceCache; - - public EventPersister(DatabaseSession session, ResourceCache resourceCache, System2 system2) { - this.session = session; - this.resourceCache = resourceCache; - this.system2 = system2; - } - - public List getEvents(Resource resource) { - return session.getResults(Event.class, "componentUuid", resource.getUuid()); - } - - public void deleteEvent(Event event) { - session.removeWithoutFlush(event); - session.commit(); - } - - public void saveEvent(Resource resource, Event event) { - BatchResource batchResource = resourceCache.get(resource.getEffectiveKey()); - checkState(batchResource != null, "Unknown component: " + resource); - - event.setCreatedAt(new Date(system2.now())); - if (event.getDate() == null) { - event.setSnapshot(batchResource.snapshot()); - event.setComponentUuid(batchResource.resource().getUuid()); - } else { - event.setComponentUuid(batchResource.resource().getUuid()); - } - - session.save(event); - session.commit(); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java index 824610b5d014..ee3f9f34a762 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/GenerateQualityGateEvents.java @@ -29,6 +29,8 @@ import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.resources.ResourceUtils; +import org.sonar.batch.protocol.Constants.EventCategory; +import org.sonar.batch.report.EventCache; import java.util.List; @@ -36,12 +38,14 @@ public class GenerateQualityGateEvents implements Decorator { private final QualityGate qualityGate; private final TimeMachine timeMachine; - private NotificationManager notificationManager; + private final NotificationManager notificationManager; + private final EventCache eventCache; - public GenerateQualityGateEvents(QualityGate qualityGate, TimeMachine timeMachine, NotificationManager notificationManager) { + public GenerateQualityGateEvents(QualityGate qualityGate, TimeMachine timeMachine, NotificationManager notificationManager, EventCache eventCache) { this.qualityGate = qualityGate; this.timeMachine = timeMachine; this.notificationManager = notificationManager; + this.eventCache = eventCache; } @Override @@ -122,6 +126,6 @@ private String getName(Measure currentStatus) { } private void createEvent(DecoratorContext context, String name, String description) { - context.createEvent(name, description, Event.CATEGORY_ALERT, null); + eventCache.createEvent(context.getResource(), name, description, EventCategory.ALERT, null); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java index 4f93d6fbcaf9..506a7f237652 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java +++ b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java @@ -30,9 +30,10 @@ import org.sonar.batch.index.ResourceCache; import org.sonar.batch.protocol.Constants; import org.sonar.batch.protocol.Constants.ComponentLinkType; -import org.sonar.batch.protocol.output.BatchReport; +import org.sonar.batch.protocol.output.*; +import org.sonar.batch.protocol.output.BatchReport.Component.Builder; import org.sonar.batch.protocol.output.BatchReport.ComponentLink; -import org.sonar.batch.protocol.output.BatchReportWriter; +import org.sonar.batch.protocol.output.BatchReport.Event; import javax.annotation.CheckForNull; @@ -43,10 +44,12 @@ public class ComponentsPublisher implements ReportPublisher { private final ResourceCache resourceCache; private final ProjectReactor reactor; + private final EventCache eventCache; - public ComponentsPublisher(ProjectReactor reactor, ResourceCache resourceCache) { + public ComponentsPublisher(ProjectReactor reactor, ResourceCache resourceCache, EventCache eventCache) { this.reactor = reactor; this.resourceCache = resourceCache; + this.eventCache = eventCache; } @Override @@ -91,6 +94,38 @@ private void recursiveWriteComponent(BatchResource batchResource, BatchReportWri for (BatchResource child : batchResource.children()) { builder.addChildRef(child.batchId()); } + writeLinks(r, builder); + writeVersion(r, builder); + writeEvents(batchResource, builder); + writer.writeComponent(builder.build()); + + for (BatchResource child : batchResource.children()) { + recursiveWriteComponent(child, writer); + } + } + + private void writeEvents(BatchResource batchResource, Builder builder) { + if (isRealProjectOrModule(batchResource.resource())) { + for (Event event : eventCache.getEvents(batchResource.batchId())) { + builder.addEvent(event); + } + } + } + + private void writeVersion(Resource r, BatchReport.Component.Builder builder) { + if (isRealProjectOrModule(r)) { + ProjectDefinition def = getProjectDefinition(reactor, r.getKey()); + String version = getVersion(def); + builder.setVersion(version); + } + } + + private String getVersion(ProjectDefinition def) { + String version = def.getVersion(); + return StringUtils.isNotBlank(version) ? version : getVersion(def.getParent()); + } + + private void writeLinks(Resource r, BatchReport.Component.Builder builder) { if (isRealProjectOrModule(r)) { ProjectDefinition def = getProjectDefinition(reactor, r.getKey()); ComponentLink.Builder linkBuilder = ComponentLink.newBuilder(); @@ -101,11 +136,6 @@ private void recursiveWriteComponent(BatchResource batchResource, BatchReportWri writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES, ComponentLinkType.SCM); writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES_DEV, ComponentLinkType.SCM_DEV); } - writer.writeComponent(builder.build()); - - for (BatchResource child : batchResource.children()) { - recursiveWriteComponent(child, writer); - } } // Exclude views diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java b/sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java new file mode 100644 index 000000000000..2cb2814d2ee2 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java @@ -0,0 +1,67 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.report; + +import org.sonar.api.BatchComponent; +import org.sonar.api.resources.Resource; +import org.sonar.batch.index.ResourceCache; +import org.sonar.batch.protocol.Constants.EventCategory; +import org.sonar.batch.protocol.output.BatchReport.Event; + +import javax.annotation.Nullable; + +import java.util.*; + +public class EventCache implements BatchComponent { + + private final Map> eventsByComponentBatchId = new HashMap<>(); + private final ResourceCache resourceCache; + + public EventCache(ResourceCache resourceCache) { + this.resourceCache = resourceCache; + } + + public void createEvent(Resource resource, String name, String description, EventCategory category, @Nullable String data) { + org.sonar.batch.protocol.output.BatchReport.Event.Builder eventBuilder = org.sonar.batch.protocol.output.BatchReport.Event.newBuilder(); + eventBuilder.setName(name); + eventBuilder.setDescription(description); + eventBuilder.setCategory(category); + if (data != null) { + eventBuilder.setEventData(data); + } + int componentBatchId = resourceCache.get(resource).batchId(); + eventBuilder.setComponentRef(componentBatchId); + addEvent(componentBatchId, eventBuilder.build()); + } + + private void addEvent(int componentBatchId, Event e) { + if (!eventsByComponentBatchId.containsKey(componentBatchId)) { + eventsByComponentBatchId.put(componentBatchId, new ArrayList()); + } + eventsByComponentBatchId.get(componentBatchId).add(e); + } + + public List getEvents(int componentBatchId) { + if (eventsByComponentBatchId.containsKey(componentBatchId)) { + return eventsByComponentBatchId.get(componentBatchId); + } + return Collections.emptyList(); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java index f3d7bffc035a..4ebc91e489ba 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java @@ -21,22 +21,14 @@ import com.google.common.collect.ImmutableSortedMap; import org.apache.commons.lang.time.DateUtils; -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.DependsUpon; -import org.sonar.api.batch.Event; -import org.sonar.api.batch.TimeMachine; -import org.sonar.api.batch.TimeMachineQuery; +import org.sonar.api.batch.*; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Resource; +import org.sonar.api.resources.*; import org.sonar.api.utils.KeyValueFormat; -import org.sonar.batch.index.EventPersister; +import org.sonar.batch.protocol.Constants.EventCategory; +import org.sonar.batch.report.EventCache; import org.sonar.core.UtcDateUtils; import javax.annotation.CheckForNull; @@ -49,12 +41,12 @@ public class QProfileEventsDecorator implements Decorator { private final TimeMachine timeMachine; private final Languages languages; - private final EventPersister eventPersister; + private final EventCache eventCache; - public QProfileEventsDecorator(TimeMachine timeMachine, Languages languages, EventPersister eventPersister) { + public QProfileEventsDecorator(TimeMachine timeMachine, Languages languages, EventCache eventCache) { this.timeMachine = timeMachine; this.languages = languages; - this.eventPersister = eventPersister; + this.eventCache = eventCache; } @DependsUpon @@ -112,18 +104,13 @@ private void detectNewOrUpdatedProfiles(DecoratorContext context, Map it = context.getEvents(project).iterator(); it.hasNext();) { - Event event = it.next(); - if (event.isVersionCategory() && version.equals(event.getName())) { - it.remove(); - context.deleteEvent(event); - } - } - } - - @Override - public String toString() { - return getClass().getSimpleName(); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java deleted file mode 100644 index b8fb1b58126c..000000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.scan.sensor; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java b/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java index d932060914a1..83c8b98a8b95 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/deprecated/components/PastSnapshotFinderByPreviousVersionTest.java @@ -19,21 +19,27 @@ */ package org.sonar.batch.deprecated.components; -import org.sonar.batch.components.PastSnapshot; - -import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousVersion; +import org.junit.Before; import org.junit.Test; import org.sonar.api.CoreProperties; import org.sonar.api.database.model.Snapshot; +import org.sonar.batch.components.PastSnapshot; import org.sonar.jpa.test.AbstractDbUnitTestCase; + import static org.assertj.core.api.Assertions.assertThat; public class PastSnapshotFinderByPreviousVersionTest extends AbstractDbUnitTestCase { + private PastSnapshotFinderByPreviousVersion finder; + + @Before + public void before() throws Exception { + finder = new PastSnapshotFinderByPreviousVersion(getSession(), getMyBatis()); + } + @Test public void shouldFindByPreviousVersion() { setupData("with-previous-version"); - PastSnapshotFinderByPreviousVersion finder = new PastSnapshotFinderByPreviousVersion(getSession()); Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003); PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot); @@ -45,7 +51,6 @@ public void shouldFindByPreviousVersion() { @Test public void shouldFindByPreviousVersionWhenPreviousVersionDeleted() { setupData("with-previous-version-deleted"); - PastSnapshotFinderByPreviousVersion finder = new PastSnapshotFinderByPreviousVersion(getSession()); Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003); PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot); @@ -57,7 +62,6 @@ public void shouldFindByPreviousVersionWhenPreviousVersionDeleted() { @Test public void testWithNoPreviousVersion() { setupData("no-previous-version"); - PastSnapshotFinderByPreviousVersion finder = new PastSnapshotFinderByPreviousVersion(getSession()); Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003); PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot); diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java index 0c62cc64ac4b..908a8194c93a 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java @@ -65,7 +65,7 @@ public void createIndex() throws IOException { ProjectTree projectTree = mock(ProjectTree.class); ResourceCache resourceCache = new ResourceCache(); - index = new DefaultIndex(resourceCache, null, null, projectTree, metricFinder, + index = new DefaultIndex(resourceCache, null, projectTree, metricFinder, mock(ResourceKeyMigration.class), mock(MeasureCache.class)); diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java index 92299c87f20c..0d9be3369a4a 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java @@ -221,7 +221,7 @@ public void shouldSaveNewMultiModulesProjectUsingIndex() throws IOException { when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB"))); when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1"))); - DefaultIndex index = new DefaultIndex(resourceCache, null, null, projectTree, mock(MetricFinder.class), + DefaultIndex index = new DefaultIndex(resourceCache, null, projectTree, mock(MetricFinder.class), mock(ResourceKeyMigration.class), mock(MeasureCache.class)); diff --git a/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java b/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java index e7e2c3328384..0385d0796ae3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/qualitygate/GenerateQualityGateEventsTest.java @@ -22,7 +22,6 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.Event; import org.sonar.api.batch.TimeMachine; import org.sonar.api.batch.TimeMachineQuery; import org.sonar.api.measures.CoreMetrics; @@ -32,21 +31,18 @@ import org.sonar.api.notifications.NotificationManager; import org.sonar.api.resources.File; import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; import org.sonar.api.test.ProjectTestBuilder; +import org.sonar.batch.protocol.Constants.EventCategory; +import org.sonar.batch.report.EventCache; import java.util.Arrays; -import java.util.Date; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class GenerateQualityGateEventsTest { private GenerateQualityGateEvents decorator; @@ -55,6 +51,7 @@ public class GenerateQualityGateEventsTest { private TimeMachine timeMachine; private NotificationManager notificationManager; private Project project; + private EventCache eventCache; @Before public void setup() { @@ -62,8 +59,10 @@ public void setup() { timeMachine = mock(TimeMachine.class); qualityGate = mock(QualityGate.class); notificationManager = mock(NotificationManager.class); - decorator = new GenerateQualityGateEvents(qualityGate, timeMachine, notificationManager); + eventCache = mock(EventCache.class); + decorator = new GenerateQualityGateEvents(qualityGate, timeMachine, notificationManager, eventCache); project = new ProjectTestBuilder().build(); + when(context.getResource()).thenReturn(project); } @Test @@ -85,7 +84,7 @@ public void shouldDecorateIfQualityGateEnabled() { @Test public void shouldNotDecorateIfNotRootProject() { decorator.decorate(File.create("Foo"), context); - verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull()); + verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString()); } @Test @@ -94,7 +93,7 @@ public void shouldCreateEventWhenNewErrorAlert() { decorator.decorate(project, context); - verify(context).createEvent(Metric.Level.ERROR.getColorName(), "desc", Event.CATEGORY_ALERT, null); + verify(eventCache).createEvent(project, Metric.Level.ERROR.getColorName(), "desc", EventCategory.ALERT, null); verifyNotificationSent("Red", "desc", "ERROR", "true"); } @@ -104,7 +103,7 @@ public void shouldCreateEventWhenNewWarnAlert() { decorator.decorate(project, context); - verify(context).createEvent(Metric.Level.WARN.getColorName(), "desc", Event.CATEGORY_ALERT, null); + verify(eventCache).createEvent(project, Metric.Level.WARN.getColorName(), "desc", EventCategory.ALERT, null); verifyNotificationSent("Orange", "desc", "WARN", "true"); } @@ -115,7 +114,7 @@ public void shouldCreateEventWhenWarnToError() { decorator.decorate(project, context); - verify(context).createEvent("Red (was Orange)", "desc", Event.CATEGORY_ALERT, null); + verify(eventCache).createEvent(project, "Red (was Orange)", "desc", EventCategory.ALERT, null); verifyNotificationSent("Red (was Orange)", "desc", "ERROR", "false"); } @@ -126,7 +125,7 @@ public void shouldCreateEventWhenErrorToOk() { decorator.decorate(project, context); - verify(context).createEvent("Green (was Red)", null, Event.CATEGORY_ALERT, null); + verify(eventCache).createEvent(project, "Green (was Red)", null, EventCategory.ALERT, null); verifyNotificationSent("Green (was Red)", null, "OK", "false"); } @@ -137,7 +136,7 @@ public void shouldCreateEventWhenOkToError() { decorator.decorate(project, context); - verify(context).createEvent("Red (was Green)", "desc", Event.CATEGORY_ALERT, null); + verify(eventCache).createEvent(project, "Red (was Green)", "desc", EventCategory.ALERT, null); verifyNotificationSent("Red (was Green)", "desc", "ERROR", "true"); } @@ -148,7 +147,7 @@ public void shouldCreateEventWhenErrorToWarn() { decorator.decorate(project, context); - verify(context).createEvent("Orange (was Red)", "desc", Event.CATEGORY_ALERT, null); + verify(eventCache).createEvent(project, "Orange (was Red)", "desc", EventCategory.ALERT, null); verifyNotificationSent("Orange (was Red)", "desc", "WARN", "false"); } @@ -156,7 +155,7 @@ public void shouldCreateEventWhenErrorToWarn() { public void shouldNotCreateEventWhenNoAlertStatus() { decorator.decorate(project, context); - verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull()); + verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString()); verify(notificationManager, never()).scheduleForSending(any(Notification.class)); } @@ -167,7 +166,7 @@ public void shouldNotCreateEventWhenSameLevel() { decorator.decorate(project, context); - verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull()); + verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString()); verify(notificationManager, never()).scheduleForSending(any(Notification.class)); } @@ -178,7 +177,7 @@ public void shouldNotCreateEventIfNoMoreAlertStatus() { decorator.decorate(project, context); - verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull()); + verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString()); verify(notificationManager, never()).scheduleForSending(any(Notification.class)); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java index 43c2e697baa7..fb0c2aa4b5f1 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java @@ -33,14 +33,17 @@ import org.sonar.api.utils.DateUtils; import org.sonar.batch.index.ResourceCache; import org.sonar.batch.protocol.Constants.ComponentLinkType; +import org.sonar.batch.protocol.Constants.EventCategory; import org.sonar.batch.protocol.output.BatchReport.Component; -import org.sonar.batch.protocol.output.BatchReportReader; -import org.sonar.batch.protocol.output.BatchReportWriter; -import org.sonar.batch.protocol.output.FileStructure; +import org.sonar.batch.protocol.output.BatchReport.Event; +import org.sonar.batch.protocol.output.*; import java.io.File; +import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class ComponentsPublisherTest { @@ -50,12 +53,15 @@ public class ComponentsPublisherTest { private ProjectReactor reactor; private ResourceCache resourceCache; private ComponentsPublisher publisher; + private EventCache eventCache; @Before public void prepare() { reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo")); + reactor.getRoot().properties().put(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0"); resourceCache = new ResourceCache(); - publisher = new ComponentsPublisher(reactor, resourceCache); + eventCache = mock(EventCache.class); + publisher = new ComponentsPublisher(reactor, resourceCache, eventCache); } @Test @@ -73,22 +79,22 @@ public void add_components_to_report() throws Exception { reactor.getRoot().addSubProject(ProjectDefinition.create().setKey("module1")); Directory dir = Directory.create("src"); - dir.setEffectiveKey("foo:src"); + dir.setEffectiveKey("module1:src"); dir.setId(3).setUuid("DIR_UUID"); resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13)); org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", Java.INSTANCE, false); - file.setEffectiveKey("foo:src/Foo.java"); + file.setEffectiveKey("module1:src/Foo.java"); file.setId(4).setUuid("FILE_UUID"); resourceCache.add(file, dir).setSnapshot(new Snapshot().setId(14)); org.sonar.api.resources.File fileWithoutLang = org.sonar.api.resources.File.create("src/make", null, false); - fileWithoutLang.setEffectiveKey("foo:src/make"); + fileWithoutLang.setEffectiveKey("module1:src/make"); fileWithoutLang.setId(5).setUuid("FILE_WITHOUT_LANG_UUID"); resourceCache.add(fileWithoutLang, dir).setSnapshot(new Snapshot().setId(15)); org.sonar.api.resources.File testFile = org.sonar.api.resources.File.create("test/FooTest.java", Java.INSTANCE, true); - testFile.setEffectiveKey("foo:test/FooTest.java"); + testFile.setEffectiveKey("module1:test/FooTest.java"); testFile.setId(6).setUuid("TEST_FILE_UUID"); resourceCache.add(testFile, dir).setSnapshot(new Snapshot().setId(16)); @@ -108,8 +114,11 @@ public void add_components_to_report() throws Exception { BatchReportReader reader = new BatchReportReader(outputDir); Component rootProtobuf = reader.readComponent(1); + assertThat(rootProtobuf.getVersion()).isEqualTo("1.0"); assertThat(rootProtobuf.getLinkCount()).isEqualTo(0); + Component module1Protobuf = reader.readComponent(2); + assertThat(module1Protobuf.getVersion()).isEqualTo("1.0"); } @Test @@ -131,12 +140,12 @@ public void add_components_with_links_and_branch() throws Exception { reactor.getRoot().addSubProject(moduleDef); Directory dir = Directory.create("src"); - dir.setEffectiveKey("foo:src"); + dir.setEffectiveKey("module1:my_branch:my_branch:src"); dir.setId(3).setUuid("DIR_UUID"); resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13)); org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", Java.INSTANCE, false); - file.setEffectiveKey("foo:src/Foo.java"); + file.setEffectiveKey("module1:my_branch:my_branch:src/Foo.java"); file.setId(4).setUuid("FILE_UUID"); resourceCache.add(file, dir).setSnapshot(new Snapshot().setId(14)); @@ -146,13 +155,52 @@ public void add_components_with_links_and_branch() throws Exception { BatchReportReader reader = new BatchReportReader(outputDir); Component rootProtobuf = reader.readComponent(1); + assertThat(rootProtobuf.getVersion()).isEqualTo("1.0"); assertThat(rootProtobuf.getLinkCount()).isEqualTo(1); assertThat(rootProtobuf.getLink(0).getType()).isEqualTo(ComponentLinkType.HOME); assertThat(rootProtobuf.getLink(0).getHref()).isEqualTo("http://home"); Component module1Protobuf = reader.readComponent(2); + assertThat(module1Protobuf.getVersion()).isEqualTo("1.0"); assertThat(module1Protobuf.getLinkCount()).isEqualTo(1); assertThat(module1Protobuf.getLink(0).getType()).isEqualTo(ComponentLinkType.CI); assertThat(module1Protobuf.getLink(0).getHref()).isEqualTo("http://ci"); } + + @Test + public void add_components_with_events() throws Exception { + // inputs + Project root = new Project("foo").setName("Root project") + .setAnalysisDate(DateUtils.parseDate(("2012-12-12"))); + root.setId(1).setUuid("PROJECT_UUID"); + resourceCache.add(root, null).setSnapshot(new Snapshot().setId(11)); + + Project module1 = new Project("module1").setName("Module1"); + module1.setParent(root); + module1.setId(2).setUuid("MODULE_UUID"); + resourceCache.add(module1, root).setSnapshot(new Snapshot().setId(12)); + ProjectDefinition moduleDef = ProjectDefinition.create().setKey("module1"); + reactor.getRoot().addSubProject(moduleDef); + + when(eventCache.getEvents(2)).thenReturn(Arrays.asList(Event.newBuilder().setName("name").setCategory(EventCategory.ALERT).setComponentRef(2).build())); + + Directory dir = Directory.create("src"); + dir.setEffectiveKey("module1:src"); + dir.setId(3).setUuid("DIR_UUID"); + resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13)); + + File outputDir = temp.newFolder(); + BatchReportWriter writer = new BatchReportWriter(outputDir); + publisher.publish(writer); + + BatchReportReader reader = new BatchReportReader(outputDir); + Component rootProtobuf = reader.readComponent(1); + assertThat(rootProtobuf.getVersion()).isEqualTo("1.0"); + assertThat(rootProtobuf.getEventCount()).isEqualTo(0); + + Component module1Protobuf = reader.readComponent(2); + assertThat(module1Protobuf.getVersion()).isEqualTo("1.0"); + assertThat(module1Protobuf.getEventCount()).isEqualTo(1); + assertThat(module1Protobuf.getEvent(0).getCategory()).isEqualTo(EventCategory.ALERT); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java index 9142cf4da6d5..b2c1ca57dcbc 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileEventsDecoratorTest.java @@ -38,11 +38,9 @@ */ package org.sonar.batch.rule; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; +import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.Event; import org.sonar.api.batch.TimeMachine; import org.sonar.api.batch.TimeMachineQuery; import org.sonar.api.measures.CoreMetrics; @@ -51,17 +49,14 @@ import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; -import org.sonar.batch.index.EventPersister; +import org.sonar.batch.protocol.Constants.EventCategory; +import org.sonar.batch.report.EventCache; import java.util.Arrays; -import java.util.Date; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.same; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -77,8 +72,13 @@ public class QProfileEventsDecoratorTest { DecoratorContext decoratorContext = mock(DecoratorContext.class); TimeMachine timeMachine = mock(TimeMachine.class); Languages languages = mock(Languages.class); - EventPersister eventPersister = mock(EventPersister.class); - QProfileEventsDecorator decorator = new QProfileEventsDecorator(timeMachine, languages, eventPersister); + EventCache eventCache = mock(EventCache.class); + QProfileEventsDecorator decorator = new QProfileEventsDecorator(timeMachine, languages, eventCache); + + @Before + public void prepare() { + when(decoratorContext.getResource()).thenReturn(project); + } @Test public void basic_tests() { @@ -98,7 +98,7 @@ public void do_not_generate_event_if_no_changes() { decorator.decorate(project, decoratorContext); - verify(decoratorContext, never()).createEvent(anyString(), anyString(), anyString(), any(Date.class)); + verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString()); } @Test @@ -115,20 +115,8 @@ public void generate_event_if_profile_change() { decorator.decorate(project, decoratorContext); - verify(eventPersister).saveEvent(any(Resource.class), argThat(new BaseMatcher() { - @Override - public void describeTo(Description description) { - } - - @Override - public boolean matches(Object item) { - Event event = (Event) item; - return event.getCategory().equals(Event.CATEGORY_PROFILE) && - "Changes in 'Java One' (Java)".equals(event.getName()) && - // "from" and "to" must have one second more because of lack of ms precision - "from=2014-01-15T12:00:01+0000;key=J1;to=2014-02-20T12:00:01+0000".equals(event.getData()); - } - })); + // "from" and "to" must have one second more because of lack of ms precision + verify(eventCache).createEvent(project, "Changes in 'Java One' (Java)", null, EventCategory.PROFILE, "from=2014-01-15T12:00:01+0000;key=J1;to=2014-02-20T12:00:01+0000"); } @Test @@ -145,10 +133,7 @@ public void generate_event_if_profile_not_used_anymore() { decorator.decorate(project, decoratorContext); - verify(decoratorContext).createEvent( - eq("Stop using 'Java One' (Java)"), - eq((String) null), - same(Event.CATEGORY_PROFILE), any(Date.class)); + verify(eventCache).createEvent(project, "Stop using 'Java One' (Java)", null, EventCategory.PROFILE, null); } @Test @@ -161,6 +146,6 @@ public void do_not_generate_event_on_first_analysis() { decorator.decorate(project, decoratorContext); - verify(decoratorContext, never()).createEvent(anyString(), anyString(), anyString(), any(Date.class)); + verify(eventCache, never()).createEvent(any(Resource.class), anyString(), anyString(), any(EventCategory.class), anyString()); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java deleted file mode 100644 index d70932f673cc..000000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.scan.sensor; - -import org.sonar.batch.scan.sensor.VersionEventsSensor; - -import com.google.common.collect.Lists; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.Event; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.Resource; - -import java.util.Date; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class VersionEventsSensorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void shouldExecuteOnProject() throws Exception { - AnalysisMode analysisMode = mock(AnalysisMode.class); - assertThat(new VersionEventsSensor(analysisMode).shouldExecuteOnProject(null)).isTrue(); - when(analysisMode.isPreview()).thenReturn(true); - assertThat(new VersionEventsSensor(analysisMode).shouldExecuteOnProject(null)).isFalse(); - } - - @Test - public void testToString() throws Exception { - assertThat(new VersionEventsSensor(null).toString(), is("VersionEventsSensor")); - } - - @Test - public void shouldDoNothingIfNoVersion() { - VersionEventsSensor sensor = new VersionEventsSensor(null); - SensorContext context = mock(SensorContext.class); - Project project = mock(Project.class); - when(project.getAnalysisVersion()).thenReturn(null); - - sensor.analyse(project, context); - - verify(context, never()).createEvent(any(Resource.class), anyString(), anyString(), anyString(), any(Date.class)); - verify(context, never()).deleteEvent(any(Event.class)); - } - - @Test - public void shouldCreateVersionEvent() { - VersionEventsSensor sensor = new VersionEventsSensor(null); - SensorContext context = mock(SensorContext.class); - - Project project = mock(Project.class); - when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); - - sensor.analyse(project, context); - - verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); - } - - @Test - public void shouldHaveOnlyOneEventByVersion() { - Event sameVersionEvent = mockVersionEvent("1.5-SNAPSHOT"); - Event otherEvent = mockVersionEvent("1.4"); - Event anotherEvent = mockVersionEvent("1.3-SNAPSHOT"); - - VersionEventsSensor sensor = new VersionEventsSensor(null); - SensorContext context = mock(SensorContext.class); - - Project project = mock(Project.class); - when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); - - when(context.getEvents(project)).thenReturn(Lists.newArrayList(sameVersionEvent, otherEvent, anotherEvent)); - - sensor.analyse(project, context); - - verify(context).deleteEvent(sameVersionEvent); - verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); - } - - private Event mockVersionEvent(String version) { - Event event = mock(Event.class); - when(event.isVersionCategory()).thenReturn(true); - when(event.getName()).thenReturn(version); - return event; - } - -} diff --git a/sonar-core/src/main/java/org/sonar/core/event/db/EventMapper.java b/sonar-core/src/main/java/org/sonar/core/event/db/EventMapper.java index 7fa3734967f8..831b5dd31603 100644 --- a/sonar-core/src/main/java/org/sonar/core/event/db/EventMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/event/db/EventMapper.java @@ -20,8 +20,11 @@ package org.sonar.core.event.db; +import org.apache.ibatis.annotations.Param; import org.sonar.core.event.EventDto; +import javax.annotation.CheckForNull; + import java.util.List; public interface EventMapper { @@ -32,4 +35,10 @@ public interface EventMapper { void delete(long id); + /** + * TODO Used by PastSnapshotFinderByVersion. Should be dropped soon. + */ + @CheckForNull + Long findSnapshotIdOfPreviousVersion(@Param("componentId") long componentId, @Param("currentVersion") String currentVersion); + } diff --git a/sonar-core/src/main/resources/META-INF/persistence.xml b/sonar-core/src/main/resources/META-INF/persistence.xml index 016767d84fbf..c4fe74068365 100644 --- a/sonar-core/src/main/resources/META-INF/persistence.xml +++ b/sonar-core/src/main/resources/META-INF/persistence.xml @@ -17,7 +17,6 @@ org.sonar.api.database.model.ResourceModel org.sonar.api.rules.Rule org.sonar.api.rules.RuleParam - org.sonar.api.batch.Event true diff --git a/sonar-core/src/main/resources/org/sonar/core/event/db/EventMapper.xml b/sonar-core/src/main/resources/org/sonar/core/event/db/EventMapper.xml index 11cd9bb3036e..0c6dc2d3eb7a 100644 --- a/sonar-core/src/main/resources/org/sonar/core/event/db/EventMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/event/db/EventMapper.xml @@ -30,6 +30,50 @@ DELETE FROM events WHERE id=#{id} + + + + + + + + diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DecoratorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DecoratorContext.java index 0e2bd8b61b0e..018d22cc0a0e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DecoratorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DecoratorContext.java @@ -28,7 +28,6 @@ import org.sonar.api.rules.Violation; import java.util.Collection; -import java.util.Date; import java.util.List; import java.util.Set; @@ -117,29 +116,4 @@ public interface DecoratorContext { @Deprecated DecoratorContext saveViolation(Violation violation); - // EVENTS - - /** - * @return the list of events associated to the current resource - */ - List getEvents(); - - /** - * Creates an event for a given date - * - * @param name the event name - * @param description the event description - * @param category the event category - * @param date the event date - * @return the created event - */ - Event createEvent(String name, String description, String category, Date date); - - /** - * Deletes an event - * - * @param event the event to delete - */ - void deleteEvent(Event event); - } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Event.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/Event.java deleted file mode 100644 index 1e756c3f6bdb..000000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Event.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.api.batch; - -import org.apache.commons.lang.builder.ToStringBuilder; -import org.sonar.api.database.BaseIdentifiable; -import org.sonar.api.database.model.ResourceModel; -import org.sonar.api.database.model.Snapshot; - -import javax.persistence.*; - -import java.util.Date; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.sonar.api.utils.DateUtils.longToDate; - -/** - * @since 1.10 - */ -@Entity -@Table(name = "events") -public class Event extends BaseIdentifiable { - public static final String CATEGORY_VERSION = "Version"; - public static final String CATEGORY_ALERT = "Alert"; - public static final String CATEGORY_PROFILE = "Profile"; - - @Column(name = "name", updatable = true, nullable = true, length = 400) - private String name; - - @Column(name = "description", updatable = true, nullable = true, length = 4000) - private String description; - - @Column(name = "category", updatable = true, nullable = true, length = 50) - private String category; - - @Column(name = "event_date", updatable = true, nullable = false) - private Long date; - - @Column(name = "created_at", updatable = true, nullable = false) - private Long createdAt; - - @Column(name = "event_data", updatable = true, nullable = true) - private String data; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "snapshot_id", updatable = true, nullable = true) - private Snapshot snapshot; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "component_uuid", referencedColumnName = "uuid", insertable = false, updatable = false, nullable = false) - private ResourceModel resource; - - @Column(name = "component_uuid", updatable = true, nullable = true) - private String componentUuid; - - public Event() { - } - - public Event(String name, String description, String category) { - this.name = name; - this.description = description; - this.category = category; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getCategory() { - return category; - } - - public void setCategory(String category) { - this.category = category; - } - - public boolean isVersionCategory() { - return CATEGORY_VERSION.equalsIgnoreCase(category); - } - - public boolean isProfileCategory() { - return CATEGORY_PROFILE.equalsIgnoreCase(category); - } - - public Date getDate() { - return longToDate(date); - } - - public void setDate(Date date) { - this.date = date.getTime(); - } - - public Snapshot getSnapshot() { - return snapshot; - } - - public Date getCreatedAt() { - return new Date(createdAt); - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt.getTime(); - } - - public final void setSnapshot(Snapshot snapshot) { - this.snapshot = checkNotNull(snapshot, "it is not possible to set a null snapshot linked to an event"); - this.date = snapshot.getCreatedAtMs(); -// this.resourceId = snapshot.getResourceId(); - } - - public ResourceModel getResource() { - return resource; - } - - public void setResource(ResourceModel resource) { - this.resource = resource; - } - - public String getComponentUuid() { - return componentUuid; - } - - public void setComponentUuid(String componentUuid) { - this.componentUuid = componentUuid; - } - - public String getData() { - return data; - } - - public void setData(String data) { - this.data = data; - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("name", name) - .append("categ", category) - .append("date", date) - .append("snapshot", snapshot) - .append("resource", resource) - .toString(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java index 25a7521cdd70..f5b73a257225 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java @@ -29,12 +29,9 @@ import org.sonar.api.rules.Violation; import javax.annotation.CheckForNull; -import javax.annotation.Nullable; import java.io.Serializable; import java.util.Collection; -import java.util.Date; -import java.util.List; import java.util.Set; /** @@ -226,31 +223,6 @@ public interface SensorContext extends org.sonar.api.batch.sensor.SensorContext @Deprecated void saveSource(Resource reference, String source); - // ----------- EVENTS -------------- - - /** - * @param resource set null for project events - */ - List getEvents(Resource resource); - - /** - * Creates an event for a given date - * - * @param name the event name - * @param description the event description - * @param category the event category - * @param date the event date - * @return the created event - */ - Event createEvent(Resource resource, String name, @Nullable String description, String category, @Nullable Date date); - - /** - * Deletes an event - * - * @param event the event to delete - */ - void deleteEvent(Event event); - /** * Save measure on {@link InputFile} * @since 4.2 diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java index a9d32eb7595d..5032c68afcc6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java @@ -29,11 +29,8 @@ import org.sonar.graph.DirectedGraphAccessor; import javax.annotation.CheckForNull; -import javax.annotation.Nullable; import java.util.Collection; -import java.util.Date; -import java.util.List; import java.util.Set; /** @@ -147,12 +144,6 @@ public final void addViolation(Violation violation) { public abstract Set getDependencies(); - public abstract List getEvents(Resource resource); - - public abstract void deleteEvent(Event event); - - public abstract Event addEvent(Resource resource, String name, String description, String category, @Nullable Date date); - public final Collection getOutgoingDependencies(Resource from) { return getOutgoingEdges(from); }