How to declaratively instruct ADF Faces RC to partially refresh other components upon an event

本文介绍如何通过ADF Faces RC的属性配置,实现在事件触发时,特定组件进行异步刷新,以及如何逆向指定启动异步刷新的组件。通过使用PartialTargetManager bean,可以灵活地在任何组件的异步请求中指定刷新其他组件。

How to declaratively instruct ADF Faces RC to partially refresh other components upon an event

 

ADF Faces RC has built in support for AJAX and Partial Page Refresh. Through the autoSubmit and partialSubmit attributes, we can indicate that a value change or an action (button or link click) should trigger an asynchronous request (PPR request). Through the partialTriggers attribute, we can configure components to be refreshed in any PPR request that is initiated by the a component whose Id is listed in the partialTriggers attribute. So you can say that through the partialTriggers attribute, we register a component as PPR listener on all components listed in the attribute value.

Sometimes, developers would like to be able to do it the other way round. To specify on a component X which other components should be refreshed when X is initiating a PPR request. In this article, we will discuss a method for doing exactly that.We will use a very simple example of an outputText that displays the value of the counter property of a managed bean. The page contains a commandLink. When this link is clicked, the counter is incremented and we would like the outputText to be (partially) refreshed.

The usual approach for this: set partialSubmit to true for the link and include the commandLink component’s ID value in the partialTriggers attribute of the outputText:

In this case, we will turn that around. The instruction to refresh the outputText when the link is activated is added to the commandLink.

The mechanism used in this approach is a generic PartialTargetManager with a setPartialTarget method that accepts a string that should hold the id for the component that should be refreshed. The setPropertyListener will fire when the link is activated (type=’action’) and will pass the string value "counter" (the id of the outputText component) to this setter method.

The PartialTargetManager bean is implemented as follows:

The setPartialTarget method tries to find the component specified in the ViewRoot. When found, the component is passed to the list of partial targets in the AdfFacesContext.

The bean is configured in faces-config.xml:

The Counter bean is trivial:

When we run the page, the outputText and its label are displayed as well as the action link. Clicking the action link will lead to an increased value in the counter value – through PPR that was declaratively instructed from the perspective of the link to refresh the outputText.

Resources

Download JDeveloper 11g sources componentToComponentPPR.zip .

