Alfresco SDK code hanging at AuthenticationUtils.startSession - sdk

i am testing the code from SDK to call Alfresco on bitNami Alresco 4.0.e-0 server with a webapp that is located on same tomcat server as Alfresco. The code hangs at the very first call to AuthenticationUtils to get session. I pretty am sure i supplied the standard bitNami Alfresco user and password for this. Did i miss any libraries? I put most available dependencies as my local maven repositories and code compiles well.
the following is code from SDK without Alfresco license as i could not format the code with it:
package org.alfresco.sample.webservice;
import org.alfresco.webservice.repository.RepositoryServiceSoapBindingStub;
import org.alfresco.webservice.types.Store;
import org.alfresco.webservice.util.AuthenticationUtils;
import org.alfresco.webservice.util.WebServiceFactory;
public class GetStores extends SamplesBase
{
/**
* Connect to the respository and print out the names of the available
*
* #param args
*/
public static void main(String[] args)
throws Exception
{
// Start the session
AuthenticationUtils.startSession(USERNAME, PASSWORD);
try
{
// Get the respoitory service
RepositoryServiceSoapBindingStub repositoryService = WebServiceFactory.getRepositoryService();
// Get array of stores available in the repository
Store[] stores = repositoryService.getStores();
if (stores == null)
{
// NOTE: empty array are returned as a null object, this is a issue with the generated web service code.
System.out.println("There are no stores avilable in the repository.");
}
else
{
// Output the names of all the stores available in the repository
System.out.println("The following stores are available in the repository:");
for (Store store : stores)
{
System.out.println(store.getScheme() + "://" + store.getAddress());
}
}
}
finally
{
// End the session
AuthenticationUtils.endSession();
}
}
}

The WebServiceFactory uses
http://localhost:8080/alfresco/api
as default endpoint.You can change the endpoint by providing a file called webserviceclient.properties on the classpath under alfresco (the resource path: alfresco/webserviceclient.properties)
The properties file must offer a property called repository.location, which specifies the endpoint URL. Since you are using a bitnami Alfresco instance, it is probably running on port 80. The file should contain the following property entry:
repository.location=http://localhost:80/alfresco/api

Related

Generate OpenAPI descriptions from JavaDoc

I have an application which provides an API with JAX-RS (Java API for RESTful Web Services / JSR-311).
For documentation purposes I provide an URL according to the OpenAPI-Specification, which is generated by Eclipse MicroProfile OpenAPI.
Everything is working fine, except the descriptions of the methods and parameters, which I need to add twice - in annotations and in JavaDoc:
/**
* Finds all resources with the given prefix.
*
* #param prefix
* the prefix of the resource
* #return the resources that start with the prefix
*/
#GET
#Path("/find/{prefix}")
#Produces(MediaType.APPLICATION_JSON)
#Operation(description = "Finds all resources with the given prefix")
public List<Resource> find(
#Parameter(description = "The prefix of the resource")
#PathParam("prefix") final String prefix) {
...
}
I know that no runtime library can read the JavaDoc (because it is not part of the class files), which is the main reason for the annotations. But I wonder if there is some other option for one of the OpenAPI generation tools (Swagger, Eclipse MicroProfile OpenAPI, ...), which prevents me from manually syncing the documentation?
In another project for example I'm using a doclet which serializes the JavaDoc and stores it in the class path, to present an Beans API documentation to the user at runtime. But even if I make use of this doclet here, I see no option to provide that JavaDoc descriptions to the OpenAPI libraries during runtime.
I know that I could drop the JavaDoc, if the users of my API use only "foreign languages", as they wouldn't see the JavaDoc anyway. But what happens if the other side of the API is a JAX-RS client? In that case the JavaDoc would be a huge support.
I got it running with Eclipse Microprofile OpenAPI.
I had to define my own OASFilter:
public class JavadocOASDescriptionFilter implements OASFilter {
#Override
public void filterOpenAPI(final OpenAPI openAPI) {
openAPI.getComponents().getSchemas().forEach(this::initializeSchema);
openAPI.getPaths().forEach(this::initializePathItem);
}
private void initializeSchema(final String name, final Schema schema) {
final SerializedJavadoc javadoc = findJavadocForSchema(name);
if (StringUtils.isEmpty(schema.getDescription())) {
schema.setDescription(javadoc.getTypeComment());
}
if (schema.getProperties() != null) {
schema.getProperties().forEach((property, propertySchema) -> {
if (StringUtils.isEmpty(propertySchema.getDescription())) {
propertySchema.setDescription(javadoc.getAttributeComments().get(property));
}
});
}
}
...
}
Then I had to declare that filter in META-INF/microprofile-config.properties:
mp.openapi.filter=mypackage.JavadocOASDescriptionReader
See here for the discussion on this topic: https://github.com/eclipse/microprofile-open-api/issues/485

