Skip to content

Commit 5a27b2e

Browse files
kishoreallwynrajTim Hess
authored andcommitted
Oracle DB Connector (#84)
* Added connector classes for Oracle and associated health checks with unit tests.
1 parent 1e2d275 commit 5a27b2e

34 files changed

Lines changed: 1906 additions & 1 deletion

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2017 the original author or authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using Autofac;
16+
using Autofac.Builder;
17+
using Microsoft.Extensions.Configuration;
18+
using Steeltoe.CloudFoundry.Connector.Oracle;
19+
using Steeltoe.CloudFoundry.Connector.Services;
20+
using System;
21+
22+
namespace Steeltoe.CloudFoundry.Connector.EF6Autofac
23+
{
24+
public static class OracleDbContextContainerBuilderExtensions
25+
{
26+
/// <summary>
27+
/// Add your Oracle-based DbContext to the ContainerBuilder
28+
/// </summary>
29+
/// <typeparam name="TContext">Your DbContext</typeparam>
30+
/// <param name="container">Autofac <see cref="ContainerBuilder" /></param>
31+
/// <param name="config">Your app config</param>
32+
/// <param name="serviceName">Name of service instance</param>
33+
/// <returns><see cref="IRegistrationBuilder{TLimit, TActivatorData, TRegistrationStyle}"/></returns>
34+
public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrationStyle> RegisterDbContext<TContext>(this ContainerBuilder container, IConfiguration config, string serviceName = null)
35+
{
36+
if (container == null)
37+
{
38+
throw new ArgumentNullException(nameof(container));
39+
}
40+
41+
if (config == null)
42+
{
43+
throw new ArgumentNullException(nameof(config));
44+
}
45+
46+
OracleServiceInfo info = serviceName == null
47+
? config.GetSingletonServiceInfo<OracleServiceInfo>()
48+
: config.GetRequiredServiceInfo<OracleServiceInfo>(serviceName);
49+
50+
var oracleConfig = new OracleProviderConnectorOptions(config);
51+
var factory = new OracleProviderConnectorFactory(info, oracleConfig, typeof(TContext));
52+
return container.Register(c => factory.Create(null)).As<TContext>();
53+
}
54+
}
55+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2017 the original author or authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using Microsoft.Extensions.Configuration;
16+
using Microsoft.Extensions.DependencyInjection;
17+
using Microsoft.Extensions.Logging;
18+
using Steeltoe.CloudFoundry.Connector.Oracle;
19+
using Steeltoe.CloudFoundry.Connector.Oracle.EF6;
20+
using Steeltoe.CloudFoundry.Connector.Services;
21+
using System;
22+
23+
namespace Steeltoe.CloudFoundry.Connector.EF6Core
24+
{
25+
public static class OracleDbContextServiceCollectionExtensions
26+
{
27+
/// <summary>
28+
/// Add a Oracle-backed DbContext and Oracle health contributor to the Service Collection
29+
/// </summary>
30+
/// <typeparam name="TContext">Type of DbContext to add</typeparam>
31+
/// <param name="services">Service Collection</param>
32+
/// <param name="config">Application Configuration</param>
33+
/// <param name="contextLifetime">Lifetime of the service to inject</param>
34+
/// <param name="logFactory">logging factory</param>
35+
/// <returns>IServiceCollection for chaining</returns>
36+
public static IServiceCollection AddDbContext<TContext>(this IServiceCollection services, IConfiguration config, ServiceLifetime contextLifetime = ServiceLifetime.Scoped, ILoggerFactory logFactory = null)
37+
{
38+
if (services == null)
39+
{
40+
throw new ArgumentNullException(nameof(services));
41+
}
42+
43+
if (config == null)
44+
{
45+
throw new ArgumentNullException(nameof(config));
46+
}
47+
48+
OracleServiceInfo info = config.GetSingletonServiceInfo<OracleServiceInfo>();
49+
DoAdd(services, config, info, typeof(TContext), contextLifetime);
50+
51+
return services;
52+
}
53+
54+
/// <summary>
55+
/// Add a Oracle-backed DbContext and Oracle health contributor to the Service Collection
56+
/// </summary>
57+
/// <typeparam name="TContext">Type of DbContext to add</typeparam>
58+
/// <param name="services">Service Collection</param>
59+
/// <param name="config">Application Configuration</param>
60+
/// <param name="serviceName">Name of service binding in Cloud Foundry</param>
61+
/// <param name="contextLifetime">Lifetime of the service to inject</param>
62+
/// <param name="logFactory">logging factory</param>
63+
/// <returns>IServiceCollection for chaining</returns>
64+
public static IServiceCollection AddDbContext<TContext>(this IServiceCollection services, IConfiguration config, string serviceName, ServiceLifetime contextLifetime = ServiceLifetime.Scoped, ILoggerFactory logFactory = null)
65+
{
66+
if (services == null)
67+
{
68+
throw new ArgumentNullException(nameof(services));
69+
}
70+
71+
if (string.IsNullOrEmpty(serviceName))
72+
{
73+
throw new ArgumentNullException(nameof(serviceName));
74+
}
75+
76+
if (config == null)
77+
{
78+
throw new ArgumentNullException(nameof(config));
79+
}
80+
81+
OracleServiceInfo info = config.GetRequiredServiceInfo<OracleServiceInfo>(serviceName);
82+
DoAdd(services, config, info, typeof(TContext), contextLifetime);
83+
84+
return services;
85+
}
86+
87+
private static void DoAdd(IServiceCollection services, IConfiguration config, OracleServiceInfo info, Type dbContextType, ServiceLifetime contextLifetime)
88+
{
89+
OracleProviderConnectorOptions oracleConfig = new OracleProviderConnectorOptions(config);
90+
91+
OracleDbContextConnectorFactory factory = new OracleDbContextConnectorFactory(info, oracleConfig, dbContextType);
92+
services.Add(new ServiceDescriptor(dbContextType, factory.Create, contextLifetime));
93+
}
94+
}
95+
}

src/Connectors/src/Connector.EFCore/EntityFrameworkCoreTypeLocator.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,21 @@ public static class EntityFrameworkCoreTypeLocator
6868
/// </summary>
6969
/// <exception cref="ConnectorException">When type is not found</exception>
7070
public static Type SqlServerDbContextOptionsType => ConnectorHelpers.FindTypeOrThrow(SqlServerEntityAssemblies, SqlServerEntityTypeNames, "DbContextOptionsBuilder", "a Microsoft SQL Server EntityFramework Core assembly");
71+
72+
/// <summary>
73+
/// Gets a list of supported Oracle Entity Framework Core Assemblies
74+
/// </summary>
75+
public static string[] OracleEntityAssemblies { get; internal set; } = new string[] { "Oracle.EntityFrameworkCore", "Devart.Data.Oracle.EFCore" };
76+
77+
/// <summary>
78+
/// Gets a list of supported fully-qualifed names for compatible DbContextOptionsExtentions used to configure EntityFrameworkCore
79+
/// </summary>
80+
public static string[] OracleEntityTypeNames { get; internal set; } = new string[] { "Microsoft.EntityFrameworkCore.OracleDbContextOptionsExtensions", "Devart.Data.Oracle.Entity.OracleOptionsExtension" };
81+
82+
/// <summary>
83+
/// Gets the type used to configure EntityFramework Core with Oracle
84+
/// </summary>
85+
/// <exception cref="ConnectorException">When type is not found</exception>
86+
public static Type OracleDbContextOptionsType => ConnectorHelpers.FindTypeOrThrow(OracleEntityAssemblies, OracleEntityTypeNames, "DbContextOptionsBuilder", "a Oracle EntityFramework Core assembly");
7187
}
7288
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Copyright 2017 the original author or authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using Microsoft.EntityFrameworkCore;
16+
using Microsoft.Extensions.Configuration;
17+
using Steeltoe.CloudFoundry.Connector.EFCore;
18+
using Steeltoe.CloudFoundry.Connector.Services;
19+
using System;
20+
using System.Reflection;
21+
22+
namespace Steeltoe.CloudFoundry.Connector.Oracle.EFCore
23+
{
24+
public static class OracleDbContextOptionsExtensions
25+
{
26+
public static DbContextOptionsBuilder UseOracle(this DbContextOptionsBuilder optionsBuilder, IConfiguration config, object oracleOptionsAction = null)
27+
{
28+
if (optionsBuilder == null)
29+
{
30+
throw new ArgumentNullException(nameof(optionsBuilder));
31+
}
32+
33+
if (config == null)
34+
{
35+
throw new ArgumentNullException(nameof(config));
36+
}
37+
38+
var connection = GetConnection(config);
39+
40+
return DoUseOracle(optionsBuilder, connection, oracleOptionsAction);
41+
}
42+
43+
public static DbContextOptionsBuilder UseOracle(this DbContextOptionsBuilder optionsBuilder, IConfiguration config, string serviceName, object oracleOptionsAction = null)
44+
{
45+
if (optionsBuilder == null)
46+
{
47+
throw new ArgumentNullException(nameof(optionsBuilder));
48+
}
49+
50+
if (config == null)
51+
{
52+
throw new ArgumentNullException(nameof(config));
53+
}
54+
55+
if (string.IsNullOrEmpty(serviceName))
56+
{
57+
throw new ArgumentException(nameof(serviceName));
58+
}
59+
60+
var connection = GetConnection(config, serviceName);
61+
62+
return DoUseOracle(optionsBuilder, connection, oracleOptionsAction);
63+
}
64+
65+
public static DbContextOptionsBuilder<TContext> UseOracle<TContext>(this DbContextOptionsBuilder<TContext> optionsBuilder, IConfiguration config, object oracleOptionsAction = null)
66+
where TContext : DbContext
67+
{
68+
if (optionsBuilder == null)
69+
{
70+
throw new ArgumentNullException(nameof(optionsBuilder));
71+
}
72+
73+
if (config == null)
74+
{
75+
throw new ArgumentNullException(nameof(config));
76+
}
77+
78+
var connection = GetConnection(config);
79+
80+
return DoUseOracle<TContext>(optionsBuilder, connection, oracleOptionsAction);
81+
}
82+
83+
public static DbContextOptionsBuilder<TContext> UseOracle<TContext>(this DbContextOptionsBuilder<TContext> optionsBuilder, IConfiguration config, string serviceName, object oracleOptionsAction = null)
84+
where TContext : DbContext
85+
{
86+
if (optionsBuilder == null)
87+
{
88+
throw new ArgumentNullException(nameof(optionsBuilder));
89+
}
90+
91+
if (config == null)
92+
{
93+
throw new ArgumentNullException(nameof(config));
94+
}
95+
96+
if (string.IsNullOrEmpty(serviceName))
97+
{
98+
throw new ArgumentException(nameof(serviceName));
99+
}
100+
101+
var connection = GetConnection(config, serviceName);
102+
103+
return DoUseOracle<TContext>(optionsBuilder, connection, oracleOptionsAction);
104+
}
105+
106+
private static DbContextOptionsBuilder DoUseOracle(DbContextOptionsBuilder optionsBuilder, object connection, object oracleOptionsAction)
107+
{
108+
Type extensionType = EntityFrameworkCoreTypeLocator.OracleDbContextOptionsType;
109+
110+
MethodInfo useMethod = FindUseSqlMethod(extensionType, new Type[] { typeof(DbContextOptionsBuilder), typeof(string) });
111+
if (extensionType == null)
112+
{
113+
throw new ConnectorException("Unable to find UseOracle extension, are you missing Oracle EntityFramework Core assembly");
114+
}
115+
116+
object result = ConnectorHelpers.Invoke(useMethod, null, new object[] { optionsBuilder, connection, oracleOptionsAction });
117+
if (result == null)
118+
{
119+
throw new ConnectorException(string.Format("Failed to invoke UseOracle extension, connection: {0}", connection));
120+
}
121+
122+
return (DbContextOptionsBuilder)result;
123+
}
124+
125+
private static DbContextOptionsBuilder<TContext> DoUseOracle<TContext>(DbContextOptionsBuilder<TContext> optionsBuilder, string connection, object oracleOptionsAction = null)
126+
where TContext : DbContext
127+
{
128+
return (DbContextOptionsBuilder<TContext>)DoUseOracle((DbContextOptionsBuilder)optionsBuilder, connection, oracleOptionsAction);
129+
}
130+
131+
private static MethodInfo FindUseSqlMethod(Type type, Type[] parameterTypes)
132+
{
133+
var typeInfo = type.GetTypeInfo();
134+
var declaredMethods = typeInfo.DeclaredMethods;
135+
136+
foreach (MethodInfo ci in declaredMethods)
137+
{
138+
var parameters = ci.GetParameters();
139+
if (parameters.Length == 3 &&
140+
ci.Name.Equals("UseOracle", StringComparison.InvariantCultureIgnoreCase) &&
141+
parameters[0].ParameterType.Equals(parameterTypes[0]) &&
142+
parameters[1].ParameterType.Equals(parameterTypes[1]) &&
143+
ci.IsPublic && ci.IsStatic)
144+
{
145+
return ci;
146+
}
147+
}
148+
149+
return null;
150+
}
151+
152+
private static string GetConnection(IConfiguration config, string serviceName = null)
153+
{
154+
OracleServiceInfo info = string.IsNullOrEmpty(serviceName)
155+
? config.GetSingletonServiceInfo<OracleServiceInfo>()
156+
: config.GetRequiredServiceInfo<OracleServiceInfo>(serviceName);
157+
158+
OracleProviderConnectorOptions oracleConfig = new OracleProviderConnectorOptions(config);
159+
160+
OracleProviderConnectorFactory factory = new OracleProviderConnectorFactory(info, oracleConfig, null);
161+
162+
return factory.CreateConnectionString();
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)