Project

General

Profile

1 26600 sandro.lab
package eu.dnetlib.enabling.datasources;
2
3
import java.io.StringReader;
4 28070 michele.ar
import java.text.ParseException;
5
import java.util.Date;
6 26600 sandro.lab
import java.util.List;
7
import java.util.Map;
8 50043 michele.ar
import java.util.stream.Collectors;
9 43842 michele.ar
10
import org.apache.commons.io.IOUtils;
11
import org.apache.commons.logging.Log;
12
import org.apache.commons.logging.LogFactory;
13
import org.dom4j.Document;
14
import org.dom4j.io.SAXReader;
15
import org.quartz.CronExpression;
16 49890 michele.ar
import org.springframework.beans.factory.annotation.Autowired;
17 43842 michele.ar
import org.springframework.beans.factory.annotation.Required;
18
import org.springframework.core.io.ClassPathResource;
19
import org.springframework.core.io.Resource;
20 49890 michele.ar
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
21 43842 michele.ar
22 49890 michele.ar
import com.google.common.collect.ImmutableMap;
23 43842 michele.ar
24 50043 michele.ar
import eu.dnetlib.enabling.datasources.common.Api;
25
import eu.dnetlib.enabling.datasources.common.ApiParam;
26 49890 michele.ar
import eu.dnetlib.enabling.datasources.common.Datasource;
27 49662 michele.ar
import eu.dnetlib.enabling.datasources.common.DatasourceManagerException;
28 49983 michele.ar
import eu.dnetlib.enabling.datasources.common.Identity;
29
import eu.dnetlib.enabling.datasources.common.Organization;
30 28070 michele.ar
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
31
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
32 26600 sandro.lab
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
33
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
34 32789 michele.ar
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
35 26600 sandro.lab
36
public class DatasourceManagerClients {
37
38
	private static final String REPOSITORY_SERVICE_RESOURCE_TYPE = "RepositoryServiceResourceType";
39
	private static final Log log = LogFactory.getLog(DatasourceManagerClients.class);
40 49890 michele.ar
41
	private static final Resource isDefinedParamQuery = new ClassPathResource("/eu/dnetlib/enabling/datasources/queries/isDefinedParam.sql");
42
	private static final Resource dsQuery = new ClassPathResource("/eu/dnetlib/enabling/datasources/queries/getDatasource.sql");
43 50154 michele.ar
	private static final Resource dsIdentitiesQuery = new ClassPathResource("/eu/dnetlib/enabling/datasources/queries/dsIdentitiesQuery.sql");
44
	private static final Resource dsOrganizationsQuery = new ClassPathResource("/eu/dnetlib/enabling/datasources/queries/dsOrganizationsQuery.sql");
45 50043 michele.ar
	private static final Resource listApisByDsId = new ClassPathResource("/eu/dnetlib/enabling/datasources/queries/listApisByDsId.sql");
46 49890 michele.ar
47
	private NamedParameterJdbcTemplate jdbcTemplate;
48
49
	public enum AfterSqlUpdate {
50
		DELETE_DS_PROFILE, UPDATE_DS_PROFILE, NONE
51
	}
52
53
	@Autowired
54 41364 claudio.at
	private UniqueServiceLocator serviceLocator;
55 26600 sandro.lab
56 49662 michele.ar
	public String findDatasourceId(final String profileId) throws DatasourceManagerException {
57 26600 sandro.lab
		try {
58 32789 michele.ar
			return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(
59 26600 sandro.lab
					"/*[.//RESOURCE_IDENTIFIER/@value='" + profileId + "']//EXTRA_FIELDS/FIELD[./key='OpenAireDataSourceId']/value/text()");
60 43842 michele.ar
		} catch (final Exception e) {
61 32789 michele.ar
			log.error("Error finding dsId of profile " + profileId, e);
62 49662 michele.ar
			throw new DatasourceManagerException(-1, "Error finding dsId of profile " + profileId, e);
63 26600 sandro.lab
		}
64
	}
65
66 49662 michele.ar
	public String getDatasourceProfile(final String dsId) throws DatasourceManagerException {
67 26600 sandro.lab
		try {
68 32789 michele.ar
			return serviceLocator.getService(ISLookUpService.class)
69 33829 michele.ar
					.getResourceProfileByQuery(
70
							"collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')/*[.//EXTRA_FIELDS/FIELD[./key='OpenAireDataSourceId']/value/text() = '"
71
									+ dsId + "']");
72 43842 michele.ar
		} catch (final Exception e) {
73 26600 sandro.lab
			return null;
74
		}
75
	}
76
77 49662 michele.ar
	public boolean deleteProfile(final String dsId) throws DatasourceManagerException {
78 26600 sandro.lab
		try {
79
			final SAXReader reader = new SAXReader();
80
81
			final String profile = getDatasourceProfile(dsId);
82
83
			if (profile != null) {
84
				final Document docOld = reader.read(new StringReader(profile));
85
				final String profId = docOld.valueOf("//RESOURCE_IDENTIFIER/@value");
86 32789 michele.ar
				serviceLocator.getService(ISRegistryService.class).deleteProfile(profId);
87 26600 sandro.lab
			}
88
			return true;
89 43842 michele.ar
		} catch (final Exception e) {
90 32789 michele.ar
			log.error("Error deleting profile", e);
91 49662 michele.ar
			throw new DatasourceManagerException(-1, "Error deleting profile", e);
92 26600 sandro.lab
		}
93
	}
94
95 49662 michele.ar
	public boolean regenerateProfile(final String dsId) throws DatasourceManagerException {
96 26600 sandro.lab
97 49983 michele.ar
		final Datasource<Organization<?>, Identity> ds = getDatasourceById(dsId);
98 50043 michele.ar
		final List<Api<ApiParam>> apis = getApis(dsId);
99 49890 michele.ar
100 26600 sandro.lab
		try {
101
102 32789 michele.ar
			final ISRegistryService registry = serviceLocator.getService(ISRegistryService.class);
103
104 49890 michele.ar
			final String oldProfile = getDatasourceProfile(dsId);
105 26600 sandro.lab
106 49890 michele.ar
			if (oldProfile != null) {
107
				final Document docOld = new SAXReader().read(new StringReader(oldProfile));
108 26600 sandro.lab
				final String profId = docOld.valueOf("//RESOURCE_IDENTIFIER/@value");
109 50043 michele.ar
				final String profile = DatasourceFunctions.dsToProfile(ds, apis, profId);
110 49890 michele.ar
				registry.updateProfile(profId, profile, REPOSITORY_SERVICE_RESOURCE_TYPE);
111 26600 sandro.lab
				log.info("Profile " + profId + " UPDATED for ds " + dsId);
112
			} else {
113 50043 michele.ar
				final String profile = DatasourceFunctions.dsToProfile(ds, apis, "");
114 49890 michele.ar
				final String profId = registry.registerProfile(profile);
115 33829 michele.ar
				log.info("Valid Profile " + profId + " REGISTERED for ds " + dsId);
116 26600 sandro.lab
			}
117
			return true;
118 43842 michele.ar
		} catch (final Exception e) {
119
			log.error("Error saving profile, id: " + dsId, e);
120 49662 michele.ar
			throw new DatasourceManagerException(-1, "Error regenerating profile", e);
121 26600 sandro.lab
		}
122
	}
123
124 49890 michele.ar
	public List<Map<String, Object>> searchSQL(final String sql, final Map<String, Object> sqlParams) throws DatasourceManagerException {
125 41364 claudio.at
		try {
126 49890 michele.ar
			log.debug("Executing SQL: " + sql);
127
			return jdbcTemplate.queryForList(sql, sqlParams);
128
		} catch (final Exception e) {
129
			log.error("Error executing sql", e);
130 41364 claudio.at
131 49890 michele.ar
			throw new DatasourceManagerException(-1, "Error obtaining datasources from db", e);
132 26600 sandro.lab
		}
133
	}
134
135 49890 michele.ar
	public List<Map<String, Object>> searchSQL(final Resource sqlResource, final Map<String, Object> sqlParams) throws DatasourceManagerException {
136 26600 sandro.lab
		try {
137 49890 michele.ar
			return searchSQL(IOUtils.toString(sqlResource.getInputStream()), sqlParams);
138 43842 michele.ar
		} catch (final Exception e) {
139 49890 michele.ar
			log.error("Error executing sql", e);
140
			throw new DatasourceManagerException(-1, "Error obtaining datasources from db", e);
141 26600 sandro.lab
		}
142
	}
143
144 49983 michele.ar
	public void updateSQL(final String dsId, final String sql, final AfterSqlUpdate op, final Map<String, Object> sqlparams)
145 49890 michele.ar
			throws DatasourceManagerException {
146
		log.debug("Executing query SQL: " + sql);
147 26600 sandro.lab
148 49890 michele.ar
		jdbcTemplate.update(sql, sqlparams);
149 26600 sandro.lab
150 49890 michele.ar
		switch (op) {
151
		case DELETE_DS_PROFILE:
152
			deleteProfile(dsId);
153
			break;
154
		case UPDATE_DS_PROFILE:
155
			regenerateProfile(dsId);
156
			break;
157
		default:
158
			break;
159 26600 sandro.lab
		}
160 49890 michele.ar
161 26600 sandro.lab
	}
162
163 49983 michele.ar
	public void updateSQL(final String dsId, final Resource sqlResource, final AfterSqlUpdate op, final Map<String, Object> sqlparams)
164 49662 michele.ar
			throws DatasourceManagerException {
165 26600 sandro.lab
		try {
166 49890 michele.ar
			updateSQL(dsId, IOUtils.toString(sqlResource.getInputStream()), op, sqlparams);
167 43842 michele.ar
		} catch (final Exception e) {
168 49890 michele.ar
			log.error("Error in updateSQL", e);
169
			throw new DatasourceManagerException(-1, "Error in updateSQL", e);
170 26600 sandro.lab
		}
171
	}
172
173 49983 michele.ar
	public Datasource<Organization<?>, Identity> getDatasourceById(final String id) throws DatasourceManagerException {
174
		final List<Map<String, Object>> list = searchSQL(dsQuery, ImmutableMap.of("dsId", id));
175 26600 sandro.lab
176 49890 michele.ar
		if (list.size() != 1) { throw new DatasourceManagerException("Invalid number of ds with id: " + id); }
177 26600 sandro.lab
178 50154 michele.ar
		final Datasource<Organization<?>, Identity> ds = DatasourceFunctions.mapToDatasource(list.get(0));
179
		ds.setIdentities(searchSQL(dsIdentitiesQuery, ImmutableMap.of("dsId", id))
180
				.stream()
181
				.map(DatasourceFunctions::mapToDsIdentity)
182
				.collect(Collectors.toSet()));
183
		ds.setOrganizations(searchSQL(dsOrganizationsQuery, ImmutableMap.of("dsId", id))
184
				.stream()
185
				.map(DatasourceFunctions::mapToDsOrganization)
186
				.collect(Collectors.toSet()));
187
188
		return ds;
189 26600 sandro.lab
	}
190
191 50043 michele.ar
	public List<Api<ApiParam>> getApis(final String dsId) throws DatasourceManagerException {
192
193
		return searchSQL(listApisByDsId, ImmutableMap.of("dsId", dsId))
194
				.stream()
195
				.map(DatasourceFunctions::mapToApi)
196
				.collect(Collectors.toList());
197
	}
198
199 49890 michele.ar
	public boolean isDefinedParam(final String apiId, final String param) throws DatasourceManagerException {
200
		return !searchSQL(isDefinedParamQuery, ImmutableMap.of("apiId", apiId, "param", param)).isEmpty();
201 26600 sandro.lab
	}
202 32789 michele.ar
203 49662 michele.ar
	public Date findNextScheduledExecution(final String dsId, final String ifaceId) throws DatasourceManagerException {
204 28070 michele.ar
		final String xquery = "/*[.//DATAPROVIDER/@interface='" + ifaceId + "' and .//SCHEDULING/@enabled='true']//CRON/text()";
205
		try {
206 32789 michele.ar
			final String cronExpression = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xquery);
207 28070 michele.ar
			final CronExpression cron = new CronExpression(cronExpression);
208
			return cron.getNextValidTimeAfter(new Date());
209 43842 michele.ar
		} catch (final ISLookUpDocumentNotFoundException e) {
210 28070 michele.ar
			// When the value is not found a null value must be returned
211
			return null;
212 43842 michele.ar
		} catch (final ISLookUpException e) {
213 32789 michele.ar
			log.error("Error in xquery: " + xquery, e);
214 49662 michele.ar
			throw new DatasourceManagerException(-1, "Error in xquery: " + xquery, e);
215 43842 michele.ar
		} catch (final ParseException e) {
216 32789 michele.ar
			log.error("Error parsing cron expression", e);
217 49662 michele.ar
			throw new DatasourceManagerException(-1, "Error parsing cron expression", e);
218 28070 michele.ar
		}
219
	}
220 26600 sandro.lab
221 49890 michele.ar
	public UniqueServiceLocator getServiceLocator() {
222
		return serviceLocator;
223 26600 sandro.lab
	}
224
225
	@Required
226 49890 michele.ar
	public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
227
		this.serviceLocator = serviceLocator;
228 26600 sandro.lab
	}
229
230 49890 michele.ar
	public NamedParameterJdbcTemplate getJdbcTemplate() {
231
		return jdbcTemplate;
232 26600 sandro.lab
	}
233
234
	@Required
235 49983 michele.ar
	public void setJdbcTemplate(final NamedParameterJdbcTemplate jdbcTemplate) {
236 49890 michele.ar
		this.jdbcTemplate = jdbcTemplate;
237 26600 sandro.lab
	}
238
239
}