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 java.util.Map;
47 import java.util.Optional;
48 import java.util.TreeMap;
49
50 public class CreateSeriesCommand extends AbstractCommand<GqlSeries> {
51
52 private AccessControlListInput aclInput;
53
54 public CreateSeriesCommand(final Builder builder) {
55 super(builder);
56 this.aclInput = builder.accessControlListInput;
57 }
58
59 @Override
60 public GqlSeries execute() {
61 OpencastContext context = OpencastContextManager.getCurrentContext();
62 final ElasticsearchIndex index = context.getService(ElasticsearchIndex.class);
63 final IndexService indexService = context.getService(IndexService.class);
64
65 final Map<String, Object> seriesMetadata = environment.getArgument("metadata");
66
67 MetadataList metadataList = createMetadataList(seriesMetadata, indexService);
68 Map<String, String> options = new TreeMap<>();
69 Optional<Long> optThemeId = Optional.empty();
70
71 final SeriesService seriesService = context.getService(SeriesService.class);
72
73 AccessControlList acl = new AccessControlList();
74 for (var entry : aclInput.getEntries()) {
75 for (var action : entry.getAction()) {
76 acl.getEntries().add(new AccessControlEntry(entry.getRole(), action, true));
77 }
78 }
79
80 if (aclInput.getManagedAclId() != null) {
81 AclService aclService = context.getService(AclServiceFactory.class)
82 .serviceFor(context.getService(SecurityService.class).getOrganization());
83 aclService.getAcl(aclInput.getManagedAclId())
84 .ifPresent(value -> acl.merge(value.getAcl()));
85 }
86 String seriesId;
87 try {
88 seriesId = indexService.createSeries(metadataList, options, Optional.of(acl), optThemeId);
89 } catch (IndexServiceException e) {
90 throw new GraphQLRuntimeException(e);
91 }
92
93 try {
94 return new GqlSeries(
95 index.getSeries(seriesId, context.getOrganization().getId(), context.getUser()).get()
96 );
97 } catch (SearchIndexException e) {
98 throw new GraphQLRuntimeException(e);
99 }
100 }
101
102 private MetadataList createMetadataList(Map<String, Object> seriesMetadata, IndexService indexService) {
103 CommonSeriesCatalogUIAdapter adapter = (CommonSeriesCatalogUIAdapter) indexService
104 .getCommonSeriesCatalogUIAdapter();
105
106 MetadataList list = new MetadataList();
107 list.add(adapter, adapter.getRawFields());
108
109 final MediaPackageElementFlavor flavor = MediaPackageElementFlavor
110 .parseFlavor("dublincore/series");
111
112 final DublinCoreMetadataCollection collection = list.getMetadataByFlavor(flavor.toString());
113
114 seriesMetadata.keySet().forEach(k -> {
115 final MetadataField target = collection.getOutputFields().get(k);
116 target.setValue(seriesMetadata.get(k));
117 });
118
119 return list;
120 }
121
122 public static Builder create(
123 GqlCommonSeriesMetadataInput seriesMetadataInput,
124 AccessControlListInput accessControlListInput
125 ) {
126 return new Builder(seriesMetadataInput, accessControlListInput);
127 }
128
129 public static class Builder extends AbstractCommand.Builder<GqlSeries> {
130
131 private final GqlCommonSeriesMetadataInput seriesMetadataInput;
132
133 private final AccessControlListInput accessControlListInput;
134
135 public Builder(GqlCommonSeriesMetadataInput seriesMetadataInput, AccessControlListInput accessControlListInput) {
136 this.seriesMetadataInput = seriesMetadataInput;
137 this.accessControlListInput = accessControlListInput;
138 }
139
140 @Override
141 public void validate() {
142 super.validate();
143 if (seriesMetadataInput == null) {
144 throw new IllegalStateException("Series metadata cannot be null");
145 }
146 if (accessControlListInput == null) {
147 throw new IllegalStateException("Access control list cannot be null");
148 }
149 }
150
151 @Override
152 public CreateSeriesCommand build() {
153 validate();
154 return new CreateSeriesCommand(this);
155 }
156 }
157
158 }