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
/**
25
 * Created by Alessia Bardi on 08/03/2018.
26
 *
27
 * @author Alessia Bardi
28
 */
29
@Component
30
public class CatalogueAPIClient {
31

    
32
	private static final Log log = LogFactory.getLog(CatalogueAPIClient.class);
33

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

    
44
	private HttpHeaders headersForResolver;
45
	private HttpHeaders headersForCatalogue;
46

    
47
	@Autowired
48
	private RestTemplate restTemplate;
49

    
50
	public CatalogueAPIClient(){
51
		headersForResolver = new HttpHeaders();
52
		headersForResolver.setContentType(MediaType.APPLICATION_JSON);
53

    
54
		headersForCatalogue = new HttpHeaders();
55
		headersForCatalogue.setContentType(MediaType.APPLICATION_JSON);
56
		headersForCatalogue.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));
57
		headersForCatalogue.set("gcube-token", getApplicationToken());
58
	}
59

    
60

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

    
84
	protected boolean isRegistered(final String resCatName) throws ParthenosPublisherException {
85
		log.debug(String.format("Catalogue --> Checking if item %s exists", resCatName));
86
		HttpEntity<String> entity = new HttpEntity<String>(headersForCatalogue);
87
		try {
88
			URI uri = new URIBuilder(getBaseURL()+itemPath).build();
89
			ResponseEntity<String> response
90
					= restTemplate.exchange(uri + "/"+resCatName, HttpMethod.GET, entity, String.class);
91
			return response.getStatusCode().is2xxSuccessful();
92
		} catch (Throwable t) {
93
			throw new ParthenosPublisherException(t);
94
		}
95
	}
96

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

    
121
	public boolean doRegister(final String json, final String resCatName) throws URISyntaxException, IOException {
122
		log.debug(String.format("Catalogue --> Registering item %s : %s", resCatName, json));
123
		return doCatalogueCall(json, resCatName, HttpMethod.POST);
124
	}
125

    
126
	public boolean doUpdate(final String json, final String resCatName) throws IOException, URISyntaxException {
127
		log.debug(String.format("Catalogue --> Updating item %s : %s", resCatName, json));
128
		return doCatalogueCall(json, resCatName, HttpMethod.PUT);
129
	}
130

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

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

    
161
	protected int purgeAll(int bulkSize) throws ParthenosPublisherException {
162
		log.debug("Catalogue --> Purge All Item");
163
		int count = 0;
164
		try {
165
		List<String> items = list(bulkSize);
166
		while (items.size() > 0){
167
			for(String itemName : items) {
168
				purgeItem(itemName);
169
				count++;
170

    
171
					Thread.sleep(50);
172

    
173
			}
174
			items = list(200);
175
			Thread.sleep(TimeUnit.SECONDS.toMillis(5));
176
		}
177
		} catch (Throwable t) {
178
			throw new ParthenosPublisherException(t);
179

    
180
		}
181
		log.debug(String.format("Catalogue --> Purged all %d Items", count));
182
		return count;
183
	}
184

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

    
204

    
205
	public String getBaseURL() {
206
		return baseURL;
207
	}
208

    
209
	public void setBaseURL(final String baseURL) {
210
		this.baseURL = baseURL;
211
	}
212

    
213
	public String getApplicationToken() {
214
		return applicationToken;
215
	}
216

    
217
	public void setApplicationToken(final String applicationToken) {
218
		this.applicationToken = applicationToken;
219
	}
220

    
221
	public RestTemplate getRestTemplate() {
222
		return restTemplate;
223
	}
224

    
225
	public void setRestTemplate(final RestTemplate restTemplate) {
226
		this.restTemplate = restTemplate;
227
	}
228

    
229
	public String getUriResolver() {
230
		return uriResolver;
231
	}
232

    
233
	public void setUriResolver(final String uri_resolver) {
234
		this.uriResolver = uriResolver;
235
	}
236

    
237
	public String getPurgeBodyTemplate() {
238
		return purgeBodyTemplate;
239
	}
240

    
241
	public void setPurgeBodyTemplate(final String purgeBodyTemplate) {
242
		this.purgeBodyTemplate = purgeBodyTemplate;
243
	}
244

    
245
}
(2-2/5)