I just created ElasticSearch class and find some codes for elasticsearch connection settings but i know i am using NEST 7.0 and these codes i found are lower version than 7.0 so, how i can change to current version because i am getting some errors. Thanks in advance.
private static readonly ConnectionSettings connSettings = new ConnectionSettings(new Uri("http://localhost:9200/"))
.DefaultIndex("change_history")
.DefaultMappingFor(m => m
.Add(typeof(ChangeLog), "change_history"));
private static readonly ElasticClient elasticClient = new ElasticClient(connSettings);
especially the defaultmapping part :)
The configuration options documentation has an example. Adapted for your example
private static readonly ConnectionSettings connSettings =
new ConnectionSettings(new Uri("http://localhost:9200/"))
.DefaultIndex("change_history")
.DefaultMappingFor<ChangeLog>(m => m
.IndexName("change_history")
);
private static readonly ElasticClient elasticClient = new ElasticClient(connSettings);
Related
I'm writing unit tests for a load balancer, the goal is to be able to filter out certain services based off its URI. However, the test always fails because it doesn't get the right URI at all! Here's the test class:
public class FilteringDiscoveryClientTest {
private static DiscoveryClient mockClient;
#BeforeAll
public static void setUp(){
SimpleDiscoveryProperties properties = new SimpleDiscoveryProperties();
Map<String, List<DefaultServiceInstance>> instances = new HashMap<>();
DefaultServiceInstance testInstance1_1 = new DefaultServiceInstance();
testInstance1_1.setUri(URI.create("http://my.service.id.1/1"));
testInstance1_1.setServiceId("my.service.id.1");
DefaultServiceInstance testInstance1_2 = new DefaultServiceInstance();
testInstance1_2.setUri(URI.create("http://my.service.id.1/2"));
testInstance1_2.setServiceId("my.service.id.1");
DefaultServiceInstance testInstance2_1 = new DefaultServiceInstance();
testInstance2_1.setUri(URI.create("http://my.service.id.2/1"));
testInstance2_1.setServiceId("my.service.id.2");
DefaultServiceInstance testInstance2_2 = new DefaultServiceInstance();
testInstance2_2.setUri(URI.create("http://my.service.id.2/2"));
testInstance2_2.setServiceId("my.service.id.2");
instances.put(
"my.service.id.1",
Arrays.asList(testInstance1_1, testInstance1_2)
);
instances.put(
"my.service.id.2",
Arrays.asList(testInstance2_1, testInstance2_2)
);
properties.setInstances(instances);
SimpleDiscoveryClient client = new SimpleDiscoveryClient(properties);
mockClient = client;
}
#Test
public void testGetServicesFilteringOutSingleService() {
FilteringDiscoveryClient client = new FilteringDiscoveryClient(
mockClient,
i -> !i.getUri().getAuthority().equals("my.service.id.1")
);
assertFalse(client.getServices().contains("my.service.id.1"), "list of services not expected to contain service 1");
assertTrue(client.getServices().contains("my.service.id.2"), "list of services expected to contain service 2");
}
}
the assertFalse fails because the i.getUri().getAuthority() returns null:80 instead of what the actual URI being passed is. It all seems to be set right according to the debugger during setup(). Any ideas where my test has gone wrong? Should I be setting URIs differently to begin with?
Edit: maybe I should add what the FilteringDiscoveryClient looks like
public class FilteringDiscoveryClient implements DiscoveryClient {
private final DiscoveryClient delegate;
private final Predicate<ServiceInstance> filter;
public FilteringDiscoveryClient(DiscoveryClient delegate, Predicate<ServiceInstance> filter) {
Assert.notNull(delegate, "delegate must not be null");
Assert.notNull(delegate, "filter must not be null");
this.delegate = delegate;
this.filter = filter;
}
#Override
public String description() {
return delegate.description();
}
#Override
public List<ServiceInstance> getInstances(String serviceId) {
return delegate.getInstances(serviceId).parallelStream().filter(filter).collect(Collectors.toList());
}
#Override
public List<String> getServices() {
return delegate.getServices().parallelStream().filter(s -> !getInstances(s).isEmpty()).collect(Collectors.toList());
}
}
maybe not an optimal solution but at least a workaround? Turns out that using .setUri() calls upon the overridden one within the class DefaultInstanceService, which does not set it the way I expected it to. It creates a new URI every time a new DefaultInstanceService is made from what I can tell, and that seems to not take the URI I give within setUri(). So I created constructors like so:
DefaultServiceInstance testInstance1_1 = new DefaultServiceInstance("http://my.service.id.1/1", "my.service.id.1", "my.service.id.1", -1, false);
DefaultServiceInstance testInstance1_2 = new DefaultServiceInstance("http://my.service.id.1/2", "my.service.id.1", "my.service.id.1", -1, false);
DefaultServiceInstance testInstance2_1 = new DefaultServiceInstance("http://my.service.id.2/1", "my.service.id.2", "my.service.id.2", -1, false);
DefaultServiceInstance testInstance2_2 = new DefaultServiceInstance("http://my.service.id.2/2", "my.service.id.2", "my.service.id.2", -1, false);
my tests work now but there is one small kink when trying to get the path, which I expected to be /2. Instead, no path is set at all because the setUri() within DefaultServiceInstance never sets a path explicitly, so it's always just an empty string. I cannot do calls like instance.getUri().getPath() because it will just give me an empty string back. To get to the "/2" I'm looking for I have to do instance.toString() and get it from there. All in all, not a great workaround but it's progress! If anyone has a better idea in the future I'd love to know.
I am trying to implement a OneToMany relationship inside my PCL using SQLite.net. I have the async extensions package (SQLiteNetExtensions.Async) and I am basing the code on the example found in https://bitbucket.org/twincoders/sqlite-net-extensions. I am using SQLiteAsyncConnection but the UpdateWithChildren method does not seem to be available, only with SQLiteConnection.
using SQLite.Net;
using SQLite.Net.Async;
using SQLite.Net.Interop;
using SQLiteNetExtensions.Extensions;
private readonly SQLiteAsyncConnection conn;
public ActivityRepository(ISQLitePlatform platform, string dbPath)
{
var connectionFactory = new Func<SQLiteConnectionWithLock>(() => new SQLiteConnectionWithLock(platform, new SQLiteConnectionString(dbPath, storeDateTimeAsTicks: true)));
conn = new SQLiteAsyncConnection(connectionFactory);
}
public void method(object object) {
conn.UpdateWithChildren(object); --function not available
}
When using SQLiteAsyncConnection, you have to use the async Nuget package, SQLiteNetExtensionsAsync.Extensions namespace and async versions of all the methods:
using SQLite.Net;
using SQLite.Net.Async;
using SQLite.Net.Interop;
using SQLiteNetExtensionsAsync.Extensions;
private readonly SQLiteAsyncConnection conn;
public ActivityRepository(ISQLitePlatform platform, string dbPath)
{
var connectionFactory = new Func<SQLiteConnectionWithLock>(() => new SQLiteConnectionWithLock(platform, new SQLiteConnectionString(dbPath, storeDateTimeAsTicks: true)));
conn = new SQLiteAsyncConnection(connectionFactory);
}
public Task method(object object) {
return conn.UpdateWithChildrenAsync(object);
}
Please note that all async methods return a Task that must be awaited or returned.
I am trying to wire up ElasticClient using ServiceStack's Funq, but I am getting a null reference exception when trying to call it.
Here is my set up:
In AppHost.cs:
var elasticSettings = new ConnectionSettings(new Uri("http://localhost:9200"), "listings");
var elasticClient = new ElasticClient(elasticSettings);
container.Register(elasticClient);
Then in my ServiceInterface project, in the ListingServices.cs class:
private ElasticClient Elastic; // also tried IElasticClient Elastic;
public object Post(CreateListing request)
{
Listing newAd = new Listing();
newAd = request.ConvertTo<Listing>();
using (IDbConnection db = DbFactory.Open())
{
db.Save(newAd);
Elastic.Index(newAd); // NULL REFERENCE EXCEPTION
}
return new CreateListingResponse { Result = true };
}
However Elastic is still set to Null & gives a null reference exception.
ANy ideas on how to resolve.
Property injection only works for public properties, so change the private field to:
public ElasticClient Elastic { get; set; }
Otherwise for private fields you need to instead use constructor injection.
looking for expert's help(i am newbie on elastic search)... have multiple nodes of elastic search.
i am using ElasticSearch java lib for indexing the json docs. would like to know how to handle the node balancing,is it possible to handle that from client side?
---elasticSearch transport client code------
public static Client getTransportClient(String host, int port) {
Settings settings = ImmutableSettings.settingsBuilder()
.put("cluster.name", "ccw_cat_es")
.put("node.name", "catsrch-pdv1-01")
.build();
return new TransportClient(settings).addTransportAddress(new InetSocketTransportAddress(host, port));
}
public static IndexResponse doIndex(Client client, String index, String type, String id, Map<String, Object> data) {
return client
.prepareIndex(index, type, id)
.setSource(data)
.execute()
.actionGet();
}
public static void main(String[] args) {
Client client = getTransportClient("catsrch-pdv1-01", 9200);
String index = "orderstatussearch";
String type = "osapi";
String id = null;
Map<String, Object> data = new HashMap<String, Object>();
data.put("OrderNumber", "444");
data.put("PO", "123");
data.put("WID", "ab234");
id= "444";
IndexResponse result = doIndex(client, index, type, id, data);
}
The TransportClient will automatically use a round robin strategy to load balance against nodes that it is connected too. In your case, you are only connecting to one node, so there is nothing to balance. You can add other nodes to the list and it will balance them appropriately.
Alternatively, you can "sniff" out the data nodes automatically by just connecting to one of them with an extra setting applied:
Settings settings = ImmutableSettings.settingsBuilder()
// ...
.put("client.transport.sniff", true)
// ...
.build()
This will then round robin against all data nodes that it finds in the cluster state.
This probably leads to the question: why isn't this the default? The reason is that, if you have standalone client nodes, then they are better proxies to the cluster rather than directly communicating with data nodes. For smaller clusters, this is a perfectly acceptable strategy though.
After reading questions and articles about using autofac with owin and webapi, I came across a solution to inject services but it does not work. Here is my code:
public class StartUp
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
var builder = new ContainerBuilder(); // Create the container builder.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // Register the Web API controllers.
var authcontext = new AuthContext();
builder.RegisterInstance(authcontext).AsSelf().SingleInstance();
//Updated
//var simpleauth = new SimpleAuthorizationServerProvider();
//Updated
// builder.RegisterInstance(simpleauth).SingleInstance().AsSelf().PropertiesAutowired();
builder.Register(x => new UserStore<IdentityUser>(authcontext)).As<IUserStore<IdentityUser>>();
//updated
builder.Register(x =>
{
var p = new SimpleAuthorizationServerProvider();
var userStore = x.Resolve<IUserStore<IdentityUser>>();
p.userManager = new UserManager<IdentityUser>(userStore);
return p;
}).AsSelf().PropertiesAutowired();
builder.RegisterType<AuthRepository>().As<IAuthRepository>().InstancePerRequest().PropertiesAutowired();
var container = builder.Build();
var resolver = new AutofacWebApiDependencyResolver(container); // Create an assign a dependency resolver for Web API to use.
config.DependencyResolver = resolver;
app.UseAutofacMiddleware(container);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
ConfigureOAuth(app, resolver);
}
public void ConfigureOAuth(IAppBuilder app, AutofacWebApiDependencyResolver resolver)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
//updated
Provider = new SimpleAuthorizationServerProvider()
//resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
But in SimpleAuthorizationServerProvider class, when a method like ValidateClientAuthentication is begin called, all the services are null, here is the code:
public readonly IAuthRepository repository;
public readonly UserManager<IdentityUser> userManager;
public readonly AuthContext dbContext;
public SimpleAuthorizationServerProvider()
{
}
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
if (context.TryGetFormCredentials(out clientId, out clientSecret))
{
try
{
Client client = await repository.FindClientById(clientId);
}
}
}
Would you help me please ?
Updated
If in ConfigureOAuth method I use the following approach:
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider
};
I get error:
An exception of type 'Autofac.Core.DependencyResolutionException' occurred in Autofac.dll but was not handled in user code
Additional information: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
When you register an instance of an object rather than a type, even if you specify PropertiesAutowired that will not take effect because Autofac assumes you've done all the work you want when you create the instance. If you want properties wired in, you need to do that in an OnActivated handler.
There are actually a lot of things at play in this sample code that will not work.
The values in SimpleAuthorizationServerProvider are fields not properties so PropertiesAutowired won't work on them.
The fields are marked readonly and they're never set.
You have UserManager<IdentityUser> registered as a lambda but also have PropertiesAutowired which won't work - you can only use PropertiesAutowired on a reflection-based component (e.g., RegisterType<T>).
Consider registering a lambda for your provider and set everything in the lambda:
builder.Register(c => {
var p = new SimpleAuthorizationServerProvider();
p.repository = c.Resolve<UserManager<IdentityUser>>();
// ...and so on
return p;
}).AsSelf().SingleInstance();
Also, keep in mind that if you register an instance (or register something as SingleInstance the properties will be resolved one time and that's it. So if you have some dependencies that are InstancePerDependency or InstancePerRequest, that's not going to work the way you think - they'll be resolved one time and effectively be singletons after that.
Update 1
Based on the original and updated code, it occurs to me that it would be good if you could check out some of the Autofac doc to understand better how it works. For example, the use of fields in SimpleAuthorizationServerProvider shows you may not totally get how injection works in Autofac or how to properly register things so Autofac can do the work for you.
Registration concepts
Web API integration
Working with per-request lifetime
For example, looking at the updates...
You now have a lambda registered for the SimpleAuthorizationServerProvider but I don't see where you set the repository field there.
You don't need PropertiesAutowired on the SimpleAuthorizationServerProvider registration because you're registering a lambda and the properties will not be autowired (as noted earlier).
The only component I see as being registered InstancePerRequest is the AuthRepository but, like I said, I don't see where that's being resolved or set - and that's the only thing that would generate the exception you noted. There is an FAQ on dealing with that exact exception that you should look into.
Also, you are showing two different versions of the OAuthServerOptions being initialized and it's hard to tell which one is "real."
I would recommend a fairly major refactoring to enable things to actually use DI correctly.
Change the SimpleAuthorizationServerProvider to stop using public fields and add them as constructor parameters so Autofac can wire the stuff up for you.
public class SimpleAuthorizationServerProvider
{
public IAuthRepository Repository { get; private set; }
public UserManager<IdentityUser> UserManager {get; private set; }
public AuthContext Context { get; private set; }
public SimpleAuthorizationServerProvider(
IAuthRepository repository,
UserManager<IdentityUser> userManager,
AuthContext context)
{
this.Repository = repository;
this.UserManager = userManager;
this.AuthContext = context;
}
}
During startup, fix your registrations to remove extraneous stuff and take advantage of the Autofac auto-wiring goodness.
public class StartUp
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// Register the auth context instance but skip
// the extra .AsSelf() and .SingleInstance() because
// it's implicit.
builder.RegisterInstance(new AuthContext());
// Use the lambda to resolve the auth context rather
// than making a closure over an instance.
builder.Register(c => new UserStore<IdentityUser>(c.Resolve<AuthContext>()))
.As<IUserStore<IdentityUser>>();
// Just register the provider type and let Autofac
// do the work without all this manual stuff. Skip
// the .AsSelf() because it's implicit if you don't
// specify other interfaces and don't auto-wire properties
// because you don't need it.
builder.RegisterType<SimpleAuthorizationProvider>();
// This is fine, but I can't tell where it's used - if
// you are using it at app startup or OUTSIDE a request,
// you will get that exception you noted. Also, unless
// you're actually using property injection, lose the
// .PropertiesAutowired() call.
builder.RegisterType<AuthRepository>()
.As<IAuthRepository>()
.InstancePerRequest()
.PropertiesAutowired();
var container = builder.Build();
var resolver = new AutofacWebApiDependencyResolver(container);
config.DependencyResolver = resolver;
app.UseAutofacMiddleware(container);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
ConfigureOAuth(app, resolver);
}
public void ConfigureOAuth(IAppBuilder app, AutofacWebApiDependencyResolver resolver)
{
var options = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
// If you want the values to be wired up, you have
// to do a resolve. Note, however, that since you're
// doing this wire-up at app startup, there's no request
// scope, so if something in here is registered `InstancePerRequest`
// you will get an exception.
Provider = resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider
};
app.UseOAuthAuthorizationServer(options);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
Under the assumption that's all the code you should be OK. If things aren't set - like one of the SimpleAuthorizationServerProvider properties comes through as null, or if you get an exception because it's missing a dependency, or if you get the exception about there being no request scope... then there's something else going on that you haven't put in your question.
Again, please take the time to check out the docs and familiarize yourself with Autofac. I think many of the troubles you're running into are the result of some misunderstanding on how things get wired up.