Neo4j ServerPlugin Configuration - neo4j

I'm building a Neo4J Server plugin. I'd like to have some configuration values that I can manually set in neo4j.properties or neo4j-server.properties and then the plugin can read and utilize these value. How can I access config values from a ServerPlugin?
Clarification:
I'd really like something that will work across future releases of Neo4J, so something that is part of the public API and is not deprecated would be best.

Using Neo4j's internal dependency mechanism, you can access a instance of Config (https://github.com/neo4j/neo4j/blob/master/community/kernel/src/main/java/org/neo4j/kernel/configuration/Config.java). This class gives you access to the configuration.
Take the following untested snippet as a guideline:
...
import org.neo4j.kernel.configuration.Config
...
#Description( "An extension to the Neo4j Server accessing config" )
public class ConfigAwarePlugin extends ServerPlugin
{
#Name( "config" )
#Description( "Do stuff with config" )
#PluginTarget( GraphDatabaseService.class )
public void sample( #Source GraphDatabaseService graphDb ) {
Config config = ((GraphDatabaseAPI)graphDb).getDependencyResolver().resolveDependency(Config.class);
// do stuff with config
}
}

I use Properties:
Properties props = new Properties();
try
{
FileInputStream in = new FileInputStream("./conf/neo4j.properties");
props.load(in);
}
catch (FileNotFoundException e)
{
try
{
FileInputStream in = new FileInputStream("./neo4j.properties");
props.load(in);
}
catch (FileNotFoundException e2)
{
logger.warn(e2.getMessage());
}
catch (IOException e2)
{
logger.warn(e2.getMessage());
}
}
catch (IOException e)
{
logger.warn(e.getMessage());
}
String myPropertyString = props.getProperty("myProperty");
if (myPropertyString != null)
{
myProperty = Integer.parseInt(myPropertyString);
}
else
{
myProperty = 100;
}
and in neo4j.properties I have:
...
# Enable shell server so that remote clients can connect via Neo4j shell.
#remote_shell_enabled=true
# Specify custom shell port (default is 1337).
#remote_shell_port=1234
myProperty=100

Related

Azure Cosmos: Register Stored Procedure If not exist already

