1 package com.oracle.jmx.remote.rest.http; |
1 package com.oracle.jmx.remote.rest.http; |
2 |
2 |
3 import com.oracle.jmx.remote.rest.json.JSONElement; |
3 import com.oracle.jmx.remote.rest.json.JSONElement; |
4 import com.oracle.jmx.remote.rest.json.JSONObject; |
4 import com.oracle.jmx.remote.rest.json.JSONObject; |
|
5 import com.oracle.jmx.remote.rest.json.parser.JSONParser; |
|
6 import com.oracle.jmx.remote.rest.json.parser.ParseException; |
5 import com.oracle.jmx.remote.rest.mapper.JSONMapper; |
7 import com.oracle.jmx.remote.rest.mapper.JSONMapper; |
6 import com.oracle.jmx.remote.rest.mapper.JSONMappingException; |
8 import com.oracle.jmx.remote.rest.mapper.JSONMappingException; |
7 import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory; |
9 import com.oracle.jmx.remote.rest.mapper.JSONMappingFactory; |
8 import com.sun.net.httpserver.HttpExchange; |
10 import com.sun.net.httpserver.HttpExchange; |
9 |
11 |
10 import javax.management.*; |
12 import javax.management.*; |
11 import javax.management.remote.rest.PlatformRestAdapter; |
13 import javax.management.remote.rest.PlatformRestAdapter; |
12 import java.io.IOException; |
14 import java.io.IOException; |
13 import java.io.UnsupportedEncodingException; |
15 import java.io.UnsupportedEncodingException; |
|
16 import java.net.HttpURLConnection; |
14 import java.util.*; |
17 import java.util.*; |
15 import java.util.concurrent.ConcurrentHashMap; |
18 import java.util.concurrent.ConcurrentHashMap; |
16 import java.util.concurrent.CopyOnWriteArrayList; |
19 import java.util.concurrent.CopyOnWriteArrayList; |
17 import java.util.concurrent.CopyOnWriteArraySet; |
|
18 import java.util.regex.Matcher; |
20 import java.util.regex.Matcher; |
19 import java.util.regex.Pattern; |
21 import java.util.regex.Pattern; |
20 |
22 |
21 public class MBeanCollectionResource implements RestResource, NotificationListener { |
23 public class MBeanCollectionResource implements RestResource, NotificationListener { |
22 |
24 |
23 private List<ObjectName> allowedMbeans; |
25 private List<ObjectName> allowedMbeans; |
24 private final MBeanServer mBeanServer; |
26 private final MBeanServer mBeanServer; |
25 private final Map<String, MBeanResource> mBeanResourceMap = new ConcurrentHashMap<>(); |
27 private final Map<String, MBeanResource> mBeanResourceMap = new ConcurrentHashMap<>(); |
26 private static final int pageSize = 10; |
28 private static final int pageSize = 10; |
|
29 private static final String pathPrefix = "^/?jmx/servers/[a-zA-Z0-9\\-\\.]+/mbeans"; |
27 |
30 |
28 private boolean isMBeanAllowed(ObjectName objName) { |
31 private boolean isMBeanAllowed(ObjectName objName) { |
29 try { |
32 try { |
30 MBeanInfo mInfo = mBeanServer.getMBeanInfo(objName); |
33 MBeanInfo mInfo = mBeanServer.getMBeanInfo(objName); |
31 MBeanAttributeInfo[] attrsInfo = mInfo.getAttributes(); |
34 MBeanAttributeInfo[] attrsInfo = mInfo.getAttributes(); |
90 } |
93 } |
91 |
94 |
92 @Override |
95 @Override |
93 public void handle(HttpExchange exchange) throws IOException { |
96 public void handle(HttpExchange exchange) throws IOException { |
94 String path = exchange.getRequestURI().getPath(); |
97 String path = exchange.getRequestURI().getPath(); |
95 String pathPrefix = "^/?jmx/servers/[a-zA-Z0-9\\-\\.]+/mbeans"; |
|
96 if (path.matches(pathPrefix + "/?$")) { |
98 if (path.matches(pathPrefix + "/?$")) { |
97 RestResource.super.handle(exchange); |
99 RestResource.super.handle(exchange); |
98 } else if (path.matches(pathPrefix + "/[^/]+/?.*")) { |
100 } else if (path.matches(pathPrefix + "/[^/]+/?.*")) { |
99 // Extract mbean name |
101 // Extract mbean name |
100 // Forward the request to its corresponding rest resource |
102 // Forward the request to its corresponding rest resource |
123 |
125 |
124 final String path = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath().replaceAll("\\/$", ""); |
126 final String path = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath().replaceAll("\\/$", ""); |
125 try { |
127 try { |
126 List<ObjectName> mbeans = allowedMbeans; |
128 List<ObjectName> mbeans = allowedMbeans; |
127 Map<String, String> queryMap = HttpUtil.getGetRequestQueryMap(exchange); |
129 Map<String, String> queryMap = HttpUtil.getGetRequestQueryMap(exchange); |
128 if(queryMap.containsKey("query")) { |
130 if (queryMap.containsKey("query")) { |
129 Set<ObjectName> queryMBeans = mBeanServer.queryNames(new ObjectName(queryMap.get("query")),null); |
131 Set<ObjectName> queryMBeans = mBeanServer.queryNames(new ObjectName(queryMap.get("query")), null); |
130 queryMBeans.retainAll(allowedMbeans); |
132 queryMBeans.retainAll(allowedMbeans); |
131 mbeans = new ArrayList<>(queryMBeans); |
133 mbeans = new ArrayList<>(queryMBeans); |
132 } |
134 } |
133 |
135 |
134 JSONObject _links = HttpUtil.getPaginationLinks(exchange, mbeans, pageSize); |
136 JSONObject _links = HttpUtil.getPaginationLinks(exchange, mbeans, pageSize); |
151 JSONMapper typeMapper2 = JSONMappingFactory.INSTANCE.getTypeMapper(properties); |
153 JSONMapper typeMapper2 = JSONMappingFactory.INSTANCE.getTypeMapper(properties); |
152 |
154 |
153 JSONElement linkElem = typeMapper1.toJsonValue(items); |
155 JSONElement linkElem = typeMapper1.toJsonValue(items); |
154 JSONElement propElem = typeMapper2.toJsonValue(properties); |
156 JSONElement propElem = typeMapper2.toJsonValue(properties); |
155 JSONObject jobj = new JSONObject(); |
157 JSONObject jobj = new JSONObject(); |
156 if(_links != null && !_links.isEmpty()) { |
158 if (_links != null && !_links.isEmpty()) { |
157 jobj.put("_links",_links); |
159 jobj.put("_links", _links); |
158 } |
160 } |
159 |
161 |
160 jobj.putAll((JSONObject) propElem); |
162 jobj.putAll((JSONObject) propElem); |
161 jobj.put("items", linkElem); |
163 jobj.put("items", linkElem); |
162 |
164 |
175 return null; |
177 return null; |
176 } |
178 } |
177 |
179 |
178 @Override |
180 @Override |
179 public HttpResponse doPost(HttpExchange exchange) { |
181 public HttpResponse doPost(HttpExchange exchange) { |
180 return null; |
182 String path = exchange.getRequestURI().getPath(); |
|
183 String reqBody = null; |
|
184 try { |
|
185 if (path.matches(pathPrefix + "/?$")) { // POST to current URL |
|
186 reqBody = HttpUtil.readRequestBody(exchange); |
|
187 if (reqBody == null || reqBody.isEmpty()) { // No Parameters |
|
188 return HttpResponse.BAD_REQUEST; |
|
189 } |
|
190 |
|
191 JSONParser parser = new JSONParser(reqBody); |
|
192 JSONElement jsonElement = parser.parse(); |
|
193 if (!(jsonElement instanceof JSONObject)) { |
|
194 return new HttpResponse(HttpResponse.BAD_REQUEST, |
|
195 "Invalid parameters : [" + reqBody + "]"); |
|
196 } |
|
197 |
|
198 JSONObject jsonObject = (JSONObject) jsonElement; |
|
199 JSONObject result = new JSONObject(); |
|
200 for (String mBeanName : jsonObject.keySet()) { |
|
201 MBeanResource mBeanResource = mBeanResourceMap.get(mBeanName); |
|
202 try { |
|
203 if (mBeanResource == null) { |
|
204 result.put(mBeanName, "Invalid MBean"); |
|
205 } else { |
|
206 JSONElement element = jsonObject.get(mBeanName); |
|
207 if (element instanceof JSONObject) { |
|
208 JSONElement res = mBeanResource.handleBulkRequest(exchange, (JSONObject) element); |
|
209 result.put(mBeanName, res); |
|
210 } else { |
|
211 result.put(mBeanName, "Invalid input"); |
|
212 } |
|
213 }} catch (Throwable e) { |
|
214 e.printStackTrace(); |
|
215 } |
|
216 } |
|
217 return new HttpResponse(HttpURLConnection.HTTP_OK, result.toJsonString()); |
|
218 } else { |
|
219 return HttpResponse.METHOD_NOT_ALLOWED; |
|
220 } |
|
221 } catch (ParseException e) { |
|
222 return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid JSON String for request body"); |
|
223 } catch (IOException e) { |
|
224 return HttpResponse.BAD_REQUEST; |
|
225 } |
181 } |
226 } |
182 |
227 |
183 @Override |
228 @Override |
184 public HttpResponse doDelete(HttpExchange exchange) { |
229 public HttpResponse doDelete(HttpExchange exchange) { |
185 return null; |
230 return null; |