How to get Redis key values on Server side Dart with Angel

Having moved my mobile app development to Flutter I am now in the process of experimenting with using Dart as my main server side language. The productivity benefits in using a single coding language in both the app and on the server are considerable. To that end I have set up a server with an Nginx front end which proxies all dynamic web requests to an Angel/Dart server.
Angel is a remarkably well written package and I had a working server written up in no time at all. However, in order to have a fully functional backend I need to be able to use both Redis and PostgreSQL from within my server side Dart code. I am using the resp_client package to access Redis. The issue I have run into is with the fact that RespCommand.get is asynchronous. With my newbie knowledge of both Dart and Angel I am unable to find a way to acquire a Redis key value via RespCommand.get in an Angel route handler and then somehow use that value in the response it returns.
My entire Dart backend server code is shown below
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/http.dart';
import 'package:postgres/postgres.dart';
import 'package:resp_client/resp_client.dart';
import 'package:resp_client/resp_commands.dart';
class DartWeb
{
static Angel angel;
static AngelHttp http;
static RespCommands redis;
static PostgreSQLConnection db;
static init() async
{
angel = Angel();
http = AngelHttp(angel);
angel.get('/',rootRoute);
await prepareRedis();
await http.startServer('localhost',3000);
}
static prepareRedis() async
{
RespServerConnection rsc = await connectSocket('localhost');
RespClient client = RespClient(rsc);
redis = RespCommands(client);
}
static preparePostgres() async
{
db = new PostgreSQLConnection('serverurl',portNo,'database',username:'user',password:'password');
await db.open();
}
static void rootRoute(RequestContext req,ResponseContext res)
{
try
{
await redis.set('test','foobar',expire:Duration(seconds:10));
String testVal = await redis.get('test');
res.write('Done $testVal');
} catch(e) {res.write('++ $e ++');}
}
}
main() async {await DartWeb.init();}
If I start up this server and then access it through my web browser I end up with a 502 Bad Gateway message. Not surprising. dart2native main.dart -o mainCompiled returns the error await can only be used in async... message.
So I tried instead
try
{
res.write('Before');
redis.set('test','foobar',expire:Duration(seconds:10)).then((bool done)
{
res.write('DONE $done');
});
res.write('After');
} catch(e) {res.write('++ $e ++');}
which simply printed out BeforeAfter in my browser with the DONE bit never showing up although a quick test via redis-cli shows that the key test had in fact been created.
My knowledge of both Dart and Angel is still in its infancy so I guess I am doing something incorrectly here. Shorn of all the detail my questions are essentially these -
how do I call and get the result from async methods in an Angel route dispatcher?
given that I am editing my Dart code in VSCode on my local Windows machine which accesses the relevant dart files on my Ubuntu server I loose the benefits of error reporting provided by the VSCode Dart plugin. dart2native, as I have used here, helps out but it would be nicer if I could somehow get a running error report within VSCode as I do when building Flutter apps locally. How can I accomplish this - if at all possible?
It turns out that Dart/Angel does not impose excessively strict constraints on the signature of a route handler. So you can quite safely declare a route handler like this one
static Future<void> rootRoute(RequestContext req,ResponseContext res) async
{
try
{
res.write('!! Before ');
await redis.set('test','foobar',expire:Duration(seconds:10));
String test = await redis.get('test');
res.write('After $test !!');
} catch(e) {res.write('++ $e ++');}
}
With the route simply returning a Future we can now safely do anything we like there - including calling other asynchronous methods: in this instance to fetch a Redis key value.

