Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.io.File;
import java.util.List;
import java.util.Set;

import org.xwiki.component.annotation.Role;

Expand Down Expand Up @@ -80,4 +81,16 @@ public interface LicensingConfiguration
* @return the email of the licensing owner or null if the value of the property is not filled up
*/
String getLicensingOwnerEmail();

/**
* @return {@link List} with the groups whose members need to be notified about the extension
* @since 1.31
*/
List<String> getNotifiedGroups();

/**
* @return {@link Set} with the groups whose members need to be notified about the extension
* @since 1.31
*/
Set<String> getNotifiedGroupsSet();
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import javax.inject.Inject;
Expand All @@ -33,8 +34,11 @@
import org.xwiki.component.annotation.Component;
import org.xwiki.configuration.ConfigurationSource;
import org.xwiki.environment.Environment;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.DocumentReferenceResolver;

import com.xwiki.licensing.LicensingConfiguration;
import com.xwiki.licensing.internal.helpers.LicensingNotificationConfigurationSource;

/**
* Default implementation of {@link LicensingConfiguration}.
Expand Down Expand Up @@ -74,6 +78,14 @@ public class DefaultLicensingConfiguration implements LicensingConfiguration
@Named("LicensingOwnerConfigurationSource")
private ConfigurationSource ownerConfig;

@Inject
@Named(LicensingNotificationConfigurationSource.HINT)
private ConfigurationSource notificationConfig;

@Inject
@Named("current")
private DocumentReferenceResolver<String> referenceResolver;

private File localStorePath;

@Override
Expand Down Expand Up @@ -137,6 +149,19 @@ public String getStoreRenewURL()
return this.storeConfig.getProperty("storeRenewURL");
}

@Override
public List<String> getNotifiedGroups()
{
return convertObjectToStringList(notificationConfig.getProperty("notifiedGroups"));
}

@Override
public Set<String> getNotifiedGroupsSet()
{
return getNotifiedGroups().stream().map(referenceResolver::resolve).map(DocumentReference::toString)
.collect(Collectors.toSet());
}

@SuppressWarnings("unchecked")
private List<String> convertObjectToStringList(Object list)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This 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 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.xwiki.licensing.internal.helpers;

import java.util.Arrays;
import java.util.List;

import javax.inject.Named;
import javax.inject.Singleton;

import org.xwiki.component.annotation.Component;
import org.xwiki.configuration.internal.AbstractDocumentConfigurationSource;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.LocalDocumentReference;

/**
* Configuration source for notification information.
*
* @version $Id$
* @since 1.31
*/
@Component
@Named(LicensingNotificationConfigurationSource.HINT)
@Singleton
public class LicensingNotificationConfigurationSource extends AbstractDocumentConfigurationSource
{
/**
* Component hint.
*/
public static final String HINT = "LicensingNotificationConfigurationSource";

protected static final List<String> CODE_SPACE = Arrays.asList("Licenses", "Code");

protected static final LocalDocumentReference LICENSING_CONFIG_DOC =
new LocalDocumentReference(CODE_SPACE, "LicensingConfig");

protected static final LocalDocumentReference OWNER_CLASS =
new LocalDocumentReference(CODE_SPACE, "LicensingNotificationClass");

@Override
protected DocumentReference getDocumentReference()
{
return new DocumentReference(LICENSING_CONFIG_DOC, this.getCurrentWikiReference());
}

@Override
protected LocalDocumentReference getClassReference()
{
return OWNER_CLASS;
}

@Override
protected String getCacheId()
{
return "licensing.configuration.notification";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,9 @@ private void notifyExtensionVersionAvailable(ExtensionId extensionId, String nam
extensionInfo.put("version", installableVersions.get(0).getValue());

this.observationManager.notify(new NewExtensionVersionAvailableEvent(
new ExtensionId(extensionId.getId(), installableVersions.get(0)), namespace),
extensionId.getId(), (new ObjectMapper()).writeValueAsString(extensionInfo));
new ExtensionId(extensionId.getId(), installableVersions.get(0)), namespace,
licensingConfig.getNotifiedGroupsSet()), extensionId.getId(),
(new ObjectMapper()).writeValueAsString(extensionInfo));
this.newVersionNotificationManager.markNotificationAsSent(extensionId.getId(), namespaceName,
installableVersions.get(0).getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.observation.ObservationManager;

import com.xwiki.licensing.LicensingConfiguration;
import com.xwiki.licensing.internal.upgrades.notifications.ExtensionAutoUpgradedEvent;
import com.xwiki.licensing.internal.upgrades.notifications.ExtensionAutoUpgradedFailedEvent;

/**
* Upgrades an extension from a namespace to the last compatible version and sends a notification. The notification will
* be displayed only for users that subscribed to it and disabled the System filter since it is send by superadmin user.
*
*
* @version $Id$
* @since 1.17
*/
Expand Down Expand Up @@ -95,9 +96,13 @@ public class UpgradeExtensionHandler
@Inject
private EntityReferenceSerializer<String> serializer;

@Inject
private LicensingConfiguration licensingConfig;


/**
* Try upgrading an extension inside a namespace to the last compatible version.
*
*
* @param installedExtension the already installed extension
* @param namespace the namespace in which the extension is installed
*/
Expand All @@ -116,7 +121,8 @@ public void tryUpgradeExtensionToLastVersion(InstalledExtension installedExtensi
"licensor.notification.autoUpgrade.done", installedExtension.getName(),
installedExtensionId.getVersion().getValue(), toInstallExtensionId.getVersion().getValue());

this.observationManager.notify(new ExtensionAutoUpgradedEvent(), LICENSOR_API_ID, doneUpgradeMessage);
this.observationManager.notify(new ExtensionAutoUpgradedEvent(licensingConfig.getNotifiedGroupsSet()),
LICENSOR_API_ID, doneUpgradeMessage);

// If the execution gets here, it means that the upgrade was done.
break;
Expand All @@ -133,7 +139,7 @@ public void tryUpgradeExtensionToLastVersion(InstalledExtension installedExtensi

/**
* Install the given extension inside a namespace.
*
*
* @param extensionId extension to install
* @param namespace namespace where the install is done
* @throws JobException error at job execution
Expand Down Expand Up @@ -183,7 +189,7 @@ protected InstallRequest getInstallRequest(ExtensionId extensionId, String names

/**
* Get the reversed list of versions that can be installed, considering the already installed version.
*
*
* @param extensionId ExtensionId of the application that is needed
* @return reversed list of versions until the already installed one
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,54 @@
*/
package com.xwiki.licensing.internal.upgrades.notifications;

import org.xwiki.eventstream.RecordableEvent;
import java.util.HashSet;
import java.util.Set;

import org.xwiki.eventstream.TargetableEvent;

/**
* The event send when an application is automatically upgraded. Used in UpgradeExtensionHandler.
*
*
* @version $Id$
* @since 1.17
*/
public class ExtensionAutoUpgradedEvent implements RecordableEvent
public class ExtensionAutoUpgradedEvent implements TargetableEvent
{
/**
* The event type used for this component.
*/
public static final String EVENT_TYPE = "ExtensionAutoUpgradedEvent";

private Set<String> notifiedGroups;

/**
* The default constructor.
*/
public ExtensionAutoUpgradedEvent()
{
notifiedGroups = new HashSet<>();
}

/**
* Created a new instance with the given data.
*
* @param notifiedGroups the groups that should be notified about the new upgrade. An empty {@link Set} means
* all users will be notified, no matter the group
*/
public ExtensionAutoUpgradedEvent(Set<String> notifiedGroups)
{
this.notifiedGroups = notifiedGroups;
}

@Override
public boolean matches(Object otherEvent)
{
return otherEvent instanceof ExtensionAutoUpgradedEvent;
}

@Override
public Set<String> getTarget()
{
return notifiedGroups;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@
*/
package com.xwiki.licensing.internal.upgrades.notifications.newVersion;

import org.xwiki.eventstream.RecordableEvent;
import java.util.Collections;
import java.util.Set;

import org.xwiki.eventstream.TargetableEvent;
import org.xwiki.extension.ExtensionId;

/**
* The event send when a new version of a licensed extension is available.
*
*
* @version $Id$
* @since 1.23
*/
public class NewExtensionVersionAvailableEvent implements RecordableEvent
public class NewExtensionVersionAvailableEvent implements TargetableEvent
{
/**
* The name of this component.
Expand All @@ -39,6 +42,8 @@ public class NewExtensionVersionAvailableEvent implements RecordableEvent

private String namespace;

private Set<String> notifiedGroups = Collections.emptySet();

/**
* The default constructor.
*/
Expand All @@ -51,14 +56,30 @@ public NewExtensionVersionAvailableEvent()
*
* @param extensionId the extension id of the new extension version detected
* @param namespace the namespace where the new extension version was detected, where {@code null} means root
* namespace (i.e. all namespaces)
* namespace (i.e. all namespaces)
*/
public NewExtensionVersionAvailableEvent(ExtensionId extensionId, String namespace)
{
this.extensionId = extensionId;
this.namespace = namespace;
}

/**
* See {@link #NewExtensionVersionAvailableEvent(ExtensionId, String)}.
*
* @param extensionId the extension id of the new extension version detected
* @param namespace the namespace where the new extension version was detected, where {@code null} means root
* namespace (i.e. all namespaces)
* @param notifiedGroups the groups that should be notified about the new version. An empty {@link Set} means
* all users will be notified, no matter the group
*/
public NewExtensionVersionAvailableEvent(ExtensionId extensionId, String namespace, Set<String> notifiedGroups)
{
this.extensionId = extensionId;
this.namespace = namespace;
this.notifiedGroups = notifiedGroups;
}

@Override
public boolean matches(Object otherEvent)
{
Expand All @@ -75,10 +96,16 @@ public ExtensionId getExtensionId()

/**
* @return the namespace where the new extension version was detected. {@code null} means root namespace (i.e all
* namespaces)
* namespaces)
*/
public String getNamespace()
{
return this.namespace;
}

@Override
public Set<String> getTarget()
{
return notifiedGroups;
}
}
Loading