1 package ejava.examples.ejbwar.inventory.client;
2
3 import java.net.URI;
4
5 import javax.ws.rs.client.Client;
6 import javax.ws.rs.client.Entity;
7 import javax.ws.rs.client.Invocation;
8 import javax.ws.rs.client.Invocation.Builder;
9 import javax.ws.rs.client.ResponseProcessingException;
10 import javax.ws.rs.client.WebTarget;
11 import javax.ws.rs.core.Form;
12 import javax.ws.rs.core.MediaType;
13 import javax.ws.rs.core.Response;
14 import javax.ws.rs.core.Response.Status.Family;
15 import javax.ws.rs.core.UriBuilder;
16
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 import ejava.examples.ejbwar.inventory.bo.Categories;
21 import ejava.examples.ejbwar.inventory.bo.Category;
22 import ejava.examples.ejbwar.inventory.bo.Product;
23 import ejava.examples.ejbwar.inventory.bo.Products;
24 import ejava.examples.ejbwar.jaxrs.JAXBUtils;
25 import ejava.examples.ejbwar.jaxrs.JSONUtils;
26
27
28
29
30
31
32
33 public class InventoryJaxRSClientImpl implements InventoryClient {
34 private static final Logger logger = LoggerFactory.getLogger(InventoryJaxRSClientImpl.class);
35 public static final String CATEGORIES_PATH = "categories";
36 public static final String CATEGORY_PATH = "categories/{categoryId}";
37 private static final String PRODUCTS_PATH = "products";
38 private static final String PRODUCT_PATH = "products/{productId}";
39 private Client client;
40
41
42
43 private URI baseUrl;
44
45
46
47
48 private MediaType mediaType = MediaType.APPLICATION_XML_TYPE;
49
50 public void setClient(Client client) {
51 this.client = client;
52 }
53
54 public void setBaseUrl(URI baseUrl) {
55 this.baseUrl = baseUrl;
56 }
57
58 public void setMediaType(String mediaType) {
59 this.mediaType = MediaType.valueOf(mediaType);
60 }
61
62 private boolean isSuccessful(Response response) {
63 return response.getStatusInfo().getFamily() == Family.SUCCESSFUL;
64 }
65
66
67
68
69
70
71 private UriBuilder getBaseUri(String...resourcePath) {
72 UriBuilder b = UriBuilder.fromUri(baseUrl).path("api");
73 if (resourcePath!=null) {
74 for (String p: resourcePath) {
75 b = b.path(p);
76 }
77 }
78 return b;
79 }
80
81 @Override
82 public Categories findCategoryByName(String name, int offset, int limit) {
83
84 URI uri = getBaseUri(CATEGORIES_PATH).build();
85
86 WebTarget target = client.target(uri)
87
88 .queryParam("name", name)
89 .queryParam("offset", offset)
90 .queryParam("limit", limit);
91 Builder request = target.request(mediaType);
92 Invocation get = request.buildGet();
93
94
95 try (Response response = get.invoke(Response.class)) {
96 logger.debug("GET {}, {} returned {}", uri, mediaType, response.getStatusInfo());
97 if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
98 return response.readEntity(Categories.class);
99 } else {
100 String payload = (response.hasEntity()) ? response.readEntity(String.class)
101 : response.getStatusInfo().toString();
102 throw new ResponseProcessingException(response, payload);
103 }
104 }
105 }
106
107 @Override
108 public Category getCategory(int id) throws ResponseProcessingException {
109
110 URI uri = getBaseUri(CATEGORY_PATH).build(id);
111
112
113 Builder request = client.target(uri)
114 .request(mediaType);
115
116
117 try (Response response = request.get()) {
118 logger.debug("GET {}, {} returned {}", uri, mediaType, response.getStatusInfo());
119 if (isSuccessful(response)) {
120 return response.readEntity(Category.class);
121 } else {
122 String payload = (response.hasEntity()) ? response.readEntity(String.class)
123 : response.getStatusInfo().toString();
124 throw new ResponseProcessingException(response, payload);
125 }
126 }
127 }
128
129 @Override
130 public boolean deleteCategory(int id) {
131
132 URI uri = getBaseUri(CATEGORY_PATH).build(id);
133
134
135 Builder request = client.target(uri)
136 .request();
137
138
139 try (Response response=request.delete()) {
140 logger.debug("DELETE {} returned {}", uri, response.getStatusInfo());
141 if (isSuccessful(response)) {
142 return true;
143 } else {
144 String payload = (response.hasEntity()) ? response.readEntity(String.class)
145 : response.getStatusInfo().toString();
146 throw new ResponseProcessingException(response, payload);
147 }
148 }
149 }
150
151
152
153
154
155 @Override
156 public Product createProduct(Product product, String categoryName) {
157
158 URI uri = getBaseUri(PRODUCTS_PATH).build();
159
160
161 Form form = new Form();
162 form.param("name", product.getName());
163 form.param("category", categoryName);
164 if (product.getQuantity()!=null) {
165 form.param("quantity", product.getQuantity().toString());
166 }
167 if (product.getPrice() != null) {
168 form.param("price", product.getPrice().toString());
169 }
170
171
172 Invocation request = client.target(uri)
173 .request(mediaType)
174 .buildPost(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
175
176
177 try (Response response=request.invoke()) {
178 logger.debug("POST {} returned {}", uri, response.getStatusInfo());
179 if (isSuccessful(response)) {
180 return response.readEntity(Product.class, Product.class.getAnnotations());
181 } else {
182 String payload = (response.hasEntity()) ? response.readEntity(String.class)
183 : response.getStatusInfo().toString();
184 throw new ResponseProcessingException(response, payload);
185 }
186 }
187 }
188
189 @Override
190 public Products findProductsByName(String name, int offset, int limit) {
191 URI uri = getBaseUri(PRODUCTS_PATH).build();
192
193
194 WebTarget target = client.target(uri)
195
196 .queryParam("name", name)
197 .queryParam("offset", offset)
198 .queryParam("limit", limit);
199 Invocation request = target
200 .request(mediaType)
201 .buildGet();
202
203
204 try (Response response=request.invoke()) {
205 logger.debug("GET {} returned {}", uri, response.getStatusInfo());
206 if (isSuccessful(response)) {
207 return response.readEntity(Products.class, Products.class.getAnnotations());
208 } else {
209 String payload = (response.hasEntity()) ? response.readEntity(String.class)
210 : response.getStatusInfo().toString();
211 throw new ResponseProcessingException(response, payload);
212 }
213 }
214 }
215
216 @Override
217 public Product getProduct(int id) {
218 URI uri = getBaseUri(PRODUCT_PATH)
219
220 .build(id);
221
222
223 Invocation request = client.target(uri)
224 .request(mediaType)
225 .buildGet();
226
227
228 try (Response response=request.invoke()) {
229 logger.debug("GET {}, {} returned {}", uri, mediaType, response.getStatusInfo());
230 if (isSuccessful(response)) {
231 return response.readEntity(Product.class);
232 } else {
233 String payload = (response.hasEntity()) ? response.readEntity(String.class)
234 : response.getStatusInfo().toString();
235 throw new ResponseProcessingException(response, payload);
236 }
237 }
238 }
239
240 @Override
241 public Product updateProduct(Product product) {
242 URI uri = getBaseUri(PRODUCT_PATH)
243
244 .build(product.getId());
245
246
247 Invocation request = client.target(uri)
248 .request(mediaType)
249 .buildPut(Entity.entity(product, mediaType, Product.class.getAnnotations()));
250
251
252 try (Response response=request.invoke()) {
253 logger.debug("PUT {}, {} returned {}", uri, mediaType, response.getStatusInfo());
254 String requestPayload = MediaType.APPLICATION_JSON_TYPE.equals(mediaType) ?
255 JSONUtils.marshal(product) :
256 JAXBUtils.marshal(product);
257 logger.debug("sent=\n{}", requestPayload);
258 if (isSuccessful(response)) {
259 String payload = response.readEntity(String.class);
260 logger.debug("rcvd=\n{}", payload);
261 return MediaType.APPLICATION_JSON_TYPE.equals(mediaType) ?
262 JSONUtils.unmarshal(payload, Product.class) :
263 JAXBUtils.unmarshal(payload, Product.class);
264
265 } else {
266 String payload = (response.hasEntity()) ? response.readEntity(String.class)
267 : response.getStatusInfo().toString();
268 throw new ResponseProcessingException(response, payload);
269 }
270 }
271 }
272
273 @Override
274 public boolean deleteProduct(int id) {
275 URI uri = getBaseUri(PRODUCT_PATH)
276
277 .build(id);
278
279
280 Invocation request = client.target(uri)
281 .request()
282 .buildDelete();
283
284
285 try (Response response=request.invoke()) {
286 logger.debug("DELETE {} returned {}", uri, response.getStatusInfo());
287 if (isSuccessful(response)) {
288 return true;
289 } else {
290 String payload = (response.hasEntity()) ? response.readEntity(String.class)
291 : response.getStatusInfo().toString();
292 throw new ResponseProcessingException(response, payload);
293 }
294 }
295 }
296 }