Skip to content

Commit

Permalink
Check requirement fulfillment and show it on ShowContentPacksPage (#4966
Browse files Browse the repository at this point in the history
)

* Check requirement fulfillment and show it on ShowContentPacksPage

We want to display if a requirement of a content pack is met by the server,
for that the server checkes if every constraint is met and adds the
information to the json result.

The frontend can now use the so send fulfilled flag to check if
the requirement is met

Also:

- fix naming of ContentPackResource function
- add download API endpoint

Fixes #4950
  • Loading branch information
kmerz authored and bernd committed Aug 15, 2018
1 parent 4106c04 commit b2a65a5
Show file tree
Hide file tree
Showing 21 changed files with 231 additions and 30 deletions.
Expand Up @@ -44,6 +44,7 @@
import org.graylog2.contentpacks.model.ModelType; import org.graylog2.contentpacks.model.ModelType;
import org.graylog2.contentpacks.model.ModelTypes; import org.graylog2.contentpacks.model.ModelTypes;
import org.graylog2.contentpacks.model.constraints.Constraint; import org.graylog2.contentpacks.model.constraints.Constraint;
import org.graylog2.contentpacks.model.constraints.ConstraintCheckResult;
import org.graylog2.contentpacks.model.constraints.GraylogVersionConstraint; import org.graylog2.contentpacks.model.constraints.GraylogVersionConstraint;
import org.graylog2.contentpacks.model.entities.EntitiesWithConstraints; import org.graylog2.contentpacks.model.entities.EntitiesWithConstraints;
import org.graylog2.contentpacks.model.entities.Entity; import org.graylog2.contentpacks.model.entities.Entity;
Expand Down Expand Up @@ -106,7 +107,7 @@ private ContentPackInstallation installContentPack(ContentPackV1 contentPack,
Map<String, ValueReference> parameters, Map<String, ValueReference> parameters,
String comment, String comment,
String user) { String user) {
checkConstraints(contentPack.requires()); ensureConstraints(contentPack.requires());


final Entity rootEntity = EntityV1.builder() final Entity rootEntity = EntityV1.builder()
.type(ModelTypes.ROOT) .type(ModelTypes.ROOT)
Expand Down Expand Up @@ -292,10 +293,10 @@ private ImmutableGraph<Entity> buildEntityGraph(Entity rootEntity,
return ImmutableGraph.copyOf(dependencyGraph); return ImmutableGraph.copyOf(dependencyGraph);
} }


