How to get Field value in User Defined Java Class in kettle? - pentaho

I am trying to get the Link field in the User Defined Java Class step from my below transformation.
Here is the code which I have written in User Defined Java Class:
private String link;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
Object[] r=getRow();
if (r == null) {
setOutputDone();
return false;
}
if (first) {
link = getParameter("Link");
first = false;
}
String linkField = get(Fields.In, link).getString(r);
logBasic("link:" + link);
return true;
}
When I run the above code, here is the error that I get at the User Defined Java Class Step:
2016/06/28 11:26:57 - User Defined Java Class.0 - ERROR (version 5.4.0.1-130, build 1 from 2015-06-14_12-34-55 by buildguy) : Unexpected error
2016/06/28 11:26:57 - User Defined Java Class.0 - ERROR (version 5.4.0.1-130, build 1 from 2015-06-14_12-34-55 by buildguy) : org.pentaho.di.core.exception.KettleStepException:
2016/06/28 11:26:57 - User Defined Java Class.0 - Unable to find In field helper for field name 'null'
2016/06/28 11:26:57 - User Defined Java Class.0 -
2016/06/28 11:26:57 - User Defined Java Class.0 - at org.pentaho.di.trans.steps.userdefinedjavaclass.TransformClassBase.get(TransformClassBase.java:628)
2016/06/28 11:26:57 - User Defined Java Class.0 - at Processor.processRow(Processor.java:15)
2016/06/28 11:26:57 - User Defined Java Class.0 - at org.pentaho.di.trans.steps.userdefinedjavaclass.UserDefinedJavaClass.processRow(UserDefinedJavaClass.java:1018)
2016/06/28 11:26:57 - User Defined Java Class.0 - at org.pentaho.di.trans.step.RunThread.run(RunThread.java:62)
2016/06/28 11:26:57 - User Defined Java Class.0 - at java.lang.Thread.run(Thread.java:745)
2016/06/28 11:26:57 - User Defined Java Class.0 - Finished processing (I=0, O=0, R=1, W=0, U=0, E=1)
To confirm the fields, here is the snapshot of Preview Data till the Filter rows step:
Where am I going wrong?

I figured out where I was missing. In the User Defined Java Class, in the Parameters tab below, I need to explicitly define the field name and it's alias, such as:

Related

Migrating ADAL Filter to MSAL on Linux running Java 11 (maven) - AuthenticationResponseParser.parse() throws exception

in AuthenticationResponseParser.parse(new URI(fullUrl), params);
where params is
Map<String, List<String>>
and is created as
for (String key : httpRequest.getParameterMap().keySet()) {
params.put(key, Collections.singletonList(httpRequest.getParameterMap().get(key)[0]));
}
throws exception
Error: class java.util.Collections$SingletonList cannot be cast to class java.lang.String (java.util.Collections$SingletonList and java.lang.String are in module java.base of loader 'bootstrap')
What could be going wrong?
I am using MSALJ maven dependency com.microsoft.azure, msal4j, 1.13.2
Tried to pass String as params but it is expecting List of strings

spring gateway unable to start with feign client

Using Spring 2.7.0 to create an API gateway, that was working fine until I tried to replace the RestTemplate with OpenFeign.
Here is the relevant build.gradle contents:
plugins {
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'org.liquibase.gradle' version '2.1.0'
id 'groovy'
}
ext {
set('springCloudVersion', "2021.0.3")
}
// implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
My application class:
#SpringBootApplication
#EnableDiscoveryClient
#EnableFeignClients
public class ApiGatewayApplication {
...
}
My FeignClient:
#FeignClient(name="identity-service")
public interface IdentityServiceClient {
#GetMapping("/api/all")
public List<ApiKey> getAllApiKeys();
}
when I try to start the application now I get:
o.s.c.openfeign.FeignClientFactoryBean : For 'identity-service' URL not provided. Will try picking an instance via load-balancing.
DiscoveryClientOptionalArgsConfiguration : Eureka HTTP Client uses RestTemplate
....
onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'apiGatewayApplication': Invocation of init method failed; nested exception is feign.codec.DecodeException: No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
com.netflix.discovery.DiscoveryClient : Shutting down DiscoveryClient ...
com.netflix.discovery.DiscoveryClient : Unregistering ...
com.netflix.discovery.DiscoveryClient : DiscoveryClient_API-GATEWAY/192.168.1.72:api-gateway:8081 - deregister status: 404
com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' in your configuration.
But none of the online examples seem to show the need for adding custom HttpMessageConverters since they are included in spring-web and spring-boot-starter-webflux
UPDATE -
this appears to be related to #Autowired. I put both my service and feign service in a regular class and it starts up fine. But when I autowire those two services, I get this error again.

#Named doesn't resolve the value parameter

After upgrading to micronaut 3.x and replacing the annotation Javax.inject to Jakarta.inject. #Named is unable resolve the property.
import io.micronaut.context.annotation.Bean
import io.micronaut.context.annotation.Factory
import io.micronaut.context.annotation.Requires
import java.util.concurrent.ExecutorService
import jakarta.inject.Named
import kotlin.coroutines.CoroutineContext
#Factory
open class ExecutorServiceCoroutineContextFactory {
#Bean
#Requires(missingBeans = [CoroutineContext::class])
fun executorServiceCoroutineContext(#Named("\${coroutines.executor}")executorService: ExecutorService): CoroutineContext {
return ExecutorServiceCoroutineDispatcher(executorService)
}
}
application.yml
coroutines:
executor: coroutines
The resulting error
Message: No bean of type [java.util.concurrent.ExecutorService] exists for the given qualifier: #Named('${coroutines.executor}'). Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
Path Taken: new Controller(Client client,CoroutineContext coroutineContext) --> new Controller(Client client,[CoroutineContext coroutineContext]) --> CoroutineContext.executorServiceCoroutineContext([ExecutorService executorService],String name)
io.micronaut.context.exceptions.DependencyInjectionException: Failed to inject value for parameter [executorService] of method [executorServiceCoroutineContext] of class: kotlin.coroutines.CoroutineContext
Hardcoding the value "coroutines" does work but wondering why the code can't resolve it.

