Cannot persist via Hibernate ORM with Panache using rubenlagus/TelegramBots - java

I'm using Quarkus 2.15.1 and rubenlagus/TelegramBots 6.3.0
My pom.xml dependencies are:
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>6.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I've configured jdbc URL, username & password as well.
The problem is when I'm trying to persist an object (via Active Record or Repository pattern) there is an exception.
The code snippet is:
#ApplicationScoped
public class VoteBot extends TelegramLongPollingBot {
#Override
public void onUpdateReceived(Update update) {
if (update.hasMessage() && update.getMessage().hasText()) {
long chatId = update.getMessage().getChatId();
String messageText = update.getMessage().getText();
if (messageText.matches("^[A-Za-z\\s]+$")) {
Participant participant = new Participant();
participant.setChatId(chatId);
participant.setName(messageText);
// Some code
Participant.persist(participant); // Here is the exceptional line goes
// Some code
}
}
Startup class looks like:
#ApplicationScoped
public class Application {
void onStart(#Observes StartupEvent ev) {
try {
TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class);
telegramBotsApi.registerBot(new VoteBot());
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
The exception message is:
2022-12-25 02:22:19,727 ERROR [org.tel.tel.upd.DefaultBotSession] (ckorovoda_vote_bot Telegram Executor) Cannot use the EntityManager/Session because neither a transaction nor a CDI request context is active. Consider adding #Transactional to your method to automatically activate a transaction, or #ActivateRequestContext if you have valid reasons not to use transactions.: javax.enterprise.context.ContextNotActiveException: Cannot use the EntityManager/Session because neither a transaction nor a CDI request context is active. Consider adding #Transactional to your method to automatically activate a transaction, or #ActivateRequestContext if you have valid reasons not to use transactions.
at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.acquireSession(TransactionScopedSession.java:106)
at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.contains(TransactionScopedSession.java:325)
at org.hibernate.engine.spi.SessionLazyDelegator.contains(SessionLazyDelegator.java:710)
at org.hibernate.Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.contains(Unknown Source)
at io.quarkus.hibernate.orm.panache.common.runtime.AbstractJpaOperations.persist(AbstractJpaOperations.java:100)
at io.quarkus.hibernate.orm.panache.common.runtime.AbstractJpaOperations.persist(AbstractJpaOperations.java:96)
at io.quarkus.hibernate.orm.panache.common.runtime.AbstractJpaOperations.persist(AbstractJpaOperations.java:112)
at io.quarkus.hibernate.orm.panache.PanacheEntityBase.persist(PanacheEntityBase.java:756)
at store.ckorovoda.Participant.persist(Participant.java)
at store.ckorovoda.VoteBot.onUpdateReceived(VoteBot.java:74)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.telegram.telegrambots.meta.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27)
at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:317)
I've tried adding #Transactional, #ActivateRequestContext and changing bean scopes. I've also tried to use EntityManager and quarkus-narayana-jta. However, I'm pretty sure it's all connected with this 3rd-party lib for Telegram.
I'm stuck with it and will appreciate any recommendation or hints for resolving that stuff.
Thank you!

Related

NiFI :- Failed to create Extension Definition for CONTROLLER_SERVICE org.apache.nifi.record.sink.lookup.RecordSinkServiceLookup

I'm trying to use DBCPConnectionPool service in my custom processor. So, how to use in-built controller services (which are already available on NiFi) in our custom processors.
Here are my properties in *-nar/->pom.xml
<dependencies>
<dependency>
<groupId>org.sample.com</groupId>
<artifactId>nifi-customprocessor-processors</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-services-api-nar</artifactId>
<version>1.14.0</version>
<type>nar</type>
</dependency>
</dependencies>
Here are my dependencies in *processors/->pom.xml
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-utils</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-mock</artifactId>
<version>1.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-dbcp-service</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-dbcp-service-api</artifactId>
<version>1.14.0</version>
</dependency>
And here is my propertydescriptor for DBCPConnetionPool service :-
public static final PropertyDescriptor DBCPConnectionPool_SERVICE = new PropertyDescriptor.Builder()
.name("DBCPConnectionPoolLookup Service")
.description("The Controller Service to use in order to establish a connection")
.required(true)
.dynamic(true)
.identifiesControllerService(DBCPService.class)
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
.build();
and in my OnTrigger method I didn't used it as :-
DBCPService DBCPService = context.getProperty(DBCPConnectionPool_SERVICE)
.asControllerService(DBCPService.class);
Connection con = DBCPService.getConnection();
and was trying to use this con object as in regular passion createStatement->executeQuery.
When I tried to package it using mvn clean install it started throwing error as : A required class was missing while executing org.apache.nifi:nifi-nar-maven-plugi
n:1.3.1:nar: org/apache/nifi/record/sink/RecordSinkService
then I added the following dependencies in processors/->pom.xml
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-record-sink-service</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-record-sink-api</artifactId>
<version>1.14.0</version>
</dependency>
This time it was new error as :- Failed to create Extension Definition for CONTROLLER_SERVICE org.apache.nifi.record.sink.lookup.RecordSinkServiceLookup: Null
PointerException
I also checked by commenting out code which I have written, to check the way I'm using that property was wrong but, even that didn't worked.:-
DBCPService DBCPService = context.getProperty(DBCPConnectionPool_SERVICE)
.asControllerService(DBCPService.class);
Connection con = DBCPService.getConnection();
Can someone help me out in order to use DBCPConnectionPoolService controller service in my custom processor?
I had the same issues the other day and I solved it by using AbstractControllerService instead of DBCPConnectionPool therefore not needing org.apache.nifi.dbcp.DBCPService anymore. Therefore my code would look like this:
MyService DBCPService = context.getProperty(DBCPConnectionPool_SERVICE)
.asControllerService(MyService.class);
Connection con = DBCPService.getConnection();
MyService is the custom interface that extends ControllerService.(you have to use it when you also define the PropertyDescriptor DBCPConnectionPool_SERVICE)
And StandardMyService the class that extends AbstractControllerService and implements MyService and getConnection() from it.

Why MongoRepository expose rest crud api and how to disable when using restController

I have a spring application exposing rest api using a restController. It calls a layer service and then a layer Dao where i'm using MongoRepository to get crud stuffs.
public interface ProjectDao extends MongoRepository<Project, String> {
}
#CrossOrigin
#RestController
#Slf4j
#RequestMapping("/api/data")
public class DataController {
...
#GetMapping(value = "projects/{id}")
public Project findProjectById(#PathVariable String id) throws ResponseStatusException {
Optional<Project> project = projectService.findById(id);
if (project.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "product with id " + id + " does not exists");
return project.get();
}
...
}
I just configured swagger to generate the documentation and have discovered i can call directly all crud methods exposed from the mongorepository!!! But i do not want this behaviour as i want to expose only api from my rest controller.
I have my method GET /api/data/projects/{id} that call the findProjectById of my controller but i have also a method GET /projects/{id} which call directly the mongorepository. And all the other like delete, put, post which is really dangerous.
I'm using this dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
I can't find how to configure that and why by default all rest api of mongorepository is exposed!
I someone know how to disable that, thanks!
Ok, i have found the solution only modifying maven dependencies.
I should use
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Instead of
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
Which publish rest service based on data model.

Spring Reactive Test case fails to start the Netty Server

I have spring test-case as shown below when I run it is not starting the Netty server and provides following exception.
Caused by: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155)
Below is my test case:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SpringWebFluxDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class CustomPriceControllerTest {
#Autowired
private ApplicationContext context;
private WebTestClient testClient;
#Before
public void init() {
testClient = WebTestClient.bindToApplicationContext(context).configureClient().baseUrl("http://localhost:8080").responseTimeout(Duration.ofSeconds(30)).build();
}
#Test
public void broadcastVoltageConsumption() {
this.testClient.get().uri("/api/getCustomPrice")
.accept(MediaType.APPLICATION_STREAM_JSON)
.exchange()
.expectBodyList(Custom.class)
.consumeWith((customResults) -> {
List<Custom> list = CustomResults.getResponseBody();
Assert.assertTrue(list != null && list.size() > 0);
});
}
}
My pom.xml has excluded the dependency for tomcat to enable Netty. My Spring boot class works perfectly fine. It boots Netty server.
Update - pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Had to add javax.servlet-api because I was facing issues with javax.servlet-api missing.
Update - 2
Removing the javax.servlet dependency from pom.xml solves the issue.
While when I try to run my main application it starts the Netty server normally. What is missing in this configuration? Can anyone help on this?
You wanted the webserver to be powered by Netty, but the exception you are getting is Servlet Specific
Since Netty is not servlet based technology, it seems you that somewhere (gradle/maven/#Configuration) you are mixing them,
so , just remove all references to Servlet dependencies and re try
If any dependency needs a servlet, it will force Jetty to come up and netty will never start in that case.
Whenever you see webflux is starting Jetty and not netty, you should run following command and then search who is including Jetty as dependency then you will find the answer.
./gradlew dependencies
In your case, you are including servlet dependency directly which is causing that issue.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
I had the same issue. I just remove this dependency (which have servlet dependency):
testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')

Running a Jersey application using GlassFish in IntelliJ gives requested resource is not available error

I have created a small Jersey application which has the following resource class.
#Path("/tests")
public class TestController {
#GET
#Produces("application/json")
public Response testJob(#PathParam("testName") String testName) {
return Response.ok("test").build();
}
}
Below is my application class.
#ApplicationPath("/")
public class ApplicationConfig extends Application {
// All request scoped resources and providers
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(TestController.class);
return classes;
}
// all singleton resources and providers
#Override
public Set<Object> getSingletons() {
Set<Object> singletons = new HashSet<>();
return singletons;
}
}
Below is my running configuration in intellij.
I just downloaded the glass fish and did no external configurations. I searched online for the default user name password for domain and gave it them as admin and admin respectively. But when I run the application using the URL,
http://localhost:8080/test-processor/tests
I am getting a 404 error saying the requested resource is not found. My war module name is test-processor. I have tried the url http://localhost:8080/tests with no luck as well. What am I doing wrong here? Any help would be much appreciated. Below is the list of dependencies I have added in my pom xml.
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.25.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-guice</artifactId>
<version>1.19.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>

How to mock a private method using PowerMock with Mockito and TestNG

I am trying to use powermock to mock a private method, but my PowerMock is not recognized in MockitoBusinessOperation MockitoBusinessOperation = PowerMock.createPartialMock(MockitoBusinessOperation.class, "inTestMethod"); . I used maven and the dependencies for mockito and powermock are defined in my pom file
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-mockito-release-full</artifactId>
<version>1.4.9</version>
<scope>test</scope>
</dependency>
I don't know if the error is related to powermock with TestNG or I am doing some mistake in my code.
#PrepareForTest(MockitoBusinessOperation.class)
#Test(enabled = true)
public void testReCalculatePrepaids() throws Exception {
MockitoBusinessOperation MockitoBusinessOperation = PowerMock.createPartialMock(MockitoBusinessOperation.class, "inTestMethod");
PowerMock.expectPrivate(MockitoBusinessOperation, "inTestMethod", Id).andReturn("working fine");
when(MockitoBusinessService.creditReport(this.Id)).thenReturn(new String("Decline by only Me"));
String report = MockitoBusinessService.creditReport(this.Id);
String mainReport = MockitoBusinessOperation.creditAproved(this.Id);
}
someone has an idea or any clue lead to the solution
According to the documentation your maven file should have the following definitions:
<properties>
<powermock.version>1.5</powermock.version>
</properties>
<dependencies>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
please try this way
#Test
public void commandEndHandlerTest() throws Exception
{
Method retryClientDetail_privateMethod =yourclass.class.getDeclaredMethod("Your_function_name",null);
retryClientDetail_privateMethod.setAccessible(true);
retryClientDetail_privateMethod.invoke(yourclass.class, null);
}

Categories