1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.console.rest;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.Optional;
28 import java.util.stream.Collectors;
29 import javax.ws.rs.core.MediaType;
30 import javax.ws.rs.core.Response;
31 import org.apache.commons.io.IOUtils;
32 import org.apache.commons.lang3.tuple.Pair;
33 import org.apache.cxf.jaxrs.client.WebClient;
34 import org.apache.syncope.client.console.SyncopeConsoleSession;
35 import org.apache.syncope.client.lib.WebClientBuilder;
36 import org.apache.syncope.common.lib.SyncopeClientException;
37 import org.apache.syncope.common.lib.to.ConnIdBundle;
38 import org.apache.syncope.common.lib.to.ConnIdObjectClass;
39 import org.apache.syncope.common.lib.to.ConnInstanceTO;
40 import org.apache.syncope.common.lib.to.PlainSchemaTO;
41 import org.apache.syncope.common.lib.types.ConnConfProperty;
42 import org.apache.syncope.common.rest.api.RESTHeaders;
43 import org.apache.syncope.common.rest.api.service.ConnectorService;
44 import org.springframework.beans.BeanUtils;
45
46
47
48
49 public class ConnectorRestClient extends BaseRestClient {
50
51 private static final long serialVersionUID = -6870366819966266617L;
52
53 public List<ConnInstanceTO> getAllConnectors() {
54 List<ConnInstanceTO> connectors = List.of();
55 try {
56 connectors = getService(ConnectorService.class).list(SyncopeConsoleSession.get().getLocale().toString());
57 } catch (Exception e) {
58 LOG.error("While reading connectors", e);
59 }
60 return connectors;
61 }
62
63 public ConnInstanceTO create(final ConnInstanceTO connectorTO) {
64 List<ConnConfProperty> filteredConf = filterProperties(connectorTO.getConf());
65 connectorTO.getConf().clear();
66 connectorTO.getConf().addAll(filteredConf);
67
68 ConnectorService service = getService(ConnectorService.class);
69 Response response = service.create(connectorTO);
70
71 return getObject(service, response.getLocation(), ConnInstanceTO.class);
72 }
73
74 public List<String> getObjectClasses(final String connectorKey) {
75 List<String> result = new ArrayList<>();
76 try {
77 ConnectorService service = getService(ConnectorService.class);
78 ConnInstanceTO connInstance = service.read(connectorKey, SyncopeConsoleSession.get().getLocale().
79 getLanguage());
80 if (connInstance != null) {
81 result.addAll(service.buildObjectClassInfo(connInstance, true).stream().
82 map(ConnIdObjectClass::getType).collect(Collectors.toList()));
83 }
84 } catch (Exception e) {
85 LOG.error("While reading object classes for connector {}", connectorKey, e);
86 }
87 return result;
88 }
89
90 public List<String> getExtAttrNames(
91 final String adminRealm,
92 final String objectClass,
93 final String connectorKey,
94 final Collection<ConnConfProperty> conf) {
95
96 ConnInstanceTO connInstanceTO = new ConnInstanceTO();
97 connInstanceTO.setAdminRealm(adminRealm);
98 connInstanceTO.setKey(connectorKey);
99 connInstanceTO.getConf().addAll(conf);
100
101
102 Optional<ConnIdObjectClass> connIdObjectClass = buildObjectClassInfo(connInstanceTO, false).stream().
103 filter(object -> object.getType().equalsIgnoreCase(objectClass)).
104 findAny();
105
106 return connIdObjectClass.map(connIdObjectClassTO -> connIdObjectClassTO.getAttributes().stream().
107 map(PlainSchemaTO::getKey).collect(Collectors.toList())).orElseGet(List::of);
108 }
109
110
111
112
113
114
115
116 public ConnInstanceTO read(final String key) {
117 ConnInstanceTO connectorTO = null;
118
119 try {
120 connectorTO = getService(ConnectorService.class).
121 read(key, SyncopeConsoleSession.get().getLocale().toString());
122 } catch (SyncopeClientException e) {
123 LOG.error("While reading a connector", e);
124 }
125
126 return connectorTO;
127 }
128
129 public void update(final ConnInstanceTO connectorTO) {
130 List<ConnConfProperty> filteredConf = filterProperties(connectorTO.getConf());
131 connectorTO.getConf().clear();
132 connectorTO.getConf().addAll(filteredConf);
133 getService(ConnectorService.class).update(connectorTO);
134 }
135
136 public ConnInstanceTO delete(final String key) {
137 ConnInstanceTO connectorTO = getService(ConnectorService.class).
138 read(key, SyncopeConsoleSession.get().getLocale().toString());
139 getService(ConnectorService.class).delete(key);
140 return connectorTO;
141 }
142
143 public List<ConnIdBundle> getAllBundles() {
144 List<ConnIdBundle> bundles = List.of();
145
146 try {
147 bundles = getService(ConnectorService.class).getBundles(SyncopeConsoleSession.get().getLocale().toString());
148 } catch (SyncopeClientException e) {
149 LOG.error("While getting connector bundles", e);
150 }
151
152 return bundles;
153 }
154
155 protected List<ConnConfProperty> filterProperties(final Collection<ConnConfProperty> properties) {
156 List<ConnConfProperty> newProperties = new ArrayList<>();
157
158 properties.stream().map(property -> {
159 ConnConfProperty prop = new ConnConfProperty();
160 prop.setSchema(property.getSchema());
161 prop.setOverridable(property.isOverridable());
162 final List<Object> parsed = new ArrayList<>();
163 if (property.getValues() != null) {
164 property.getValues().stream().
165 filter(obj -> (obj != null && !obj.toString().isEmpty())).
166 forEachOrdered(parsed::add);
167 }
168 prop.getValues().addAll(parsed);
169 return prop;
170 }).forEachOrdered(newProperties::add);
171 return newProperties;
172 }
173
174 public boolean check(final String coreAddress, final String domain, final String jwt, final String key)
175 throws IOException {
176
177 WebClient client = WebClientBuilder.build(coreAddress).
178 path("connectors").
179 accept(MediaType.APPLICATION_JSON_TYPE).
180 type(MediaType.APPLICATION_JSON_TYPE).
181 header(RESTHeaders.DOMAIN, domain).
182 authorization("Bearer " + jwt);
183 Response response = client.path(key).get();
184 if (response.getStatus() == Response.Status.OK.getStatusCode()) {
185 response = client.back(false).path("check").
186 post(IOUtils.toString((InputStream) response.getEntity(), StandardCharsets.UTF_8));
187 return response.getStatus() == Response.Status.NO_CONTENT.getStatusCode();
188 }
189 return false;
190 }
191
192 public Pair<Boolean, String> check(final ConnInstanceTO connectorTO) {
193 ConnInstanceTO toBeChecked = new ConnInstanceTO();
194 BeanUtils.copyProperties(connectorTO, toBeChecked, new String[] { "configuration", "configurationMap" });
195 toBeChecked.getConf().addAll(filterProperties(connectorTO.getConf()));
196
197 boolean check = false;
198 String errorMessage = null;
199 try {
200 getService(ConnectorService.class).check(toBeChecked);
201 check = true;
202 } catch (Exception e) {
203 LOG.error("While checking {}", toBeChecked, e);
204 errorMessage = e.getMessage();
205 }
206
207 return Pair.of(check, errorMessage);
208 }
209
210 public List<ConnIdObjectClass> buildObjectClassInfo(
211 final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
212
213 List<ConnIdObjectClass> result = List.of();
214 try {
215 result = getService(ConnectorService.class).buildObjectClassInfo(connInstanceTO, includeSpecial);
216 } catch (Exception e) {
217 LOG.error("While getting supported object classes", e);
218 }
219
220 return result;
221 }
222
223 public void reload() {
224 getService(ConnectorService.class).reload();
225 }
226 }