private void checkConstraints(Set<Constraint> requiredConstraints) { private void ensureConstraints(Set<Constraint> requiredConstraints) {
final Set<Constraint> fulfilledConstraints = new HashSet<>(); final Set<Constraint> fulfilledConstraints = new HashSet<>();
for (ConstraintChecker constraintChecker : constraintCheckers) { for (ConstraintChecker constraintChecker : constraintCheckers) {
fulfilledConstraints.addAll(constraintChecker.checkConstraints(requiredConstraints)); fulfilledConstraints.addAll(constraintChecker.ensureConstraints(requiredConstraints));
} }


if (!fulfilledConstraints.equals(requiredConstraints)) { if (!fulfilledConstraints.equals(requiredConstraints)) {
Expand All @@ -304,6 +305,16 @@ private void checkConstraints(Set<Constraint> requiredConstraints) {
} }
} }


public Set<ConstraintCheckResult> checkConstraints(ContentPack contentPackV1) {
Set<Constraint> requiredConstraints = contentPackV1.requires();
final Set<ConstraintCheckResult> fulfilledConstraints = new HashSet<>();
for (ConstraintChecker constraintChecker : constraintCheckers) {
fulfilledConstraints.addAll(constraintChecker.checkConstraints(requiredConstraints));
}
return fulfilledConstraints;
}


private ImmutableMap<String, ValueReference> validateParameters(Map<String, ValueReference> parameters, private ImmutableMap<String, ValueReference> validateParameters(Map<String, ValueReference> parameters,
Set<Parameter> contentPackParameters) { Set<Parameter> contentPackParameters) {
final Set<String> contentPackParameterNames = contentPackParameters.stream() final Set<String> contentPackParameterNames = contentPackParameters.stream()
Expand Down
Expand Up @@ -17,10 +17,12 @@
package org.graylog2.contentpacks.constraints; package org.graylog2.contentpacks.constraints;


import org.graylog2.contentpacks.model.constraints.Constraint; import org.graylog2.contentpacks.model.constraints.Constraint;
import org.graylog2.contentpacks.model.constraints.ConstraintCheckResult;


import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;


public interface ConstraintChecker { public interface ConstraintChecker {
Set<Constraint> checkConstraints(Collection<Constraint> requestedConstraints); Set<Constraint> ensureConstraints(Collection<Constraint> requestedConstraints);
Set<ConstraintCheckResult> checkConstraints(Collection<Constraint> requestedConstraints);
} }
Expand Up @@ -21,6 +21,7 @@
import com.vdurmont.semver4j.Requirement; import com.vdurmont.semver4j.Requirement;
import com.vdurmont.semver4j.Semver; import com.vdurmont.semver4j.Semver;
import org.graylog2.contentpacks.model.constraints.Constraint; import org.graylog2.contentpacks.model.constraints.Constraint;
import org.graylog2.contentpacks.model.constraints.ConstraintCheckResult;
import org.graylog2.contentpacks.model.constraints.GraylogVersionConstraint; import org.graylog2.contentpacks.model.constraints.GraylogVersionConstraint;


import java.util.Collection; import java.util.Collection;
Expand All @@ -43,19 +44,34 @@ public GraylogVersionConstraintChecker() {
this.graylogVersion = graylogVersion; this.graylogVersion = graylogVersion;
} }



@Override @Override
public Set<Constraint> checkConstraints(Collection<Constraint> requestedConstraints) { public Set<Constraint> ensureConstraints(Collection<Constraint> requestedConstraints) {
final ImmutableSet.Builder<Constraint> fulfilledConstraints = ImmutableSet.builder(); final ImmutableSet.Builder<Constraint> fulfilledConstraints = ImmutableSet.builder();
for (Constraint constraint : requestedConstraints) { for (Constraint constraint : requestedConstraints) {
if (constraint instanceof GraylogVersionConstraint) { if (constraint instanceof GraylogVersionConstraint) {
final GraylogVersionConstraint versionConstraint = (GraylogVersionConstraint) constraint; final GraylogVersionConstraint versionConstraint = (GraylogVersionConstraint) constraint;
final Requirement requiredVersion = versionConstraint.version(); final Requirement requiredVersion = versionConstraint.version();

if (requiredVersion.isSatisfiedBy(graylogVersion.toString())) { if (requiredVersion.isSatisfiedBy(graylogVersion.toString())) {
fulfilledConstraints.add(constraint); fulfilledConstraints.add(constraint);
} }
} }
} }
return fulfilledConstraints.build(); return fulfilledConstraints.build();
} }

@Override
public Set<ConstraintCheckResult> checkConstraints(Collection<Constraint> requestedConstraints) {
final ImmutableSet.Builder<ConstraintCheckResult> fulfilledConstraints = ImmutableSet.builder();
for (Constraint constraint : requestedConstraints) {
if (constraint instanceof GraylogVersionConstraint) {
final GraylogVersionConstraint versionConstraint = (GraylogVersionConstraint) constraint;
final Requirement requiredVersion = versionConstraint.version();
final ConstraintCheckResult constraintCheckResult = ConstraintCheckResult.create(versionConstraint,
requiredVersion.isSatisfiedBy(graylogVersion.toString()));
fulfilledConstraints.add(constraintCheckResult);
}
}
return fulfilledConstraints.build();
}
} }
Expand Up @@ -20,6 +20,7 @@
import com.vdurmont.semver4j.Requirement; import com.vdurmont.semver4j.Requirement;
import com.vdurmont.semver4j.Semver; import com.vdurmont.semver4j.Semver;
import org.graylog2.contentpacks.model.constraints.Constraint; import org.graylog2.contentpacks.model.constraints.Constraint;
import org.graylog2.contentpacks.model.constraints.ConstraintCheckResult;
import org.graylog2.contentpacks.model.constraints.PluginVersionConstraint; import org.graylog2.contentpacks.model.constraints.PluginVersionConstraint;
import org.graylog2.plugin.PluginMetaData; import org.graylog2.plugin.PluginMetaData;
import org.graylog2.plugin.Version; import org.graylog2.plugin.Version;
Expand All @@ -42,7 +43,7 @@ public PluginVersionConstraintChecker(Set<PluginMetaData> pluginMetaData) {
} }


