Having this configuration :
#Configuration
#EnableNeo4jRepositories("com.mydb.repository")
#EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {
#Bean
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer( "http://localhost:7474" );
}
#Bean
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( new File("./mydb.db") )
.setConfig( ServerSettings.auth_enabled, Boolean.FALSE.toString() )
.newGraphDatabase();
}
#Bean
#Override
#Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
#Bean
#Override
public SessionFactory getSessionFactory() {
return new SessionFactory("com.mydb.model");
}
}
I have 2 errors :
1_ I can't keep the Session in scope "session"
2_ I have the exception : Connect to localhost:7474 failed: Connection refused:
The server is Embedded, it should start without instaling any server on my local machine ?
Spring-boot 1.3.0 (Last) and
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
Version 4.0 of Spring Data for Neo4j doesn't support embedded version of Neo4j.
You need to install Neo4j on your local machine.
"SDN 4.1 will support embedded version." #Luanne
Related
Tries to create an web application based on spring boot with web-socket support
Define public static main class annotated with #SpringBootApplication
#SpringBootApplication
public class Facade {
public static void main(String[] argv) throws IOException {
Map<String,Object> contextProperties = new HashMap<>();
contextProperties.put("server.port",p.getProperty("server.port","8091"));
SpringApplication app = new SpringApplication(Facade.class);
app.setDefaultProperties(contextProperties);
app.run(argv);
}
}
Add configuration class
#Configuration
#EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketTextHandler(), "/ws").setAllowedOrigins("*");
}
}
Add handler
#Component
public class SocketTextHandler extends TextWebSocketHandler {
#Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
String payload = message.getPayload();
session.sendMessage(new TextMessage("Hi " + payload + " how may we help you?"));
}
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
session.sendMessage(new TextMessage("Connected!"));
}
}
There are maven dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>9.0.31</version>
</dependency>
spring boot version is 2.5.5
When I connect to socket using JavaScript
webSocket = new WebSocket(wsUrl);
I see in app logs
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.socket.server.HandshakeFailureException: Servlet request failed to upgrade to WebSocket: http://127.0.0.1:8091/ws; nested exception is javax.servlet.ServletException: java.lang.reflect.InvocationTargetException] with root cause
java.lang.ClassNotFoundException: org.apache.coyote.http11.upgrade.UpgradeInfo
The tomcat-coyote dependency is in pom.xlm
I used web-sockets in jersey implementation under tomcat9. Now I tries to migrate application to spring-boot, but confused with NoClassDef exception.
Could you please explain or suggest solution for this cause.
I have my DAO layers with an expensive method as followed:
#Component
#CacheConfig(cacheNames = {"userStories"})
public class UserStoryDaoImpl implements IUserStoryDao {
#Override
#Cacheable
public List<UserStory> getUserStoriesForProjectAndRelease(UserDto userDto, Set<Integer>
reportProjectId, int releaseId) {
//Slow performing business logic that returns a list
return new ArrayList();
}
and another as
#Component
#CacheConfig(cacheNames = {"features"})
public class FeatureDaoImpl implements IFeatureDao {
#Override
#Cacheable
public List<Features> geFeaturesForProjectAndRelease(UserDto userDto, Set<Integer> reportProjectId,
int releaseId) {
//Slow performing business logic that returns a list
return new ArrayList();
}
}
and my cache config class as :
#Configuration
public class CaffeineCacheConfig {
#Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager("features", "userStories");
cacheManager.setCaffeine(caffeineCacheBuilder());
return cacheManager;
}
Caffeine< Object, Object > caffeineCacheBuilder() {
return Caffeine.newBuilder()
.initialCapacity(100)
.maximumSize(500)
.expireAfterAccess(5, TimeUnit.MINUTES)
.refreshAfterWrite(2, TimeUnit.MINUTES)
.weakKeys()
.recordStats();
}
}
I am using spring boot :: 2.2.6.RELEASE and my pom include :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.2</version>
</dependency>
Am I missing something in this? I want to maintain a cache "features" &"userStories" and update it asynchronously after call to the DAO method is made.
I am getting following error :
Cannot load configuration class: com.packageName.CaffeineCacheConfig
Caused by: java.lang.NoClassDefFoundError: com/github/benmanes/caffeine/cache/Caffeine
Caused by: java.lang.ClassNotFoundException: com.github.benmanes.caffeine.cache.Caffeine
I have found these reports related to a similar issue: CaffeineGit-1 and CaffeineGit-Related
I created a new sample and slipted the codes into client and server side.
The complete codes can be found here.
There are 3 version of server side.
server None Spring Boot app, using Spring Integration RSocket InboundGateway.
server-boot Reuse Spring RSocket autconfiguration, and created ServerRSocketConnecter through ServerRSocketMessageHanlder.
server-boot-messsagemapping Not use Spring Integration, just use Spring Boot RSocket autconfiguration, and #Controller and #MessageMapping.
There are 2 versions of client.
client, Sending messages using Spring Integration Rocket OutboundGateway.
client-requester Send messages using RSocketRequester, not use Spring Integration at all.
The client and server interaction mode is REQUEST_CHANNEL, and connect server via TCP/localhost:7000.
server
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-rsocket</artifactId>
</dependency>
The application class:
#Configuration
#ComponentScan
#IntegrationComponentScan
#EnableIntegration
public class DemoApplication {
public static void main(String[] args) throws IOException {
try (ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class)) {
System.out.println("Press any key to exit.");
System.in.read();
} finally {
System.out.println("Exited.");
}
}
#Bean
public ServerRSocketConnector serverRSocketConnector() {
return new ServerRSocketConnector("localhost", 7000);
}
#Bean
public IntegrationFlow rsocketUpperCaseFlow(ServerRSocketConnector serverRSocketConnector) {
return IntegrationFlows
.from(RSockets.inboundGateway("/uppercase")
.interactionModels(RSocketInteractionModel.requestChannel)
.rsocketConnector(serverRSocketConnector)
)
.<Flux<String>, Flux<String>>transform((flux) -> flux.map(String::toUpperCase))
.get();
}
}
server-boot
Dependencies in pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-rsocket</artifactId>
</dependency>
application.properties
spring.rsocket.server.port=7000
spring.rsocket.server.transport=tcp
Application class.
#SpringBootApplication
#EnableIntegration
public class DemoApplication {
public static void main(String[] args) throws IOException {
SpringApplication.run(DemoApplication.class, args);
}
// see PR: https://github.com/spring-projects/spring-boot/pull/18834
#Bean
ServerRSocketMessageHandler serverRSocketMessageHandler(RSocketStrategies rSocketStrategies) {
var handler = new ServerRSocketMessageHandler(true);
handler.setRSocketStrategies(rSocketStrategies);
return handler;
}
#Bean
public ServerRSocketConnector serverRSocketConnector(ServerRSocketMessageHandler serverRSocketMessageHandler) {
return new ServerRSocketConnector(serverRSocketMessageHandler);
}
#Bean
public IntegrationFlow rsocketUpperCaseFlow(ServerRSocketConnector serverRSocketConnector) {
return IntegrationFlows
.from(RSockets.inboundGateway("/uppercase")
.interactionModels(RSocketInteractionModel.requestChannel)
.rsocketConnector(serverRSocketConnector)
)
.<Flux<String>, Flux<String>>transform((flux) -> flux.map(String::toUpperCase))
.get();
}
}
server-boot-messagemapping
Dependencies in pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
The application.properties.
spring.rsocket.server.port=7000
spring.rsocket.server.transport=tcp
The applcition class.
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
#Controller
class UpperCaseHandler {
#MessageMapping("/uppercase")
public Flux<String> uppercase(Flux<String> input) {
return input.map(String::toUpperCase);
}
}
client
In the client, the dependencies in the pom.xml is like.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-rsocket</artifactId>
</dependency>
The application class:
#SpringBootApplication
#EnableIntegration
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public ClientRSocketConnector clientRSocketConnector() {
ClientRSocketConnector clientRSocketConnector = new ClientRSocketConnector("localhost", 7000);
clientRSocketConnector.setAutoStartup(false);
return clientRSocketConnector;
}
#Bean
public IntegrationFlow rsocketUpperCaseRequestFlow(ClientRSocketConnector clientRSocketConnector) {
return IntegrationFlows
.from(Function.class)
.handle(RSockets.outboundGateway("/uppercase")
.interactionModel((message) -> RSocketInteractionModel.requestChannel)
.expectedResponseType("T(java.lang.String)")
.clientRSocketConnector(clientRSocketConnector))
.get();
}
}
#RestController
class HelloController {
#Autowired()
#Lazy
#Qualifier("rsocketUpperCaseRequestFlow.gateway")
private Function<Flux<String>, Flux<String>> rsocketUpperCaseFlowFunction;
#GetMapping(value = "hello", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> uppercase() {
return rsocketUpperCaseFlowFunction.apply(Flux.just("a", "b", "c", "d"));
}
}
When running the client and server application, and try to access the http://localhost:8080/hello by curl.
When using server and server-boot which uses InboundGateway to handle messages, the output looks like this.
curl http://localhost:8080/hello
data:ABCD
When using server-boot-messagemapping, the output is woking as I expected:
data:A
data:B
data:C
data:D
client-requester
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
The application class:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
#RestController
class HelloController {
Mono<RSocketRequester> requesterMono;
public HelloController(RSocketRequester.Builder builder) {
this.requesterMono = builder.connectTcp("localhost", 7000);
}
#GetMapping(value = "hello", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> uppercase() {
return requesterMono.flatMapMany(
rSocketRequester -> rSocketRequester.route("/uppercase")
.data(Flux.just("a", "b", "c", "d"))
.retrieveFlux(String.class)
);
}
}
When running this client and the 3 servers, and try to access the http://localhost:8080/hello by curl.
When using server and server-boot which uses InboundGateway to handle messages, it throws a class cast exception.
When using server-boot-messagemapping, the output is woking as I expected:
data:A
data:B
data:C
data:D
I do not know where is the problem of the configuration of InboundGateway and OutboundGateway?
Thank you for such a detailed sample!
So, what I see. Both clients (plain RSocketRequester and Spring Integration) work well with plain RSocket server.
To make them working with Spring Integration server you have to do this changes:
The server side:
Add .requestElementType(ResolvableType.forClass(String.class)) into an RSockets.inboundGateway() definition, so it will know to what to convert an incoming payloads.
The client side:
.data(Flux.just("a\n", "b\n", "c\n", "d\n")).
Currently the server side of Spring Integration doesn't treat an incoming Flux as a stream of independent payloads. So, we try to connect all of them into a single value.
The new line delimiter is an indicator that we expect independent values. Spring Messaging on its side does exactly opposite: it checks for multi-value expected type and decode every element in the incoming Flux in its map() instead of an attempt for the whole Publisher decoding.
It's going to be kinda breaking change, but possibly need to consider to fix RSocketInboundGateway logic to be consistent with regular #MessageMapping for RSocket support. Feel free to raise a GH issue!
I'm trying to introduce Hystrix to my Spring Project, however when I add the following dependency to my pom (tried from 1.4.4 to latest version 2.1.1):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
I get the following exception:
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route queue-name-consumer: Route(queue-name-consumer)[[From[aws-sqs://u... because of The specified queue does not exist or you do not have access to it. (Service: AmazonSQS; Status Code: 400; Error Code: AWS.SimpleQueueService.NonExistentQueue)
at org.apache.camel.impl.RouteService.warmUp(RouteService.java:147) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doWarmUpRoutes(DefaultCamelContext.java:3949) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3856) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3642) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3494) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:209) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3253) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3272) ~[camel-core-2.22.2.jar:2.22.2]
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:3249) ~[camel-core-2.22.2.jar:2.22.2]
I am using:
- Spring Boot 2.0.5
- Camel 2.22.2
- AWS-Java-SDK 1.11.381
My SQS queues are configured in my spring app in the format
#Configuration
public class QueueConfig implements CamelContextAware {
private final AmazonSQSAsync amazonSQSClient;
private CamelContext camelContext;
#Autowired
public QueueConfig(AmazonSQSAsync amazonSQSClient) {
this.amazonSQSClient = amazonSQSClient;
}
#Override
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}
#Override
public CamelContext getCamelContext() {
return camelContext;
}
#Bean(name = "ExampleListenerBean)
public MessageListener<Exchange> amazonMessageListener(
RequestHandler handler,
Acknowledger<AmazonMessage> acknowledger) {
MessageListener<Exchange> listener =
new AmazonMessageListener<>(handler, acknowledger, new CamelSQSMessageConverter());
return listener;
}
#Bean(name = "ExampleRequestRouteDefinition")
public RouteBuilder exampleRouteDefinition(
#Qualifier(ExampleListenerBean) MessageListener<Exchange> listener) {
SqsQueueRouteProps properties =
SqsQueueRouteProps.main("queueDefinition", "path-to-queue").build();
String queue = properties.getFullQueueName();
return SqsQueueRouteBuilder.newBuilder(queue, amazonSQSClient, listener, getCamelContext())
.withRouteName("example-route-name")
.withProperties(properties)
.build();
}
This set up all works without the hystrix dependency, I'm not sure what incompatibilities to look for here, the error message is misleading because the queues exist there is a conflict somewhere I can not find.
Mention the version as well, and try this!
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
I have the following Spring Data MongoDb Repository Java configuration:
#EnableMongoRepositories(basePackages= {"com.example.repositories.mongodb"})
public class MongoConfig extends AbstractMongoConfiguration {
private #Value("${mongo.host}") String mongoHost;
private #Value("${mongo.port}") int mongoPort;
private #Value("${mongo.database}") String mongoDatabase;
#Override
protected String getDatabaseName() {
return mongoDatabase;
}
#Override
public Mongo mongo() throws Exception {
MongoClientOptions options = MongoClientOptions.builder()
.connectionsPerHost(100)
.connectTimeout(120000)
.socketTimeout(120000)
.maxWaitTime(1200000)
.threadsAllowedToBlockForConnectionMultiplier(1500)
.writeConcern(WriteConcern.ACKNOWLEDGED)
.build();
MongoClient client = new MongoClient(new ServerAddress(mongoHost, mongoPort), options);
return client;
}
public #Bean PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
I am trying to figure out if the writeConcern is really turned on due to some jUnits not working when running repeatedly. If I place a breakpoint after the client is created above and inspect the client object I can see its property WriteConcern equals:
{w=null, wTimeout=null ms, fsync=null, journal=null}
Which suggests to me that it was not set to ACKNOWLEDGED.
Am I setting it properly and is there a way to see if the correct concern is set? None of the logger options I tried made it output.
My dependencies are:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${spring.data.mongodb}</version>
</dependency>