1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.graphql.command;
23
24 import org.opencastproject.authorization.xacml.manager.api.AclService;
25 import org.opencastproject.authorization.xacml.manager.api.AclServiceFactory;
26 import org.opencastproject.elasticsearch.api.SearchIndexException;
27 import org.opencastproject.elasticsearch.index.ElasticsearchIndex;
28 import org.opencastproject.graphql.exception.GraphQLRuntimeException;
29 import org.opencastproject.graphql.execution.context.OpencastContext;
30 import org.opencastproject.graphql.execution.context.OpencastContextManager;
31 import org.opencastproject.graphql.series.GqlSeries;
32 import org.opencastproject.graphql.type.input.AccessControlListInput;
33 import org.opencastproject.graphql.type.input.GqlCommonSeriesMetadataInput;
34 import org.opencastproject.index.service.api.IndexService;
35 import org.opencastproject.index.service.catalog.adapter.series.CommonSeriesCatalogUIAdapter;
36 import org.opencastproject.index.service.exception.IndexServiceException;
37 import org.opencastproject.mediapackage.MediaPackageElementFlavor;
38 import org.opencastproject.metadata.dublincore.DublinCoreMetadataCollection;
39 import org.opencastproject.metadata.dublincore.MetadataField;
40 import org.opencastproject.metadata.dublincore.MetadataList;
41 import org.opencastproject.security.api.AccessControlEntry;
42 import org.opencastproject.security.api.AccessControlList;
43 import org.opencastproject.security.api.SecurityService;
44 import org.opencastproject.series.api.SeriesService;
45
46 import com.entwinemedia.fn.data.Opt;
47
48 import java.util.Map;
49 import java.util.TreeMap;
50
51 public class CreateSeriesCommand extends AbstractCommand<GqlSeries> {
52
53 private AccessControlListInput aclInput;
54
55 public CreateSeriesCommand(final Builder builder) {
56 super(builder);
57 this.aclInput = builder.accessControlListInput;
58 }
59
60 @Override
61 public GqlSeries execute() {
62 OpencastContext context = OpencastContextManager.getCurrentContext();
63 final ElasticsearchIndex index = context.getService(ElasticsearchIndex.class);
64 final IndexService indexService = context.getService(IndexService.class);
65
66 final Map<String, Object> seriesMetadata = environment.getArgument("metadata");
67
68 MetadataList metadataList = createMetadataList(seriesMetadata, indexService);
69 Map<String, String> options = new TreeMap<>();
70 Opt<Long> optThemeId = Opt.none();
71
72 final SeriesService seriesService = context.getService(SeriesService.class);
73
74 AccessControlList acl = new AccessControlList();
75 for (var entry : aclInput.getEntries()) {
76 for (var action : entry.getAction()) {
77 acl.getEntries().add(new AccessControlEntry(entry.getRole(), action, true));
78 }
79 }
80
81 if (aclInput.getManagedAclId() != null) {
82 AclService aclService = context.getService(AclServiceFactory.class)
83 .serviceFor(context.getService(SecurityService.class).getOrganization());
84 aclService.getAcl(aclInput.getManagedAclId())
85 .ifPresent(value -> acl.merge(value.getAcl()));
86 }
87 String seriesId;
88 try {
89 seriesId = indexService.createSeries(metadataList, options, Opt.some(acl), optThemeId);
90 } catch (IndexServiceException e) {
91 throw new GraphQLRuntimeException(e);
92 }
93
94 try {
95 return new GqlSeries(
96 index.getSeries(seriesId, context.getOrganization().getId(), context.getUser()).get()
97 );
98 } catch (SearchIndexException e) {
99 throw new GraphQLRuntimeException(e);
100 }
101 }
102
103 private MetadataList createMetadataList(Map<String, Object> seriesMetadata, IndexService indexService) {
104 CommonSeriesCatalogUIAdapter adapter = (CommonSeriesCatalogUIAdapter) indexService
105 .getCommonSeriesCatalogUIAdapter();
106
107 MetadataList list = new MetadataList();
108 list.add(adapter, adapter.getRawFields());
109
110 final MediaPackageElementFlavor flavor = MediaPackageElementFlavor
111 .parseFlavor("dublincore/series");
112
113 final DublinCoreMetadataCollection collection = list.getMetadataByFlavor(flavor.toString());
114
115 seriesMetadata.keySet().forEach(k -> {
116 final MetadataField target = collection.getOutputFields().get(k);
117 target.setValue(seriesMetadata.get(k));
118 });
119
120 return list;
121 }
122
123 public static Builder create(
124 GqlCommonSeriesMetadataInput seriesMetadataInput,
125 AccessControlListInput accessControlListInput
126 ) {
127 return new Builder(seriesMetadataInput, accessControlListInput);
128 }
129
130 public static class Builder extends AbstractCommand.Builder<GqlSeries> {
131
132 private final GqlCommonSeriesMetadataInput seriesMetadataInput;
133
134 private final AccessControlListInput accessControlListInput;
135
136 public Builder(GqlCommonSeriesMetadataInput seriesMetadataInput, AccessControlListInput accessControlListInput) {
137 this.seriesMetadataInput = seriesMetadataInput;
138 this.accessControlListInput = accessControlListInput;
139 }
140
141 @Override
142 public void validate() {
143 super.validate();
144 if (seriesMetadataInput == null) {
145 throw new IllegalStateException("Series metadata cannot be null");
146 }
147 if (accessControlListInput == null) {
148 throw new IllegalStateException("Access control list cannot be null");
149 }
150 }
151
152 @Override
153 public CreateSeriesCommand build() {
154 validate();
155 return new CreateSeriesCommand(this);
156 }
157 }
158
159 }