View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.pi.doi.client.crossref;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.URISyntaxException;
24  import java.nio.charset.StandardCharsets;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.stream.Collectors;
28  
29  import org.apache.commons.io.IOUtils;
30  import org.apache.http.HttpEntity;
31  import org.apache.http.client.methods.CloseableHttpResponse;
32  import org.apache.http.client.methods.HttpPost;
33  import org.apache.http.client.utils.URIBuilder;
34  import org.apache.http.entity.ContentType;
35  import org.apache.http.entity.mime.MultipartEntityBuilder;
36  import org.apache.http.impl.client.CloseableHttpClient;
37  import org.apache.http.impl.client.HttpClientBuilder;
38  import org.apache.logging.log4j.LogManager;
39  import org.apache.logging.log4j.Logger;
40  import org.jdom2.Document;
41  import org.jdom2.output.Format;
42  import org.jdom2.output.XMLOutputter;
43  import org.mycore.pi.exceptions.MCRDatacenterException;
44  import org.mycore.pi.exceptions.MCRPersistentIdentifierException;
45  
46  import jakarta.validation.constraints.NotNull;
47  
48  public class MCRCrossrefClient {
49  
50      public static final Logger LOGGER = LogManager.getLogger();
51  
52      private static final String HTTP_SCHEME_PREFIX = "http://";
53  
54      private static final String HTTPS_SCHEME_PREFIX = "https://";
55  
56      private static final String NOT_NULL_MESSAGE = "%s needs to be not null!";
57  
58      private static final String DEPOSIT_PATH = "servlet/deposit";
59  
60      private static final String OPERATION_PARAM = "operation";
61  
62      private static final String USER_PARAM = "login_id";
63  
64      private static final String PASSWORD_PARAM = "login_passwd";
65  
66      private static final String OPERATION_DOMDUPLOAD = "doMDUpload";
67  
68      private static final XMLOutputter METADATA_OUTPUTTER = new XMLOutputter(Format.getPrettyFormat());
69  
70      private String host, username, password;
71  
72      public MCRCrossrefClient(@NotNull String host, @NotNull String username, @NotNull String password) {
73          if (host == null) {
74              throw new IllegalArgumentException(String.format(Locale.ROOT, NOT_NULL_MESSAGE, "Host"));
75          }
76          if (username == null) {
77              throw new IllegalArgumentException(String.format(Locale.ROOT, NOT_NULL_MESSAGE, "Username"));
78          }
79          if (password == null) {
80              throw new IllegalArgumentException(String.format(Locale.ROOT, NOT_NULL_MESSAGE, "Password"));
81          }
82  
83          this.host = host;
84          this.username = username;
85          this.password = password;
86  
87          if (host.endsWith("/")) {
88              this.host = this.host.substring(0, host.length() - 1);
89          }
90  
91          if (this.host.startsWith(HTTP_SCHEME_PREFIX)) {
92              this.host = this.host.substring(HTTP_SCHEME_PREFIX.length());
93          } else if (this.host.startsWith(HTTPS_SCHEME_PREFIX)) {
94              this.host = this.host.substring(HTTPS_SCHEME_PREFIX.length());
95          }
96      }
97  
98      private static CloseableHttpClient getHttpClient() {
99          return HttpClientBuilder.create().build();
100     }
101 
102     public void doMDUpload(Document metadata) throws MCRPersistentIdentifierException {
103         final HttpPost postRequest;
104 
105         try {
106             final URIBuilder uriBuilder;
107             uriBuilder = new URIBuilder("https://" + this.host + "/" + DEPOSIT_PATH);
108             addAuthParameters(uriBuilder);
109             uriBuilder.addParameter(OPERATION_PARAM, OPERATION_DOMDUPLOAD);
110             postRequest = new HttpPost(uriBuilder.build());
111         } catch (URISyntaxException e) {
112             throw new MCRPersistentIdentifierException(
113                 String.format(Locale.ROOT, "Can not build a valid URL with  host: %s", this.host));
114         }
115 
116         final String metadataXmlAsString = METADATA_OUTPUTTER.outputString(metadata);
117 
118         HttpEntity reqEntity = MultipartEntityBuilder.create()
119             .addBinaryBody("fname", metadataXmlAsString.getBytes(StandardCharsets.UTF_8), ContentType.APPLICATION_XML,
120                 "crossref_query.xml")
121             .build();
122         postRequest.setEntity(reqEntity);
123 
124         try (CloseableHttpClient client = getHttpClient()) {
125             try (CloseableHttpResponse response = client.execute(postRequest)) {
126                 final int statusCode = response.getStatusLine().getStatusCode();
127                 final HttpEntity entity = response.getEntity();
128                 String message = "";
129 
130                 switch (statusCode) {
131                 case 200:
132                     if (entity != null) {
133                         try (InputStream inputStream = entity.getContent()) {
134                             List<String> doc = IOUtils.readLines(inputStream, StandardCharsets.UTF_8);
135                             message = doc.stream().collect(Collectors.joining(System.lineSeparator()));
136                             LOGGER.debug(message);
137                         }
138                     }
139                     return; // everything OK!
140                 case 503:
141                     LOGGER.error("Seems like the quota of 10000 Entries is exceeded!");
142                 default:
143                     if (entity != null) {
144                         try (InputStream inputStream = entity.getContent()) {
145                             List<String> doc = IOUtils.readLines(inputStream, StandardCharsets.UTF_8);
146                             message = doc.stream().collect(Collectors.joining(System.lineSeparator()));
147                         }
148                     }
149                     throw new MCRDatacenterException(
150                         String.format(Locale.ROOT, "Error while doMDUpload: (%d)%s%s%s", statusCode,
151                             response.getStatusLine().getReasonPhrase(), System.lineSeparator(), message));
152                 }
153             }
154         } catch (IOException e) {
155             throw new MCRDatacenterException(String.format(Locale.ROOT, "Error while sending request to %s", host), e);
156         }
157     }
158 
159     private void addAuthParameters(URIBuilder uriBuilder) {
160         uriBuilder.addParameter(USER_PARAM, this.username);
161         uriBuilder.addParameter(PASSWORD_PARAM, this.password);
162     }
163 
164 }