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.publication.oaipmh.remote;
22  
23  import static java.lang.String.format;
24  import static java.nio.charset.StandardCharsets.UTF_8;
25  
26  import org.opencastproject.job.api.Job;
27  import org.opencastproject.job.api.JobParser;
28  import org.opencastproject.mediapackage.MediaPackage;
29  import org.opencastproject.mediapackage.MediaPackageElement;
30  import org.opencastproject.mediapackage.MediaPackageElementFlavor;
31  import org.opencastproject.mediapackage.MediaPackageElementParser;
32  import org.opencastproject.mediapackage.MediaPackageException;
33  import org.opencastproject.mediapackage.MediaPackageParser;
34  import org.opencastproject.mediapackage.Publication;
35  import org.opencastproject.publication.api.OaiPmhPublicationService;
36  import org.opencastproject.publication.api.PublicationException;
37  import org.opencastproject.security.api.TrustedHttpClient;
38  import org.opencastproject.serviceregistry.api.RemoteBase;
39  import org.opencastproject.serviceregistry.api.ServiceRegistry;
40  
41  import org.apache.commons.io.IOUtils;
42  import org.apache.commons.lang3.StringUtils;
43  import org.apache.http.HttpResponse;
44  import org.apache.http.client.entity.UrlEncodedFormEntity;
45  import org.apache.http.client.methods.HttpPost;
46  import org.apache.http.message.BasicNameValuePair;
47  import org.osgi.service.component.annotations.Component;
48  import org.osgi.service.component.annotations.Reference;
49  import org.slf4j.Logger;
50  import org.slf4j.LoggerFactory;
51  
52  import java.nio.charset.Charset;
53  import java.util.ArrayList;
54  import java.util.Arrays;
55  import java.util.List;
56  import java.util.Set;
57  
58  /**
59   * A remote publication service invoker.
60   */
61  @Component(
62      immediate = true,
63      service = OaiPmhPublicationService.class,
64      property = {
65          "service.description=Publication (OAI-PMH) Remote Service Proxy"
66      }
67  )
68  public class OaiPmhPublicationServiceRemoteImpl extends RemoteBase implements OaiPmhPublicationService {
69  
70    /** The logger */
71    private static final Logger logger = LoggerFactory.getLogger(OaiPmhPublicationServiceRemoteImpl.class);
72  
73    public OaiPmhPublicationServiceRemoteImpl() {
74      super(JOB_TYPE);
75    }
76  
77    @Override
78    public Job publish(
79        MediaPackage mediaPackage,
80        String repository,
81        Set<String> downloadIds,
82        Set<String> streamingIds,
83        boolean checkAvailability
84    ) throws PublicationException, MediaPackageException {
85      final String mediapackageXml = MediaPackageParser.getAsXml(mediaPackage);
86      final List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
87      params.add(new BasicNameValuePair("mediapackage", mediapackageXml));
88      params.add(new BasicNameValuePair("channel", repository));
89      params.add(new BasicNameValuePair("downloadElementIds", StringUtils.join(downloadIds, SEPARATOR)));
90      params.add(new BasicNameValuePair("streamingElementIds", StringUtils.join(streamingIds, SEPARATOR)));
91      params.add(new BasicNameValuePair("checkAvailability", Boolean.toString(checkAvailability)));
92      final HttpPost post = new HttpPost();
93      HttpResponse response = null;
94      try {
95        post.setEntity(new UrlEncodedFormEntity(params, UTF_8));
96        response = getResponse(post);
97        if (response != null) {
98          logger.info("Publishing media package {} to OAI-PMH channel {} using a remote publication service",
99                  mediaPackage, repository);
100         try {
101           return JobParser.parseJob(response.getEntity().getContent());
102         } catch (Exception e) {
103           throw new PublicationException(
104               "Unable to publish media package '" + mediaPackage + "' using a remote OAI-PMH publication service", e);
105         }
106       }
107     } catch (Exception e) {
108       throw new PublicationException(
109               "Unable to publish media package " + mediaPackage + " using a remote OAI-PMH publication service.", e);
110     } finally {
111       closeConnection(response);
112     }
113     throw new PublicationException(
114             "Unable to publish mediapackage " + mediaPackage + " using a remote OAI-PMH publication service.");
115   }
116 
117   @Override
118   public Job replace(
119       MediaPackage mediaPackage,
120       String repository,
121       Set<? extends MediaPackageElement> downloadElements,
122       Set<? extends MediaPackageElement> streamingElements,
123       Set<MediaPackageElementFlavor> retractDownloadFlavors,
124       Set<MediaPackageElementFlavor> retractStreamingFlavors,
125       Set<? extends Publication> publications,
126       boolean checkAvailability
127   ) throws PublicationException {
128     HttpResponse response = null;
129     try {
130       final String mediapackageXml = MediaPackageParser.getAsXml(mediaPackage);
131       final String downloadElementsXml = MediaPackageElementParser.getArrayAsXml(downloadElements);
132       final String streamingElementsXml = MediaPackageElementParser.getArrayAsXml(streamingElements);
133       final String retractDownloadFlavorsString = StringUtils.join(retractDownloadFlavors, SEPARATOR);
134       final String retractStreamingFlavorsString = StringUtils.join(retractStreamingFlavors, SEPARATOR);
135       final String publicationsXml = MediaPackageElementParser.getArrayAsXml(publications);
136       final List<BasicNameValuePair> params = Arrays.asList(
137               new BasicNameValuePair("mediapackage", mediapackageXml),
138               new BasicNameValuePair("channel", repository),
139               new BasicNameValuePair("downloadElements", downloadElementsXml),
140               new BasicNameValuePair("streamingElements", streamingElementsXml),
141               new BasicNameValuePair("retractDownloadFlavors", retractDownloadFlavorsString),
142               new BasicNameValuePair("retractStreamingFlavors", retractStreamingFlavorsString),
143               new BasicNameValuePair("publications", publicationsXml),
144               new BasicNameValuePair("checkAvailability", Boolean.toString(checkAvailability)));
145       final HttpPost post = new HttpPost("replace");
146       post.setEntity(new UrlEncodedFormEntity(params, UTF_8));
147       response = getResponse(post);
148       if (response != null) {
149         logger.info("Replace media package {} in OAI-PMH channel {} using a remote publication service", mediaPackage,
150             repository);
151 
152         return JobParser.parseJob(response.getEntity().getContent());
153       }
154     } catch (final Exception e) {
155       throw new PublicationException(
156               "Unable to replace media package " + mediaPackage + " using a remote OAI-PMH publication service.", e);
157     } finally {
158       closeConnection(response);
159     }
160     throw new PublicationException(
161             "Unable to replace media package " + mediaPackage + " using a remote OAI-PMH publication service.");
162   }
163 
164   @Override
165   public Publication replaceSync(
166       MediaPackage mediaPackage,
167       String repository,
168       Set<? extends MediaPackageElement> downloadElements,
169       Set<? extends MediaPackageElement> streamingElements,
170       Set<MediaPackageElementFlavor> retractDownloadFlavors,
171       Set<MediaPackageElementFlavor> retractStreamingFlavors,
172       Set<? extends Publication> publications,
173       boolean checkAvailability
174   ) throws PublicationException {
175     HttpResponse response = null;
176     try {
177       final String mediapackageXml = MediaPackageParser.getAsXml(mediaPackage);
178       final String downloadElementsXml = MediaPackageElementParser.getArrayAsXml(downloadElements);
179       final String streamingElementsXml = MediaPackageElementParser.getArrayAsXml(streamingElements);
180       final String retractDownloadFlavorsString = StringUtils.join(retractDownloadFlavors, SEPARATOR);
181       final String retractStreamingFlavorsString = StringUtils.join(retractStreamingFlavors, SEPARATOR);
182       final String publicationsXml = MediaPackageElementParser.getArrayAsXml(publications);
183       final List<BasicNameValuePair> params = Arrays.asList(
184           new BasicNameValuePair("mediapackage", mediapackageXml),
185           new BasicNameValuePair("channel", repository),
186           new BasicNameValuePair("downloadElements", downloadElementsXml),
187           new BasicNameValuePair("streamingElements", streamingElementsXml),
188           new BasicNameValuePair("retractDownloadFlavors", retractDownloadFlavorsString),
189           new BasicNameValuePair("retractStreamingFlavors", retractStreamingFlavorsString),
190           new BasicNameValuePair("publications", publicationsXml),
191           new BasicNameValuePair("checkAvailability", Boolean.toString(checkAvailability)));
192       final HttpPost post = new HttpPost("replacesync");
193       post.setEntity(new UrlEncodedFormEntity(params, UTF_8));
194       response = getResponse(post);
195       if (response != null) {
196         logger.info("Replace media package {} in OAI-PMH channel {} using a remote publication service", mediaPackage,
197             repository);
198 
199         final String xml = IOUtils.toString(response.getEntity().getContent(), Charset.forName("utf-8"));
200         return (Publication) MediaPackageElementParser.getFromXml(xml);
201       }
202     } catch (final Exception e) {
203       throw new PublicationException(
204           "Unable to replace media package " + mediaPackage + " using a remote OAI-PMH publication service.", e);
205     } finally {
206       closeConnection(response);
207     }
208     throw new PublicationException(
209         "Unable to replace media package " + mediaPackage + " using a remote OAI-PMH publication service.");
210   }
211 
212   @Override
213   public Job retract(MediaPackage mediaPackage, String repository) throws PublicationException {
214     String mediapackageXml = MediaPackageParser.getAsXml(mediaPackage);
215     List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
216     params.add(new BasicNameValuePair("mediapackage", mediapackageXml));
217     params.add(new BasicNameValuePair("channel", repository));
218     HttpPost post = new HttpPost("/retract");
219     HttpResponse response = null;
220     post.setEntity(new UrlEncodedFormEntity(params, UTF_8));
221     try {
222       response = getResponse(post);
223       Job receipt = null;
224       if (response != null) {
225         logger.info("Retracting {} from OAI-PMH channel {} using a remote publication service",
226                 mediaPackage.getIdentifier().toString(), repository);
227         try {
228           receipt = JobParser.parseJob(response.getEntity().getContent());
229           return receipt;
230         } catch (Exception e) {
231           throw new PublicationException(format(
232               "Unable to retract media package %s from OAI-PMH channel %s using a remote publication service",
233               mediaPackage.getIdentifier().toString(), repository), e);
234         }
235       }
236     } finally {
237       closeConnection(response);
238     }
239     throw new PublicationException(format(
240         "Unable to retract media package %s from OAI-PMH channel %s using a remote publication service",
241         mediaPackage.getIdentifier().toString(), repository));
242   }
243 
244   @Override
245   public Job updateMetadata(
246       MediaPackage mediaPackage,
247       String repository,
248       Set<String> flavors,
249       Set<String> tags,
250       boolean checkAvailability
251   ) throws PublicationException {
252     final String mediapackageXml = MediaPackageParser.getAsXml(mediaPackage);
253     final List<BasicNameValuePair> params = new ArrayList<>();
254     params.add(new BasicNameValuePair("mediapackage", mediapackageXml));
255     params.add(new BasicNameValuePair("channel", repository));
256     params.add(new BasicNameValuePair("flavors", StringUtils.join(flavors, SEPARATOR)));
257     params.add(new BasicNameValuePair("tags", StringUtils.join(tags, SEPARATOR)));
258     params.add(new BasicNameValuePair("checkAvailability", Boolean.toString(checkAvailability)));
259     final HttpPost post = new HttpPost("/updateMetadata");
260     HttpResponse response = null;
261     try {
262       post.setEntity(new UrlEncodedFormEntity(params, UTF_8));
263       response = getResponse(post);
264       if (response != null) {
265         logger.info("Update media package {} metadata in OAI-PMH channel {} using a remote publication service",
266             mediaPackage.getIdentifier().toString(), repository);
267         return JobParser.parseJob(response.getEntity().getContent());
268       }
269     } catch (Exception e) {
270       throw new PublicationException(format(
271           "Unable to update media package %s metadata in OAI-PMH repository %s using a remote publication service.",
272           mediaPackage.getIdentifier().toString(), repository), e);
273     } finally {
274       closeConnection(response);
275     }
276     throw new PublicationException(format(
277         "Unable to update media package %s metadata in OAI-PMH repository %s using a remote publication service.",
278         mediaPackage.getIdentifier().toString(), repository));
279   }
280 
281   @Reference
282   @Override
283   public void setTrustedHttpClient(TrustedHttpClient trustedHttpClient) {
284     super.setTrustedHttpClient(trustedHttpClient);
285   }
286   @Reference
287   @Override
288   public void setRemoteServiceManager(ServiceRegistry serviceRegistry) {
289     super.setRemoteServiceManager(serviceRegistry);
290   }
291 
292 }