Project

General

Profile

1
package eu.dnetlib.parthenos.catalogue;
2

    
3
import java.io.IOException;
4
import java.net.URI;
5
import java.net.URISyntaxException;
6
import java.util.ArrayList;
7
import java.util.List;
8
import java.util.concurrent.TimeUnit;
9

    
10
import com.fasterxml.jackson.databind.JavaType;
11
import com.fasterxml.jackson.databind.ObjectMapper;
12
import com.google.common.collect.Lists;
13
import eu.dnetlib.parthenos.jrr.ParthenosRegistryResource;
14
import eu.dnetlib.parthenos.publisher.ParthenosPublisherException;
15
import org.apache.commons.logging.Log;
16
import org.apache.commons.logging.LogFactory;
17
import org.apache.http.client.utils.URIBuilder;
18
import org.springframework.beans.factory.annotation.Autowired;
19
import org.springframework.beans.factory.annotation.Value;
20
import org.springframework.http.*;
21
import org.springframework.stereotype.Component;
22
import org.springframework.web.client.RestTemplate;
23

    
24
import javax.annotation.PostConstruct;
25

    
26
/**
27
 * Created by Alessia Bardi on 08/03/2018.
28
 *
29
 * @author Alessia Bardi
30
 */
31
@Component
32
public class CatalogueAPIClient {
33

    
34
	private static final Log log = LogFactory.getLog(CatalogueAPIClient.class);
35

    
36
	@Value("${gcube.catalogue.baseurl}")
37
	private String baseURL;
38
	private final String itemPath = "items/";
39
	@Value("${gcube.registry.application.token}")
40
	private String applicationToken;
41
	@Value("${gcube.uri.resolver}")
42
	private String uriResolver;
43
	private String resolverBodyTemplate = "{ \"entity_name\": \"%s\" }";
44
	private String purgeBodyTemplate = "{\"id\":\"%s\"}";
45

    
46
	private HttpHeaders headersForResolver;
47
	private HttpHeaders headersForCatalogue;
48

    
49
	@Autowired
50
	private RestTemplate restTemplate;
51

    
52

    
53
	public CatalogueAPIClient(){}
54

    
55
	@PostConstruct
56
	public void init(){
57
		headersForResolver = new HttpHeaders();
58
		headersForResolver.setContentType(MediaType.APPLICATION_JSON);
59

    
60
		headersForCatalogue = new HttpHeaders();
61
		headersForCatalogue.setContentType(MediaType.APPLICATION_JSON);
62
		headersForCatalogue.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));
63
		headersForCatalogue.set("gcube-token", getApplicationToken());
64
	}
65

    
66

    
67
	/**
68
	 * Calls the parthenos resolver to get the name to use for the catalogue
69
	 * @param resName Given a Parthenos URL like: http://parthenos.d4science.org/handle/Ariadne/AriadnePortal/rhdsq5xm3e40, the resName is Ariadne/AriadnePortal/rhdsq5xm3e40.
70
	 * @return the name as computed by the Parthenos resolver. Null if the request was not successfull.
71
	 */
72
	public String getNameForCatalogue(final String resName) throws URISyntaxException {
73
		log.debug("Calling Parthenos resolver for "+resName);
74
		String body = String.format(resolverBodyTemplate, resName);
75
		HttpEntity<String> entity = new HttpEntity<String>(body, headersForResolver);
76
		URI uri = new URIBuilder(getUriResolver()).build();
77
		log.debug("Resolver at "+getUriResolver()+" post body:\n"+body);
78
		ResponseEntity<String> res = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class);
79
		if(res.getStatusCode().is2xxSuccessful()){
80
			String resolved = res.getBody();
81
			log.debug(String.format("Parthenos resolver resolved %s with %s", resName, resolved ));
82
			return resolved;
83
		}
84
		else{
85
			log.debug(String.format("Parthenos resolver returned %s with cause %s for %s", res.getStatusCodeValue(), res.getStatusCode().getReasonPhrase(), resName));
86
			return null;
87
		}
88
	}
89

    
90
	public boolean isRegistered(final String resCatName) throws ParthenosPublisherException {
91
		log.debug(String.format("Catalogue --> Checking if item %s exists", resCatName));
92
		HttpEntity<String> entity = new HttpEntity<String>(headersForCatalogue);
93
		try {
94
			URI uri = new URIBuilder(getBaseURL()+itemPath+resCatName).build();
95
			log.info(uri);
96
			log.info(headersForCatalogue.toString());
97
			ResponseEntity<String> response
98
					= restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
99
			return response.getStatusCode().is2xxSuccessful();
100
		} catch (Throwable t) {
101
			throw new ParthenosPublisherException(t);
102
		}
103
	}
104

    
105
	@Deprecated
106
	public ParthenosRegistryResource getRegistered(final String resCatName) throws ParthenosPublisherException {
107
		log.debug(String.format("Catalogue --> Checking if item %s exists", resCatName));
108
		HttpEntity<String> entity = new HttpEntity<String>(headersForCatalogue);
109
		try {
110
			URI uri = new URIBuilder(getBaseURL()+itemPath).build();
111
			ResponseEntity<String> response
112
					= restTemplate.exchange(uri +resCatName, HttpMethod.GET, entity, String.class);
113
			if(response.getStatusCode().is2xxSuccessful()){
114
				CatalogueAPIResponse body = new CatalogueAPIResponse();
115
				body.setResponseBody(response.getBody());
116
				ParthenosRegistryResource r = body.getParthenosRegistryResource();
117
				log.debug(String.format("Resource %s is in the catalogue with uuid %s", resCatName, r.getUuid()));
118
				return r;
119
			}
120
			else{
121
				log.debug(String.format("Resource %s is not in the catalogue yet", resCatName));
122
				return null;
123
			}
124
		} catch (Throwable t) {
125
			throw new ParthenosPublisherException(t);
126
		}
127
	}
