admin@glassfish.java.net

custom validator for configRef

From: Jennifer Chou <jennifer.chou_at_oracle.com>
Date: Sun, 19 Dec 2010 17:53:08 -0500

I'm trying to create a custom constraint/validator for configRef on the
Server config bean.
There are 2 cases:
1) cannot change config ref of a clustered instance
2) cannot use a non-existent config

 which only need to be validated when the server instance already exists
in domain.xml, like when using the set command.
And should not be validated during _register-instance when the server
hasn't been created yet. So the following commands should NOT fail
create-local-instance --cluster c1 i1
create-local-instance i1

but these should fail
set servers.server.i2.config-ref=c1-config (if i2 is a clustered instance)
set servers.server.i2.config-ref=xxx

Anybody know if there's maybe a way I can tell inside the custom
validator if the server already exists in domain.xml?

Issues:
http://java.net/jira/browse/GLASSFISH-15087
http://java.net/jira/browse/GLASSFISH-15218


Thanks,
Jennifer


Index: src/main/java/com/sun/enterprise/config/serverbeans/Server.java
===================================================================
--- src/main/java/com/sun/enterprise/config/serverbeans/Server.java (revision 43948)
+++ src/main/java/com/sun/enterprise/config/serverbeans/Server.java (working copy)
@@ -42,6 +42,7 @@
 
 import com.sun.enterprise.config.util.InstanceRegisterInstanceCommandParameters;
 import static com.sun.enterprise.config.util.RegisterInstanceCommandParameters.ParameterNames.*;
+import com.sun.enterprise.config.serverbeans.customvalidators.ConfigRefConstraint;
 import com.sun.enterprise.config.serverbeans.customvalidators.NotTargetKeyword;
 import com.sun.enterprise.config.serverbeans.customvalidators.NotDuplicateTargetName;
 import com.sun.enterprise.config.util.ServerHelper;
@@ -81,6 +82,7 @@
 import java.util.logging.Logger;
 import javax.validation.Payload;
 import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
 
 import org.glassfish.api.admin.ServerEnvironment;
@@ -96,6 +98,7 @@
  * User applications cannot be deployed to an Administration Server instance
  */
 @Configured
+_at_ConfigRefConstraint
 @SuppressWarnings("unused")
 @NotDuplicateTargetName(message="{server.duplicate.name}", payload=Server.class)
 public interface Server extends ConfigBeanProxy, Injectable, PropertyBag, Named, SystemPropertyBag, ReferenceContainer, RefContainer, Payload {
@@ -121,6 +124,7 @@
      * {_at_link String }
      */
     @Attribute
+ @NotNull
     @NotTargetKeyword(message="{server.reserved.name}", payload=Server.class)
     @Pattern(regexp = NAME_SERVER_REGEX)
     String getConfigRef();

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License"). You
 * may not use this file except in compliance with the License. You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt. See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license." If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above. However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.config.serverbeans.customvalidators;


import com.sun.enterprise.config.serverbeans.Cluster;
import com.sun.enterprise.config.serverbeans.Clusters;
import com.sun.enterprise.config.serverbeans.Configs;
import com.sun.enterprise.config.serverbeans.ConfigBeansUtilities;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.config.serverbeans.Servers;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.logging.LogDomains;
import org.jvnet.hk2.config.*;

import java.util.logging.Logger;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.jvnet.hk2.config.Dom;
import com.sun.enterprise.util.SystemPropertyConstants;

public class ConfigRefValidator
    implements ConstraintValidator<ConfigRefConstraint, Server> {

    static final Logger logger = LogDomains.getLogger(ConfigRefValidator.class, LogDomains.ADMIN_LOGGER);
    static final LocalStringManagerImpl localStrings = new LocalStringManagerImpl(ConfigRefValidator.class);
    //static final Domain domain = ConfigBeansUtilities.getDomain();

    public void initialize(final ConfigRefConstraint constraint) {
    }

    @Override
    public boolean isValid(final Server server,
        final ConstraintValidatorContext constraintValidatorContext) {

        if (server == null) return true;
        if (server.isDas()) return true;

        final String configRef = server.getConfigRef();
        if (configRef == null) return true; // skip validation @NotNull is already on getConfigRef
        
        final String serverName = server.getName();

        System.out.println("**************server name = " + serverName);
        System.out.println("**************config-ref = " + configRef);

        // cannot use server-config
        if (configRef.equals(SystemPropertyConstants.DAS_SERVER_CONFIG)) {
            logger.warning(localStrings.getLocalString("configref.serverconfig",
                    "The configuration of the Domain Administration Server "
                    + "(named server-config) cannot be referenced by a server"));
           return false;
        }
        // cannot use default-config
        if (configRef.equals(SystemPropertyConstants.TEMPLATE_CONFIG_NAME)) {
            logger.warning(localStrings.getLocalString("configref.defaultconfig",
                    "The default configuration template (named default-config) "
                    + "cannot be referenced by a server"));
           return false;
        }

        //final Dom serverDom = Dom.unwrap(server);
        //final Configs configs = domain.getConfigs();
        //final Servers servers = domain.getServers();
        final Servers servers = server.getParent(Servers.class);
        final Domain domain = servers.getParent(Domain.class);
        final Configs configs = domain.getConfigs();

        if (servers.getServer(serverName) != null) { // Only validate for set, not _register-instance
            // cannot change config ref of a clustered instance
            if (domain.getClusterForInstance(serverName) != null) {
                logger.warning(localStrings.getLocalString("configref.clusteredinstance",
                        "Cannot change a config-ref when the instance is part of a cluster"));
                return false;
            }
            // cannot use a non-existent config
            if (configs == null || configs.getConfigByName(configRef) == null) {
                logger.warning(localStrings.getLocalString("configref.nonexistent",
                        "A configuration that doesn't exist cannot be referenced by a server."));
                return false;
            }
        }
  
        return true;
    }
}


/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License"). You
 * may not use this file except in compliance with the License. You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt. See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license." If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above. However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.config.serverbeans.customvalidators;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Retention(RUNTIME)
@Target({METHOD, FIELD, TYPE})
@Documented
@Constraint(validatedBy = ConfigRefValidator.class)
public @interface ConfigRefConstraint {
    String message() default "{configref.invalid}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}