Strip prefix to remove the environment passed in URL

My frontend application attaches an environment attribute as a prefix in the URI -- I am having difficulty getting Zuul to strip this prefix.
For example, the frontend application is making a request to Zuul proxy locally http://localhost:9080/local/domains/metrs/subdomains/medicare/base-templates/. Zuul needs to strip out the environment "local" as seen in the URL and then forward to the web service located (with the environment "local" stripped) at http://localhost:9090/icews/admin/domains/metrs/subdomains/medicare/base-templates/
Unfortunately, I get a 404 error because the prefix "local" is not being stripped -- when reading the logs on the server hosting the web service, I still see the environment "local" forwarded in the call.
Here is my Zuul configuration:
ice.ws.local.url=http://localhost:9090/icews/admin
ice.ws.dev.url=http://developmentserver/icews/admin
zuul.routes.base-templates.path=/local/**/base-templates/**
zuul.routes.base-templates.url=${ice.ws.local.url}
zuul.routes.base-templates.strip-prefix=true
zuul.routes.base-templates.path=/dev/**/base-templates/**
zuul.routes.base-templates.url=${ice.ws.dev.url}
zuul.routes.base-templates.strip-prefix=true
UPDATE
I went ahead and used the approach as outlined here: https://github.com/spring-cloud/spring-cloud-netflix/issues/1893 and https://github.com/spring-cloud/spring-cloud-netflix/issues/2408
I did not use the strip-prefix in the application.properties but instead followed the approach outlined here https://github.com/spring-cloud/spring-cloud-netflix/issues/1893
Specifically for my case where I have a frontend that needs to route on different environments (each being a different microservice), I have another Zuul filter that runs in order 6 (PRE_DECORATION_FILTER_ORDER + 1):
#Component
public class PostDecorFilter extends ZuulFilter {
#Value("${zuul.PostSendResponseCustomFilter.post.disable:false}")
private boolean isDisableFilter;
#Override
public int filterOrder() {
// run this filter after zuul..PreDecorationFilter
return PRE_DECORATION_FILTER_ORDER + 1;
}
#Override
public String filterType() {
return PRE_TYPE;
}
#Override
public boolean shouldFilter() {
return !isDisableFilter;
}
/**
* Add custom response processing here
*
* #return
*/
#Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
// environment is added by frontend Angular app, e.g. dev, dev-t, qa, qa-t
String environment = RequestContext.getCurrentContext().getRequest().getRequestURI().split("/")[1];
if ( "dev".equals(environment) || "dev-t".equals(environment) || "qa".equals(environment) || "qa-t".equals(environment) ) {
// e.g. /dev/some/resource/
String requestUriWithEnvironment = RequestContext.getCurrentContext().getRequest().getRequestURI();
// e.g. /some/resource/
String requestUriWithoutEnvironment =
requestUriWithEnvironment.substring(environment.length() + 1);
context.put(REQUEST_URI_KEY, requestUriWithoutEnvironment);
}
return null;
}
I also had to use a CustomRouteLocator as outlined here: https://github.com/spring-cloud/spring-cloud-netflix/issues/2408
The reason is that the paths in application.properties are
ice.ws.local.url=http://localhost:9090/icews/admin
ice.ws.dev.url=http://developmentserver/icews/admin
zuul.routes.base-templates.path=/local/**/base-templates/**
zuul.routes.base-templates.url=${ice.ws.local.url}
zuul.routes.base-templates.path=/dev/**/base-templates/**
zuul.routes.base-templates.url=${ice.ws.dev.url}
Essentially, I was experiencing the same behavior as outlined here: "it seems that SimpleRouteLocator iterates over all routes, not in the order they're in config file and just pick the first match" https://github.com/spring-cloud/spring-cloud-netflix/issues/2408

Configure bitbucket plugin to avoid hardcoding of secure variable

I have developed an Atlasian Bitbucket plugin which globally listens for push/PR and send repository details to databases using REST API.
I need to configure REST API URL and credential so that my plugin can make an API call. Currently I have hardcoded REST API URL and credential in my plugin properties file. Which I don't like because every time if I need to create a package to target my test environment or production, I have to change. Also, I don't like to keep credentials in the source code.
What is the best way to add configuration screen in the bitbucket plugin? I would like to have form for URL, username and password (once I installed the plugin) and update the storage in Bitbucket only once. If I need to restart my bitbucket, I do not want to lose saved data.
I tried to search on how to configure a bitbucket plugin, however I could not find an easy way. I do see multiple approaches, for example to add "Configure" button which will open a servelet to take user input. Seems very cryptic to me. Also, I see so many recommendations for template, for example velocity, soy etc which confused me a lot.
Since I am new to plugin development therefore not able to explore. Looking for some help.
I have solution for this case:
From pom.xml please add more library:
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-core</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
Create new abc-server.properties on resources/ folder with following content:
server.username=YOUR_USERNAME
server.password=YOUR_PASSWORD
Get value from abc-server.properties on service class as the following:
import com.atlassian.plugin.util.ClassLoaderUtils;
...
final Properties p = new Properties();
final InputStream is = ClassLoaderUtils.getResourceAsStream("abc-server.properties", this.getClass());
try {
if (is != null) {
p.load(is);
String username = p.getProperty("server.username");
String password = p.getProperty("server.password");
}
} catch (IOException e) {
e.printStackTrace();
}
Please try to implement it. Thanks!
One possibility for a simple configuration file, is to read somefile.properties from the Bitbucket home directory, this way the config file will survive application updates.
Create somefile.properties in BITBUCKET_HOME
server.username=YOUR_USERNAME
server.password=YOUR_PASSWORD
Read the properties in your plugin class like this
// imports
import com.atlassian.bitbucket.server.StorageService;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
private final StorageService storageService;
// StorageService injected via constructor injection
public SomePlugin(#ComponentImport final StorageService storageService) {
this.storageService = storageService;
}
Properties p = new Properties();
File file = new File(storageService.getHomeDir().toString(), "somefile.properties");
FileInputStream fileInputStream;
try {
fileInputStream = new FileInputStream(file);
p.load(fileInputStream);
String username = p.getProperty("server.username");
String password = p.getProperty("server.password");
} catch (IOException e) {
//handle exception
}

Access Neo4j in server mode with EmbeddedGraphDatabase?

If I run neo4j in server mode so it is accessible using the REST API, can I access the same neo4j instance with EmbeddedGraphDatabase-class?
I am thinking of a production setup where a Java-app using EmbeddedGraphDatabase is driving the logic, but other clients might navigate the data with REST in readonly mode.
What you are describing is a server plugin or extension. That way you expose your database via the REST API but at the same time you can access the embedded graph db hihgly performant from your custom plugin/extension code.
In your custom code you can get a GraphDatabaseService injected on which you operate.
You deploy your custom extensions as jars with your neo4j-server and have client code operate over a domain oriented restful API with it.
// extension sample
#Path( "/helloworld" )
public class HelloWorldResource {
private final GraphDatabaseService database;
public HelloWorldResource( #Context GraphDatabaseService database) {
this.database = database;
}
#GET
#Produces( MediaType.TEXT_PLAIN )
#Path( "/{nodeId}" )
public Response hello( #PathParam( "nodeId" ) long nodeId ) {
// Do stuff with the database
return Response.status( Status.OK ).entity(
( "Hello World, nodeId=" + nodeId).getBytes() ).build();
}
}
Docs for writing plugins and extensions.

Resources