cancel
Showing results for 
Search instead for 
Did you mean: 

Control de concurrencia con behaviors

spilby
Confirmed Champ
Confirmed Champ
Ya estoy aquí con mis preguntas raras. Smiley Happy

Me gustaría implementar en Java un behavior. Hasta ahora, una vez creado un modo y terminada la transacción, llamaba a un método que actualizaba una property en todos los nodos padre hasta la raíz (un contador concretamente). Pero debido al elevado uso, esta operación ocasionaba excepciones de concurrencia que debía tratar (guardando una lista de los nodos cuyo valor no había podido actualizar para hacerlo un tiempo más tarde).

Conociendo la existencia de behaviors, mi idea es crear uno que actualice esta property en el modo y sus padres, y que se lance en el createNode.

Mi duda es… Como gestiona Alfresco las excepciones de concurrencia en un behavior? Nunca se dan? Se dan y él se ocupa de ejecutar todo el código del behavior cuando pueda? O igualmente he de controlarlo yo si se produjera la excepción? Porque de ser este tercer caso, me plantearía dejarlo como lo tengo hecho ya que el behavior creo que no me aportaría nada, entiendo.

Merciii!
9 REPLIES 9

angelborroy
Community Manager Community Manager
Community Manager
Aplica esta técnica: https://angelborroy.wordpress.com/2015/05/21/alfresco-implementando-el-behavior-de-borrado/

Esperas a que termine la transacción actual para realizar la acción que involucra a nodos modificados en la transacción actual.
Hyland Developer Evangelist

Ah, genial Angel. La usaré entonces. Muchas gracias!

spilby
Confirmed Champ
Confirmed Champ
Una pregunta al respecto… ¿Hay alguna manera de crear behaviours para propiedades específicas? Que se dispare cuando se hace un update de una propiedad X. Lo único que encuentro son updates en las propiedades de un nodo (OnUpdatePropertiesPolicy), pero yo necesito saber cuando se ha modificado una propiedad en concreto.

O a las malas, usando el OnUpdatePropertiesPolicy si no hay otra opción, no veo forma de saber si la propiedad X ha cambiado de valor.

douglascrp
World-Class Innovator
World-Class Innovator
Hey Spilby.

I'm going to answer in English.

You can use this method in order to determine what has changed:

private Set<QName> determineChangedProps(Map<QName, Serializable> oldProps, Map<QName, Serializable> newProps) {
        Set<QName> result = new HashSet<QName>();
        for (QName qn : oldProps.keySet()) {
            if (newProps.get(qn) == null ||
                    newProps.get(qn).equals(oldProps.get(qn)) == false) {
                result.add(qn);
            }
        }
        for (QName qn : newProps.keySet()) {
            if (oldProps.get(qn) == null) {
                result.add(qn);
            }
        }

        return result;
    }


And then use it as follow:

 public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after) {
        if (nodeService.exists(nodeRef)) {
            Set<QName> changedProps = determineChangedProps(before, after);

            if (changedProps.contains(YourModel.PROP_YOUR_CUSTOM_PROPERTY_QNAME)) {
                // DO WHATEVER YOU WANT HERE
            }
        }

Gracias, Douglas. Pero busco algo más directo, que no requiera hacer un bucle, ya que el webscript se usará mucho, hay peticiones cada pocos segundos, y si he de recorrer para cada nodo sus propiedades así…  Además que al behaviour no podría enviar las propiedades antes de haber sido modificadas. Pero gracias por la idea igualmente.

¿Hay alguna otra forma? Una especie de onUpdate de una propiedad determinada.

douglascrp
World-Class Innovator
World-Class Innovator
Spilby, I think you can do that.

If you look at the PolicyComponente, there are methods for that:

/**
* Register a Property-level Policy
*
* @param <P>  the policy interface 
* @param policy  the policy interface class
* @return  A delegate for the property-level policy (typed by the policy interface)
*/
public <P extends PropertyPolicy> PropertyPolicyDelegate<P> registerPropertyPolicy(Class<P> policy);


and

/**
* Bind a Service specific behaviour to a Property-level Policy
*
* @param policy  the fully qualified policy name
* @param service  the binding service
* @param behaviour  the behaviour
* @return  the registered behaviour definition
*/
public BehaviourDefinition<ServiceBehaviourBinding> bindPropertyBehaviour(QName policy, Object service, Behaviour behaviour);

Muchas gracias, Douglas. Esos métodos se aproximan mucho más a lo que necesito. Lo que pasa que al intentar usarlos, probándolo de varias formas, me da un error al levantar Alfresco. No debo estar usándolo bien.

Lo que estoy haciendo es:


   getPolicyComponent().bindPropertyBehaviour(
             NodeServicePolicies.OnUpdatePropertiesPolicy.QNAME,
             QName.createQName("myModel1", "AAA"),
             this.onUpdateProperties);


Y por lo que veo en el log de error, está esperando una clase en lugar de "AAA", no una propiedad. ¿Puede que el onUpdateProperties no se puede emplear para propiedades concretas?

Quizás poniendo un ejemplo me pueda explicar mejor…

Tengo una property AAA dentro del tipo X. Y la misma property AAA dentro de un tipo Y. Lo que necesito es que salte un behaviour cuando se ha modificado la property AAA del tipo Y.

Al método bindPropertyBehaviour le puedo pasar QNames, y el método onUpdateProperties que hay que sobreescribir recibe un NodeRef, un Map y otro Map.

¿Es posible hacer lo que quiero? No encuentro la forma si es así… Smiley Surprised\


douglascrp
World-Class Innovator
World-Class Innovator
You can find some really good sample code in alfresco's source code:

https://github.com/Alfresco/community-edition/blob/master/projects/repository/source/test-java/org/a...

Oks, thanks Docuglas. Miraré el link con los ejemplos a ver si encuentro el problema.