@Override public boolean checkAccepts(final HttpRequest message) { if (message instanceof MappingHttpRequest) { final MappingHttpRequest httpRequest = (MappingHttpRequest) message; final boolean usesServicePath = Iterables.any(servicePathPrefixes, Strings.isPrefixOf(message.getUri())); final boolean noPath = message.getUri().isEmpty() || message.getUri().equals("/") || message.getUri().startsWith("/?"); if (!usesServicePath && !(noPath && resolvesByHost(message.getHeader(HttpHeaders.Names.HOST)))) { return false; } if (httpRequest.getMethod().equals(HttpMethod.POST) && !message.getHeaderNames().contains("SOAPAction")) { Map<String, String> parameters = new HashMap<String, String>(httpRequest.getParameters()); Set<String> nonQueryParameters = Sets.newHashSet(); final String query = httpRequest.getContentAsString(); for (String p : query.split("&")) { String[] splitParam = p.split("=", 2); String lhs = splitParam[0]; String rhs = splitParam.length == 2 ? splitParam[1] : null; try { if (lhs != null) lhs = new URLCodec().decode(lhs); } catch (DecoderException e) { } try { if (rhs != null) rhs = new URLCodec().decode(rhs); } catch (DecoderException e) { } parameters.put(lhs, rhs); nonQueryParameters.add(lhs); } for (RequiredQueryParams p : requiredQueryParams) { if (!parameters.containsKey(p.toString())) { return false; } } httpRequest.getParameters().putAll(parameters); httpRequest.addNonQueryParameterKeys(nonQueryParameters); } else { for (RequiredQueryParams p : requiredQueryParams) { if (!httpRequest.getParameters().containsKey(p.toString())) { return false; } } } return true; } return false; }
private final String extractOperationName(final MappingHttpRequest httpRequest) { if (httpRequest.getParameters().containsKey(this.operationParam.toString())) { return httpRequest.getParameters().get(this.operationParam.toString()); } else { for (final T param : this.altOperationParams) { if (httpRequest.getParameters().containsKey(param.toString())) { return httpRequest.getParameters().get(this.operationParam.toString()); } } } LOG.error( "Failed to find operation parameter an " + Lists.asList(this.operationParam, this.altOperationParams.toArray()).toString() + " in HTTP request: " + httpRequest); return null; }
@Override public boolean checkAccepts(final HttpRequest message) { if (message instanceof MappingHttpRequest) { final MappingHttpRequest httpRequest = (MappingHttpRequest) message; if (httpRequest.getMethod().equals(HttpMethod.POST)) { final Map<String, String> parameters = new HashMap<String, String>(httpRequest.getParameters()); final ChannelBuffer buffer = httpRequest.getContent(); buffer.markReaderIndex(); final byte[] read = new byte[buffer.readableBytes()]; buffer.readBytes(read); final String query = new String(read); buffer.resetReaderIndex(); for (final String p : query.split("&")) { final String[] splitParam = p.split("="); String lhs = splitParam[0]; String rhs = splitParam.length == 2 ? splitParam[1] : null; try { if (lhs != null) lhs = new URLCodec().decode(lhs); } catch (final DecoderException e) { } try { if (rhs != null) rhs = new URLCodec().decode(rhs); } catch (final DecoderException e) { } parameters.put(lhs, rhs); } for (final RequiredQueryParams p : RequiredQueryParams.values()) { if (!parameters.containsKey(p.toString())) { return false; } } httpRequest.getParameters().putAll(parameters); } else { for (final RequiredQueryParams p : RequiredQueryParams.values()) { if (!httpRequest.getParameters().containsKey(p.toString())) { return false; } } } return (message.getUri().startsWith(this.servicePath) || message.getUri().startsWith(this.internalServicePath)); } return false; }
@Override public Object bind(final MappingHttpRequest httpRequest) throws BindingException { final String operationName = this.extractOperationName(httpRequest); final String operationNameType = operationName + "Type"; for (final T op : this.possibleParams) httpRequest.getParameters().remove(op.name()); final Map<String, String> params = httpRequest.getParameters(); BaseMessage eucaMsg = null; Map<String, String> fieldMap = null; Class<?> targetType = null; Binding currentBinding = null; try { if (this.getBinding().hasElementClass(operationName)) { currentBinding = this.getBinding(); targetType = currentBinding.getElementClass(operationName); } else if (this.getBinding().hasElementClass(operationNameType)) { currentBinding = this.getBinding(); targetType = currentBinding.getElementClass(operationNameType); } else if (this.getDefaultBinding().hasElementClass(operationName)) { currentBinding = this.getDefaultBinding(); targetType = currentBinding.getElementClass(operationName); } else if (this.getDefaultBinding().hasElementClass(operationNameType)) { currentBinding = this.getDefaultBinding(); targetType = currentBinding.getElementClass(operationNameType); } else if (BindingManager.getDefaultBinding().hasElementClass(operationName)) { currentBinding = BindingManager.getDefaultBinding(); targetType = currentBinding.getElementClass(operationName); } else if (BindingManager.getDefaultBinding().hasElementClass(operationNameType)) { currentBinding = BindingManager.getDefaultBinding(); targetType = currentBinding.getElementClass(operationNameType); } else { // this will necessarily fault. try { targetType = this.getBinding().getElementClass(operationName); } catch (final BindingException ex) { LOG.error(ex, ex); throw ex; } } fieldMap = this.buildFieldMap(targetType); eucaMsg = (BaseMessage) targetType.newInstance(); } catch (final BindingException e) { LOG.debug("Failed to construct message of type: " + operationName, e); LOG.error(e, e); throw e; } catch (final Exception e) { throw new BindingException("Failed to construct message of type " + operationName, e); } final List<String> failedMappings = this.populateObject((GroovyObject) eucaMsg, fieldMap, params); if (!failedMappings.isEmpty() || !params.isEmpty()) { final StringBuilder errMsg = new StringBuilder("Failed to bind the following fields:\n"); for (final String f : failedMappings) errMsg.append(f).append('\n'); for (final Map.Entry<String, String> f : params.entrySet()) errMsg.append(f.getKey()).append(" = ").append(f.getValue()).append('\n'); throw new BindingException(errMsg.toString()); } try { currentBinding.toOM(eucaMsg, this.getNamespace()); } catch (final RuntimeException e) { LOG.error( "Falling back to default (unvalidated) binding for: " + operationName + " with params=" + params); LOG.error("Failed to build a valid message: " + e.getMessage(), e); try { BindingManager.getDefaultBinding().toOM(eucaMsg, BindingManager.defaultBindingNamespace()); } catch (final RuntimeException ex) { throw new BindingException( "Default binding failed to build a valid message: " + ex.getMessage(), ex); } } return eucaMsg; }