src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/http/MBeanResource.java
branchjmx-rest-api
changeset 55996 e8d4ccaf6877
parent 55995 a798bdd52997
child 55997 f881344569d9
equal deleted inserted replaced
55995:a798bdd52997 55996:e8d4ccaf6877
   193             t.printStackTrace();
   193             t.printStackTrace();
   194         }
   194         }
   195         return jobj2;
   195         return jobj2;
   196     }
   196     }
   197 
   197 
   198     private Map<String, Object> getAttributes(String[] attrs) throws IntrospectionException,
   198     private Map<String, Object> getAttributes(String[] attrs) throws InstanceNotFoundException,
   199             InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
   199             ReflectionException {
   200         Map<String, Object> result = new LinkedHashMap<>();
   200         Map<String, Object> result = new LinkedHashMap<>();
   201         if (attrs.length == 1) {
   201         if (attrs == null || attrs.length == 0) {
   202             result.put(attrs[0], mBeanServer.getAttribute(objectName, attrs[0]));
   202             return result;
       
   203         }
       
   204         AttributeList attrVals = mBeanServer.getAttributes(objectName, attrs);
       
   205         if (attrVals.size() != attrs.length) {
       
   206             List<String> missingAttrs = new ArrayList<>(Arrays.asList(attrs));
       
   207             for (Attribute a : attrVals.asList()) {
       
   208                 missingAttrs.remove(a.getName());
       
   209                 result.put(a.getName(), a.getValue());
       
   210             }
       
   211             for (String attr : missingAttrs) {
       
   212                 result.put(attr, "< Error: No such attribute >");
       
   213             }
   203         } else {
   214         } else {
   204             AttributeList attrVals = mBeanServer.getAttributes(objectName, attrs);
   215             attrVals.asList().forEach((a) -> result.put(a.getName(), a.getValue()));
   205             if (attrVals.size() != attrs.length) {
   216         }
   206                 List<String> missingAttrs = new ArrayList<>(Arrays.asList(attrs));
   217 
   207                 for (Attribute a : attrVals.asList()) {
       
   208                     missingAttrs.remove(a.getName());
       
   209                     result.put(a.getName(), a.getValue());
       
   210                 }
       
   211                 for (String attr : missingAttrs) {
       
   212                     result.put(attr, "< Error: No such attribute >");
       
   213                 }
       
   214             } else {
       
   215                 attrVals.asList().forEach((a) -> result.put(a.getName(), a.getValue()));
       
   216             }
       
   217         }
       
   218         return result;
   218         return result;
   219     }
   219     }
   220 
   220 
   221     private Map<String, Object> getAllAttributes() throws IntrospectionException,
   221     private Map<String, Object> getAllAttributes() throws IntrospectionException,
   222             InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
   222             InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
   251             });
   251             });
   252         }
   252         }
   253         return result;
   253         return result;
   254     }
   254     }
   255 
   255 
   256     private Map<String, Object> setAttributes(JSONObject attrMap) throws IntrospectionException,
   256     private Map<String, Object> setAttributes(JSONObject attrMap) throws JSONDataException,
   257             InstanceNotFoundException, ReflectionException, JSONDataException, ClassNotFoundException, MBeanException {
   257             IntrospectionException, InstanceNotFoundException, ReflectionException {
   258         if (attrMap == null || attrMap.isEmpty()) {
   258         if (attrMap == null || attrMap.isEmpty()) {
   259             throw new JSONDataException("Null arguments for set attribute");
   259             throw new JSONDataException("Null arguments for set attribute");
   260         }
   260         }
   261         Map<String, Object> result = new HashMap<>();
   261         Map<String, Object> result = new HashMap<>();
   262         for (String attrName : attrMap.keySet()) {
   262         for (String attrName : attrMap.keySet()) {
   289                     result.put(attrName, "success");
   289                     result.put(attrName, "success");
   290                 } catch (InvalidAttributeValueException | JSONDataException e) {
   290                 } catch (InvalidAttributeValueException | JSONDataException e) {
   291                     result.put(attrName, "<Invalid value for the attribute>");
   291                     result.put(attrName, "<Invalid value for the attribute>");
   292                 } catch (AttributeNotFoundException e) {
   292                 } catch (AttributeNotFoundException e) {
   293                     result.put(attrName, "<Attribute not found>");
   293                     result.put(attrName, "<Attribute not found>");
       
   294                 } catch (ReflectionException | InstanceNotFoundException | MBeanException e) {
       
   295                     result.put(attrName, "<ERROR: Unable to retrieve value>");
   294                 }
   296                 }
   295             }
   297             }
   296         }
   298         }
   297         return result;
   299         return result;
   298     }
   300     }
   329 
   331 
   330     private Map<String, Object> getParameters(Map<String, JSONElement> jsonValues, Map<String, MBeanParameterInfo> typeMap) {
   332     private Map<String, Object> getParameters(Map<String, JSONElement> jsonValues, Map<String, MBeanParameterInfo> typeMap) {
   331         if (jsonValues.size() != typeMap.size()) {
   333         if (jsonValues.size() != typeMap.size()) {
   332             throw new IllegalArgumentException("Invalid parameters : expected - " + typeMap.size() + " parameters, got - " + jsonValues.size());
   334             throw new IllegalArgumentException("Invalid parameters : expected - " + typeMap.size() + " parameters, got - " + jsonValues.size());
   333         }
   335         }
   334         if(!jsonValues.keySet().equals(typeMap.keySet())) {
   336         if (!jsonValues.keySet().equals(typeMap.keySet())) {
   335             throw new IllegalArgumentException("Invalid parameters - expected : " + Arrays.toString(typeMap.keySet().toArray()));
   337             throw new IllegalArgumentException("Invalid parameters - expected : " + Arrays.toString(typeMap.keySet().toArray()));
   336         }
   338         }
   337         Map<String, Object> parameters = new LinkedHashMap<>();
   339         Map<String, Object> parameters = new LinkedHashMap<>();
   338         if (typeMap.size() == 0 && jsonValues.isEmpty()) {
   340         if (typeMap.size() == 0 && jsonValues.isEmpty()) {
   339             return parameters;
   341             return parameters;
   529                 }
   531                 }
   530 
   532 
   531                 JSONObject jsonObject = (JSONObject) jsonElement;
   533                 JSONObject jsonObject = (JSONObject) jsonElement;
   532 
   534 
   533                 if (jsonObject.keySet().contains("attributes") | jsonObject.keySet().contains("operations")) {
   535                 if (jsonObject.keySet().contains("attributes") | jsonObject.keySet().contains("operations")) {
   534                     return handleBulkRequest(exchange, jsonObject);
   536                     return new HttpResponse(HttpURLConnection.HTTP_OK, handleBulkRequest(exchange, jsonObject).toJsonString());
   535                 } else {
   537                 } else {
   536                     Map<String, Object> stringObjectMap = setAttributes(jsonObject);
   538                     Map<String, Object> stringObjectMap = setAttributes(jsonObject);
   537                     JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(stringObjectMap);
   539                     JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(stringObjectMap);
   538                     if (typeMapper != null) {
   540                     if (typeMapper != null) {
   539                         return new HttpResponse(HttpURLConnection.HTTP_OK, typeMapper.toJsonValue(stringObjectMap).toJsonString());
   541                         return new HttpResponse(HttpURLConnection.HTTP_OK, typeMapper.toJsonValue(stringObjectMap).toJsonString());
   568             } else {
   570             } else {
   569                 return HttpResponse.REQUEST_NOT_FOUND;
   571                 return HttpResponse.REQUEST_NOT_FOUND;
   570             }
   572             }
   571         } catch (InstanceNotFoundException e) {
   573         } catch (InstanceNotFoundException e) {
   572             // Should never happen
   574             // Should never happen
   573         } catch (ClassNotFoundException | JSONDataException | ParseException e) {
   575         } catch (JSONDataException | ParseException e) {
   574             return new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Invalid JSON : " + reqBody, e.getMessage());
   576             return new HttpResponse(HttpURLConnection.HTTP_BAD_REQUEST, "Invalid JSON : " + reqBody, e.getMessage());
   575         } catch (IntrospectionException | JSONMappingException | MBeanException | ReflectionException | IOException e) {
   577         } catch (IntrospectionException | JSONMappingException | MBeanException | ReflectionException | IOException e) {
   576             return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
   578             return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
   577         } catch (IllegalArgumentException e) {
   579         } catch (IllegalArgumentException e) {
   578             return new HttpResponse(HttpResponse.BAD_REQUEST, e.getMessage());
   580             return new HttpResponse(HttpResponse.BAD_REQUEST, e.getMessage());
   580             return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
   582             return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
   581         }
   583         }
   582         return HttpResponse.REQUEST_NOT_FOUND;
   584         return HttpResponse.REQUEST_NOT_FOUND;
   583     }
   585     }
   584 
   586 
   585     private HttpResponse handleBulkRequest(HttpExchange exchange, JSONObject reqObject) {
   587     public JSONElement handleBulkRequest(HttpExchange exchange, JSONObject reqObject) {
   586         try {
   588 
   587             JSONObject result = new JSONObject();
   589         JSONObject result = new JSONObject();
   588 
   590 
   589             do {
   591         // Handle attributes
   590                 // Handle attributes
   592         JSONElement element = reqObject.get("attributes");
   591                 JSONElement element = reqObject.get("attributes");
   593         if (element != null && element instanceof JSONObject) {
   592                 if (element != null && !(element instanceof JSONObject))    // input validation
   594             JSONObject attrInfo = (JSONObject) element;
   593                     break;
   595             JSONObject attrNode = new JSONObject();
   594                 if (element != null && element instanceof JSONObject) {
   596             // Read attributes
   595                     JSONObject attrInfo = (JSONObject) element;
   597             JSONElement read = attrInfo.get("get");
   596                     JSONObject attrNode = new JSONObject();
   598             if (read != null && read instanceof JSONArray) {
   597                     // atleast one of get/set must be present
   599                 JSONArray jattrs = (JSONArray) read;
   598                     if (attrInfo.get("get") == null && attrInfo.get("set") == null)
   600                 JSONElement jAttrRead;
   599                         break;
   601                 Map<String, Object> attrRead = null;
   600                     // Read attributes
   602                 try {
   601                     JSONElement read = attrInfo.get("get");
   603                     String[] attributes = getStrings(jattrs);
   602                     if (read != null && !(read instanceof JSONArray))
   604                     attrRead = getAttributes(attributes);
   603                         break;
   605                     JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrRead);
   604                     if (read != null && read instanceof JSONArray) {
   606                     jAttrRead = typeMapper.toJsonValue(attrRead);
   605                         JSONArray jattrs = (JSONArray) read;
   607                 } catch (InstanceNotFoundException | ReflectionException | JSONMappingException e) {
   606                         String[] attributes = getStrings(jattrs);
   608                     jAttrRead = new JSONPrimitive("<ERROR: Unable to retrieve value>");
   607                         Map<String, Object> attrRead = getAttributes(attributes);
   609                 } catch (JSONDataException e) {
   608                         JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrRead);
   610                     jAttrRead = new JSONPrimitive("Invalid JSON : " + read.toJsonString());
   609                         JSONElement jAttrRead = typeMapper.toJsonValue(attrRead);
   611                 }
   610                         attrNode.put("get", jAttrRead);
   612 
       
   613                 attrNode.put("get", jAttrRead);
       
   614             }
       
   615 
       
   616             // Write attributes
       
   617             JSONElement write = attrInfo.get("set");
       
   618             JSONElement jAttrRead;
       
   619             if (write != null && write instanceof JSONObject) {
       
   620                 JSONObject jattrs = (JSONObject) write;
       
   621                 try {
       
   622                     Map<String, Object> attrMap = setAttributes(jattrs);
       
   623                     JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrMap);
       
   624                     jAttrRead = typeMapper.toJsonValue(attrMap);
       
   625                 } catch (JSONDataException ex) {
       
   626                     jAttrRead = new JSONPrimitive("Invalid JSON : " + write.toJsonString());
       
   627                 } catch (JSONMappingException | IntrospectionException | InstanceNotFoundException | ReflectionException e) {
       
   628                     jAttrRead = new JSONPrimitive("<ERROR: Unable to retrieve value>");
       
   629                 }
       
   630                 attrNode.put("set", jAttrRead);
       
   631             }
       
   632             result.put("attributes", attrNode);
       
   633         }
       
   634 
       
   635         // Execute operations
       
   636         element = reqObject.get("operations");
       
   637         if (element != null) {
       
   638             JSONArray operationList;
       
   639             if (element instanceof JSONPrimitive             // Single no-arg operation
       
   640                     || element instanceof JSONObject) {     // single/mulitple operations
       
   641                 operationList = new JSONArray();
       
   642                 operationList.add(element);
       
   643             } else if (element instanceof JSONArray) {  // List of no-arg/with-arg operation
       
   644                 operationList = (JSONArray) element;
       
   645             } else {
       
   646                 operationList = new JSONArray();
       
   647             }
       
   648             JSONObject opResult = new JSONObject();
       
   649             for (JSONElement elem : operationList) {
       
   650                 if (elem instanceof JSONPrimitive
       
   651                         && ((JSONPrimitive) elem).getValue() instanceof String) { // no-arg operation
       
   652                     String opName = (String) ((JSONPrimitive) elem).getValue();
       
   653                     try {
       
   654                         JSONElement obj = execOperation(opName, null);
       
   655                         opResult.put(opName, obj);
       
   656                     } catch (IllegalArgumentException e) {
       
   657                         opResult.put(opName, e.getMessage());
       
   658                     } catch (IntrospectionException | InstanceNotFoundException | MBeanException | ReflectionException e) {
       
   659                         opResult.put(opName, "<ERROR while executing operation>");
   611                     }
   660                     }
   612 
   661                 } else if (elem instanceof JSONObject) {
   613                     // Write attributes
   662                     Set<String> opNames = ((JSONObject) element).keySet();
   614                     JSONElement write = attrInfo.get("set");
   663                     for (String opName : opNames) {
   615 
   664                         try {
   616                     if (write != null && !(write instanceof JSONObject))
   665                             JSONElement obj = execOperation(opName, (JSONObject) ((JSONObject) element).get(opName));
   617                         break;
       
   618 
       
   619                     if (write != null && write instanceof JSONObject) {
       
   620                         JSONObject jattrs = (JSONObject) write;
       
   621                         Map<String, Object> attrMap = setAttributes(jattrs);
       
   622                         JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(attrMap);
       
   623                         JSONElement jAttrRead = typeMapper.toJsonValue(attrMap);
       
   624                         attrNode.put("set", jAttrRead);
       
   625                     }
       
   626                     result.put("attributes", attrNode);
       
   627                 }
       
   628 
       
   629                 // Execute operations
       
   630                 element = reqObject.get("operations");
       
   631                 if (element != null) {
       
   632                     JSONArray operationList;
       
   633                     if (element instanceof JSONPrimitive             // Single no-arg operation
       
   634                             || element instanceof JSONObject) {     // single/mulitple operations
       
   635                         operationList = new JSONArray();
       
   636                         operationList.add(element);
       
   637                     } else if (element instanceof JSONArray) {  // List of no-arg/with-arg operation
       
   638                         operationList = (JSONArray) element;
       
   639                     } else {
       
   640                         // Should never happen
       
   641                         return HttpResponse.BAD_REQUEST;
       
   642                     }
       
   643                     JSONObject opResult = new JSONObject();
       
   644                     for (JSONElement elem : operationList) {
       
   645                         if (elem instanceof JSONPrimitive
       
   646                                 && ((JSONPrimitive) elem).getValue() instanceof String) { // no-arg operation
       
   647                             String opName = (String) ((JSONPrimitive) elem).getValue();
       
   648                             JSONElement obj = execOperation(opName, null);
       
   649                             opResult.put(opName, obj);
   666                             opResult.put(opName, obj);
   650                         } else if (elem instanceof JSONObject) {
   667                         } catch (IllegalArgumentException e) {
   651                             Set<String> opNames = ((JSONObject) element).keySet();
   668                             opResult.put(opName, e.getMessage());
   652                             for (String opName : opNames) {
   669                         } catch (IntrospectionException | InstanceNotFoundException | MBeanException | ReflectionException e) {
   653                                 JSONElement obj = execOperation(opName, (JSONObject) ((JSONObject) element).get(opName));
   670                             opResult.put(opName, "<ERROR while executing operation>");
   654                                 opResult.put(opName, obj);
       
   655                             }
       
   656                         }
   671                         }
   657                     }
   672                     }
   658                     result.put("operations", opResult);
   673                 }
   659                 }
   674             }
   660                 return new HttpResponse(HttpURLConnection.HTTP_OK, result.toJsonString());
   675             result.put("operations", opResult);
   661             } while (false);
   676         }
   662             throw new JSONDataException("Invalid request body : " + reqObject.toJsonString());
   677         return result;
   663         } catch (InstanceNotFoundException e) {
       
   664             // Should never happen
       
   665         } catch (ClassNotFoundException | JSONDataException e) {
       
   666             return new HttpResponse(HttpResponse.BAD_REQUEST, "Invalid JSON : " + e.getMessage());
       
   667         } catch (IntrospectionException | JSONMappingException | MBeanException | ReflectionException e) {
       
   668             return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
       
   669         } catch (IllegalArgumentException e) {
       
   670             return new HttpResponse(HttpResponse.BAD_REQUEST, e.getMessage());
       
   671         } catch (Exception e) {
       
   672             return new HttpResponse(HttpResponse.SERVER_ERROR, HttpResponse.getErrorMessage(e));
       
   673         }
       
   674         return HttpResponse.REQUEST_NOT_FOUND;
       
   675     }
   678     }
   676 
   679 
   677     private String[] getStrings(JSONArray jsonArray) throws JSONDataException {
   680     private String[] getStrings(JSONArray jsonArray) throws JSONDataException {
   678         List<String> attributes = new ArrayList<>();
   681         List<String> attributes = new ArrayList<>();
   679         for (JSONElement element : jsonArray) {
   682         for (JSONElement element : jsonArray) {