예제 #1
0
 /**
  * Removes all the successful minor results. Also checks if the result is roughly consistent and
  * complete. (e.g. does not have unknown operation status, etc.)
  *
  * <p>The argument "e" is for easier use of the cleanup in the exceptions handlers. The original
  * exception is passed to the IAE that this method produces for easier debugging.
  */
 public void cleanupResult(Throwable e) {
   if (status == OperationResultStatus.UNKNOWN) {
     LOGGER.error(
         "Attempt to cleanup result of operation " + operation + " that is still UNKNOWN:\n{}",
         this.debugDump());
     throw new IllegalStateException(
         "Attempt to cleanup result of operation " + operation + " that is still UNKNOWN");
   }
   if (subresults == null) {
     return;
   }
   Iterator<OperationResult> iterator = subresults.iterator();
   while (iterator.hasNext()) {
     OperationResult subresult = iterator.next();
     if (subresult.getStatus() == OperationResultStatus.UNKNOWN) {
       String message =
           "Subresult "
               + subresult.getOperation()
               + " of operation "
               + operation
               + " is still UNKNOWN during cleanup";
       LOGGER.error("{}:\n{}", message, this.debugDump(), e);
       if (e == null) {
         throw new IllegalStateException(message);
       } else {
         throw new IllegalStateException(message + "; during handling of exception " + e, e);
       }
     }
     if (subresult.canCleanup()) {
       iterator.remove();
     }
   }
 }
예제 #2
0
  /**
   * Check whether system configuration has not changed in repository (e.g. by another node in
   * cluster). Applies new configuration if so.
   *
   * @param parentResult
   */
  public void checkSystemConfigurationChanged(OperationResult parentResult) {

    OperationResult result = parentResult.createSubresult(CHECK_SYSTEM_CONFIGURATION_CHANGED);

    PrismObject<SystemConfigurationType> systemConfiguration;
    try {
      PrismObject<SystemConfigurationType> config =
          getRepositoryService()
              .getObject(
                  SystemConfigurationType.class,
                  SystemObjectsType.SYSTEM_CONFIGURATION.value(),
                  null,
                  result);

      String versionInRepo = config.getVersion();
      String versionApplied = LoggingConfigurationManager.getCurrentlyUsedVersion();

      // we do not try to determine which one is "newer" - we simply use the one from repo
      if (!versionInRepo.equals(versionApplied)) {
        LoggingConfigurationType loggingConfig =
            ProfilingConfigurationManager.checkSystemProfilingConfiguration(config);
        LoggingConfigurationManager.configure(loggingConfig, versionInRepo, result);
      } else {
        if (LOGGER.isTraceEnabled()) {
          LOGGER.trace(
              "System configuration change check: version in repo = version currently applied = {}",
              versionApplied);
        }
      }

      if (result.isUnknown()) {
        result.computeStatus();
      }

    } catch (ObjectNotFoundException e) {
      LoggingConfigurationManager
          .resetCurrentlyUsedVersion(); // because the new config (if any) will have version number
                                        // probably starting at 1 - so to be sure to read it when it
                                        // comes [hope this never occurs :)]
      String message = "No system configuration found, skipping application of system settings";
      LOGGER.error(message + ": " + e.getMessage(), e);
      result.recordWarning(message, e);
    } catch (SchemaException e) {
      String message =
          "Schema error in system configuration, skipping application of system settings";
      LOGGER.error(message + ": " + e.getMessage(), e);
      result.recordWarning(message, e);
    } catch (RuntimeException e) {
      String message =
          "Runtime exception in system configuration processing, skipping application of system settings";
      LOGGER.error(message + ": " + e.getMessage(), e);
      result.recordWarning(message, e);
    }
  }
예제 #3
0
  public <O extends ObjectType> List<PrismObject<O>> resolveLinkRefs(
      Collection<ObjectReferenceType> refs, Class type) {

    List<PrismObject<O>> objects = new ArrayList<>();

    for (ObjectReferenceType ref : refs) {
      Class clazz = getClassForType(ref.getType());
      if (!clazz.equals(type)) {
        continue;
      }
      Task task = taskManager.createTaskInstance();
      OperationResult parentResult = task.getResult();
      try {
        PrismObject<O> obj =
            model.getObject(
                type,
                ref.getOid(),
                SelectorOptions.createCollection(GetOperationOptions.createResolveNames()),
                task,
                parentResult);
        objects.add(obj);
      } catch (ObjectNotFoundException
          | SchemaException
          | SecurityViolationException
          | CommunicationException
          | ConfigurationException e) {
        // TODO Auto-generated catch block
        LOGGER.error(
            "Could not get object with oid " + ref.getOid() + ". Reason: " + e.getMessage());
      }
    }
    return objects;
  }