<think>我们正在解决一个问题:在使用 `kubectl apply -f provisioner.yaml` 更新 StorageClass 时,出现了两个错误: 1. 更新 reclaimPolicy 被禁止。 2. 缺少 `kubectl.kubernetes.io/last-applied-configuration` 注解。 根据引用内容,我们注意到: - 引用[1]提到注解(annotations)是存储在资源上的键值对,并且我们可以通过设置注解来标记默认存储类。 - 引用[2]提供了关于如何更改默认存储类的参考链接。 - 引用[3]显示了PV和PVC的状态,但与本问题关联不大。 - 引用[4]展示了应用yaml文件的示例命令。 但用户的问题是关于更新StorageClass时遇到的两个具体错误。 分析问题: 1. 更新reclaimPolicy被禁止: - 在Kubernetes中,StorageClass一旦创建,其`reclaimPolicy`字段是不可变的。这是因为StorageClass被设计为在创建后不允许更改回收策略。因此,如果我们尝试修改现有StorageClass的reclaimPolicy,就会收到禁止更新的错误。 2. 缺少`kubectl.kubernetes.io/last-applied-configuration`注解: - 这个注解是`kubectl apply`命令用来记录上次应用的配置的。如果我们在创建资源时没有使用`apply`命令(比如使用了`create`命令),那么这个注解就不会存在。当我们后续使用`apply`命令更新资源时,可能会因为缺少这个注解而报错。 解决方案: 针对第一个问题:由于reclaimPolicy不可变,我们无法直接更新。因此,我们需要先删除现有的StorageClass,然后再使用新的reclaimPolicy重新创建。 注意:删除StorageClass不会影响已经创建的PV(因为PV是独立资源),但会影响后续动态创建的PV。因此,在删除前要确保没有PVC依赖此StorageClass(或者已经做好迁移准备)。 针对第二个问题:我们可以使用以下两种方法之一: 方法1:使用`kubectl replace`代替`kubectl apply`。因为`replace`不会依赖`last-applied-configuration`注解。 方法2:如果仍然想使用`apply`命令,我们可以先通过`kubectl apply`命令的`--save-config`选项来为资源添加last-applied-configuration注解(但这通常需要在第一次创建资源时就使用,或者我们可以手动添加注解)。 但是,由于我们同时需要修改不可变的字段(reclaimPolicy),因此删除并重新创建StorageClass可能是必要的步骤。在重新创建的过程中,我们可以确保使用`apply`命令并添加`--save-config`选项,这样就会生成last-applied-configuration注解。 具体步骤: 步骤1:删除现有的StorageClass ```bash kubectl delete storageclass <storageclass-name> ``` 注意:删除前确保没有正在使用该StorageClass的PVC(动态创建的PV将不再受此StorageClass管理,但已存在的PV会继续存在,它们的回收策略已经确定,不会改变)。 步骤2:修改provisioner.yaml文件,设置正确的reclaimPolicy(例如,Retain或Delete)。 步骤3:重新创建StorageClass,并确保在第一次创建时使用`apply`命令并添加`--save-config`选项,这样就会记录注解。但注意,`--save-config`选项已经在新版本的kubectl中默认启用。所以我们通常直接使用: ```bash kubectl apply -f provisioner.yaml ``` 然而,如果你已经有一个没有last-applied-configuration的资源,并且希望后续能够使用`apply`命令,则可以这样做: - 先获取当前资源的配置并保存(例如,通过`kubectl get storageclass <name> -o yaml > current.yaml`) - 然后删除该资源 - 修改current.yaml,添加`kubectl.kubernetes.io/last-applied-configuration`注解(注解的值就是你要应用的yaml文件内容,但是需要转换成json格式并压缩成一行字符串?这很麻烦) - 重新应用这个修改后的current.yaml(使用replace或apply) 实际上,更简单的方法是删除后重新创建,并且在创建时使用`kubectl apply`(这样就会自动记录注解)。 因此,我们建议: 1. 备份现有的StorageClass配置(如果需要参考): ```bash kubectl get storageclass <storageclass-name> -o yaml > storageclass-backup.yaml ``` 2. 删除现有的StorageClass: ```bash kubectl delete storageclass <storageclass-name> ``` 3. 修改provisioner.yaml文件,确保reclaimPolicy设置为你想要的值(例如`reclaimPolicy: Retain`),同时检查其他设置是否正确。 4. 重新应用: ```bash kubectl apply -f provisioner.yaml ``` 这样,新的StorageClass就会被创建,并且会记录last-applied-configuration注解。 注意:如果这个StorageClass被设置为默认的存储类(通过注解`storageclass.kubernetes.io/is-default-class: "true"`),那么在删除之前,需要确保另一个存储类被设置为默认(或者先移除默认设置,再重新创建后设置回去),以避免在删除期间创建PVC时出现没有默认存储类的问题。 另外,根据引用[1]和[2],设置默认存储类的方法就是在StorageClass的metadata.annotations中添加: annotations: storageclass.kubernetes.io/is-default-class: "true" 因此,如果你的StorageClass需要作为默认的,请确保在provisioner.yaml中包含了这个注解。 总结:由于不可变字段的修改限制,我们需要删除并重新创建StorageClass。同时,重新创建时正确使用`kubectl apply`可以解决last-applied-configuration缺失的问题。 如果用户不想删除现有的StorageClass(例如在生产环境中不允许删除),那么就需要考虑其他方案: - 创建一个新的StorageClass(使用不同的名称),并将PVC的存储类指向新的StorageClass。但注意,PVC的存储类在创建后是不可变的(除了通过删除并重新创建PVC),所以这种方法可能比较麻烦。 因此,我们主要推荐删除重建的方法。 最后,请确保在操作前做好备份和评估影响。 相关问题: 1. 为什么StorageClass的reclaimPolicy不可变? 2. 如何安全地删除一个StorageClass? 3. 如何设置Kubernetes的默认StorageClass? 4. 如何解决kubectl apply时缺少last-applied-configuration注解的问题? </think>### Kubernetes StorageClass 更新问题解决方案 在 Kubernetes 中更新 StorageClass 时遇到 `reclaimPolicy` 更新被禁止和缺少 `last-applied-configuration` 注解的问题,主要是由于 StorageClass 的**不可变特性**和 `kubectl apply` 的工作机制导致。以下是具体解决方案: --- ### 一、问题原因分析 1. **`reclaimPolicy` 更新被禁止** StorageClass 的 `reclaimPolicy` 字段在创建后**不可修改**(PVC/PV 生命周期依赖此策略)。Kubernetes 会阻止直接更新该字段[^1]。 2. **缺少 `last-applied-configuration` 注解** 当首次使用 `kubectl create` 而非 `kubectl apply` 创建资源时,系统不会自动添加此注解,导致后续 `apply` 操作无法计算配置差异[^2][^4]。 --- ### 二、解决方案 #### 步骤 1:删除并重建 StorageClass(推荐) 这是最彻底的解决方式,适用于非生产环境或可接受短暂中断的场景: ```bash # 1. 备份当前配置 kubectl get storageclass <storageclass-name> -o yaml > storageclass-backup.yaml # 2. 删除旧 StorageClass kubectl delete storageclass <storageclass-name> # 3. 修改 provisioner.yaml 确保包含: # a. 正确的 reclaimPolicy(Retain/Delete) # b. 注解(如需设为默认类): metadata: annotations: storageclass.kubernetes.io/is-default-class: "true" # [^1] # 4. 重建资源(此时会添加 last-applied-configuration) kubectl apply -f provisioner.yaml ``` #### 步骤 2:通过 `kubectl replace` 绕过注解问题 适用于需要保留原有 StorageClass 名称的场景: ```bash # 1. 修改 provisioner.yaml 更新其他字段(保持 reclaimPolicy 不变) # 2. 强制替换配置(跳过 apply 的差异检查) kubectl replace -f provisioner.yaml --force --save-config # --save-config 会添加 last-applied-configuration ``` #### 步骤 3:手动添加注解(临时方案) 如果必须保留原有 StorageClass 并使用 `apply`: ```bash # 1. 添加 last-applied-configuration 注解 kubectl annotate storageclass <storageclass-name> \ kubectl.kubernetes.io/last-applied-configuration="$(cat provisioner.yaml | jq -Rs)" # 2. 再次应用(此时可更新其他允许修改的字段) kubectl apply -f provisioner.yaml ``` --- ### 关键注意事项 1. **`reclaimPolicy` 修改限制** 如果需要更改回收策略,必须重建 StorageClass。新策略仅影响**后续创建**的 PV,已有 PV 不受影响[^1][^3]。 2. **默认存储类的切换** 若需设为默认类,必须在注解中明确声明: ```yaml metadata: annotations: storageclass.kubernetes.io/is-default-class: "true" ``` 同一集群只能有一个默认 StorageClass[^1][^2]。 3. **动态供应场景** 删除 StorageClass 后,已通过它动态创建的 PV 仍会保留(根据其自身的 `reclaimPolicy` 处理),但新 PVC 将无法使用该存储类[^3]。 --- ### 操作验证 ```bash # 检查注解是否添加 kubectl get storageclass <storageclass-name> -o jsonpath='{.metadata.annotations}' # 验证 reclaimPolicy 更新 kubectl get storageclass <storageclass-name> -o jsonpath='{.reclaimPolicy}' ``` 通过以上步骤,即可解决 StorageClass 更新时的字段限制和注解缺失问题。建议优先采用删除重建方案以确保配置一致性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值