I want to register and execute stored proc. I am using spring+Java with cosmos DB. Everytime I stop my application and restart it , it tried to create new sproc and since it already exists in cosmos DB it fails with below error . Is their any option available like "only create if not exist". I am fetching js file from src/main/resources folder.
I am following below doc to register the stored proc
https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/how-to-use-stored-procedures-triggers-udfs?tabs=java-sdk
#Configuration
public class StoredProcConfig
{
#Autowired
#Qualifier(BeansConstants.PAYMENT_CONTAINER)
CosmosContainer container;
#Bean
public CosmosStoredProcedureResponse registerSp() throws IOException
{
InputStream is = getFileFromResourceAsStream("storedProcedures/createStudent.js");
CosmosStoredProcedureProperties definition = new CosmosStoredProcedureProperties("spCreateToDoItems",
IOUtils.toString(is, StandardCharsets.UTF_8));
return container.getScripts().createStoredProcedure(definition);
}
private InputStream getFileFromResourceAsStream(String fileName)
{
// The class loader that loaded the class
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(fileName);
// the stream holding the file content
if (inputStream == null)
{
throw new IllegalArgumentException("file not found! " + fileName);
} else
{
return inputStream;
}
}
}
Error
Caused by: com.azure.cosmos.CosmosException: {"innerErrorMessage":"Message: {\"Errors\":[\"Resource with specified id, name, or unique index already exists.\"]}
Modify your registerSp() bean as below:
private static final Logger logger = LoggerFactory.getLogger(CosmosConfiguration.class);
#Bean
public CosmosStoredProcedureResponse registerSp() throws IOException
{
InputStream is = getFileFromResourceAsStream("storedProcedures/createStudent.js");
CosmosStoredProcedureProperties definition = new CosmosStoredProcedureProperties("spCreateToDoItems",
IOUtils.toString(is, StandardCharsets.UTF_8));
return createStoredProcedureIfNotExists(definition);
}
public CosmosStoredProcedureResponse createStoredProcedureIfNotExists(CosmosStoredProcedureProperties definition){
try {
CosmosStoredProcedureResponse storedProc = container.getScripts().getStoredProcedure(definition.getId()).read();
logger.info("found stored proc");
return storedProc;
}
catch (CosmosException e){
logger.info("stored proc not found, creating....");
return container.getScripts().createStoredProcedure(definition);
}
}

How to configure Micronaut and Micrometer to write ILP directly to InfluxDB?

I have a Micronaut application that uses Micrometer to report metrics to InfluxDB with the micronaut-micrometer project. Currently it is using the Statsd Registry provided via the io.micronaut.configuration:micronaut-micrometer-registry-statsd dependency.
I would like to instead output metrics in Influx Line Protocol (ILP), but the micronaut-micrometer project does not offer an Influx Registry currently. I tried to work around this by importing the io.micrometer:micrometer-registry-influx dependency and configuring an InfluxMeterRegistry manually like this:
#Factory
public class MyMetricRegistryConfigurer implements MeterRegistryConfigurer {
#Bean
#Primary
#Singleton
public MeterRegistry getMeterRegistry() {
InfluxConfig config = new InfluxConfig() {
#Override
public Duration step() {
return Duration.ofSeconds(10);
}
#Override
public String db() {
return "metrics";
}
#Override
public String get(String k) {
return null; // accept the rest of the defaults
}
};
return new InfluxMeterRegistry(config, Clock.SYSTEM);
}
#Override
public boolean supports(MeterRegistry meterRegistry) {
return meterRegistry instanceof InfluxMeterRegistry;
}
}
When the application runs, the metrics are exposed on my /metrics endpoint as I would expect, but nothing gets written to InfluxDB. I confirmed that my local InfluxDB accepts metrics at the expected localhost:8086/write?db=metrics endpoint using curl. Can anyone give me some pointers to get this working? I'm wondering if I need to manually define a reporter somewhere...
After playing around for a bit, I got this working with the following code:
#Factory
public class InfluxMeterRegistryFactory {
#Bean
#Singleton
#Requires(property = MeterRegistryFactory.MICRONAUT_METRICS_ENABLED, value =
StringUtils.TRUE, defaultValue = StringUtils.TRUE)
#Requires(beans = CompositeMeterRegistry.class)
public InfluxMeterRegistry getMeterRegistry() {
InfluxConfig config = new InfluxConfig() {
#Override
public Duration step() {
return Duration.ofSeconds(10);
}
#Override
public String db() {
return "metrics";
}
#Override
public String get(String k) {
return null; // accept the rest of the defaults
}
};
return new InfluxMeterRegistry(config, Clock.SYSTEM);
}
}
I also noticed that an InfluxMeterRegistry will be available out of the box in the future for micronaut-micrometer as of v1.2.0.

Graph Database Not updated Neo4j

I am using neo4j version 3.1.0 . i have created 20 million graph.Each graph consists of 9 nodes with their respective properties.I am using embedded mode (api 3.1.0) .I am trying to change the property of a node .In the runtime I changed property of a node but it is not reflecting in the database when i am trying to fetch the node property using neo4j shell.
The database size is almost 20GB.I am running it on a server. i Guess that the changes are taking place in cache but it is not reflected in graph database.What changes should i make to get updated in the graph database???
try(Transaction tx=GraphCreation.getInstance().dbService.beginTx()){
Node n= GraphCreation.getInstance().dbService.findNode(MyLabels.IMSI,"IMSI" ,"A"+0);
n.setProperty("MSISDN", "Z"+0);
tx.success(); // commit
} catch(Exception e)
{
e.printStackTrace();
}
try(Transaction tx=GraphCreation.getInstance().dbService.beginTx())
{
String cql ="match(a:IMSI{IMSI : 'A0'}) return a.MSISDN";
Result result= GraphCreation.getInstance().dbService.execute(cql);
while ( result.hasNext() )
{
Map<String, Object> row = result.next();
for ( String key : result.columns() )
{
System.out.printf( "%s = %s%n", key, row.get( key ) );
}
}
tx.success();
timerContext.close();
} catch(Exception e)
{
e.printStackTrace();
}
The issue has been solved .Graph DB hasn't been shutdown properly when trying to stop the code by pressing Cntrl +C.Hence to handle this case add this snippet to your code.
private static void registerShutdownHook( final GraphDatabaseService graphDb )
{
// Registers a shutdown hook for the Neo4j instance so that it
// shuts down nicely when the VM exits (even if you "Ctrl-C" the
// running application).
Runtime.getRuntime().addShutdownHook( new Thread()
{
#Override
public void run()
{
graphDb.shutdown();
}
} );
}

