001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.component.extension; 018 019import java.io.Serializable; 020import java.util.List; 021import java.util.Map; 022import java.util.Set; 023 024import org.apache.camel.Component; 025import org.apache.camel.component.extension.verifier.ComponentVerifierExtensionHelper; 026import org.apache.camel.component.extension.verifier.ResultErrorBuilder; 027import org.apache.camel.util.ObjectHelper; 028/** 029 * Defines the interface used for validating component/endpoint parameters. The central method of this 030 * interface is {@link #verify(ComponentVerifierExtension.Scope, Map)} which takes a scope and a set of parameters which should be verified. 031 * <p/> 032 * The return value is a {@link ComponentVerifierExtension.Result} of the verification 033 * 034 */ 035public interface ComponentVerifierExtension extends ComponentExtension { 036 037 /** 038 * Verify the given parameters against a provided scope. 039 * 040 * <p> 041 * The supported scopes are: 042 * <ul> 043 * <li><strong>{@link ComponentVerifierExtension.Scope#PARAMETERS}</strong>: to validate that all the mandatory options are provided and syntactically correct.</li> 044 * <li><strong>{@link ComponentVerifierExtension.Scope#CONNECTIVITY}</strong>: to validate that the given options (i.e. credentials, addresses) are correct. Verifying with this 045 * scope typically implies reaching out to the backend via some sort of network connection.</li> 046 * </ul> 047 * 048 * @param scope the scope of the verification 049 * @param parameters the parameters to verify which are interpreted individually by each component verifier 050 * @return the verification result 051 */ 052 ComponentVerifierExtension.Result verify(ComponentVerifierExtension.Scope scope, Map<String, Object> parameters); 053 054 /** 055 * The result of a verification 056 */ 057 interface Result extends Serializable { 058 059 /** 060 * Status of the verification 061 */ 062 enum Status { 063 /** 064 * Verification succeeded 065 */ 066 OK, 067 /** 068 * Error occurred during the verification 069 */ 070 ERROR, 071 /** 072 * Verification is not supported. This can depend on the given scope. 073 */ 074 UNSUPPORTED 075 } 076 077 /** 078 * Scope of the verification. This is the scope given to the call to {@link #verify(ComponentVerifierExtension.Scope, Map)} and 079 * can be used for correlation. 080 * 081 * @return the scope against which the parameters have been validated. 082 */ 083 ComponentVerifierExtension.Scope getScope(); 084 085 /** 086 * Result of the validation as status. This should be the first datum to check after a verification 087 * happened. 088 * 089 * @return the status 090 */ 091 ComponentVerifierExtension.Result.Status getStatus(); 092 093 /** 094 * Collection of errors happened for the verification. This list is empty (but non null) if the verification 095 * succeeded. 096 * 097 * @return a list of errors. Can be empty when verification was successful 098 */ 099 List<ComponentVerifierExtension.VerificationError> getErrors(); 100 } 101 102 /** 103 * The scope defines how the parameters should be verified. 104 */ 105 enum Scope { 106 /** 107 * Only validate the parameters for their <em>syntactic</em> soundness. Verifications in this scope should 108 * be as fast as possible 109 */ 110 PARAMETERS, 111 112 /** 113 * Reach out to the backend and verify that a connection can be established. This means, if the verification 114 * in this scope succeeds, then it can safely be assumed that the component can be used. 115 */ 116 CONNECTIVITY; 117 118 private static final ComponentVerifierExtension.Scope[] VALUES = values(); 119 120 /** 121 * Get an instance of this scope from a string representation 122 * 123 * @param scope the scope as string, which can be in any case 124 * @return the scope enum represented by this string 125 */ 126 public static ComponentVerifierExtension.Scope fromString(String scope) { 127 for (ComponentVerifierExtension.Scope value : VALUES) { 128 if (ObjectHelper.equal(scope, value.name(), true)) { 129 return value; 130 } 131 } 132 throw new IllegalArgumentException("Unknown scope <" + scope + ">"); 133 } 134 } 135 136 // ============================================================================================= 137 138 /** 139 * This interface represents a detailed error in case when the verification fails. 140 */ 141 interface VerificationError extends Serializable { 142 143 /** 144 * The overall error code, which can be either a {@link StandardCode} or a custom code. It is 145 * recommended to stick to the predefined standard codes 146 * 147 * @return the general error code. 148 */ 149 Code getCode(); 150 151 /** 152 * A human readable description of the error in plain english 153 * 154 * @return the error description (if available) 155 */ 156 String getDescription(); 157 158 /** 159 * A set of input parameter names which fails the verification. These are keys to the parameter provided 160 * to {@link #verify(ComponentVerifierExtension.Scope, Map)}. 161 * 162 * @return the parameter names which are malformed and caused the failure of the validation 163 */ 164 Set<String> getParameterKeys(); 165 166 /** 167 * Details about the failed verification. The keys can be either predefined values 168 * ({@link ExceptionAttribute}, {@link HttpAttribute}, {@link GroupAttribute}) or it can be free-form 169 * custom keys specific to a component. The standard attributes are defined as enums in all uppercase (with 170 * underscore as separator), custom attributes are supposed to be in all lower case (also with underscores 171 * as separators) 172 * 173 * @return a number of key/value pair with additional information related to the verification. 174 */ 175 Map<ComponentVerifierExtension.VerificationError.Attribute, Object> getDetails(); 176 177 /** 178 * Get a single detail for a given attribute 179 * 180 * @param attribute the attribute to lookup 181 * @return the detail value or null if no such attribute exists 182 */ 183 default Object getDetail(ComponentVerifierExtension.VerificationError.Attribute attribute) { 184 Map<ComponentVerifierExtension.VerificationError.Attribute, Object> details = getDetails(); 185 if (details != null) { 186 return details.get(attribute); 187 } 188 return null; 189 } 190 191 /** 192 * Get a single detail for a given attribute 193 * 194 * @param attribute the attribute to lookup 195 * @return the detail value or null if no such attribute exists 196 */ 197 default Object getDetail(String attribute) { 198 return getDetail(asAttribute(attribute)); 199 } 200 201 /** 202 * Convert a string to an {@link Code} 203 * 204 * @param code the code to convert. It should be in all lower case (with 205 * underscore as a separator) to avoid overlap with {@link StandardCode} 206 * @return error code 207 */ 208 static Code asCode(String code) { 209 return new ComponentVerifierExtensionHelper.ErrorCode(code); 210 } 211 212 /** 213 * Convert a string to an {@link Attribute} 214 * 215 * @param attribute the string representation of an attribute to convert. It should be in all lower case (with 216 * underscore as a separator) to avoid overlap with standard attributes like {@linkExceptionAttribute}, 217 * {@linkHttpAttribute} or {@link GroupAttribute} 218 * @return generated attribute 219 */ 220 static Attribute asAttribute(String attribute) { 221 return new ComponentVerifierExtensionHelper.ErrorAttribute(attribute); 222 } 223 224 /** 225 * Interface defining an error code. This is implemented by the {@link StandardCode} but also 226 * own code can be generated by implementing this interface. This is best done via {@link #asCode(String)} 227 * If possible, the standard codes should be reused 228 */ 229 interface Code extends Serializable { 230 /** 231 * Name of the code. All uppercase for standard codes, all lower case for custom codes. 232 * Separator between two words is an underscore. 233 * 234 * @return code name 235 */ 236 String name(); 237 238 /** 239 * Bean style accessor to name. 240 * This is required for framework like Jackson using bean convention for object serialization. 241 * 242 * @return code name 243 */ 244 default String getName() { 245 return name(); 246 } 247 } 248 249 /** 250 * Standard set of error codes 251 */ 252 interface StandardCode extends Code { 253 /** 254 * Authentication failed 255 */ 256 StandardCode AUTHENTICATION = new ComponentVerifierExtensionHelper.StandardErrorCode("AUTHENTICATION"); 257 /** 258 * An exception occurred 259 */ 260 StandardCode EXCEPTION = new ComponentVerifierExtensionHelper.StandardErrorCode("EXCEPTION"); 261 /** 262 * Internal error while performing the verification 263 */ 264 StandardCode INTERNAL = new ComponentVerifierExtensionHelper.StandardErrorCode("INTERNAL"); 265 /** 266 * A mandatory parameter is missing 267 */ 268 StandardCode MISSING_PARAMETER = new ComponentVerifierExtensionHelper.StandardErrorCode("MISSING_PARAMETER"); 269 /** 270 * A given parameter is not known to the component 271 */ 272 StandardCode UNKNOWN_PARAMETER = new ComponentVerifierExtensionHelper.StandardErrorCode("UNKNOWN_PARAMETER"); 273 /** 274 * A given parameter is illegal 275 */ 276 StandardCode ILLEGAL_PARAMETER = new ComponentVerifierExtensionHelper.StandardErrorCode("ILLEGAL_PARAMETER"); 277 /** 278 * A combination of parameters is illegal. See {@link ComponentVerifierExtension.VerificationError#getParameterKeys()} for the set 279 * of affected parameters 280 */ 281 StandardCode ILLEGAL_PARAMETER_GROUP_COMBINATION = new ComponentVerifierExtensionHelper.StandardErrorCode("ILLEGAL_PARAMETER_GROUP_COMBINATION"); 282 /** 283 * A parameter <em>value</em> is not valid 284 */ 285 StandardCode ILLEGAL_PARAMETER_VALUE = new ComponentVerifierExtensionHelper.StandardErrorCode("ILLEGAL_PARAMETER_VALUE"); 286 /** 287 * A group of parameters is not complete in order to be valid 288 */ 289 StandardCode INCOMPLETE_PARAMETER_GROUP = new ComponentVerifierExtensionHelper.StandardErrorCode("INCOMPLETE_PARAMETER_GROUP"); 290 /** 291 * The verification is not supported 292 */ 293 StandardCode UNSUPPORTED = new ComponentVerifierExtensionHelper.StandardErrorCode("UNSUPPORTED"); 294 /** 295 * The requested {@link ComponentVerifierExtension.Scope} is not supported 296 */ 297 StandardCode UNSUPPORTED_SCOPE = new ComponentVerifierExtensionHelper.StandardErrorCode("UNSUPPORTED_SCOPE"); 298 /** 299 * The requested {@link Component} is not supported 300 */ 301 StandardCode UNSUPPORTED_COMPONENT = new ComponentVerifierExtensionHelper.StandardErrorCode("UNSUPPORTED_COMPONENT"); 302 /** 303 * Generic error which is explained in more details with {@link ComponentVerifierExtension.VerificationError#getDetails()} 304 */ 305 StandardCode GENERIC = new ComponentVerifierExtensionHelper.StandardErrorCode("GENERIC"); 306 } 307 308 /** 309 * Interface defining an attribute which is a key for the detailed error messages. This is implemented by several 310 * standard enums like {@link ExceptionAttribute}, {@link HttpAttribute} or {@link GroupAttribute} but can also 311 * implemented for component specific details. This is best done via {@link #asAttribute(String)} 312 * or using one of the other builder method in this error builder (like {@link ResultErrorBuilder#detail(String, Object)} 313 * <p> 314 * With respecting to name, the same rules as for {@link Code} apply: Standard attributes are all upper case with _ 315 * as separators, whereas custom attributes are lower case with underscore separators. 316 */ 317 interface Attribute extends Serializable { 318 /** 319 * Name of the attribute. All uppercase for standard attributes and all lower case for custom attributes. 320 * Separator between words is an underscore. 321 * 322 * @return attribute name 323 */ 324 String name(); 325 326 /** 327 * Bean style accessor to name; 328 * This is required for framework like Jackson using bean convention for object serialization. 329 * 330 * @return attribute name 331 */ 332 default String getName() { 333 return name(); 334 } 335 } 336 337 /** 338 * Attributes for details about an exception that was raised 339 */ 340 interface ExceptionAttribute extends Attribute { 341 /** 342 * The exception object that has been thrown. Note that this can be a complex 343 * object and can cause large content when e.g. serialized as JSON 344 */ 345 ExceptionAttribute EXCEPTION_INSTANCE = new ComponentVerifierExtensionHelper.ExceptionErrorAttribute("EXCEPTION_INSTANCE"); 346 /** 347 * The exception class 348 */ 349 ExceptionAttribute EXCEPTION_CLASS = new ComponentVerifierExtensionHelper.ExceptionErrorAttribute("EXCEPTION_CLASS"); 350 } 351 352 /** 353 * HTTP related error details 354 */ 355 interface HttpAttribute extends Attribute { 356 /** 357 * The erroneous HTTP code that occurred 358 */ 359 HttpAttribute HTTP_CODE = new ComponentVerifierExtensionHelper.HttpErrorAttribute("HTTP_CODE"); 360 /** 361 * HTTP response's body 362 */ 363 HttpAttribute HTTP_TEXT = new ComponentVerifierExtensionHelper.HttpErrorAttribute("HTTP_TEXT"); 364 /** 365 * If given as details, specifies that a redirect happened and the 366 * content of this detail is the redirect URL 367 */ 368 HttpAttribute HTTP_REDIRECT = new ComponentVerifierExtensionHelper.HttpErrorAttribute("HTTP_REDIRECT"); 369 } 370 371 /** 372 * Group related details 373 */ 374 interface GroupAttribute extends Attribute { 375 /** 376 * Group name 377 */ 378 GroupAttribute GROUP_NAME = new ComponentVerifierExtensionHelper.GroupErrorAttribute("GROUP_NAME"); 379 /** 380 * Options for the group 381 */ 382 GroupAttribute GROUP_OPTIONS = new ComponentVerifierExtensionHelper.GroupErrorAttribute("GROUP_OPTIONS"); 383 } 384 } 385}