Meta annotation for #Controller doesn't work in Micronaut

I am trying to implement a custom annotation (meta annotation) for #Controller as follows:
#MustBeDocumented
#Retention(AnnotationRetention.RUNTIME)
#Target(AnnotationTarget.CLASS)
#Secured(SecurityRule.IS_AUTHENTICATED)
#Controller
annotation class CustomController(
#get:AliasFor(annotation = Controller::class)
val value: String
)
//Usage:
#CustomController("/demo-api")
class ChangeController(private val changeGroupApi: ChangeGroupApi) {
//...
}
However, Micronaut behaves as if the controller class isn't even annotated at all. See related log, it's the same with that when the class isn't annotated.
Related log:
10:56:47.351 [default-nioEventLoopGroup-1-2] DEBUG i.m.s.rules.InterceptUrlMapRule - One or more of the IP patterns matched the host address [127.0.0.1]. Continuing request processing.
10:56:47.352 [default-nioEventLoopGroup-1-2] DEBUG i.m.s.rules.InterceptUrlMapRule - No url map pattern exact match found for path [/demo-api] and method [GET]. Searching in patterns with no defined method.
10:56:47.352 [default-nioEventLoopGroup-1-2] DEBUG i.m.s.rules.InterceptUrlMapRule - No url map pattern match found for path [/demo-api]. Returning unknown.
10:56:47.352 [default-nioEventLoopGroup-1-2] DEBUG i.m.security.filters.SecurityFilter - Authorized request GET /demo-api. No rule provider authorized or rejected the request.
Any ideas to make it work?

spring-data-geode and spring-boot-starter-webflux application run failed

I have a webflux project and I am adding apache geode. In my build.gradle I have:
implementation 'org.springframework.data:spring-data-geode:2.2.4.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-webflux:2.2.4.RELEASE'
Once adding the spring-data-geode implementation the application crashes with:
2020-01-28T16:29:51,965 INFO [main] org.eclip.jetty.util.log.Log 169 initialized: Logging initialized #4337ms to org.eclipse.jetty.util.log.Slf4jLog
2020-01-28T16:29:52,050 WARN [main] org.sprin.conte.suppo.AbstractApplicationContext 558 refresh: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is java.lang.NoClassDefFoundError: org/eclipse/jetty/servlet/ServletHolder
2020-01-28T16:29:52,064 INFO [main] org.sprin.boot.autoc.loggi.ConditionEvaluationReportLoggingListener 136 logMessage:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-01-28T16:29:52,072 ERROR [main] org.sprin.boot.SpringApplication 826 reportFailure: Application run failed
org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is java.lang.NoClassDefFoundError: org/eclipse/jetty/servlet/ServletHolder
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:81)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544)
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
The trouble is, if I add
spring.main.web-application-type=none or spring.main.web-application-type=reactive to my application.properties then that interferes with the #ClientCacheApplication(name = "Web", locators = #Locator(host="1.2.3.4", port=10334), logLevel = "debug", subscriptionEnabled = true) annotation and the application does not connect to the geode locator, nor then run the #EnableClusterDefinedRegions which causes problems defining simple regions that I want to pick up from the server.
UPDATE To add spring-boot-starter-web to build.gradle and make the spring boot application type NONE as below appears to fix the instant problem, but...
SpringApplication app = new SpringApplication(Web.class);
app.setWebApplicationType(WebApplicationType.NONE);
SpringApplication.run(Web.class, args);
... but then the webflux mapping cannot find the #Bean websocket handler:
2020-01-28T16:54:26,236 DEBUG [http-nio-8082-exec-2] org.sprin.web.servl.handl.AbstractHandlerMapping 412 getHandler: Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2020-01-28T16:54:26,246 DEBUG [http-nio-8082-exec-2] org.sprin.web.servl.resou.ResourceHttpRequestHandler 454 handleRequest: Resource not found
2020-01-28T16:54:26,246 DEBUG [http-nio-8082-exec-2] org.sprin.web.servl.FrameworkServlet 1131 logResult: Completed 404 NOT_FOUND
and this causes the website to error:
The console log says
WebSocket connection to 'ws://localhost:8082/ws/data' failed: Error during WebSocket handshake: Unexpected response code: 404
The problems with regions was because the classes using the regions defined by #EnableClusterDefinedRegions were (a) instantiated by new command rather than Spring #Autowired; and (b) in another package not seen by the Spring Boot #ComponentScan. Once these were fixed then the regions were auto-defined and handled using #Resource annotation.
#Resource(name = "Example") private Region<Object, Object> example
Also the main program was given
SpringApplication app = new SpringApplication(Web.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
SpringApplication.run(Web.class, args);
The other problem was fixed by getting the correct dependencies in the build.gradle and then annotating endpoints for rSocket / webSocket with:
#MessageMapping(value = "helloWorld")
public Flux<String> getFluxSocket() {
log.traceEntry();
log.info("In hello world");
return Flux.just("{\"Hello\":\"World\"}");
}
or
#GetMapping(value = "/helloWorld", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> getRestSocket() {
log.traceEntry();
return Flux.just("Hello World");
}
for HTTP endpoints.