forked from PowerShell/PowerShell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCreateInstanceJob.cs
More file actions
145 lines (130 loc) · 5.7 KB
/
Copy pathCreateInstanceJob.cs
File metadata and controls
145 lines (130 loc) · 5.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using Microsoft.Management.Infrastructure;
using Dbg = System.Management.Automation.Diagnostics;
namespace Microsoft.PowerShell.Cmdletization.Cim
{
/// <summary>
/// Job wrapping invocation of a CreateInstance intrinsic CIM method
/// </summary>
internal class CreateInstanceJob : PropertySettingJob<CimInstance>
{
private CimInstance _resultFromCreateInstance;
private CimInstance _resultFromGetInstance;
private static CimInstance GetEmptyInstance(CimJobContext jobContext)
{
Dbg.Assert(jobContext != null, "Caller should verify jobContext != null");
var result = new CimInstance(jobContext.ClassName, jobContext.Namespace);
return result;
}
internal CreateInstanceJob(CimJobContext jobContext, MethodInvocationInfo methodInvocationInfo)
: base(jobContext, true /* passThru */, GetEmptyInstance(jobContext), methodInvocationInfo)
{
}
private IObservable<CimInstance> GetCreateInstanceOperation()
{
CimInstance instanceToCreate = GetEmptyInstance(JobContext);
ModifyLocalCimInstance(instanceToCreate);
IObservable<CimInstance> observable = this.JobContext.Session.CreateInstanceAsync(
this.JobContext.Namespace,
instanceToCreate,
this.CreateOperationOptions());
return observable;
}
private IObservable<CimInstance> GetGetInstanceOperation()
{
Dbg.Assert(_resultFromCreateInstance != null, "GetInstance should only be called after CreteInstance came back with a keyed instance");
IObservable<CimInstance> observable = this.JobContext.Session.GetInstanceAsync(
this.JobContext.Namespace,
_resultFromCreateInstance,
this.CreateOperationOptions());
return observable;
}
#if DEBUG
private bool _createInstanceOperationGotStarted;
private bool _getInstanceOperationGotStarted;
#endif
internal override IObservable<CimInstance> GetCimOperation()
{
if (_resultFromCreateInstance == null)
{
if (!this.ShouldProcess())
{
return null;
}
#if DEBUG
Dbg.Assert(_getInstanceOperationGotStarted == false, "CreateInstance should be started *before* GetInstance");
Dbg.Assert(_createInstanceOperationGotStarted == false, "Should not start CreateInstance operation twice");
_createInstanceOperationGotStarted = true;
#endif
return GetCreateInstanceOperation();
}
else
{
#if DEBUG
Dbg.Assert(_createInstanceOperationGotStarted == true, "GetInstance should be started *after* CreateInstance");
Dbg.Assert(_getInstanceOperationGotStarted == false, "Should not start GetInstance operation twice");
Dbg.Assert(_resultFromGetInstance == null, "GetInstance operation shouldn't happen twice");
_getInstanceOperationGotStarted = true;
#endif
return GetGetInstanceOperation();
}
}
public override void OnNext(CimInstance item)
{
Dbg.Assert(item != null, "CreateInstance and GetInstance should never return null");
if (_resultFromCreateInstance == null)
{
_resultFromCreateInstance = item;
}
else
{
Dbg.Assert(_resultFromGetInstance == null, "GetInstance operation shouldn't happen twice");
_resultFromGetInstance = item;
}
}
public override void OnError(Exception exception)
{
if (this.DidUserSuppressTheOperation)
{
// If user suppressed CreateInstance operation, then no instance should be returned by the cmdlet
// If the provider's CreateInstance implementation doesn't post an instance and returns a success, then WMI infra will error out to flag an incorrect implementation of CreateInstance (by design)
// Therefore cmdletization layer has to suppress the error and treat this as normal/successful completion
this.OnCompleted();
}
else
{
base.OnError(exception);
}
}
public override void OnCompleted()
{
Dbg.Assert(this.DidUserSuppressTheOperation || (_resultFromCreateInstance != null), "OnNext should always be called before OnComplete by CreateInstance");
#if DEBUG
Dbg.Assert(
!_getInstanceOperationGotStarted || this.DidUserSuppressTheOperation || (_resultFromGetInstance != null),
// <=> (this._getInstanceOperationGotStarted => (this._resultFromGetInstance != null))
"GetInstance should cause OnNext to be called which should set this._resultFromGetInstance to non-null");
#endif
if (this.IsPassThruObjectNeeded() && (_resultFromGetInstance == null))
{
IObservable<CimInstance> observable = this.GetGetInstanceOperation();
observable.Subscribe(this);
return;
}
else
{
base.OnCompleted();
}
}
internal override object PassThruObject
{
get
{
return _resultFromGetInstance;
}
}
}
}