예제 #4
0
 static {
   try {
     initTypeMap();
   } catch (Exception e) {
     LOGGER.error("Cannot initialize XSD type mapping: " + e.getMessage(), e);
     throw new IllegalStateException("Cannot initialize XSD type mapping: " + e.getMessage(), e);
   }
 }
예제 #5
0
  public String resolveRefName(ObjectReferenceType ref) {
    if (ref == null) {
      return null;
    }
    PrismReferenceValue refValue = ref.asReferenceValue();
    Object name = refValue.getTargetName() != null ? ref.getTargetName().getOrig() : null;
    if (!(name instanceof String)) {
      LOGGER.error("Couldn't resolve object name");
    }

    return (String) name;
  }
예제 #6
0
  public <O extends ObjectType> List<PrismObject<O>> resolveAssignments(
      Collection<AssignmentType> assignments, Class<O> type) {
    List<PrismObject<O>> resolvedAssignments = new ArrayList<>();
    if (assignments == null) {
      return resolvedAssignments;
    }
    for (AssignmentType assignment : assignments) {
      Class clazz = null;
      String oid = null;
      if (assignment.getTargetRef() != null) {
        clazz = getClassForType(assignment.getTargetRef().getType());
        oid = assignment.getTargetRef().getOid();
      } else if (assignment.getTarget() != null) {
        clazz = assignment.getTarget().getClass();
      } else if (assignment.getTenantRef() != null) {
        clazz = getClassForType(assignment.getTenantRef().getType());
        oid = assignment.getTenantRef().getOid();
      }

      if (clazz == null && assignment.getConstruction() != null) {
        continue;
      } else {
        LOGGER.debug("Could not resolve assignment for type {}. No target type defined.", type);
      }

      if (!clazz.equals(type)) {
        continue;
      }

      if (assignment.getTarget() != null) {
        resolvedAssignments.add(assignment.getTarget().asPrismObject());
        continue;
      }

      Task task = taskManager.createTaskInstance();
      try {
        PrismObject<O> obj = model.getObject(type, oid, null, task, task.getResult());
        resolvedAssignments.add(obj);
      } catch (ObjectNotFoundException
          | SchemaException
          | SecurityViolationException
          | CommunicationException
          | ConfigurationException e) {
        LOGGER.error("Could not get object with oid " + oid + ". Reason: " + e.getMessage());
      }
    }

    return resolvedAssignments;
  }
예제 #7
0
 private void traceFailure(
     ExpressionEvaluationContext context, ExpressionVariables processedVariables, Exception e) {
   LOGGER.error(
       "Error evaluating expression in {}: {}",
       new Object[] {context.getContextDescription(), e.getMessage(), e});
   if (!LOGGER.isTraceEnabled()) {
     return;
   }
   StringBuilder sb = new StringBuilder();
   sb.append("Expression failure:\n");
   appendTraceHeader(sb, context, processedVariables);
   sb.append("\nERROR: ").append(e.getClass().getSimpleName()).append(": ").append(e.getMessage());
   appendTraceFooter(sb);
   LOGGER.trace(sb.toString());
 }
예제 #8
0
  public UserType getShadowOwner(String shadowOid) {
    Task task = taskManager.createTaskInstance();
    try {
      PrismObject<UserType> owner = model.findShadowOwner(shadowOid, task, task.getResult());
      return owner.asObjectable();
    } catch (ObjectNotFoundException
        | SecurityViolationException
        | SchemaException
        | ConfigurationException e) {
      // TODO Auto-generated catch block
      LOGGER.error(
          "Could not find owner for shadow with oid " + shadowOid + ". Reason: " + e.getMessage());
    }

    return null;
  }
