View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  package org.opencastproject.assetmanager.util;
22  
23  import static org.opencastproject.assetmanager.api.AssetManager.DEFAULT_OWNER;
24  import static org.opencastproject.mediapackage.MediaPackageElements.XACML_POLICY_EPISODE;
25  import static org.opencastproject.mediapackage.MediaPackageElements.XACML_POLICY_SERIES;
26  import static org.opencastproject.systems.OpencastConstants.WORKFLOW_PROPERTIES_NAMESPACE;
27  
28  import org.opencastproject.assetmanager.api.AssetManager;
29  import org.opencastproject.assetmanager.api.Property;
30  import org.opencastproject.assetmanager.api.PropertyId;
31  import org.opencastproject.assetmanager.api.Value;
32  import org.opencastproject.mediapackage.Attachment;
33  import org.opencastproject.mediapackage.Catalog;
34  import org.opencastproject.mediapackage.MediaPackage;
35  import org.opencastproject.mediapackage.MediaPackageElement;
36  import org.opencastproject.mediapackage.MediaPackageElementFlavor;
37  
38  import java.util.Arrays;
39  import java.util.Collection;
40  import java.util.Collections;
41  import java.util.HashMap;
42  import java.util.HashSet;
43  import java.util.List;
44  import java.util.Map;
45  import java.util.Set;
46  import java.util.stream.Collectors;
47  
48  /**
49   * Utility class to store and retrieve Workflow Properties (which are stored in specially prefixed Asset Manager
50   * properties)
51   */
52  public final class WorkflowPropertiesUtil {
53    private static final Set<MediaPackageElementFlavor> SECURITY_FLAVORS = new HashSet<>(
54            Arrays.asList(XACML_POLICY_EPISODE, XACML_POLICY_SERIES));
55  
56    private WorkflowPropertiesUtil() {
57    }
58  
59    /**
60     * Retrieve latest properties for a set of event ids
61     * @param assetManager The Asset Manager to use
62     * @param eventIds Collection of event IDs (can be a set, but doesn't have to be)
63     * @return A map mapping event IDs to key value pairs (which are themselves maps) representing the properties
64     */
65    public static Map<String, Map<String, String>> getLatestWorkflowPropertiesForEvents(final AssetManager assetManager,
66            final Collection<String> eventIds) {
67      final Map<String, Map<String, String>> workflowProperties = new HashMap<>(eventIds.size());
68      for (String eventId : eventIds) {
69        final List<Property> properties = assetManager.selectProperties(eventId, WORKFLOW_PROPERTIES_NAMESPACE);
70        final Map<String, String> eventMap = new HashMap<>(properties.size());
71        for (final Property property : properties) {
72          eventMap.put(property.getId().getName(), property.getValue().get(Value.STRING));
73        }
74        workflowProperties.put(eventId, eventMap);
75      }
76      return workflowProperties;
77    }
78  
79    /**
80     * Retrieve the latest properties for a single media package
81     * @param assetManager The Asset Manager to use
82     * @param mediaPackageId The media package to query
83     * @return A list of properties represented by a Map
84     */
85    public static Map<String, String> getLatestWorkflowProperties(final AssetManager assetManager,
86            final String mediaPackageId) {
87      return assetManager.selectProperties(mediaPackageId, WORKFLOW_PROPERTIES_NAMESPACE)
88              .parallelStream()
89              .collect(Collectors.toMap(
90                      p -> p.getId().getName(),
91                      p -> p.getValue().get(Value.STRING)));
92    }
93  
94    /**
95     * Store selected properties for a media package
96     * @param assetManager The Asset Manager to use
97     * @param mediaPackage The media package to store properties relative to
98     * @param properties A list of properties represented by a Map
99     */
100   public static void storeProperties(final AssetManager assetManager, final MediaPackage mediaPackage,
101           final Map<String, String> properties) {
102 
103     // Properties can only be created if a snapshot exists. Hence, we create a snapshot if there is none right now.
104     // Although, to avoid lots of potentially slow IO operations, we archive a slimmer version of the media package,
105     // containing only metadata and security attachments.
106     if (!assetManager.snapshotExists(mediaPackage.getIdentifier().toString())) {
107       MediaPackage simplifiedMediaPackage = (MediaPackage) mediaPackage.clone();
108       for (MediaPackageElement element : mediaPackage.getElements()) {
109         if (element instanceof Catalog) {
110           continue;
111         }
112         if (element instanceof Attachment && SECURITY_FLAVORS.contains(element.getFlavor())) {
113           continue;
114         }
115         simplifiedMediaPackage.remove(element);
116       }
117 
118       assetManager.takeSnapshot(DEFAULT_OWNER, simplifiedMediaPackage);
119     }
120 
121     // Store all properties
122     for (final Map.Entry<String, String> entry : properties.entrySet()) {
123       final PropertyId propertyId = PropertyId
124               .mk(mediaPackage.getIdentifier().toString(), WORKFLOW_PROPERTIES_NAMESPACE, entry.getKey());
125       final Property property = Property.mk(propertyId, Value.mk(entry.getValue()));
126       assetManager.setProperty(property);
127     }
128   }
129 
130   public static void storeProperty(final AssetManager assetManager, final MediaPackage mediaPackage,
131           final String name, final String value) {
132     storeProperties(assetManager, mediaPackage, Collections.singletonMap(name, value));
133   }
134 }