@Override @Override
public Set<Constraint> checkConstraints(Collection<Constraint> requestedConstraints) { public Set<Constraint> ensureConstraints(Collection<Constraint> requestedConstraints) {
final ImmutableSet.Builder<Constraint> fulfilledConstraints = ImmutableSet.builder(); final ImmutableSet.Builder<Constraint> fulfilledConstraints = ImmutableSet.builder();
for (Constraint constraint : requestedConstraints) { for (Constraint constraint : requestedConstraints) {
if (constraint instanceof PluginVersionConstraint) { if (constraint instanceof PluginVersionConstraint) {
Expand All @@ -58,4 +59,25 @@ public Set<Constraint> checkConstraints(Collection<Constraint> requestedConstrai
} }
return fulfilledConstraints.build(); return fulfilledConstraints.build();
} }

@Override
public Set<ConstraintCheckResult> checkConstraints(Collection<Constraint> requestedConstraints) {
final ImmutableSet.Builder<ConstraintCheckResult> fulfilledConstraints = ImmutableSet.builder();
for (Constraint constraint : requestedConstraints) {
if (constraint instanceof PluginVersionConstraint) {
final PluginVersionConstraint versionConstraint = (PluginVersionConstraint) constraint;
final Requirement requiredVersion = versionConstraint.version();

boolean result = false;
for (Semver pluginVersion : pluginVersions) {
if (requiredVersion.isSatisfiedBy(pluginVersion)) {
result = true;
}
}
ConstraintCheckResult constraintCheckResult = ConstraintCheckResult.create(versionConstraint, result);
fulfilledConstraints.add(constraintCheckResult);
}
}
return fulfilledConstraints.build();
}
} }
Expand Up @@ -18,6 +18,9 @@


import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.graylog2.contentpacks.model.constraints.Constraint;

import java.util.Set;


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = Versioned.FIELD_META_VERSION, defaultImpl = LegacyContentPack.class) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = Versioned.FIELD_META_VERSION, defaultImpl = LegacyContentPack.class)
@JsonSubTypes({ @JsonSubTypes({
Expand All @@ -27,4 +30,6 @@
public interface ContentPack extends Identified, Revisioned, Versioned { public interface ContentPack extends Identified, Revisioned, Versioned {
interface ContentPackBuilder<SELF> extends IdBuilder<SELF>, RevisionBuilder<SELF>, VersionBuilder<SELF> { interface ContentPackBuilder<SELF> extends IdBuilder<SELF>, RevisionBuilder<SELF>, VersionBuilder<SELF> {
} }

Set<Constraint> requires();
} }
Expand Up @@ -20,6 +20,8 @@
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.graylog2.contentpacks.model.Typed; import org.graylog2.contentpacks.model.Typed;


import java.util.Optional;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = Constraint.FIELD_META_TYPE) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = Constraint.FIELD_META_TYPE)
@JsonSubTypes({ @JsonSubTypes({
@JsonSubTypes.Type(value = GraylogVersionConstraint.class, name = GraylogVersionConstraint.TYPE_NAME), @JsonSubTypes.Type(value = GraylogVersionConstraint.class, name = GraylogVersionConstraint.TYPE_NAME),
Expand Down
@@ -0,0 +1,40 @@
/**
* This file is part of Graylog.
*
* Graylog is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Graylog. If not, see <http://www.gnu.org/licenses/>.
*/
package org.graylog2.contentpacks.model.constraints;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;
import org.graylog.autovalue.WithBeanGetter;

@JsonAutoDetect

@AutoValue
@WithBeanGetter
public abstract class ConstraintCheckResult {
@JsonProperty
public abstract Constraint constraint();

@JsonProperty
public abstract boolean fulfilled();

@JsonCreator
public static ConstraintCheckResult create(@JsonProperty("constraint") Constraint constraint, @JsonProperty("fulfilled") boolean fulfilled) {
return new AutoValue_ConstraintCheckResult(constraint, fulfilled);
}
}
Expand Up @@ -17,13 +17,17 @@
package org.graylog2.contentpacks.model.constraints; package org.graylog2.contentpacks.model.constraints;


import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import com.vdurmont.semver4j.Requirement; import com.vdurmont.semver4j.Requirement;
import org.graylog2.contentpacks.model.ModelType; import org.graylog2.contentpacks.model.ModelType;
import org.graylog2.plugin.Version; import org.graylog2.plugin.Version;


import javax.annotation.Nullable;
import java.util.Optional;

@AutoValue @AutoValue
@JsonDeserialize(builder = AutoValue_GraylogVersionConstraint.Builder.class) @JsonDeserialize(builder = AutoValue_GraylogVersionConstraint.Builder.class)
public abstract class GraylogVersionConstraint implements Constraint { public abstract class GraylogVersionConstraint implements Constraint {
Expand All @@ -34,6 +38,8 @@ public abstract class GraylogVersionConstraint implements Constraint {
@JsonProperty(FIELD_GRAYLOG_VERSION) @JsonProperty(FIELD_GRAYLOG_VERSION)
public abstract Requirement version(); public abstract Requirement version();


public abstract Builder toBuilder();

public static Builder builder() { public static Builder builder() {
return new AutoValue_GraylogVersionConstraint.Builder(); return new AutoValue_GraylogVersionConstraint.Builder();
} }
Expand Down
Expand Up @@ -17,6 +17,7 @@
package org.graylog2.contentpacks.model.constraints; package org.graylog2.contentpacks.model.constraints;


import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
Expand All @@ -25,6 +26,8 @@
import org.graylog2.plugin.PluginMetaData; import org.graylog2.plugin.PluginMetaData;
import org.graylog2.plugin.Version; import org.graylog2.plugin.Version;


import java.util.Optional;

@AutoValue @AutoValue
@JsonDeserialize(builder = AutoValue_PluginVersionConstraint.Builder.class) @JsonDeserialize(builder = AutoValue_PluginVersionConstraint.Builder.class)
public abstract class PluginVersionConstraint implements Constraint { public abstract class PluginVersionConstraint implements Constraint {
Expand All @@ -38,6 +41,8 @@ public abstract class PluginVersionConstraint implements Constraint {
@JsonProperty(FIELD_PLUGIN_VERSION) @JsonProperty(FIELD_PLUGIN_VERSION)
public abstract Requirement version(); public abstract Requirement version();


public abstract Builder toBuilder();

public static PluginVersionConstraint of(PluginMetaData pluginMetaData) { public static PluginVersionConstraint of(PluginMetaData pluginMetaData) {
final Version version = pluginMetaData.getVersion(); final Version version = pluginMetaData.getVersion();
final String versionString = version.toString().replace("-SNAPSHOT", ""); final String versionString = version.toString().replace("-SNAPSHOT", "");
Expand Down
@@ -0,0 +1,41 @@
/**
* This file is part of Graylog.
*
* Graylog is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Graylog. If not, see <http://www.gnu.org/licenses/>.
*/
package org.graylog2.rest.models.system.contenpacks.responses;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;
import org.graylog2.contentpacks.model.ContentPack;
import org.graylog2.contentpacks.model.constraints.ConstraintCheckResult;

import java.util.Set;

@JsonAutoDetect
@AutoValue
public abstract class ContentPackResponse {
@JsonProperty("content_pack")
public abstract ContentPack contentPack();

@JsonProperty("constraints_result")
public abstract Set<ConstraintCheckResult> constraints();

@JsonCreator
public static ContentPackResponse create(@JsonProperty("content_pack") ContentPack contentPack, @JsonProperty("constraints_result") Set<ConstraintCheckResult> constraints) {
return new AutoValue_ContentPackResponse(contentPack, constraints);
}
}
Expand Up @@ -22,19 +22,25 @@
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import org.graylog.autovalue.WithBeanGetter; import org.graylog.autovalue.WithBeanGetter;
import org.graylog2.contentpacks.model.ContentPack; import org.graylog2.contentpacks.model.ContentPack;
import org.graylog2.contentpacks.model.constraints.ConstraintCheckResult;


import java.util.Map; import java.util.Map;
import java.util.Set;


@JsonAutoDetect @JsonAutoDetect


@AutoValue @AutoValue
@WithBeanGetter @WithBeanGetter
public abstract class ContentPackRevisions { public abstract class ContentPackRevisions {
@JsonProperty @JsonProperty("content_pack_revisions")
public abstract Map<Integer, ContentPack> contentPackRevisions(); public abstract Map<Integer, ContentPack> contentPackRevisions();


@JsonProperty("constraints_result")
public abstract Map<Integer, Set<ConstraintCheckResult>> constraints();

@JsonCreator @JsonCreator
public static ContentPackRevisions create(@JsonProperty("content_pack_revisions") Map<Integer, ContentPack> contentPackRevisions) { public static ContentPackRevisions create(@JsonProperty("content_pack_revisions") Map<Integer, ContentPack> contentPackRevisions,
return new AutoValue_ContentPackRevisions(contentPackRevisions); @JsonProperty("constraints_result")Map<Integer, Set<ConstraintCheckResult>> constraints) {
return new AutoValue_ContentPackRevisions(contentPackRevisions, constraints);
} }
} }

0 comments on commit b2a65a5

Please sign in to comment.