private boolean uriMatchesComparison(URI actual, ComparisonTerm comparison) { String actualString = actual.toString(); Value value = comparison.operand(); if (!(value instanceof UriRefValue)) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } UriRefValue uriRef = (UriRefValue) value; String uri = uriRef.value(); switch (comparison.operator()) { case EQUALS: return actualString.equals(uri); case NOT_EQUALS: return !actualString.equals(uri); default: throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } }
/* * Determine the Hudson parameter values from the OSLC parameter instances * in the AutomationRequest */ private List<ParameterValue> getParameterValues( AbstractProject<?, ?> project, ParameterInstance[] parameters) { ParametersDefinitionProperty pp = project.getProperty(ParametersDefinitionProperty.class); if (pp == null) { LOG.log(Level.FINE, "Job does not take parameters: " + project.getName()); throw HttpResponses.status( HttpServletResponse.SC_BAD_REQUEST); // This build is not parameterized. } HashMap<String, String> inputMap = new HashMap<String, String>(); for (ParameterInstance param : parameters) { inputMap.put(param.getName(), param.getValue()); } List<ParameterValue> values = new ArrayList<ParameterValue>(); for (ParameterDefinition def : pp.getParameterDefinitions()) { String inputValue = inputMap.get(def.getName()); if (inputValue == null) { ParameterValue defaultValue = def.getDefaultParameterValue(); if (defaultValue == null) { LOG.log( Level.FINE, "Missing parameter " + def.getName() + " for job " + project.getName()); throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } values.add(defaultValue); } else { if (def instanceof SimpleParameterDefinition) { SimpleParameterDefinition simple = (SimpleParameterDefinition) def; values.add(simple.createValue(inputValue)); } else { LOG.log( Level.WARNING, "Unsupported parameter type with name " + def.getName() + " for project " + project.getName()); throw HttpResponses.status(HttpServletResponse.SC_NOT_IMPLEMENTED); } } } return values; }
/* * Parse the where clause from the oslc.where and oslc.prefix parameters. */ private WhereClause parseWhere(String where, String prefixes) { final Map<String, String> prefixMap; if (prefixes == null) { prefixMap = PREFIX_MAP; } else { try { prefixMap = QueryUtils.parsePrefixes(prefixes); } catch (ParseException e) { LOG.log(Level.FINE, "Bad oslc.prefix", e); throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } } try { return QueryUtils.parseWhere(where, prefixMap); } catch (ParseException e) { LOG.log(Level.FINE, "Bad oslc.where", e); throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } }
private boolean uriMatches(URI actual, SimpleTerm term) { switch (term.type()) { case COMPARISON: return uriMatchesComparison(actual, (ComparisonTerm) term); case IN_TERM: return uriMatchesInTerm(actual, (InTerm) term); case NESTED: throw HttpResponses.status(HttpServletResponse.SC_NOT_IMPLEMENTED); default: return true; } }
private boolean uriMatchesInTerm(URI actual, InTerm in) { String actualString = actual.toString(); for (Object element : in.values()) { Value value = (Value) element; if (!(value instanceof UriRefValue)) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } UriRefValue uriRef = (UriRefValue) value; String uri = uriRef.value(); if (uri.equals(actualString)) { return true; } } return false; }
/* * Set the correct media based on the request Accept header and marshal the * response. Set any common headers for all responses. */ private void marshal(Object objects[]) throws IOException { OSLC4JMarshaller marshaller = OSLC4JContext.newInstance().createMarshaller(); MediaType type = AcceptUtil.matchMediaType(Stapler.getCurrentRequest()); if (type == null) { throw HttpResponses.status(HttpServletResponse.SC_NOT_ACCEPTABLE); } marshaller.setMediaType(type); StaplerResponse response = Stapler.getCurrentResponse(); response.setCharacterEncoding("UTF-8"); response.setHeader("OSLC-Core-Version", "2.0"); response.setHeader("Content-Type", type.toString()); response.setHeader("Vary", "Accept, Accept-Encoding"); // Use WriterOutputStream since Stapler has already called response.getWriter(). WriterOutputStream out = new WriterOutputStream(response.getWriter()); marshaller.marshal(objects, out); }
private void requireMethod(String method) { if (!method.equals(Stapler.getCurrentRequest().getMethod())) { throw HttpResponses.status(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } }
/* * Path: /auto/scheduleBuild * * POST to create automation requests to schedule builds. */ public void doScheduleBuild(StaplerRequest request, StaplerResponse response) throws Exception { requirePOST(); OSLC4JUnmarshaller unmarshaller = OSLC4JContext.newInstance().createUnmarshaller(); String contentType = request.getContentType(); if (contentType == null) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } unmarshaller.setMediaType(MediaType.valueOf(contentType)); final AutomationRequest autoRequest = unmarshaller.unmarshal(request.getInputStream(), AutomationRequest.class); if (autoRequest == null) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } Link planLink = autoRequest.getExecutesAutomationPlan(); if (planLink == null) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } URI planURI = planLink.getValue(); String jobName = getJobNameFromURI(planURI); if (jobName == null) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } Job<?, ?> job = getJob(jobName); if (job == null) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } if (!job.isBuildable()) { throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } if (!(job instanceof AbstractProject)) { LOG.log( Level.WARNING, "Cannot schedule builds for jobs that don't extend AbstractProject: " + jobName); throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST); } AbstractProject<?, ?> project = (AbstractProject<?, ?>) job; int nextBuildNumber = project.getNextBuildNumber(); Cause cause = new Cause() { @Override public String getShortDescription() { String description = autoRequest.getDescription(); return description != null ? description : "OSLC Automation Request"; } }; ParameterInstance[] parameters = autoRequest.getInputParameters(); boolean suceeded; if (parameters.length == 0) { suceeded = project.scheduleBuild(cause); } else { List<ParameterValue> values = getParameterValues(project, parameters); suceeded = project.scheduleBuild2(project.getQuietPeriod(), cause, new ParametersAction(values)) != null; } if (!suceeded) { // Build already queued. LOG.log( Level.WARNING, "Automation request rejected (409 conflict) since build is already queued: " + jobName); throw HttpResponses.status(HttpServletResponse.SC_CONFLICT); } URI requestURI = getAutoRequestURI(job, nextBuildNumber); response.setStatus(HttpServletResponse.SC_CREATED); response.setHeader("Location", requestURI.toString()); }
// TODO: Break up this method and clean up URL handling. public void doJob(StaplerRequest request, StaplerResponse response) throws IOException, URISyntaxException, ServletException { requireGET(); MediaType type = AcceptUtil.matchMediaType(request, ACCEPTABLE); if (type == null) { throw HttpResponses.status(HttpServletResponse.SC_NOT_ACCEPTABLE); } String restOfPath = request.getRestOfPath(); if (restOfPath == null) { throw HttpResponses.notFound(); } // Remove leading '/' restOfPath = restOfPath.substring(1); String segments[] = restOfPath.split("/"); // URI patterns: // <job-name> // <job-name>/preview // <job-name>/run/<run-number> // <job-name>/run/<run-number>/preview // <job-name>/run/<run-number>/request // Find the job. String jobName = segments[0]; Job<?, ?> job = getJob(jobName); if (job == null) { throw HttpResponses.notFound(); } // Is it a run? // <job-name>/run/<run-number> if (segments.length >= 3 && PATH_RUN.equals(segments[1])) { String runNumber = segments[2]; int i; try { i = Integer.valueOf(Integer.parseInt(runNumber)); } catch (NumberFormatException e) { throw HttpResponses.notFound(); } Run<?, ?> run = job.getBuildByNumber(i); if (run == null) { throw HttpResponses.notFound(); } if (segments.length == 4) { // Is it a run preview? // <job-name>/run/<run-number>/preview if (PATH_PREVIEW.equals(segments[3])) { /* * See /hudson-oslc-auto/src/main/resources/hudson/model/Run/preview.jelly */ response.forward(run, "preview", request); return; } // Is it an AutomationRequest? // <job-name>/run/<run-number>/request if (PATH_REQUEST.equals(segments[3])) { AutomationRequest autoRequest = toAutomationRequest(request, job, run); marshal(autoRequest); } if ("buildStatus".equals(segments[3])) { throw HttpResponses.redirectViaContextPath(run.getUrl() + "/buildStatus"); } } else if (segments.length == 3) { // <job-name>/run/<run-number> if (MediaType.TEXT_HTML_TYPE.isCompatible(type)) { throw HttpResponses.redirectViaContextPath(run.getUrl()); } if (MarshallerConstants.MT_OSLC_COMPACT.isCompatible(type)) { handleCompact(job, run); } else { AutomationResult result = toAutomationResult(request, job, run); marshal(result); } } else { throw HttpResponses.notFound(); } } else { // Is it a job preview? // <job-name>/preview if (segments.length == 2 && PATH_PREVIEW.equals(segments[1])) { /* * See /hudson-oslc-auto/src/main/resources/hudson/model/Job/preview.jelly */ response.forward(job, "preview", request); return; } if (segments.length != 1) { throw HttpResponses.notFound(); } // Is it just a job name with no other segments? // <job-name> if (MediaType.TEXT_HTML_TYPE.isCompatible(type)) { throw HttpResponses.redirectViaContextPath(job.getUrl()); } if (MarshallerConstants.MT_OSLC_COMPACT.isCompatible(type)) { handleCompact(job); } else { AutomationPlan plan = toAutomationPlan(job); marshal(plan); } } }