graphql .NET core solution - unable to include related objects - graphql

I am a newbie to graphql, and use it in a .Net core solution. My solution includes an SQlite-database, that may be accessed via a manager. I use the manager in the resolver functions in my GraphTypes. In the models, I have a class 'Ticket' and a class 'TicketResponse' - one ticket includes a list of ticketResponses.
The problem is that I am unable to include the nested data of an ObjectGraphType. Here's my code:
namespace SupportCenter.Schema.GraphQLTypes
{
public class TicketType : ObjectGraphType<Ticket>
{
public TicketType(ITicketManager manager)
{
Name = "Ticket";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The id of the ticket");
Field(x => x.AccountId).Description("THe account the ticket was issued from");
Field(x => x.Text).Description("The description of the problem");
Field(x => x.DateOpened).Description("The date the ticket was opened");
Field<TicketStateEnum>("state", resolve: context => context.Source.State);
Field<ListGraphType<TicketResponseType>>("ticketresponses",
resolve: context => manager.GetTicketResponses(context.Source.Id));
}
}
}
The error I get is the following:
"GraphQL.ExecutionError: No service for type
'GraphQL.Types.ObjectGraphType1[SupportCenter.Schema.GraphQLTypes.TicketType]'
has been registered. ---> System.InvalidOperationException: No service
for type
'GraphQL.Types.ObjectGraphType1[SupportCenter.Schema.GraphQLTypes.TicketType]'
has been registered.\n at
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider
provider, Type serviceType)\n at
GraphQL.Types.Schema.b__56_2(Type type)\n at
GraphQL.Types.GraphTypesLookup.AddTypeIfNotRegistered(Type type,
TypeCollectionContext context)\n at
GraphQL.Types.GraphTypesLookup.HandleField(Type parentType, FieldType
field, TypeCollectionContext context)\n at
GraphQL.Types.GraphTypesLookup.AddType(IGraphType type,
TypeCollectionContext context)\n at
GraphQL.Types.GraphTypesLookup.HandleField(Type parentType, FieldType
field, TypeCollectionContext context)\n at
GraphQL.Types.GraphTypesLookup.AddType(IGraphType type,
TypeCollectionContext context)\n at
GraphQL.Types.GraphTypesLookup.HandleField(Type parentType, FieldType
field, TypeCollectionContext context)\n at
GraphQL.Types.GraphTypesLookup.AddType(IGraphType type,
TypeCollectionContext context)\n at
GraphQL.Types.GraphTypesLookup.Create(IEnumerable1 types,
IEnumerable1 directives, Func2 resolveType, IFieldNameConverter
fieldNameConverter)\n at
System.Lazy1.ViaFactory(LazyThreadSafetyMode mode)\n--- End of stack
trace from previous location where exception was thrown ---\n at
System.Lazy`1.CreateValue()\n at
GraphQL.Types.Schema.get_AllTypes()\n at
GraphQL.Instrumentation.FieldMiddlewareBuilder.ApplyTo(ISchema
schema)\n at GraphQL.DocumentExecuter.ExecuteAsync(ExecutionOptions
options)\n --- End of inner exception stack trace ---",
I have registered both the TicketType and the TicketResponseType in the services in the startup-file. Any ideas what I'm doing wrong?
Here's my startup-file:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<SupportCenterDbContext>();
services.AddSingleton<TicketType>();
services.AddSingleton<TicketInputCreateType>();
services.AddSingleton<TicketResponseType>();
services.AddSingleton<TicketStateEnum>();
services.AddSingleton<ResponseQuery>();
services.AddSingleton<ITicketManager, TicketManager>();
services.AddSingleton<SupportCentreQuery>();
services.AddSingleton<TicketsQuery>();
services.AddSingleton<TicketsMutation>();
services.AddSingleton<SupportCentreSchema>();
services.AddSingleton<IDependencyResolver>(
c => new FuncDependencyResolver(c.GetRequiredService));
services.AddSingleton<IDocumentExecuter, DocumentExecuter>();
services.AddSingleton<IDocumentWriter, DocumentWriter>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IGraphQLExecuter<SupportCentreSchema>, DefaultGraphQLExecuter<SupportCentreSchema>>();
services.AddGraphQL(options =>
{
options.EnableMetrics = true;
options.ExposeExceptions = true;
})
.AddWebSockets()
.AddDataLoader();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseGraphQL<SupportCentreSchema>("/graphql");
app.UseGraphiQLServer(new GraphiQLOptions
{
GraphiQLPath = "/ui/graphiql",
GraphQLEndPoint = "/graphql"
});
app.UseMvc();
}
}

Related

How to create system wide retry policy in MassTransit and modify/overwrite it in specific consumer?

I would like to create system wide retry policy (retry x times every y seconds) but modify/overwrite it in specific consumer (some exception should be ignored and moved to error queue without retry)
I was thinking that something like this should work(bus configuration part):
services.AddMassTransit<T>(
massTransit =>
{
massTransit.UsingRabbitMq(
(context, cfg) =>
{
cfg.UseMessageRetry(r =>
{
r.Intervals(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30));
});
....
massTransit.AddConsumers(assembly);
consumer definition part:
public class DoSomethingConsumerDefinition :
ConsumerDefinition<DoSomethingConsumer>
{
protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
IConsumerConfigurator<DoSomethingConsumer> consumerConfigurator)
{
endpointConfigurator.UseMessageRetry(r =>
{
r.Ignore<DoSomethingSpecificException>();
r.Intervals(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30));
});
}
}
I can't achieve it this way. DoSomethingSpecificException is retried using global policy.
What is the correct way to achieve it?
When configuring multiple retry policies, which is what happens in this case, you'd need to ensure that exceptions you do not want retried are properly overridden. If you ignore the exception, it isn't handled by the retry filter, so you'd need to handle it with no retry:
public class DoSomethingConsumerDefinition :
ConsumerDefinition<DoSomethingConsumer>
{
protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
IConsumerConfigurator<DoSomethingConsumer> consumerConfigurator)
{
endpointConfigurator.UseMessageRetry(r =>
{
r.Handle<DoSomethingSpecificException>();
r.None();
});
endpointConfigurator.UseMessageRetry(r =>
{
r.Ignore<DoSomethingSpecificException>();
r.Intervals(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30));
});
}
}
With the None retry filter, it would signify that exception should not be retried by a retry/redelivery filter defined prior to the None filter.

How to use PersistentUnorderedMap on NEAR contract using AssemblyScript? PersistentUnorderedMap does not appear in Contract Storage after init

In my contract I am attempting to use PersistentMap and PersistentUnorderedMap.
In my class I'm doing the following:
import { PersistentMap, PersistentUnorderedMap } from "near-sdk-core";
public vehicleOwners: PersistentMap<AccountId, VehicleOwner>;
public vehicleOwnersPmap: PersistentUnorderedMap<AccountId, VehicleOwner>;
constructor(public vehicle:string = 'Mini') {
this.vehicleOwners = new PersistentMap<AccountId, VehicleOwner>("vo"),
this.vehicleOwnersPmap = new PersistentUnorderedMap<AccountId,VehicleOwner>("pma")
}
// Model
#nearBindgen
class VehicleOwner {
constructor(public vehicleOwner: AccountId, public dateAcquired: string) {}
}
After running the init method near call $CONTRACT init --accountId $CONTRACT
If I check the contract's storage I see vehicleOwners but I do not see vehicleOwnersPmap.
state: {
"vehicle": "Mini",
"vehicleOwners": {
"_elementPrefix": "vo::"
}
}
I figured out that after running one transaction and then seeing storage I can now see in state the PersistentUnorderedMap instance variable being set to null. I am still not sure why it won't show after init. This is different from PersistentMap where you can see it on state after init.
state: {
"vehicle": "Mini",
"vehicleOwnersPmap": null,
"vehicleOwners": {
"_elementPrefix": "vo::"
}
}

How to start GraphQL server when running .net5 integration tests?

I believe I am missing/misunderstanding something fundamental about the way .net5 works. In setting up an integration test environment for my GraphQL API, I am missing the step on how to start the GraphQL server from said test environment.
When I run the main project, the server is started properly and I can navigate to localhost in the browser and successfully execute GraphQL queries/mutations. My goal here is to set up some automated integration tests.
I'm using NUnit as my test runner and am using WebApplicationFactory<Startup> to "start the server" as I understand it.
In my test project, I'm under the impression that WebApplicationFactory<Startup> is supposed to basically use the Startup.cs class from my main project in my test project so that I don't have to duplicate all the settings, configurations, and injected services. Please correct me if that assumption is not correct.
I've pasted the code I think is relevant.
ApiWebApplicationFactory<Startup>
public class ApiWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
{
public static IConfigurationRoot Configuration { get; set; }
public ApiWebApplicationFactory()
{
var configBuilder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
Configuration = configBuilder.Build();
}
protected override void ConfigureClient(HttpClient client)
{
base.ConfigureClient(client);
client.BaseAddress = new Uri("https://localhost");
client.Timeout = new TimeSpan(0, 10, 0);
}
// Based on my assumption this class reuses everything in the Startup.cs class
// I don't actually think this is necessary, but thought it was worth trying
// the test with and without this code.
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.AddType<GraphQLContentItem>()
.AddType<GraphQLFolder>();
});
}
}
OneTimesetUp
[OneTimeSetUp]
public void OneTimeSetUp()
{
_factory = new ApiWebApplicationFactory<Startup>();
_client = _factory.WithWebHostBuilder(builder =>
{
builder.ConfigureServices(services =>
{
services.AddScoped<ICacheRepository, MockCache>();
});
}).CreateClient();
var connString = ApiWebApplicationFactory<Startup>.Configuration.GetConnectionString("DefaultConnection");
var options = new DbContextOptionsBuilder<CmsContext>()
.UseMySql(connString, ServerVersion.AutoDetect(connString))
.Options;
_dbContext = new CmsContext(options);
_dbContext.Database.EnsureCreated();
}
Test
[Test]
public async Task Test()
{
// If I set a breakpoint here, I can't navigate to the URL like I'm expecting to
var graphQLHttpClient =
new GraphQLHttpClient(
new GraphQLHttpClientOptions { EndPoint = new Uri("https://localhost/graphql") },
new NewtonsoftJsonSerializer(),
_client);
var request = new GraphQLRequest
{
Query = #"
query GetCurrentSession() {
getCurrentSession() {
id
name
}
}",
OperationName = "GetCurrentSession"
};
// Error is thrown here with "Bad Request"
var response = await graphQLHttpClient.SendQueryAsync<Session>(request);
// Further code is omitted
}
Please let me know if you see what I am missing. Thanks in advance~

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. (.net core 5)

I use .net 5 web api to create my application.
I put [Authorize] top of my controller.
I use Identityserver4 as auth-server.(localhost:5000)
and here is my startup.cs class:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<MyContext>(opts =>
opts.UseInMemoryDatabase("MyDb"));
services.AddAuthentication("bearer")
.AddIdentityServerAuthentication(opts =>
{
opts.Authority = "http://locallhost:5000";
opts.RequireHttpsMetadata = false;
opts.ApiName = "myApi";
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "CustomerApi", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CustomerApi v1"));
}
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
but I get below error:
error
please guide me to resolve my problem.
I search much time but the answers is for .net 3.1 .
Your code is ok.
but you should write:
services.AddAuthentication("Bearer")
instead of
services.AddAuthentication("bearer")
After that you might run correctly.
I typically have this setup:
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
I would also not use AddIdentityServerAuthentication (Used by older version of IdentityServer) and instead focus on using AddJwtBearer method instead. See the documentation here

How/where do I register the IDbPerTenantConnectionStringResolver

Trying to run core api host. i have this in the EntityFrameworkModule
public override void PreInitialize()
{
Configuration.MultiTenancy.IsEnabled = true;`
// CONNECTION STRING RESOLVER
Configuration.ReplaceService<IConnectionStringResolver, DbPerTenantConnectionStringResolver>(DependencyLifeStyle.Transient);
Configuration.DefaultNameOrConnectionString = MyConsts.DefaultConnectionStringName;
if (!SkipDbContextRegistration)
{
//DEFAULT
Configuration.Modules.AbpEfCore().AddDbContext<MyContext>(options =>
{
if (options.ExistingConnection != null)
MyContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
else
MyContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
});
}
}
ERROR
Mvc.ExceptionHandling.AbpExceptionFilter - Can't create component 'Ccre.EntityFrameworkCore.AbpZeroDbMigrator' as it has dependencies to be satisfied.
'Ccre.EntityFrameworkCore.AbpZeroDbMigrator' is waiting for the following dependencies:
- Service 'Abp.MultiTenancy.IDbPerTenantConnectionStringResolver' which was not registered.
How/where do I register the IDbPerTenantConnectionStringResolver?
I have this line in the PreInitialize of the Migrator.MigratorModule
Configuration.ReplaceService<IConnectionStringResolver, DbPerTenantConnectionStringResolver>(DependencyLifeStyle.Transient);
as well as in the EntityFrameworkModule

Resources