void doPost(final HttpServletRequest req, final HttpServletResponse resp) { try { // Parse out the required API versions. final AcceptAPIVersion acceptVersion = parseAcceptAPIVersion(req); // Prepare response. prepareResponse(req, resp); // Validate request. preprocessRequest(req); rejectIfNoneMatch(req); rejectIfMatch(req); final Map<String, String[]> parameters = req.getParameterMap(); final String action = asSingleValue(PARAM_ACTION, getParameter(req, PARAM_ACTION)); if (action.equalsIgnoreCase(ACTION_ID_CREATE)) { final JsonValue content = getJsonContent(req); final CreateRequest request = Requests.newCreateRequest(getResourceName(req), content); for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (parseCommonParameter(name, values, request)) { continue; } else if (name.equalsIgnoreCase(PARAM_ACTION)) { // Ignore - already handled. } else if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } else { // Action request. final JsonValue content = getJsonActionContent(req); final ActionRequest request = Requests.newActionRequest(getResourceName(req), action).setContent(content); for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (parseCommonParameter(name, values, request)) { continue; } else if (name.equalsIgnoreCase(PARAM_ACTION)) { // Ignore - already handled. } else if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } } catch (final Exception e) { fail(req, resp, e); } }
/** * Persist the supplied {@link JsonValue} {@code value} as the new state of this singleton * relationship on {@code resourceId}. * * <p><em>This is currently the only means of creating an instance of this singleton</em> * * @param context The context of this request * @param resourceId Id of the resource relation fields in value are to be memebers of * @param value A {@link JsonValue} map of relationship fields and their values * @return The persisted instance of {@code value} */ @Override public Promise<JsonValue, ResourceException> setRelationshipValueForResource( Context context, String resourceId, JsonValue value) { if (value.isNotNull()) { try { final JsonValue id = value.get(FIELD_ID); // Update if we got an id, otherwise replace if (id != null && id.isNotNull()) { final UpdateRequest updateRequest = Requests.newUpdateRequest("", value); updateRequest.setAdditionalParameter(PARAM_FIRST_ID, resourceId); return updateInstance(context, value.get(FIELD_ID).asString(), updateRequest) .then( new Function<ResourceResponse, JsonValue, ResourceException>() { @Override public JsonValue apply(ResourceResponse resourceResponse) throws ResourceException { return resourceResponse.getContent(); } }); } else { // no id, replace current instance clear(context, resourceId); final CreateRequest createRequest = Requests.newCreateRequest("", value); createRequest.setAdditionalParameter(PARAM_FIRST_ID, resourceId); return createInstance(context, createRequest) .then( new Function<ResourceResponse, JsonValue, ResourceException>() { @Override public JsonValue apply(ResourceResponse resourceResponse) throws ResourceException { return resourceResponse.getContent(); } }); } } catch (ResourceException e) { return e.asPromise(); } } else { clear(context, resourceId); return newResultPromise(json(null)); } }
@Override public Promise<ResourceResponse, ResourceException> createInstance( Context context, CreateRequest request) { TokenGenerationServiceInvocationState invocationState; try { invocationState = TokenGenerationServiceInvocationState.fromJson(request.getContent()); } catch (Exception e) { logger.error( "Exception caught marshalling json into TokenGenerationServiceInvocationState instance: " + e); return new BadRequestException(e.getMessage(), e).asPromise(); } SSOToken subjectToken; try { subjectToken = validateAssertionSubjectSession(invocationState); } catch (ForbiddenException e) { return e.asPromise(); } STSInstanceState stsInstanceState; try { stsInstanceState = getSTSInstanceState(invocationState); } catch (ResourceException e) { return e.asPromise(); } if (TokenType.SAML2.equals(invocationState.getTokenType())) { try { final String assertion = saml2TokenGeneration.generate(subjectToken, stsInstanceState, invocationState); return newResultPromise(issuedTokenResource(assertion)); } catch (TokenCreationException e) { logger.error("Exception caught generating saml2 token: " + e, e); return e.asPromise(); } catch (Exception e) { logger.error("Exception caught generating saml2 token: " + e, e); return new InternalServerErrorException(e.toString(), e).asPromise(); } } else if (TokenType.OPENIDCONNECT.equals(invocationState.getTokenType())) { try { final String assertion = openIdConnectTokenGeneration.generate(subjectToken, stsInstanceState, invocationState); return newResultPromise(issuedTokenResource(assertion)); } catch (TokenCreationException e) { logger.error("Exception caught generating OpenIdConnect token: " + e, e); return e.asPromise(); } catch (Exception e) { logger.error("Exception caught generating OpenIdConnect token: " + e, e); return new InternalServerErrorException(e.toString(), e).asPromise(); } } else { String message = "Bad request: unexpected token type:" + invocationState.getTokenType(); logger.error(message); return new BadRequestException(message).asPromise(); } }
/** {@inheritDoc} */ @Override public void createInstance( final ServerContext context, final CreateRequest request, final ResultHandler<Resource> handler) { RealmContext realmContext = context.asContext(RealmContext.class); String realmPath = realmContext.getResolvedRealm(); Resource resource; String parentRealm; String childRealm; String realm = null; try { hasPermission(context); final JsonValue jVal = request.getContent(); // get the realm realm = jVal.get("realm").asString(); realm = checkForTopLevelRealm(realm); if (realm == null || realm.isEmpty()) { throw new BadRequestException("No realm name provided."); } else if (!realm.startsWith("/")) { realm = "/" + realm; } if (!realmPath.equalsIgnoreCase("/")) { // build realm to comply with format if not top level realm = realmPath + realm; } parentRealm = RealmUtils.getParentRealm(realm); childRealm = RealmUtils.getChildRealm(realm); OrganizationConfigManager ocm = new OrganizationConfigManager(getSSOToken(), parentRealm); Map defaultValues = createServicesMap(jVal); ocm.createSubOrganization(childRealm, defaultValues); String principalName = PrincipalRestUtils.getPrincipalNameFromServerContext(context); debug.message( "RealmResource.createInstance :: CREATE of realm " + childRealm + " in realm " + parentRealm + " performed by " + principalName); // create a resource for handler to return OrganizationConfigManager realmCreated = new OrganizationConfigManager(getSSOToken(), realm); resource = new Resource( childRealm, String.valueOf(System.currentTimeMillis()), createJsonMessage("realmCreated", realmCreated.getOrganizationName())); handler.handleResult(resource); } catch (SMSException smse) { debug.error("RealmResource.createInstance() : Cannot find " + realm, smse); try { configureErrorMessage(smse); } catch (NotFoundException nf) { debug.error("RealmResource.createInstance() : Cannot find " + realm, nf); handler.handleError(nf); } catch (ForbiddenException fe) { // User does not have authorization debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, fe); handler.handleError(fe); } catch (PermanentException pe) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, pe); // Cannot recover from this exception handler.handleError(pe); } catch (ConflictException ce) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, ce); handler.handleError(ce); } catch (BadRequestException be) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, be); handler.handleError(be); } catch (Exception e) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, e); handler.handleError(new BadRequestException(e.getMessage(), e)); } } catch (SSOException sso) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, sso); handler.handleError(new PermanentException(401, "Access Denied", null)); } catch (ForbiddenException fe) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, fe); handler.handleError(fe); } catch (BadRequestException be) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, be); handler.handleError(be); } catch (PermanentException pe) { debug.error("RealmResource.createInstance() : Cannot CREATE " + realm, pe); // Cannot recover from this exception handler.handleError(pe); } catch (Exception e) { debug.error("RealmResource.createInstance()" + realm + ":" + e); handler.handleError(new BadRequestException(e.getMessage(), e)); } }
/** * Creates a new object in the object set. * * <p>This method sets the {@code _id} property to the assigned identifier for the object, and the * {@code _rev} property to the revised object version (For optimistic concurrency) * * @param request the contents of the object to create in the object set. * @throws NotFoundException if the specified id could not be resolved. * @throws ForbiddenException if access to the object or object set is forbidden. * @throws ConflictException if an object with the same ID already exists. */ @Override public ResourceResponse create(CreateRequest request) throws ResourceException { if (request.getResourcePathObject().isEmpty()) { throw new NotFoundException( "The object identifier did not include sufficient information to determine the object type: " + request.getResourcePath()); } final String type = request.getResourcePath(); // TODO: should CREST support server side generation of ID itself? final String localId = (request.getNewResourceId() == null || "".equals(request.getNewResourceId())) ? UUID.randomUUID().toString() // Generate ID server side. : request.getNewResourceId(); // Used currently for logging String fullId = request.getResourcePathObject().child(localId).toString(); String orientClassName = typeToOrientClassName(type); JsonValue obj = request.getContent(); obj.put(DocumentUtil.TAG_ID, localId); ODatabaseDocumentTx db = getConnection(); try { // Rather than using MVCC for insert, rely on primary key uniqueness constraints to detect // duplicate create ODocument newDoc = DocumentUtil.toDocument(obj, null, db, orientClassName); logger.trace("Created doc for id: {} to save {}", fullId, newDoc); newDoc.save(); obj.put(DocumentUtil.TAG_REV, Integer.toString(newDoc.getVersion())); logger.debug("Completed create for id: {} revision: {}", fullId, newDoc.getVersion()); logger.trace("Create payload for id: {} doc: {}", fullId, newDoc); return newResourceResponse( obj.get(DocumentUtil.TAG_ID).asString(), obj.get(DocumentUtil.TAG_REV).asString(), obj); } catch (ORecordDuplicatedException ex) { // Because the OpenIDM ID is defined as unique, duplicate inserts must fail throw new PreconditionFailedException( "Create rejected as Object with same ID already exists. " + ex.getMessage(), ex); } catch (OIndexException ex) { // Because the OpenIDM ID is defined as unique, duplicate inserts must fail throw new PreconditionFailedException( "Create rejected as Object with same ID already exists. " + ex.getMessage(), ex); } catch (ODatabaseException ex) { // Because the OpenIDM ID is defined as unique, duplicate inserts must fail. // OrientDB may wrap the IndexException root cause. if (isCauseIndexException(ex, 10) || isCauseRecordDuplicatedException(ex, 10)) { throw new PreconditionFailedException( "Create rejected as Object with same ID already exists and was detected. " + ex.getMessage(), ex); } else { throw ex; } } catch (RuntimeException e) { throw e; } finally { if (db != null) { db.close(); } } }
void doPut(final HttpServletRequest req, final HttpServletResponse resp) { try { // Parse out the required API versions. final AcceptAPIVersion acceptVersion = parseAcceptAPIVersion(req); // Prepare response. prepareResponse(req, resp); // Validate request. preprocessRequest(req); if (req.getHeader(HEADER_IF_MATCH) != null && req.getHeader(HEADER_IF_NONE_MATCH) != null) { // FIXME: i18n throw new PreconditionFailedException( "Simultaneous use of If-Match and If-None-Match not " + "supported for PUT requests"); } final Map<String, String[]> parameters = req.getParameterMap(); final JsonValue content = getJsonContent(req); final String rev = getIfNoneMatch(req); if (ETAG_ANY.equals(rev)) { // This is a create with a user provided resource ID: split the // path into the parent resource name and resource ID. final String resourceName = getResourceName(req); final int i = resourceName.lastIndexOf('/'); final CreateRequest request; if (resourceName.isEmpty()) { // FIXME: i18n. throw new BadRequestException("No new resource ID in HTTP PUT request"); } else if (i < 0) { // We have a pathInfo of the form "{id}" request = Requests.newCreateRequest(EMPTY_STRING, content); request.setNewResourceId(resourceName); } else { // We have a pathInfo of the form "{container}/{id}" request = Requests.newCreateRequest(resourceName.substring(0, i), content); request.setNewResourceId(resourceName.substring(i + 1)); } for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else if (parseCommonParameter(name, values, request)) { continue; } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } else { final UpdateRequest request = Requests.newUpdateRequest(getResourceName(req), content).setRevision(getIfMatch(req)); for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else if (parseCommonParameter(name, values, request)) { continue; } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } } catch (final Exception e) { fail(req, resp, e); } }
/** * Stores the <code>Dictionary</code> under the given <code>pid</code>. * * @param pid The identifier of the dictionary. * @param properties The <code>Dictionary</code> to store. * @throws IOException If an error occurrs storing the dictionary. If this exception is thrown, it * is expected, that {@link #exists(String) exists(pid} returns <code>false</code>. */ public void store(String pid, Dictionary properties) throws IOException { logger.debug("Store call for {} {}", pid, properties); // Store config handling settings in memory if (pid.startsWith("org.apache.felix.fileinstall")) { tempStore.put(pid, properties); return; } try { if (isReady(0) && requireRepository) { String id = pidToId(pid); Map<String, Object> obj = dictToMap(properties); JsonValue content = new JsonValue(obj); String configResourceId = ConfigBootstrapHelper.getId( content.get(ConfigBootstrapHelper.CONFIG_ALIAS).asString(), content.get(ConfigBootstrapHelper.SERVICE_PID).asString(), content.get(ConfigBootstrapHelper.SERVICE_FACTORY_PID).asString()); String configString = (String) obj.get(JSONEnhancedConfig.JSON_CONFIG_PROPERTY); Map<Object, Object> configMap = deserializeConfig(configString); if (configMap != null) { configMap.put("_id", configResourceId); } obj.put(JSONEnhancedConfig.JSON_CONFIG_PROPERTY, configMap); Map<String, Object> existing = null; try { ReadRequest readRequest = Requests.newReadRequest(id); existing = repo.read(readRequest).getContent().asMap(); } catch (NotFoundException ex) { // Just detect that it doesn't exist } if (existing != null) { String rev = (String) existing.get("_rev"); existing.remove("_rev"); existing.remove("_id"); obj.remove("_rev"); // beware, this means _id and _rev should not be in config file obj.remove("_id"); // beware, this means _id and _rev should not be in config file obj.remove(RepoPersistenceManager.BUNDLE_LOCATION); obj.remove(RepoPersistenceManager.FELIX_FILEINSTALL_FILENAME); if (!existing.equals(obj)) { logger.trace("Not matching {} {}", existing, obj); boolean retry; do { retry = false; try { UpdateRequest r = Requests.newUpdateRequest(id, new JsonValue(obj)); r.setRevision(rev); repo.update(r); } catch (PreconditionFailedException ex) { logger.debug("Concurrent change during update, retrying {} {}", pid, rev); ReadRequest readRequest = Requests.newReadRequest(id); existing = repo.read(readRequest).getContent().asMap(); retry = true; } } while (retry); logger.debug("Updated existing config {} {} {}", new Object[] {pid, rev, obj}); } else { logger.debug( "Existing config same as store request, ignoring {} {} {}", new Object[] {pid, rev, obj}); } } else { logger.trace("Creating: {} {} ", id, obj); // This may create a new (empty) configuration, which felix marks with // _felix___cm__newConfiguration=true String newResourceId = id.substring(CONFIG_CONTEXT_PREFIX.length()); CreateRequest createRequest = Requests.newCreateRequest(CONFIG_CONTEXT_PREFIX, new JsonValue(obj)); createRequest.setNewResourceId(newResourceId); obj = repo.create(createRequest).getContent().asMap(); logger.debug("Stored new config in repository {} {}", pid, obj); } } else { tempStore.put(pid, properties); logger.debug("Stored in memory {} {}", pid, properties); } } catch (ResourceException ex) { throw new IOException("Failed to store configuration in repository: " + ex.getMessage(), ex); } }