예제 #9
0
 public <O extends ObjectType> O resolveObject(Class type, String oid) {
   Task task = taskManager.createTaskInstance();
   OperationResult parentResult = task.getResult();
   PrismObject<O> obj;
   try {
     obj =
         model.getObject(
             type,
             oid,
             SelectorOptions.createCollection(GetOperationOptions.createResolveNames()),
             task,
             parentResult);
     return obj.asObjectable();
   } catch (ObjectNotFoundException
       | SchemaException
       | SecurityViolationException
       | CommunicationException
       | ConfigurationException e) {
     // TODO Auto-generated catch block
     LOGGER.error("Could not get object with oid " + oid + ". Reason: " + e.getMessage());
   }
   return null;
 }
예제 #10
0
 <T extends ObjectType> List<T> searchObjects(Class<T> type, ObjectQuery query) {
   List<T> ret = new ArrayList();
   Task task = taskManager.createTaskInstance();
   try {
     List<PrismObject<T>> list =
         model.searchObjects(type, query, null, task, task.getResult()).getList();
     for (PrismObject<T> po : list) {
       ret.add(po.asObjectable());
     }
   } catch (SchemaException
       | ObjectNotFoundException
       | SecurityViolationException
       | CommunicationException
       | ConfigurationException e) {
     LOGGER.error(
         "Could not search objects of type: "
             + type
             + " with query "
             + query
             + ". Reason: "
             + e.getMessage());
   }
   return ret;
 }
 private void fail(String message, OperationResult result) {
   result.recordFatalError(message);
   LOGGER.error("Repository self-test assertion failed: {}", message);
 }
예제 #12
0
  private void addOrdering(InterpretationContext context, ObjectOrdering ordering)
      throws QueryException {

    ItemPath orderByPath = ordering.getOrderBy();

    // TODO if we'd like to have order-by extension properties, we'd need to provide itemDefinition
    // for them
    ProperDataSearchResult<JpaDataNodeDefinition> result =
        context
            .getItemPathResolver()
            .findProperDataDefinition(
                context.getRootEntityDefinition(), orderByPath, null, JpaDataNodeDefinition.class);
    if (result == null) {
      LOGGER.error(
          "Unknown path '"
              + orderByPath
              + "', couldn't find definition for it, "
              + "list will not be ordered by it.");
      return;
    }
    JpaDataNodeDefinition targetDefinition = result.getLinkDefinition().getTargetDefinition();
    if (targetDefinition instanceof JpaAnyContainerDefinition) {
      throw new QueryException(
          "Sorting based on extension item or attribute is not supported yet: " + orderByPath);
    } else if (targetDefinition instanceof JpaReferenceDefinition) {
      throw new QueryException("Sorting based on reference is not supported: " + orderByPath);
    } else if (result.getLinkDefinition().isMultivalued()) {
      throw new QueryException(
          "Sorting based on multi-valued item is not supported: " + orderByPath);
    } else if (targetDefinition instanceof JpaEntityDefinition) {
      throw new QueryException("Sorting based on entity is not supported: " + orderByPath);
    } else if (!(targetDefinition instanceof JpaPropertyDefinition)) {
      throw new IllegalStateException("Unknown item definition type: " + result.getClass());
    }

    JpaEntityDefinition baseEntityDefinition = result.getEntityDefinition();
    JpaPropertyDefinition orderByDefinition = (JpaPropertyDefinition) targetDefinition;
    String hqlPropertyPath =
        context
            .getItemPathResolver()
            .resolveItemPath(
                orderByPath, null, context.getPrimaryEntityAlias(), baseEntityDefinition, true)
            .getHqlPath();
    if (RPolyString.class.equals(orderByDefinition.getJpaClass())) {
      hqlPropertyPath += ".orig";
    }

    RootHibernateQuery hibernateQuery = context.getHibernateQuery();
    if (ordering.getDirection() != null) {
      switch (ordering.getDirection()) {
        case ASCENDING:
          hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.ASCENDING);
          break;
        case DESCENDING:
          hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.DESCENDING);
          break;
      }
    } else {
      hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.ASCENDING);
    }
  }