How to get application port programmatically in Dropwizard

I am using dropwizard version 0.7.1. It is configured to use "random" (ephemeral?) port (server.applicationConnectors.port=0). I want to get what port is really in use after startup, but I can't find any information how to do that.
You can get a serverStarted callback from a lifecycle listener to figure this out.
#Override
public void run(ExampleConfiguration configuration, Environment environment) throws Exception {
environment.lifecycle().addServerLifecycleListener(new ServerLifecycleListener() {
#Override
public void serverStarted(Server server) {
for (Connector connector : server.getConnectors()) {
if (connector instanceof ServerConnector) {
ServerConnector serverConnector = (ServerConnector) connector;
System.out.println(serverConnector.getName() + " " + serverConnector.getLocalPort());
// Do something useful with serverConnector.getLocalPort()
}
}
}
});
}
I find this approach worked well for me with both the Simple and Default server configurations in Dropwizard.
public void run(ExampleConfiguration configuration, Environment environment) throws Exception {
Stream<ConnectorFactory> connectors = configuration.getServerFactory() instanceof DefaultServerFactory
? ((DefaultServerFactory)configuration.getServerFactory()).getApplicationConnectors().stream()
: Stream.of((SimpleServerFactory)configuration.getServerFactory()).map(SimpleServerFactory::getConnector);
int port = connectors.filter(connector -> connector.getClass().isAssignableFrom(HttpConnectorFactory.class))
.map(connector -> (HttpConnectorFactory) connector)
.mapToInt(HttpConnectorFactory::getPort)
.findFirst()
.orElseThrow(IllegalStateException::new);
}

Modify tokenizer in ANTLR

In ANTLR, how to make output the tokens one by one following like push "enter" in keyboard that I try to a class named hello.java like this
public class Hello{
public static void main(String args[]){
System.out.println("Hello World ...");
}
}
Now, it is time to parse the tokens
final Antlr3JavaLexer lexer = new Antlr3JavaLexer();
try {
lexer.setCharStream(new ANTLRReaderStream(in)); // in is a file
} catch (IOException e) {
e.printStackTrace();
}
final CommonTokenStream tokens = new CommonTokenStream();
tokens.setTokenSource(lexer);
tokens.LT(10); // force load
Antlr3JavaParser parser = new Antlr3JavaParser(tokens);
System.out.println(tokens);
it gives me an output like this,
publicclassHello{publicstaticvoidmain(Stringarggs[]){System.out.println("Hello World ...");}}
How to make an output looked like this
public
class
Hello
{
public
static ... untill the end...
I've try using Stringbuilder, but it's not working.
Thanks 4 the help..
Instead of just printing out tokens, you have to iterate over tokenstream to get back desired result.
Modify your code like this.
final Antlr3JavaLexer lexer = new Antlr3JavaLexer();
try {
lexer.setCharStream(new ANTLRReaderStream(in)); // in is a file
} catch (IOException e) {
e.printStackTrace();
}
final CommonTokenStream tokens = new CommonTokenStream();
tokens.setTokenSource(lexer);
//tokens.LT(10); // force load - not needed
Antlr3JavaParser parser = new Antlr3JavaParser(tokens);
// Iterate over tokenstream
for (Object tk: tokens.getTokens())
{
CommonToken commontk = (CommonToken) tk;
if (commontk.getText() != null && commontk.getText().trim().isEmpty() == false)
{
System.out.println(commontk.getText());
}
}
After this, You will get this result.
public
class
Hello
{
public
static ... etc...
Hope this will solve your issue.

Resources