128

    
129
	public boolean doRegister(final String json, final String resCatName) throws URISyntaxException, IOException {
130
		log.debug(String.format("Catalogue --> Registering item %s : %s", resCatName, json));
131
		return doCatalogueCall(json, resCatName, HttpMethod.POST);
132
	}
133

    
134
	public boolean doUpdate(final String json, final String resCatName) throws IOException, URISyntaxException {
135
		log.debug(String.format("Catalogue --> Updating item %s : %s", resCatName, json));
136
		return doCatalogueCall(json, resCatName, HttpMethod.PUT);
137
	}
138

    
139
	protected boolean doCatalogueCall(final String json, final String resCatName, final HttpMethod method) throws URISyntaxException, IOException {
140
		HttpEntity<String> entity = new HttpEntity<String>(json, headersForCatalogue);
141
		URI uri = new URIBuilder(getBaseURL()+itemPath).build();
142
		ResponseEntity<String> res = restTemplate.exchange(uri, method, entity, String.class);
143
		if (res.getStatusCode().is2xxSuccessful()) {
144
			return true;
145
		} else {
146
			log.error(String.format("Method %s on resource %s failed with code %s, reason: %s", method.name(), resCatName, res.getStatusCodeValue(), res.getBody()));
147
			return false;
148
		}
149
	}
150

    
151
	protected boolean purgeItem(final String resCatName) throws URISyntaxException, ParthenosPublisherException {
152
		log.debug(String.format("Catalogue --> Purge Item %s", resCatName));
153
		HttpEntity<String> entity = new HttpEntity<String>(headersForCatalogue);
154
		try {
155
			URI uri = new URIBuilder(getBaseURL()+itemPath+resCatName).addParameter("purge", "true").build();
156
			ResponseEntity<String> res
157
					= restTemplate.exchange(uri, HttpMethod.DELETE, entity, String.class);
158
			if (res.getStatusCode().is2xxSuccessful()) {
159
				return true;
160
			} else {
161
				log.error(String.format("Cannot purge item %s. HTTP error code %s, reason: %s", resCatName, res.getStatusCodeValue(), res.getBody()));
162
				return false;
163
			}
164
		} catch (Throwable t) {
165
			throw new ParthenosPublisherException(t);
166
		}
167
	}
168

    
169
	protected int purgeAll(int bulkSize) throws ParthenosPublisherException {
170
		log.debug("Catalogue --> Purge All Item");
171
		int count = 0;
172
		try {
173
			List<String> items = list(bulkSize);
174
			while (items.size() > 0){
175
				for(String itemName : items) {
176
					purgeItem(itemName);
177
					count++;
178

    
179
						Thread.sleep(50);
180

    
181
				}
182
				items = list(200);
183
				Thread.sleep(TimeUnit.SECONDS.toMillis(5));
184
			}
185
			} catch (Throwable t) {
186
				throw new ParthenosPublisherException(t);
187
		}
188
		log.debug(String.format("Catalogue --> Purged all %d Items", count));
189
		return count;
190
	}
191

    
192
	protected List<String> list(int limit) throws ParthenosPublisherException {
193
		log.debug(String.format("Getting list of items"));
194
		ObjectMapper mapper = new ObjectMapper();
195
		JavaType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, String.class);
196
		HttpEntity<String> entity = new HttpEntity<String>(headersForCatalogue);
197
		try {
198
			URI uri = new URIBuilder(getBaseURL()+"list").addParameter("limit", String.valueOf(limit)).addParameter("offset", "0").build();
199
			ResponseEntity<String> response
200
					= restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
201
			if(response.getStatusCode().is2xxSuccessful()){
202
				String res = response.getBody();
203
				return mapper.readValue(res, listType);
204
			}
205
			throw new ParthenosPublisherException("Cannot get list of items to purge");
206
		} catch (Throwable t) {
207
			throw new ParthenosPublisherException(t);
208
		}
209
	}
210

    
211

    
212
	public String getBaseURL() {
213
		return baseURL;
214
	}
215

    
216
	public void setBaseURL(final String baseURL) {
217
		this.baseURL = baseURL;
218
	}
219

    
220
	public String getApplicationToken() {
221
		return applicationToken;
222
	}
223

    
224
	public void setApplicationToken(final String applicationToken) {
225
		this.applicationToken = applicationToken;
226
	}
227

    
228
	public RestTemplate getRestTemplate() {
229
		return restTemplate;
230
	}
231

    
232
	public void setRestTemplate(final RestTemplate restTemplate) {
233
		this.restTemplate = restTemplate;
234
	}
235

    
236
	public String getUriResolver() {
237
		return uriResolver;
238
	}
239

    
240
	public void setUriResolver(final String uri_resolver) {
241
		this.uriResolver = uriResolver;
242
	}
243

    
244
	public String getPurgeBodyTemplate() {
245
		return purgeBodyTemplate;
246
	}
247

    
248
	public void setPurgeBodyTemplate(final String purgeBodyTemplate) {
249
		this.purgeBodyTemplate = purgeBodyTemplate;
250
	}
251

    
252
}
(2-2/5)