예제 #13
0
  private List<ItemWrapper> createProperties(PageBase pageBase) {
    result = new OperationResult(CREATE_PROPERTIES);

    List<ItemWrapper> properties = new ArrayList<ItemWrapper>();

    PrismContainerDefinition definition = null;
    PrismObject parent = getObject().getObject();
    Class clazz = parent.getCompileTimeClass();
    if (ShadowType.class.isAssignableFrom(clazz)) {
      QName name = containerDefinition.getName();

      if (ShadowType.F_ATTRIBUTES.equals(name)) {
        try {
          definition = objectWrapper.getRefinedAttributeDefinition();

          if (definition == null) {
            PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF);
            PrismObject<ResourceType> resource = resourceRef.getValue().getObject();

            definition =
                pageBase
                    .getModelInteractionService()
                    .getEditObjectClassDefinition(
                        (PrismObject<ShadowType>) objectWrapper.getObject(),
                        resource,
                        AuthorizationPhaseType.REQUEST)
                    .toResourceAttributeContainerDefinition();

            if (LOGGER.isTraceEnabled()) {
              LOGGER.trace("Refined account def:\n{}", definition.debugDump());
            }
          }
        } catch (Exception ex) {
          LoggingUtils.logException(
              LOGGER, "Couldn't load definitions from refined schema for shadow", ex);
          result.recordFatalError(
              "Couldn't load definitions from refined schema for shadow, reason: "
                  + ex.getMessage(),
              ex);

          return properties;
        }
      } else {
        definition = containerDefinition;
      }
    } else if (ResourceType.class.isAssignableFrom(clazz)) {
      if (containerDefinition != null) {
        definition = containerDefinition;
      } else {
        definition = container.getDefinition();
      }
    } else {
      definition = containerDefinition;
    }

    if (definition == null) {
      LOGGER.error(
          "Couldn't get property list from null definition {}",
          new Object[] {container.getElementName()});
      return properties;
    }

    // assignments are treated in a special way -- we display names of
    // org.units and roles
    // (but only if ObjectWrapper.isShowAssignments() is true; otherwise
    // they are filtered out by ObjectWrapper)
    if (container.getCompileTimeClass() != null
        && AssignmentType.class.isAssignableFrom(container.getCompileTimeClass())) {

      for (Object o : container.getValues()) {
        PrismContainerValue<AssignmentType> pcv = (PrismContainerValue<AssignmentType>) o;

        AssignmentType assignmentType = pcv.asContainerable();

        if (assignmentType.getTargetRef() == null) {
          continue;
        }

        // hack... we want to create a definition for Name
        // PrismPropertyDefinition def = ((PrismContainerValue)
        // pcv.getContainer().getParent()).getContainer().findProperty(ObjectType.F_NAME).getDefinition();
        PrismPropertyDefinition def =
            new PrismPropertyDefinition(
                ObjectType.F_NAME, DOMUtil.XSD_STRING, pcv.getPrismContext());

        if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) {
          def.setDisplayName("Org.Unit");
          def.setDisplayOrder(100);
        } else if (RoleType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) {
          def.setDisplayName("Role");
          def.setDisplayOrder(200);
        } else {
          continue;
        }

        PrismProperty<Object> temp = def.instantiate();

        String value = formatAssignmentBrief(assignmentType);

        temp.setValue(new PrismPropertyValue<Object>(value));
        // TODO: do this.isReadOnly() - is that OK? (originally it was the default behavior for all
        // cases)
        properties.add(new PropertyWrapper(this, temp, this.isReadonly(), ValueStatus.NOT_CHANGED));
      }

    } else if (isShadowAssociation()) {
      PrismContext prismContext = objectWrapper.getObject().getPrismContext();
      Map<QName, PrismContainer<ShadowAssociationType>> assocMap = new HashMap<>();
      if (objectWrapper.getAssociations() != null) {
        for (PrismContainerValue<ShadowAssociationType> cval : objectWrapper.getAssociations()) {
          ShadowAssociationType associationType = cval.asContainerable();
          QName assocName = associationType.getName();
          PrismContainer<ShadowAssociationType> fractionalContainer = assocMap.get(assocName);
          if (fractionalContainer == null) {
            fractionalContainer =
                new PrismContainer<>(
                    ShadowType.F_ASSOCIATION, ShadowAssociationType.class, cval.getPrismContext());
            fractionalContainer.setDefinition(cval.getParent().getDefinition());
            // HACK: set the name of the association as the element name so wrapper.getName() will
            // return correct data.
            fractionalContainer.setElementName(assocName);
            assocMap.put(assocName, fractionalContainer);
          }
          try {
            fractionalContainer.add(cval.clone());
          } catch (SchemaException e) {
            // Should not happen
            throw new SystemException("Unexpected error: " + e.getMessage(), e);
          }
        }
      }

      PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF);
      PrismObject<ResourceType> resource = resourceRef.getValue().getObject();

      // HACK. The revive should not be here. Revive is no good. The next use of the resource will
      // cause parsing of resource schema. We need some centralized place to maintain live cached
      // copies
      // of resources.
      try {
        resource.revive(prismContext);
      } catch (SchemaException e) {
        throw new SystemException(e.getMessage(), e);
      }
      RefinedResourceSchema refinedSchema;
      CompositeRefinedObjectClassDefinition rOcDef;
      try {
        refinedSchema = RefinedResourceSchema.getRefinedSchema(resource);
        rOcDef = refinedSchema.determineCompositeObjectClassDefinition(parent);
      } catch (SchemaException e) {
        throw new SystemException(e.getMessage(), e);
      }
      // Make sure even empty associations have their wrappers so they can be displayed and edited
      for (RefinedAssociationDefinition assocDef : rOcDef.getAssociations()) {
        QName name = assocDef.getName();
        if (!assocMap.containsKey(name)) {
          PrismContainer<ShadowAssociationType> fractionalContainer =
              new PrismContainer<>(
                  ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext);
          fractionalContainer.setDefinition(getItemDefinition());
          // HACK: set the name of the association as the element name so wrapper.getName() will
          // return correct data.
          fractionalContainer.setElementName(name);
          assocMap.put(name, fractionalContainer);
        }
      }

      for (Entry<QName, PrismContainer<ShadowAssociationType>> assocEntry : assocMap.entrySet()) {
        // HACK HACK HACK, the container wrapper should not parse itself. This code should not be
        // here.
        AssociationWrapper assocWrapper =
            new AssociationWrapper(
                this, assocEntry.getValue(), this.isReadonly(), ValueStatus.NOT_CHANGED);
        properties.add(assocWrapper);
      }

    } else { // if not an assignment

      if ((container.getValues().size() == 1 || container.getValues().isEmpty())
          && (containerDefinition == null || containerDefinition.isSingleValue())) {

        // there's no point in showing properties for non-single-valued
        // parent containers,
        // so we continue only if the parent is single-valued

        Collection<ItemDefinition> propertyDefinitions = definition.getDefinitions();
        for (ItemDefinition itemDef : propertyDefinitions) {
          if (itemDef instanceof PrismPropertyDefinition) {

            PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef;
            if (def.isIgnored() || skipProperty(def)) {
              continue;
            }
            if (!showInheritedObjectAttributes
                && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) {
              continue;
            }

            // capability handling for activation properties
            if (isShadowActivation() && !hasCapability(def)) {
              continue;
            }

            if (isShadowAssociation()) {
              continue;
            }

            PrismProperty property = container.findProperty(def.getName());
            boolean propertyIsReadOnly;
            // decision is based on parent object status, not this
            // container's one (because container can be added also
            // to an existing object)
            if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) {

              propertyIsReadOnly = !def.canModify();
            } else {
              propertyIsReadOnly = !def.canAdd();
            }
            if (property == null) {
              properties.add(
                  new PropertyWrapper(
                      this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED));
            } else {
              properties.add(
                  new PropertyWrapper(this, property, propertyIsReadOnly, ValueStatus.NOT_CHANGED));
            }
          } else if (itemDef instanceof PrismReferenceDefinition) {
            PrismReferenceDefinition def = (PrismReferenceDefinition) itemDef;

            if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) {
              continue;
            }

            PrismReference reference = container.findReference(def.getName());
            boolean propertyIsReadOnly;
            // decision is based on parent object status, not this
            // container's one (because container can be added also
            // to an existing object)
            if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) {

              propertyIsReadOnly = !def.canModify();
            } else {
              propertyIsReadOnly = !def.canAdd();
            }
            if (reference == null) {
              properties.add(
                  new ReferenceWrapper(
                      this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED));
            } else {
              properties.add(
                  new ReferenceWrapper(
                      this, reference, propertyIsReadOnly, ValueStatus.NOT_CHANGED));
            }
          }
        }
      }
    }

    Collections.sort(properties, new ItemWrapperComparator());

    result.recomputeStatus();

    return properties;
  }