1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.resteasy.client.command;
35
36 import info.magnolia.commands.MgnlCommand;
37 import info.magnolia.context.Context;
38 import info.magnolia.registry.RegistrationException;
39 import info.magnolia.rest.client.registry.RestClientRegistry;
40 import info.magnolia.resteasy.client.RestEasyClient;
41
42 import java.util.Map;
43 import java.util.concurrent.ConcurrentHashMap;
44 import java.util.concurrent.atomic.AtomicBoolean;
45
46 import javax.inject.Inject;
47 import javax.ws.rs.NotAuthorizedException;
48 import javax.ws.rs.WebApplicationException;
49 import javax.ws.rs.core.MediaType;
50
51 import com.fasterxml.jackson.databind.JsonNode;
52
53
54
55
56
57
58 public abstract class AbstractRestEasyCommand<S> extends MgnlCommand {
59
60 private final RestClientRegistry restClientRegistry;
61 private final Class<S> serviceClass;
62 private final String restClientName;
63 private final String parameterResultName;
64 private static Map<Class, AtomicBoolean> relogingStatus = new ConcurrentHashMap<>();
65 private final Class<AbstractRestEasyCommand> clazz;
66
67 @Inject
68 public AbstractRestEasyCommand(RestClientRegistry restClientRegistry, Class<S> serviceClass, String restClientName, String parameterResultName) {
69 this.restClientRegistry = restClientRegistry;
70 this.serviceClass = serviceClass;
71 this.restClientName = restClientName;
72 this.parameterResultName = parameterResultName;
73
74 this.clazz = this.getClassToSynchronize();
75 if (relogingStatus.get(clazz) == null) {
76 relogingStatus.put(clazz, new AtomicBoolean(false));
77 }
78 }
79
80 @Override
81 public boolean execute(Context ctx) throws RestEasyCommandException {
82 try {
83 Object result = this.onExecute(ctx);
84 ctx.put(parameterResultName, result);
85 } catch (NotAuthorizedException e) {
86 this.onUnauthorizedException(ctx, e);
87 } catch (WebApplicationException e) {
88 throw this.wrapException(e);
89 } catch (RegistrationException e) {
90 throw new RestEasyCommandException("Rest client not found: ", e);
91 }
92 return true;
93 }
94
95 protected abstract JsonNode onExecute(Context ctx) throws RegistrationException;
96
97
98
99
100
101
102 protected abstract boolean handleNotAuthorizedException(Context ctx, NotAuthorizedException e) throws RestEasyCommandException;
103
104 protected S getService() throws RegistrationException {
105 return ((RestEasyClient) restClientRegistry.getRestClient(restClientName)).getClientService(serviceClass);
106 }
107
108 protected RestEasyCommandException wrapException(WebApplicationException e) {
109 return new RestEasyCommandException(String.valueOf(this.getErrorCodeAndMessage(e)), e);
110 }
111
112
113
114
115 private void onUnauthorizedException(Context ctx, NotAuthorizedException e) throws RestEasyCommandException {
116
117 AtomicBoolean reloging = relogingStatus.get(clazz);
118
119 if (!reloging.get()) {
120 try {
121 synchronized (clazz) {
122 reloging.set(true);
123 if (this.handleNotAuthorizedException(ctx, e)) {
124 Object result = this.onExecute(ctx);
125 ctx.put(parameterResultName, result);
126 } else {
127 throw this.wrapException(e);
128 }
129 }
130 } catch (WebApplicationException e1) {
131 throw this.wrapException(e1);
132 } catch (RegistrationException e1) {
133 throw new RestEasyCommandException("Rest client not found: ", e);
134 } finally {
135 reloging.set(false);
136 }
137 } else {
138 while (reloging.get()) ;
139
140 try {
141 Object result = this.onExecute(ctx);
142 ctx.put(parameterResultName, result);
143 } catch (WebApplicationException e1) {
144 throw this.wrapException(e1);
145 } catch (RegistrationException e1) {
146 throw new RestEasyCommandException("Rest client not found: ", e);
147 }
148 }
149 }
150
151
152
153
154 protected Class getClassToSynchronize() {
155 Class clazz = this.getClass();
156 while (!AbstractRestEasyCommand.class.equals(clazz.getSuperclass())) {
157 clazz = clazz.getSuperclass();
158 }
159 return clazz;
160 }
161
162 private String getErrorCodeAndMessage(WebApplicationException e) {
163 String errorMessage = e.getMessage();
164 if (MediaType.APPLICATION_JSON_TYPE.isCompatible(e.getResponse().getMediaType()) && e.getResponse().hasEntity()) {
165 JsonNode node = e.getResponse().readEntity(JsonNode.class);
166 errorMessage = node.toString();
167 e.getResponse().close();
168 }
169 return errorMessage;
170 }
171 }